Skip to content

Commit 4e33567

Browse files
Merge pull request manfredsteyer#427 from jeroenheijmans/refactor/decouple-from-console
Decouple OAuthService from console
2 parents 45d8d75 + 888ea47 commit 4e33567

File tree

3 files changed

+60
-39
lines changed

3 files changed

+60
-39
lines changed

projects/lib/src/angular-oauth-oidic.module.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { OAuthStorage } from './types';
1+
import { OAuthStorage, OAuthLogger } from './types';
22
import { NgModule, ModuleWithProviders } from '@angular/core';
33
import { CommonModule } from '@angular/common';
44
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
@@ -15,6 +15,10 @@ import { DefaultOAuthInterceptor } from './interceptors/default-oauth.intercepto
1515
import { ValidationHandler } from './token-validation/validation-handler';
1616
import { NullValidationHandler } from './token-validation/null-validation-handler';
1717

18+
export function createDefaultLogger() {
19+
return console;
20+
}
21+
1822
export function createDefaultStorage() {
1923
return typeof sessionStorage !== 'undefined' ? sessionStorage : null;
2024
}
@@ -36,6 +40,7 @@ export class OAuthModule {
3640
providers: [
3741
OAuthService,
3842
UrlHelperService,
43+
{ provide: OAuthLogger, useFactory: createDefaultLogger },
3944
{ provide: OAuthStorage, useFactory: createDefaultStorage },
4045
{ provide: ValidationHandler, useClass: validationHandlerClass},
4146
{

projects/lib/src/oauth-service.ts

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
OAuthSuccessEvent
1616
} from './events';
1717
import {
18+
OAuthLogger,
1819
OAuthStorage,
1920
LoginOptions,
2021
ParsedIdToken,
@@ -87,7 +88,8 @@ export class OAuthService extends AuthConfig {
8788
@Optional() storage: OAuthStorage,
8889
@Optional() tokenValidationHandler: ValidationHandler,
8990
@Optional() private config: AuthConfig,
90-
private urlHelper: UrlHelperService
91+
private urlHelper: UrlHelperService,
92+
private logger: OAuthLogger,
9193
) {
9294
super();
9395

@@ -109,7 +111,7 @@ export class OAuthService extends AuthConfig {
109111
this.setStorage(sessionStorage);
110112
}
111113
} catch (e) {
112-
console.error(
114+
this.logger.error(
113115
'cannot access sessionStorage. Consider setting an own storage implementation using setStorage',
114116
e
115117
);
@@ -186,7 +188,7 @@ export class OAuthService extends AuthConfig {
186188

187189
private debug(...args): void {
188190
if (this.showDebugInformation) {
189-
console.debug.apply(console, args);
191+
this.logger.debug.apply(console, args);
190192
}
191193
}
192194

@@ -420,7 +422,7 @@ export class OAuthService extends AuthConfig {
420422
});
421423
},
422424
err => {
423-
console.error('error loading discovery document', err);
425+
this.logger.error('error loading discovery document', err);
424426
this.eventsSubject.next(
425427
new OAuthErrorEvent('discovery_document_load_error', err)
426428
);
@@ -442,7 +444,7 @@ export class OAuthService extends AuthConfig {
442444
resolve(jwks);
443445
},
444446
err => {
445-
console.error('error loading jwks', err);
447+
this.logger.error('error loading jwks', err);
446448
this.eventsSubject.next(
447449
new OAuthErrorEvent('jwks_load_error', err)
448450
);
@@ -459,7 +461,7 @@ export class OAuthService extends AuthConfig {
459461
let errors: string[];
460462

461463
if (!this.skipIssuerCheck && doc.issuer !== this.issuer) {
462-
console.error(
464+
this.logger.error(
463465
'invalid issuer in discovery document',
464466
'expected: ' + this.issuer,
465467
'current: ' + doc.issuer
@@ -469,7 +471,7 @@ export class OAuthService extends AuthConfig {
469471

470472
errors = this.validateUrlFromDiscoveryDocument(doc.authorization_endpoint);
471473
if (errors.length > 0) {
472-
console.error(
474+
this.logger.error(
473475
'error validating authorization_endpoint in discovery document',
474476
errors
475477
);
@@ -478,7 +480,7 @@ export class OAuthService extends AuthConfig {
478480

479481
errors = this.validateUrlFromDiscoveryDocument(doc.end_session_endpoint);
480482
if (errors.length > 0) {
481-
console.error(
483+
this.logger.error(
482484
'error validating end_session_endpoint in discovery document',
483485
errors
484486
);
@@ -487,15 +489,15 @@ export class OAuthService extends AuthConfig {
487489

488490
errors = this.validateUrlFromDiscoveryDocument(doc.token_endpoint);
489491
if (errors.length > 0) {
490-
console.error(
492+
this.logger.error(
491493
'error validating token_endpoint in discovery document',
492494
errors
493495
);
494496
}
495497

496498
errors = this.validateUrlFromDiscoveryDocument(doc.userinfo_endpoint);
497499
if (errors.length > 0) {
498-
console.error(
500+
this.logger.error(
499501
'error validating userinfo_endpoint in discovery document',
500502
errors
501503
);
@@ -504,12 +506,12 @@ export class OAuthService extends AuthConfig {
504506

505507
errors = this.validateUrlFromDiscoveryDocument(doc.jwks_uri);
506508
if (errors.length > 0) {
507-
console.error('error validating jwks_uri in discovery document', errors);
509+
this.logger.error('error validating jwks_uri in discovery document', errors);
508510
return false;
509511
}
510512

511513
if (this.sessionChecksEnabled && !doc.check_session_iframe) {
512-
console.warn(
514+
this.logger.warn(
513515
'sessionChecksEnabled is activated but discovery document' +
514516
' does not contain a check_session_iframe field'
515517
);
@@ -595,7 +597,7 @@ export class OAuthService extends AuthConfig {
595597
resolve(info);
596598
},
597599
err => {
598-
console.error('error loading user info', err);
600+
this.logger.error('error loading user info', err);
599601
this.eventsSubject.next(
600602
new OAuthErrorEvent('user_profile_load_error', err)
601603
);
@@ -677,7 +679,7 @@ export class OAuthService extends AuthConfig {
677679
resolve(tokenResponse);
678680
},
679681
err => {
680-
console.error('Error performing password flow', err);
682+
this.logger.error('Error performing password flow', err);
681683
this.eventsSubject.next(new OAuthErrorEvent('token_error', err));
682684
reject(err);
683685
}
@@ -738,7 +740,7 @@ export class OAuthService extends AuthConfig {
738740
resolve(tokenResponse);
739741
},
740742
err => {
741-
console.error('Error performing password flow', err);
743+
this.logger.error('Error performing password flow', err);
742744
this.eventsSubject.next(
743745
new OAuthErrorEvent('token_refresh_error', err)
744746
);
@@ -886,15 +888,15 @@ export class OAuthService extends AuthConfig {
886888
return false;
887889
}
888890
if (!this.sessionCheckIFrameUrl) {
889-
console.warn(
891+
this.logger.warn(
890892
'sessionChecksEnabled is activated but there ' +
891893
'is no sessionCheckIFrameUrl'
892894
);
893895
return false;
894896
}
895897
const sessionState = this.getSessionState();
896898
if (!sessionState) {
897-
console.warn(
899+
this.logger.warn(
898900
'sessionChecksEnabled is activated but there ' + 'is no session_state'
899901
);
900902
return false;
@@ -1037,7 +1039,7 @@ export class OAuthService extends AuthConfig {
10371039
const iframe: any = document.getElementById(this.sessionCheckIFrameName);
10381040

10391041
if (!iframe) {
1040-
console.warn(
1042+
this.logger.warn(
10411043
'checkSession did not find iframe',
10421044
this.sessionCheckIFrameName
10431045
);
@@ -1175,8 +1177,8 @@ export class OAuthService extends AuthConfig {
11751177
location.href = url;
11761178
})
11771179
.catch(error => {
1178-
console.error('Error in initImplicitFlow');
1179-
console.error(error);
1180+
this.logger.error('Error in initImplicitFlow');
1181+
this.logger.error(error);
11801182
this.inImplicitFlow = false;
11811183
});
11821184
}
@@ -1302,7 +1304,7 @@ export class OAuthService extends AuthConfig {
13021304
}
13031305

13041306
if (this.sessionChecksEnabled && !sessionState) {
1305-
console.warn(
1307+
this.logger.warn(
13061308
'session checks (Session Status Change Notification) ' +
13071309
'is activated in the configuration but the id_token ' +
13081310
'does not contain a session_state claim'
@@ -1366,8 +1368,8 @@ export class OAuthService extends AuthConfig {
13661368
this.eventsSubject.next(
13671369
new OAuthErrorEvent('token_validation_error', reason)
13681370
);
1369-
console.error('Error validating tokens');
1370-
console.error(reason);
1371+
this.logger.error('Error validating tokens');
1372+
this.logger.error(reason);
13711373
return Promise.reject(reason);
13721374
});
13731375
}
@@ -1379,7 +1381,7 @@ export class OAuthService extends AuthConfig {
13791381
const savedNonce = this._storage.getItem('nonce');
13801382
if (savedNonce !== nonceInState) {
13811383
const err = 'validating access_token failed. wrong state/nonce.';
1382-
console.error(err, savedNonce, nonceInState);
1384+
this.logger.error(err, savedNonce, nonceInState);
13831385
return false;
13841386
}
13851387
return true;
@@ -1428,28 +1430,28 @@ export class OAuthService extends AuthConfig {
14281430
if (Array.isArray(claims.aud)) {
14291431
if (claims.aud.every(v => v !== this.clientId)) {
14301432
const err = 'Wrong audience: ' + claims.aud.join(',');
1431-
console.warn(err);
1433+
this.logger.warn(err);
14321434
return Promise.reject(err);
14331435
}
14341436
} else {
14351437
if (claims.aud !== this.clientId) {
14361438
const err = 'Wrong audience: ' + claims.aud;
1437-
console.warn(err);
1439+
this.logger.warn(err);
14381440
return Promise.reject(err);
14391441
}
14401442
}
14411443

14421444
/*
14431445
if (this.getKeyCount() > 1 && !header.kid) {
14441446
let err = 'There needs to be a kid property in the id_token header when multiple keys are defined via the property jwks';
1445-
console.warn(err);
1447+
this.logger.warn(err);
14461448
return Promise.reject(err);
14471449
}
14481450
*/
14491451

14501452
if (!claims.sub) {
14511453
const err = 'No sub claim in id_token';
1452-
console.warn(err);
1454+
this.logger.warn(err);
14531455
return Promise.reject(err);
14541456
}
14551457

@@ -1469,25 +1471,25 @@ export class OAuthService extends AuthConfig {
14691471
claims['sub']
14701472
}`;
14711473

1472-
console.warn(err);
1474+
this.logger.warn(err);
14731475
return Promise.reject(err);
14741476
}
14751477

14761478
if (!claims.iat) {
14771479
const err = 'No iat claim in id_token';
1478-
console.warn(err);
1480+
this.logger.warn(err);
14791481
return Promise.reject(err);
14801482
}
14811483

14821484
if (claims.iss !== this.issuer) {
14831485
const err = 'Wrong issuer: ' + claims.iss;
1484-
console.warn(err);
1486+
this.logger.warn(err);
14851487
return Promise.reject(err);
14861488
}
14871489

14881490
if (claims.nonce !== savedNonce) {
14891491
const err = 'Wrong nonce: ' + claims.nonce;
1490-
console.warn(err);
1492+
this.logger.warn(err);
14911493
return Promise.reject(err);
14921494
}
14931495

@@ -1497,7 +1499,7 @@ export class OAuthService extends AuthConfig {
14971499
!claims['at_hash']
14981500
) {
14991501
const err = 'An at_hash is needed!';
1500-
console.warn(err);
1502+
this.logger.warn(err);
15011503
return Promise.reject(err);
15021504
}
15031505

@@ -1511,8 +1513,8 @@ export class OAuthService extends AuthConfig {
15111513
expiresAtMSec + tenMinutesInMsec <= now
15121514
) {
15131515
const err = 'Token has been expired';
1514-
console.error(err);
1515-
console.error({
1516+
this.logger.error(err);
1517+
this.logger.error({
15161518
now: now,
15171519
issuedAtMSec: issuedAtMSec,
15181520
expiresAtMSec: expiresAtMSec
@@ -1535,7 +1537,7 @@ export class OAuthService extends AuthConfig {
15351537
!this.checkAtHash(validationParams)
15361538
) {
15371539
const err = 'Wrong at_hash';
1538-
console.warn(err);
1540+
this.logger.warn(err);
15391541
return Promise.reject(err);
15401542
}
15411543

@@ -1776,7 +1778,7 @@ export class OAuthService extends AuthConfig {
17761778

17771779
private checkAtHash(params: ValidationParams): boolean {
17781780
if (!this.tokenValidationHandler) {
1779-
console.warn(
1781+
this.logger.warn(
17801782
'No tokenValidationHandler configured. Cannot check at_hash.'
17811783
);
17821784
return true;
@@ -1786,7 +1788,7 @@ export class OAuthService extends AuthConfig {
17861788

17871789
private checkSignature(params: ValidationParams): Promise<any> {
17881790
if (!this.tokenValidationHandler) {
1789-
console.warn(
1791+
this.logger.warn(
17901792
'No tokenValidationHandler configured. Cannot check signature.'
17911793
);
17921794
return Promise.resolve(null);

projects/lib/src/types.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ export class LoginOptions {
4949
preventClearHashAfterLogin? = false;
5050
}
5151

52+
/**
53+
* Defines the logging interface the OAuthService uses
54+
* internally. Is compatible with the `console` object,
55+
* but you can provide your own implementation as well
56+
* through dependency injection.
57+
*/
58+
export abstract class OAuthLogger {
59+
abstract debug(message?: any, ...optionalParams: any[]): void;
60+
abstract info(message?: any, ...optionalParams: any[]): void;
61+
abstract log(message?: any, ...optionalParams: any[]): void;
62+
abstract warn(message?: any, ...optionalParams: any[]): void;
63+
abstract error(message?: any, ...optionalParams: any[]): void;
64+
}
65+
5266
/**
5367
* Defines a simple storage that can be used for
5468
* storing the tokens at client side.

0 commit comments

Comments
 (0)