mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2025-12-13 01:36:22 +00:00
committed by
Rainer Killinger
parent
a8c7d5ab59
commit
8cd2d777ab
@@ -31,6 +31,7 @@ import {RouterTestingModule} from '@angular/router/testing';
|
||||
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
|
||||
import {sampleAuthConfiguration} from './_helpers/data/sample-configuration';
|
||||
import {StorageProvider} from './modules/storage/storage.provider';
|
||||
import {SimpleBrowser} from './util/browser.factory';
|
||||
|
||||
describe('AppComponent', () => {
|
||||
let platformReadySpy: any;
|
||||
@@ -43,6 +44,7 @@ describe('AppComponent', () => {
|
||||
let scheduleSyncServiceSpy: jasmine.SpyObj<ScheduleSyncService>;
|
||||
let platformIsSpy;
|
||||
let storageProvider: jasmine.SpyObj<StorageProvider>;
|
||||
let simpleBrowser: jasmine.SpyObj<SimpleBrowser>;
|
||||
|
||||
beforeEach(() => {
|
||||
platformReadySpy = Promise.resolve();
|
||||
@@ -68,6 +70,7 @@ describe('AppComponent', () => {
|
||||
});
|
||||
ngxLogger = jasmine.createSpyObj('NGXLogger', ['log', 'error', 'warn']);
|
||||
storageProvider = jasmine.createSpyObj('StorageProvider', ['init', 'get', 'has', 'put']);
|
||||
simpleBrowser = jasmine.createSpyObj('SimpleBrowser', ['open']);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [RouterTestingModule.withRoutes([]), HttpClientTestingModule, AuthModule],
|
||||
@@ -81,6 +84,7 @@ describe('AppComponent', () => {
|
||||
{provide: ConfigProvider, useValue: configProvider},
|
||||
{provide: NGXLogger, useValue: ngxLogger},
|
||||
{provide: StorageProvider, useValue: storageProvider},
|
||||
{provide: SimpleBrowser, useValue: simpleBrowser},
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
}).compileComponents();
|
||||
|
||||
@@ -51,7 +51,6 @@ import {FavoritesModule} from './modules/favorites/favorites.module';
|
||||
import {ProfilePageModule} from './modules/profile/profile.module';
|
||||
import {FeedbackModule} from './modules/feedback/feedback.module';
|
||||
import {DebugDataCollectorService} from './modules/data/debug-data-collector.service';
|
||||
import {Browser, browserFactory} from './util/browser.factory';
|
||||
import {AuthModule} from './modules/auth/auth.module';
|
||||
import {BackgroundModule} from './modules/background/background.module';
|
||||
import {LibraryModule} from './modules/library/library.module';
|
||||
@@ -64,6 +63,7 @@ import {DefaultAuthService} from './modules/auth/default-auth.service';
|
||||
import {PAIAAuthService} from './modules/auth/paia/paia-auth.service';
|
||||
import {IonIconModule} from './util/ion-icon/ion-icon.module';
|
||||
import {NavigationModule} from './modules/menu/navigation/navigation.module';
|
||||
import {browserFactory, SimpleBrowser} from './util/browser.factory';
|
||||
|
||||
registerLocaleData(localeDe);
|
||||
|
||||
@@ -184,7 +184,7 @@ export function createTranslateLoader(http: HttpClient) {
|
||||
useClass: PathLocationStrategy,
|
||||
},
|
||||
{
|
||||
provide: Browser,
|
||||
provide: SimpleBrowser,
|
||||
useFactory: browserFactory,
|
||||
deps: [Platform],
|
||||
},
|
||||
|
||||
@@ -24,6 +24,7 @@ import {PAIAAuthService} from './paia/paia-auth.service';
|
||||
import {LoggerConfig, LoggerModule, NGXLogger} from 'ngx-logger';
|
||||
import {StAppsWebHttpClient} from '../data/stapps-web-http-client.provider';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {SimpleBrowser} from '../../util/browser.factory';
|
||||
|
||||
describe('AuthHelperService', () => {
|
||||
let authHelperService: AuthHelperService;
|
||||
@@ -32,6 +33,7 @@ describe('AuthHelperService', () => {
|
||||
const defaultAuthServiceMock = jasmine.createSpyObj('DefaultAuthService', ['init', 'setupConfiguration']);
|
||||
const paiaAuthServiceMock = jasmine.createSpyObj('PAIAAuthService', ['init', 'setupConfiguration']);
|
||||
const authHelperServiceMock = jasmine.createSpyObj('AuthHelperService', ['constructor']);
|
||||
const simpleBrowserMock = jasmine.createSpyObj('SimpleBrowser', ['open']);
|
||||
const configProvider = jasmine.createSpyObj('ConfigProvider', {
|
||||
getAnyValue: {
|
||||
default: {
|
||||
@@ -84,6 +86,10 @@ describe('AuthHelperService', () => {
|
||||
provider: AuthHelperService,
|
||||
useValue: authHelperServiceMock,
|
||||
},
|
||||
{
|
||||
provide: SimpleBrowser,
|
||||
useValue: simpleBrowserMock,
|
||||
},
|
||||
],
|
||||
});
|
||||
authHelperService = TestBed.inject(AuthHelperService);
|
||||
|
||||
@@ -28,6 +28,7 @@ import {ConfigProvider} from '../config/config.provider';
|
||||
import {StorageProvider} from '../storage/storage.provider';
|
||||
import {DefaultAuthService} from './default-auth.service';
|
||||
import {PAIAAuthService} from './paia/paia-auth.service';
|
||||
import {SimpleBrowser} from '../../util/browser.factory';
|
||||
|
||||
const AUTH_ORIGIN_PATH = 'stapps.auth.origin_path';
|
||||
|
||||
@@ -43,6 +44,7 @@ export class AuthHelperService {
|
||||
private storageProvider: StorageProvider,
|
||||
private defaultAuth: DefaultAuthService,
|
||||
private paiaAuth: PAIAAuthService,
|
||||
private browser: SimpleBrowser,
|
||||
) {
|
||||
this.userConfigurationMap = (
|
||||
this.configProvider.getAnyValue('auth') as {
|
||||
@@ -113,4 +115,14 @@ export class AuthHelperService {
|
||||
? (this.paiaAuth as PAIAAuthService)
|
||||
: (this.defaultAuth as DefaultAuthService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends browser session by opening endSessionEndpoint URL of the provider
|
||||
*/
|
||||
async endBrowserSession(providerType: SCAuthorizationProviderType) {
|
||||
const endSessionEndpoint = (await this.getProvider(providerType).configuration).endSessionEndpoint ?? '';
|
||||
if (endSessionEndpoint.length > 0) {
|
||||
this.browser.open(new URL(endSessionEndpoint).href);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 StApps
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {Platform} from '@ionic/angular';
|
||||
import {DefaultBrowser} from 'ionic-appauth';
|
||||
import {CapacitorBrowser} from 'ionic-appauth/lib/capacitor';
|
||||
|
||||
export const browserFactory = (platform: Platform) => {
|
||||
return platform.is('capacitor') ? new CapacitorBrowser() : new DefaultBrowser();
|
||||
};
|
||||
@@ -1,2 +1 @@
|
||||
export * from './browser.factory';
|
||||
export * from './storage.factory';
|
||||
|
||||
@@ -17,7 +17,7 @@ import {CommonModule} from '@angular/common';
|
||||
import {HttpClientModule} from '@angular/common/http';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {FormsModule} from '@angular/forms';
|
||||
import {IonicModule} from '@ionic/angular';
|
||||
import {IonicModule, Platform} from '@ionic/angular';
|
||||
import {TranslateModule} from '@ngx-translate/core';
|
||||
import {MarkdownModule} from 'ngx-markdown';
|
||||
import {MomentModule} from 'ngx-moment';
|
||||
@@ -98,6 +98,7 @@ import {PeriodicalDetailContentComponent} from './types/periodical/periodical-de
|
||||
import {SCThingListItemVirtualScrollStrategyDirective} from './list/sc-thing-list-item-virtual-scroll-strategy.directive';
|
||||
import {DataListItemHostDirective} from './list/data-list-item-host.directive';
|
||||
import {DataListItemHostDefaultComponent} from './list/data-list-item-host-default.component';
|
||||
import {browserFactory, SimpleBrowser} from '../../util/browser.factory';
|
||||
|
||||
/**
|
||||
* Module for handling data
|
||||
@@ -199,6 +200,11 @@ import {DataListItemHostDefaultComponent} from './list/data-list-item-host-defau
|
||||
CalendarService,
|
||||
RoutingStackService,
|
||||
SettingsProvider,
|
||||
{
|
||||
provide: SimpleBrowser,
|
||||
useFactory: browserFactory,
|
||||
deps: [Platform],
|
||||
},
|
||||
],
|
||||
exports: [
|
||||
SCThingListItemVirtualScrollStrategyDirective,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {Browser} from '../../../util/browser.factory';
|
||||
import {SimpleBrowser} from '../../../util/browser.factory';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-external-link',
|
||||
@@ -26,7 +26,7 @@ export class ExternalLinkComponent {
|
||||
|
||||
@Input() text: string;
|
||||
|
||||
constructor(private browser: Browser) {}
|
||||
constructor(private browser: SimpleBrowser) {}
|
||||
|
||||
onLinkClick(url: string) {
|
||||
// make sure if the url is valid and then open it in the browser (prevent problem in iOS)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
*/
|
||||
import {Component, Input} from '@angular/core';
|
||||
import {SCMessage} from '@openstapps/core';
|
||||
import {Browser} from '../../../../util/browser.factory';
|
||||
import {SimpleBrowser} from '../../../../util/browser.factory';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@@ -25,7 +25,7 @@ import {Browser} from '../../../../util/browser.factory';
|
||||
styleUrls: ['message-detail-content.scss'],
|
||||
})
|
||||
export class MessageDetailContentComponent {
|
||||
constructor(private browser: Browser) {}
|
||||
constructor(private browser: SimpleBrowser) {}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
|
||||
@@ -19,6 +19,8 @@ import {AuthHelperService} from '../../auth/auth-helper.service';
|
||||
import {Observable, Subscription} from 'rxjs';
|
||||
import {SCAuthorizationProviderType} from '@openstapps/core';
|
||||
import Swiper from 'swiper';
|
||||
import {AlertController} from '@ionic/angular';
|
||||
import {TranslateService} from '@ngx-translate/core';
|
||||
|
||||
@Component({
|
||||
selector: 'stapps-profile-page-section',
|
||||
@@ -53,7 +55,11 @@ export class ProfilePageSectionComponent implements OnInit, OnDestroy {
|
||||
},
|
||||
};
|
||||
|
||||
constructor(private authHelper: AuthHelperService) {}
|
||||
constructor(
|
||||
private authHelper: AuthHelperService,
|
||||
private alertController: AlertController,
|
||||
private translateService: TranslateService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (this.item.authProvider) {
|
||||
@@ -94,6 +100,27 @@ export class ProfilePageSectionComponent implements OnInit, OnDestroy {
|
||||
|
||||
async signOut(providerType: SCAuthorizationProviderType) {
|
||||
await this.authHelper.getProvider(providerType).signOut();
|
||||
|
||||
const alert: HTMLIonAlertElement = await this.alertController.create({
|
||||
header: this.translateService.instant(`auth.messages.${providerType}.log_out_alert.header`),
|
||||
message: this.translateService.instant(`auth.messages.${providerType}.log_out_alert.message`),
|
||||
buttons: [
|
||||
{
|
||||
text: this.translateService.instant('no'),
|
||||
cssClass: 'default',
|
||||
},
|
||||
{
|
||||
text: this.translateService.instant('yes'),
|
||||
role: 'confirm',
|
||||
cssClass: 'preferred',
|
||||
handler: () => {
|
||||
this.authHelper.endBrowserSession(providerType);
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await alert.present();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
|
||||
@@ -26,16 +26,19 @@ import {StorageProvider} from '../../storage/storage.provider';
|
||||
import {ScheduleProvider} from '../../calendar/schedule.provider';
|
||||
import {DataProvider} from '../../data/data.provider';
|
||||
import {StAppsWebHttpClient} from '../../data/stapps-web-http-client.provider';
|
||||
import {SimpleBrowser} from '../../../util/browser.factory';
|
||||
|
||||
describe('ProfilePage', () => {
|
||||
let component: ProfilePageComponent;
|
||||
let fixture: ComponentFixture<ProfilePageComponent>;
|
||||
let configProvider: ConfigProvider;
|
||||
let storageProvider: jasmine.SpyObj<StorageProvider>;
|
||||
let simpleBrowser: jasmine.SpyObj<SimpleBrowser>;
|
||||
|
||||
beforeEach(() => {
|
||||
configProvider = jasmine.createSpyObj('ConfigProvider', ['init', 'getAnyValue']);
|
||||
storageProvider = jasmine.createSpyObj('StorageProvider', ['init', 'get', 'has', 'put']);
|
||||
simpleBrowser = jasmine.createSpyObj('SimpleBrowser', ['open']);
|
||||
configProvider.getAnyValue = jasmine.createSpy().and.callFake(function () {
|
||||
return sampleAuthConfiguration;
|
||||
});
|
||||
@@ -49,6 +52,7 @@ describe('ProfilePage', () => {
|
||||
{provide: ConfigProvider, useValue: configProvider},
|
||||
{provide: StorageProvider, useValue: storageProvider},
|
||||
{provide: StAppsWebHttpClient, useValue: webHttpClientMethodSpy},
|
||||
{provide: SimpleBrowser, useValue: simpleBrowser},
|
||||
ScheduleProvider,
|
||||
DataProvider,
|
||||
],
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
import {Platform} from '@ionic/angular';
|
||||
import {Browser as BrowserPlugin} from '@capacitor/browser';
|
||||
|
||||
export abstract class Browser {
|
||||
export abstract class SimpleBrowser {
|
||||
abstract open(url: string): Promise<void> | void;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"ok": "Ok",
|
||||
"yes": "Ja",
|
||||
"no": "Nein",
|
||||
"abort": "Abbrechen",
|
||||
"save": "Speichern",
|
||||
"back": "Zurück",
|
||||
@@ -45,12 +47,20 @@
|
||||
"default": {
|
||||
"authorizing": "Autorisierung läuft...",
|
||||
"logged_in_success": "Erfolgreich eingeloggt.",
|
||||
"logged_out_success": "Erfolgreich ausgeloggt."
|
||||
"logged_out_success": "Erfolgreich ausgeloggt.",
|
||||
"log_out_alert": {
|
||||
"header": "Komplett ausloggen",
|
||||
"message": "Du wurdest innerhalb der App ausgeloggt. Soll zudem die Browser Session beendet werden? Wähle im Zweifelsfall \"Ja\"."
|
||||
}
|
||||
},
|
||||
"paia": {
|
||||
"authorizing": "Autorisierung (Bibliothek) läuft...",
|
||||
"logged_in_success": "Erfolgreich ins Bibliothekskonto eingeloggt.",
|
||||
"logged_out_success": "Erfolgreich aus dem Bibliothekskonto ausgeloggt."
|
||||
"logged_out_success": "Erfolgreich aus dem Bibliothekskonto ausgeloggt.",
|
||||
"log_out_alert": {
|
||||
"header": "Ausgeloggt...",
|
||||
"message": "Du wurdest aus der App ausgeloggt. Möchtest du Dich dazu vom Identitätsanbieter der Bibliothek in Deinem Browser ausloggen? Falls unsicher, bitte wähle \"Ja\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"ok": "Ok",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"abort": "Abort",
|
||||
"save": "Save",
|
||||
"back": "back",
|
||||
@@ -45,12 +47,20 @@
|
||||
"default": {
|
||||
"authorizing": "Authorizing...",
|
||||
"logged_in_success": "Successfully logged in.",
|
||||
"logged_out_success": "Successfully logged out."
|
||||
"logged_out_success": "Successfully logged out.",
|
||||
"log_out_alert": {
|
||||
"header": "Complete logout",
|
||||
"message": "You are now logged out in your app. Do you want to log out from your identity provider as well? If unsure, please choose \"Yes\"."
|
||||
}
|
||||
},
|
||||
"paia": {
|
||||
"authorizing": "Authorizing (library)...",
|
||||
"logged_in_success": "Successfully logged in to library.",
|
||||
"logged_out_success": "Successfully logged out from library."
|
||||
"logged_out_success": "Successfully logged out from library.",
|
||||
"log_out_alert": {
|
||||
"header": "Logged out...",
|
||||
"message": "You are now logged out within the app. Do you also want to end the browser session? If in doubt, choose \"Yes\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -127,3 +127,14 @@ ion-header {
|
||||
.ion-content-parallax {
|
||||
@include ion-content-parallax();
|
||||
}
|
||||
|
||||
ion-alert {
|
||||
button.alert-button.preferred {
|
||||
background-color: var(--ion-color-primary);
|
||||
color: var(--ion-color-primary-contrast);
|
||||
}
|
||||
button.alert-button.default {
|
||||
background-color: transparent;
|
||||
color: var(--ion-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user