From b7ae2cf019661521c791d144e10df7d940e64b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jovan=20Kruni=C4=87?= Date: Fri, 13 May 2022 09:05:33 +0000 Subject: [PATCH] Resolve "Auth providers should be ready on components init" --- cypress.json | 5 +- src/app/app.component.ts | 6 +- src/app/app.module.ts | 8 +++ src/app/modules/auth/auth.module.ts | 19 ++---- ...th.factory.ts => auth.provider.methods.ts} | 62 +++---------------- src/app/modules/auth/default-auth.service.ts | 18 ++++++ src/app/modules/auth/factories/index.ts | 1 - .../modules/auth/paia/paia-auth.service.ts | 26 ++++++-- src/app/modules/calendar/ical/ical.ts | 6 +- .../menu/navigation/navigation.component.ts | 20 +++--- .../modules/menu/navigation/navigation.html | 2 +- 11 files changed, 77 insertions(+), 96 deletions(-) rename src/app/modules/auth/{factories/auth.factory.ts => auth.provider.methods.ts} (61%) diff --git a/cypress.json b/cypress.json index bd321dcb..7c09149f 100644 --- a/cypress.json +++ b/cypress.json @@ -5,5 +5,6 @@ "screenshotsFolder": "cypress/screenshots", "pluginsFile": "cypress/plugins/index.ts", "fixturesFolder": "cypress/fixtures", - "baseUrl": "http://localhost:4200" -} \ No newline at end of file + "baseUrl": "http://localhost:4200", + "defaultCommandTimeout": 10000 +} diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2a43b6f6..c82c61e0 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -89,7 +89,7 @@ export class AppComponent implements AfterContentInit { if (Capacitor.isNativePlatform()) { await StatusBar.setStyle({style: Style.Dark}); } - await this.authInit(); + await this.authNotificationsInit(); // set order of categories in settings this.settingsProvider.setCategoriesOrder([ @@ -101,9 +101,7 @@ export class AppComponent implements AfterContentInit { }); } - private async authInit() { - await this.authHelper.getProvider('default').init(); - await this.authHelper.getProvider('paia').init(); + private async authNotificationsInit() { this.authHelper .getProvider('default') .events$.subscribe(action => diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 8c2224c6..05d442f7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -66,6 +66,8 @@ import {StorageProvider} from './modules/storage/storage.provider'; import {AssessmentsModule} from './modules/assessments/assessments.module'; import {RoutingStackService} from './util/routing-stack.service'; import {SCSettingValue} from '@openstapps/core'; +import {DefaultAuthService} from './modules/auth/default-auth.service'; +import {PAIAAuthService} from './modules/auth/paia/paia-auth.service'; registerLocaleData(localeDe); @@ -86,6 +88,8 @@ export function initializerFactory( configProvider: ConfigProvider, translateService: TranslateService, _routingStackService: RoutingStackService, + defaultAuthService: DefaultAuthService, + paiaAuthService: PAIAAuthService, ) { return async () => { initLogger(logger); @@ -109,6 +113,8 @@ export function initializerFactory( translateService.setDefaultLang('en'); translateService.use(languageCode); moment.locale(languageCode); + await defaultAuthService.init(); + await paiaAuthService.init(); } catch (error) { logger.warn(error); } @@ -196,6 +202,8 @@ export function createTranslateLoader(http: HttpClient) { ConfigProvider, TranslateService, RoutingStackService, + DefaultAuthService, + PAIAAuthService, ], useFactory: initializerFactory, }, diff --git a/src/app/modules/auth/auth.module.ts b/src/app/modules/auth/auth.module.ts index ec2be531..17708add 100644 --- a/src/app/modules/auth/auth.module.ts +++ b/src/app/modules/auth/auth.module.ts @@ -2,18 +2,17 @@ import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {Platform} from '@ionic/angular'; import {Requestor, StorageBackend} from '@openid/appauth'; -import {authFactory, paiaAuthFactory, storageFactory} from './factories'; -import {DefaultAuthService} from './default-auth.service'; +import {storageFactory} from './factories'; import {Browser} from 'ionic-appauth'; import {CapacitorBrowser} from 'ionic-appauth/lib/capacitor'; import {httpFactory} from './factories/http.factory'; import {HttpClient} from '@angular/common/http'; -import {PAIAAuthService} from './paia/paia-auth.service'; import {AuthRoutingModule} from './auth-routing.module'; import {TranslateModule} from '@ngx-translate/core'; -import {ConfigProvider} from '../config/config.provider'; import {AuthCallbackPageComponent} from './auth-callback/page/auth-callback-page.component'; import {PAIAAuthCallbackPageComponent} from './paia/auth-callback/page/paiaauth-callback-page.component'; +import {DefaultAuthService} from './default-auth.service'; +import {PAIAAuthService} from './paia/paia-auth.service'; @NgModule({ declarations: [AuthCallbackPageComponent, PAIAAuthCallbackPageComponent], @@ -33,16 +32,8 @@ import {PAIAAuthCallbackPageComponent} from './paia/auth-callback/page/paiaauth- provide: Browser, useClass: CapacitorBrowser, }, - { - provide: DefaultAuthService, - useFactory: authFactory, - deps: [Requestor, Browser, StorageBackend, ConfigProvider], - }, - { - provide: PAIAAuthService, - useFactory: paiaAuthFactory, - deps: [Requestor, Browser, StorageBackend, ConfigProvider], - }, + DefaultAuthService, + PAIAAuthService, ], }) export class AuthModule {} diff --git a/src/app/modules/auth/factories/auth.factory.ts b/src/app/modules/auth/auth.provider.methods.ts similarity index 61% rename from src/app/modules/auth/factories/auth.factory.ts rename to src/app/modules/auth/auth.provider.methods.ts index 6bb4ad75..0213086d 100644 --- a/src/app/modules/auth/factories/auth.factory.ts +++ b/src/app/modules/auth/auth.provider.methods.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 StApps + * 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. @@ -13,68 +13,20 @@ * this program. If not, see . */ -import { - StorageBackend, - Requestor, - AuthorizationServiceConfiguration, - AuthorizationServiceConfigurationJson, -} from '@openid/appauth'; -import {Browser, IAuthConfig} from 'ionic-appauth'; -import {PAIAAuthService} from '../paia/paia-auth.service'; -import {ConfigProvider} from '../../config/config.provider'; +import {AuthorizationServiceConfigurationJson} from '@openid/appauth'; +import {IAuthConfig} from 'ionic-appauth'; import { SCAuthorizationProvider, SCAuthorizationProviderType, } from '@openstapps/core'; -import {DefaultAuthService} from '../default-auth.service'; import {Capacitor} from '@capacitor/core'; -import {authPaths} from '../auth-paths'; -import {environment} from '../../../../environments/environment'; - -export const authFactory = ( - requestor: Requestor, - browser: Browser, - storage: StorageBackend, - configProvider: ConfigProvider, -) => { - const authService = new DefaultAuthService(browser, storage, requestor); - const authConfig = configProvider.getAnyValue('auth') as { - default: SCAuthorizationProvider; - }; - - authService.authConfig = getClientConfig('default', authConfig); - - authService.localConfiguration = new AuthorizationServiceConfiguration( - getEndpointsConfig('default', authConfig), - ); - - return authService; -}; - -export const paiaAuthFactory = ( - requestor: Requestor, - browser: Browser, - storage: StorageBackend, - configProvider: ConfigProvider, -) => { - const authService = new PAIAAuthService(browser, storage, requestor); - const authConfig = configProvider.getAnyValue('auth') as { - paia: SCAuthorizationProvider; - }; - - authService.authConfig = getClientConfig('paia', authConfig); - - authService.localConfiguration = new AuthorizationServiceConfiguration( - getEndpointsConfig('paia', authConfig), - ); - - return authService; -}; +import {authPaths} from './auth-paths'; +import {environment} from '../../../environments/environment'; /** * Get configuration of an OAuth2 client */ -function getClientConfig( +export function getClientConfig( providerType: SCAuthorizationProviderType, authConfig: { default?: SCAuthorizationProvider; @@ -95,7 +47,7 @@ function getClientConfig( /** * Get configuration about endpoints of an OAuth2 server */ -function getEndpointsConfig( +export function getEndpointsConfig( providerType: SCAuthorizationProviderType, authConfig: { default?: SCAuthorizationProvider; diff --git a/src/app/modules/auth/default-auth.service.ts b/src/app/modules/auth/default-auth.service.ts index ad450bc6..cff00d81 100644 --- a/src/app/modules/auth/default-auth.service.ts +++ b/src/app/modules/auth/default-auth.service.ts @@ -15,9 +15,16 @@ import { AuthService, AuthActionBuilder, } from 'ionic-appauth'; +import {ConfigProvider} from '../config/config.provider'; +import {SCAuthorizationProvider} from '@openstapps/core'; +import {getClientConfig, getEndpointsConfig} from './auth.provider.methods'; +import {Injectable} from '@angular/core'; const TOKEN_RESPONSE_KEY = 'token_response'; +@Injectable({ + providedIn: 'root', +}) export class DefaultAuthService extends AuthService { public localConfiguration: AuthorizationServiceConfiguration; @@ -33,6 +40,7 @@ export class DefaultAuthService extends AuthService { protected browser: Browser = new DefaultBrowser(), protected storage: StorageBackend = new LocalStorageBackend(), protected requestor: Requestor = new JQueryRequestor(), + private readonly configProvider: ConfigProvider, ) { super(browser, storage, requestor); } @@ -44,6 +52,16 @@ export class DefaultAuthService extends AuthService { return Promise.resolve(this.localConfiguration); } + setupConfiguration() { + const authConfig = this.configProvider.getAnyValue('auth') as { + default: SCAuthorizationProvider; + }; + this.authConfig = getClientConfig('default', authConfig); + this.localConfiguration = new AuthorizationServiceConfiguration( + getEndpointsConfig('default', authConfig), + ); + } + public async signOut() { await this.storage.removeItem(TOKEN_RESPONSE_KEY).catch(error => { this.notifyActionListers(AuthActionBuilder.SignOutFailed(error)); diff --git a/src/app/modules/auth/factories/index.ts b/src/app/modules/auth/factories/index.ts index b3f4218f..817c59f5 100644 --- a/src/app/modules/auth/factories/index.ts +++ b/src/app/modules/auth/factories/index.ts @@ -1,3 +1,2 @@ -export * from './auth.factory'; export * from './browser.factory'; export * from './storage.factory'; diff --git a/src/app/modules/auth/paia/paia-auth.service.ts b/src/app/modules/auth/paia/paia-auth.service.ts index b820b0f7..1b84e66b 100644 --- a/src/app/modules/auth/paia/paia-auth.service.ts +++ b/src/app/modules/auth/paia/paia-auth.service.ts @@ -31,6 +31,10 @@ import {PAIAAuthorizationResponse} from './paia-authorization-response'; import {PAIAAuthorizationNotifier} from './paia-authorization-notifier'; import {PAIATokenResponse} from './paia-token-response'; import {IPAIAAuthAction, PAIAAuthActionBuilder} from './paia-auth-action'; +import {SCAuthorizationProvider} from '@openstapps/core'; +import {ConfigProvider} from '../../config/config.provider'; +import {getClientConfig, getEndpointsConfig} from '../auth.provider.methods'; +import {Injectable} from '@angular/core'; const TOKEN_KEY = 'auth_paia_token'; const AUTH_EXPIRY_BUFFER = 10 * 60 * -1; // 10 mins in seconds @@ -44,7 +48,10 @@ export interface IAuthService { getValidToken(buffer?: number): Promise; } -export class PAIAAuthService implements IAuthService { +@Injectable({ + providedIn: 'root', +}) +export class PAIAAuthService { private _authConfig?: IAuthConfig; private _authSubject: AuthSubject = new AuthSubject(); @@ -78,14 +85,14 @@ export class PAIAAuthService implements IAuthService { protected browser: Browser = new DefaultBrowser(), protected storage: StorageBackend = new LocalStorageBackend(), protected requestor: Requestor = new JQueryRequestor(), - utils = new BasicQueryStringUtils(), + private readonly configProvider: ConfigProvider, ) { this.tokenHandler = new PAIATokenRequestHandler(requestor); this.userInfoHandler = new IonicUserInfoHandler(requestor); this.requestHandler = new PAIAAuthorizationRequestHandler( browser, storage, - utils, + new BasicQueryStringUtils(), crypto, ); this.endSessionHandler = new IonicEndSessionHandler(browser); @@ -130,8 +137,19 @@ export class PAIAAuthService implements IAuthService { } public async init() { + this.setupConfiguration(); this.setupAuthorizationNotifier(); - this.loadTokenFromStorage(); + await this.loadTokenFromStorage(); + } + + setupConfiguration() { + const authConfig = this.configProvider.getAnyValue('auth') as { + paia: SCAuthorizationProvider; + }; + this.authConfig = getClientConfig('paia', authConfig); + this.localConfiguration = new AuthorizationServiceConfiguration( + getEndpointsConfig('paia', authConfig), + ); } protected notifyActionListers(action: IPAIAAuthAction) { diff --git a/src/app/modules/calendar/ical/ical.ts b/src/app/modules/calendar/ical/ical.ts index 9dc1bf2e..a263ff73 100644 --- a/src/app/modules/calendar/ical/ical.ts +++ b/src/app/modules/calendar/ical/ical.ts @@ -53,7 +53,7 @@ export type ICalLike = ICalKeyValuePair[]; /** * */ -function timeDist( +function timeDistance( current: SCISO8601Date, next: SCISO8601Date | undefined, recurrence: unitOfTime.Diff, @@ -127,11 +127,11 @@ export function findRRules( const freq = minBy( units.map(recurrence => ({ recurrence: recurrence, - dist: timeDist(current, next, recurrence), + dist: timeDistance(current, next, recurrence), })), it => it.dist, )?.recurrence; - const interval = freq ? timeDist(current, next, freq) : undefined; + const interval = freq ? timeDistance(current, next, freq) : undefined; if (element?.interval === -1) { element.freq = freq; diff --git a/src/app/modules/menu/navigation/navigation.component.ts b/src/app/modules/menu/navigation/navigation.component.ts index fc9bc28a..025c5656 100644 --- a/src/app/modules/menu/navigation/navigation.component.ts +++ b/src/app/modules/menu/navigation/navigation.component.ts @@ -22,6 +22,7 @@ import { } from '@openstapps/core'; import {NavigationService} from './navigation.service'; import config from 'capacitor.config'; +import {SettingsProvider} from '../../settings/settings.provider'; /** * Generated class for the MenuPage page. @@ -43,23 +44,13 @@ export class NavigationComponent implements OnInit { /** * Possible languages to be used for translation */ - language: keyof SCTranslations = 'en'; + language: keyof SCTranslations; /** * Menu entries from config module */ menu: SCAppConfigurationMenuCategory[]; - /** - * Possible languages to be used for translation - */ - public pages = [ - {title: 'Search', url: '/search', icon: 'search'}, - {title: 'Hebis Search', url: '/hebis-search', icon: 'search'}, - {title: 'Schedule', url: '/schedule', icon: 'calendar'}, - {title: 'Settings', url: '/settings', icon: 'settings'}, - ]; - /** * Core translator */ @@ -68,15 +59,20 @@ export class NavigationComponent implements OnInit { constructor( public translateService: TranslateService, private navigationService: NavigationService, + private settingsProvider: SettingsProvider, ) { translateService.onLangChange.subscribe((event: LangChangeEvent) => { this.language = event.lang as keyof SCTranslations; this.translator = new SCThingTranslator(this.language); }); - this.translator = new SCThingTranslator('en'); } async ngOnInit() { + this.language = (await this.settingsProvider.getValue( + 'profile', + 'language', + )) as keyof SCTranslations; + this.translator = new SCThingTranslator(this.language); this.menu = await this.navigationService.getMenu(); } } diff --git a/src/app/modules/menu/navigation/navigation.html b/src/app/modules/menu/navigation/navigation.html index ca06212e..085ca19f 100644 --- a/src/app/modules/menu/navigation/navigation.html +++ b/src/app/modules/menu/navigation/navigation.html @@ -11,7 +11,7 @@ - +