From 03c52d51ec4287a6437940beff228b3de0667070 Mon Sep 17 00:00:00 2001 From: Fabian Gosebrink Date: Mon, 4 Jan 2021 19:16:23 +0100 Subject: [PATCH 1/3] Added event to throw when config could not be loaded --- .../src/lib/config/auth-well-known.service.ts | 19 +++++-- .../src/lib/config/config.service.ts | 57 +++++++++---------- .../src/lib/public-events/event-types.ts | 1 + .../sample-code-flow/src/app/app.module.ts | 5 ++ 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.ts b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.ts index 2ac41fb47..0f49312c9 100644 --- a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.ts @@ -1,13 +1,20 @@ import { Injectable } from '@angular/core'; -import { of } from 'rxjs'; -import { tap } from 'rxjs/operators'; +import { of, throwError } from 'rxjs'; +import { catchError, tap } from 'rxjs/operators'; +import { EventTypes } from '../public-events/event-types'; +import { PublicEventsService } from '../public-events/public-events.service'; import { StoragePersistanceService } from '../storage/storage-persistance.service'; import { AuthWellKnownDataService } from './auth-well-known-data.service'; import { AuthWellKnownEndpoints } from './auth-well-known-endpoints'; +import { PublicConfiguration } from './public-configuration'; @Injectable() export class AuthWellKnownService { - constructor(private dataService: AuthWellKnownDataService, private storagePersistanceService: StoragePersistanceService) {} + constructor( + private publicEventsService: PublicEventsService, + private dataService: AuthWellKnownDataService, + private storagePersistanceService: StoragePersistanceService + ) {} getAuthWellKnownEndPoints(authWellknownEndpoint: string) { const alreadySavedWellKnownEndpoints = this.storagePersistanceService.read('authWellKnownEndPoints'); @@ -16,7 +23,11 @@ export class AuthWellKnownService { } return this.getWellKnownEndPointsFromUrl(authWellknownEndpoint).pipe( - tap((mappedWellKnownEndpoints) => this.storeWellKnownEndpoints(mappedWellKnownEndpoints)) + tap((mappedWellKnownEndpoints) => this.storeWellKnownEndpoints(mappedWellKnownEndpoints)), + catchError((error) => { + this.publicEventsService.fireEvent(EventTypes.ConfigLoadingFailed, null); + return throwError(error); + }) ); } diff --git a/projects/angular-auth-oidc-client/src/lib/config/config.service.ts b/projects/angular-auth-oidc-client/src/lib/config/config.service.ts index d80323925..3efd3a618 100644 --- a/projects/angular-auth-oidc-client/src/lib/config/config.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/config/config.service.ts @@ -15,19 +15,19 @@ import { PublicConfiguration } from './public-configuration'; @Injectable() export class OidcConfigService { constructor( - private readonly loggerService: LoggerService, - private readonly publicEventsService: PublicEventsService, - private readonly configurationProvider: ConfigurationProvider, - private readonly authWellKnownService: AuthWellKnownService, + private loggerService: LoggerService, + private publicEventsService: PublicEventsService, + private configurationProvider: ConfigurationProvider, + private authWellKnownService: AuthWellKnownService, private storagePersistanceService: StoragePersistanceService, private configValidationService: ConfigValidationService ) {} - withConfig(passedConfig: OpenIdConfiguration, passedAuthWellKnownEndpoints?: AuthWellKnownEndpoints): Promise { + withConfig(passedConfig: OpenIdConfiguration, passedAuthWellKnownEndpoints?: AuthWellKnownEndpoints): Promise { return new Promise((resolve, reject) => { if (!this.configValidationService.validateConfig(passedConfig)) { this.loggerService.logError('Validation of config rejected with errors. Config is NOT set.'); - return resolve(); + resolve(); } if (!passedConfig.authWellknownEndpoint) { @@ -43,7 +43,7 @@ export class OidcConfigService { wellknown: alreadyExistingAuthWellKnownEndpoints, }); - return resolve(); + resolve(); } if (!!passedAuthWellKnownEndpoints) { @@ -53,35 +53,34 @@ export class OidcConfigService { wellknown: passedAuthWellKnownEndpoints, }); - return resolve(); + resolve(); } - - if (usedConfig.eagerLoadAuthWellKnownEndpoints) { - this.authWellKnownService - .getAuthWellKnownEndPoints(usedConfig.authWellknownEndpoint) - .pipe( - catchError((error) => { - this.loggerService.logError('Getting auth well known endpoints failed on start', error); - return throwError(error); - }), - tap((wellknownEndPoints) => - this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { - configuration: passedConfig, - wellknown: wellknownEndPoints, - }) - ) - ) - .subscribe( - () => resolve(), - () => reject() - ); - } else { + if (!usedConfig.eagerLoadAuthWellKnownEndpoints) { this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { configuration: passedConfig, wellknown: null, }); resolve(); } + + this.authWellKnownService + .getAuthWellKnownEndPoints(usedConfig.authWellknownEndpoint) + .pipe( + catchError((error) => { + this.loggerService.logError('Getting auth well known endpoints failed on start', error); + return throwError(error); + }), + tap((wellknownEndPoints) => + this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { + configuration: passedConfig, + wellknown: wellknownEndPoints, + }) + ) + ) + .subscribe( + () => resolve(), + () => reject() + ); }); } } diff --git a/projects/angular-auth-oidc-client/src/lib/public-events/event-types.ts b/projects/angular-auth-oidc-client/src/lib/public-events/event-types.ts index 53ef1c9a5..3a1b05720 100644 --- a/projects/angular-auth-oidc-client/src/lib/public-events/event-types.ts +++ b/projects/angular-auth-oidc-client/src/lib/public-events/event-types.ts @@ -3,6 +3,7 @@ export enum EventTypes { * This only works in the AppModule Constructor */ ConfigLoaded, + ConfigLoadingFailed, CheckSessionReceived, UserDataChanged, NewAuthorizationResult, diff --git a/projects/sample-code-flow/src/app/app.module.ts b/projects/sample-code-flow/src/app/app.module.ts index 9a3e75140..ccf12da02 100644 --- a/projects/sample-code-flow/src/app/app.module.ts +++ b/projects/sample-code-flow/src/app/app.module.ts @@ -28,5 +28,10 @@ export class AppModule { .registerForEvents() .pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded)) .subscribe((config) => console.log('ConfigLoaded', config)); + + this.eventService + .registerForEvents() + .pipe(filter((notification) => notification.type === EventTypes.ConfigLoadingFailed)) + .subscribe(({ value }) => console.log('ConfigLoadingFailed', value)); } } From 12b7651974a8b183b714492a2e081fb723051420 Mon Sep 17 00:00:00 2001 From: Fabian Gosebrink Date: Mon, 4 Jan 2021 19:24:37 +0100 Subject: [PATCH 2/3] fixing tests --- .../config/auth-well-known.service.spec.ts | 2 + .../src/lib/config/config.service.ts | 40 +++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts index 2dd43f5c4..6d73bdefa 100644 --- a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts @@ -2,6 +2,7 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { of } from 'rxjs'; import { DataService } from '../api/data.service'; import { DataServiceMock } from '../api/data.service-mock'; +import { PublicEventsService } from '../public-events/public-events.service'; import { StoragePersistanceService } from '../storage/storage-persistance.service'; import { StoragePersistanceServiceMock } from '../storage/storage-persistance.service-mock'; import { AuthWellKnownDataService } from './auth-well-known-data.service'; @@ -19,6 +20,7 @@ describe('AuthWellKnownService', () => { { provide: StoragePersistanceService, useClass: StoragePersistanceServiceMock }, { provide: DataService, useClass: DataServiceMock }, AuthWellKnownDataService, + PublicEventsService, ], }); }); diff --git a/projects/angular-auth-oidc-client/src/lib/config/config.service.ts b/projects/angular-auth-oidc-client/src/lib/config/config.service.ts index 3efd3a618..edcebe4b2 100644 --- a/projects/angular-auth-oidc-client/src/lib/config/config.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/config/config.service.ts @@ -55,32 +55,32 @@ export class OidcConfigService { resolve(); } - if (!usedConfig.eagerLoadAuthWellKnownEndpoints) { + if (usedConfig.eagerLoadAuthWellKnownEndpoints) { + this.authWellKnownService + .getAuthWellKnownEndPoints(usedConfig.authWellknownEndpoint) + .pipe( + catchError((error) => { + this.loggerService.logError('Getting auth well known endpoints failed on start', error); + return throwError(error); + }), + tap((wellknownEndPoints) => + this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { + configuration: passedConfig, + wellknown: wellknownEndPoints, + }) + ) + ) + .subscribe( + () => resolve(), + () => reject() + ); + } else { this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { configuration: passedConfig, wellknown: null, }); resolve(); } - - this.authWellKnownService - .getAuthWellKnownEndPoints(usedConfig.authWellknownEndpoint) - .pipe( - catchError((error) => { - this.loggerService.logError('Getting auth well known endpoints failed on start', error); - return throwError(error); - }), - tap((wellknownEndPoints) => - this.publicEventsService.fireEvent(EventTypes.ConfigLoaded, { - configuration: passedConfig, - wellknown: wellknownEndPoints, - }) - ) - ) - .subscribe( - () => resolve(), - () => reject() - ); }); } } From 3570eb77efd77070317780d75bf5d4f4035b7be8 Mon Sep 17 00:00:00 2001 From: Fabian Gosebrink Date: Mon, 4 Jan 2021 21:29:06 +0100 Subject: [PATCH 3/3] added test for new event --- .../config/auth-well-known.service.spec.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts index 6d73bdefa..d65a855b9 100644 --- a/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/config/auth-well-known.service.spec.ts @@ -1,7 +1,8 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; -import { of } from 'rxjs'; +import { of, throwError } from 'rxjs'; import { DataService } from '../api/data.service'; import { DataServiceMock } from '../api/data.service-mock'; +import { EventTypes } from '../public-events/event-types'; import { PublicEventsService } from '../public-events/public-events.service'; import { StoragePersistanceService } from '../storage/storage-persistance.service'; import { StoragePersistanceServiceMock } from '../storage/storage-persistance.service-mock'; @@ -12,6 +13,7 @@ describe('AuthWellKnownService', () => { let service: AuthWellKnownService; let dataService: AuthWellKnownDataService; let storagePersistanceService: StoragePersistanceService; + let publicEventsService: PublicEventsService; beforeEach(() => { TestBed.configureTestingModule({ @@ -29,6 +31,7 @@ describe('AuthWellKnownService', () => { service = TestBed.inject(AuthWellKnownService); dataService = TestBed.inject(AuthWellKnownDataService); storagePersistanceService = TestBed.inject(StoragePersistanceService); + publicEventsService = TestBed.inject(PublicEventsService); }); it('should create', () => { @@ -73,5 +76,20 @@ describe('AuthWellKnownService', () => { }); }) ); + + it( + 'throws `ConfigLoadingFailed` event when error happens from http', + waitForAsync(() => { + spyOn(dataService, 'getWellKnownEndPointsFromUrl').and.returnValue(throwError('This is an error')); + const publicEventsServiceSpy = spyOn(publicEventsService, 'fireEvent'); + service.getAuthWellKnownEndPoints('any-url').subscribe({ + error: (err) => { + expect(err).toBeTruthy(); + expect(publicEventsServiceSpy).toHaveBeenCalledTimes(1); + expect(publicEventsServiceSpy).toHaveBeenCalledWith(EventTypes.ConfigLoadingFailed, null); + }, + }); + }) + ); }); });