diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..1537f8abb --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +/projects/schematics +.gitkeep +/**/favicon.ico +/**/.browserslistrc +/**/*.jpg diff --git a/README.md b/README.md index 89238de63..3826444bc 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ This library is certified by ## Features -- Supports OpenID Connect Code Flow with PKCE -- Supports Code Flow PKCE with Refresh tokens -- Supports Revocation Endpoint -- Support for current best practice -- Implements OIDC validation as specified, complete client side validation for REQUIRED features -- [Supports OpenID Connect Implicit Flow](http://openid.net/specs/openid-connect-implicit-1_0.html) -- [OpenID Connect Session Management 1.0](http://openid.net/specs/openid-connect-session-1_0.html) -- Samples for most of the common use cases +- Supports OpenID Connect Code Flow with PKCE +- Supports Code Flow PKCE with Refresh tokens +- Supports Revocation Endpoint +- Support for current best practice +- Implements OIDC validation as specified, complete client side validation for REQUIRED features +- [Supports OpenID Connect Implicit Flow](http://openid.net/specs/openid-connect-implicit-1_0.html) +- [OpenID Connect Session Management 1.0](http://openid.net/specs/openid-connect-session-1_0.html) +- Samples for most of the common use cases ## Installation @@ -51,40 +51,42 @@ or with yarn ## Documentation -- [Quickstart](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/quickstart.md) -- [Samples](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md) - - - [Code Flow with PKCE Using a configuration from an http source and silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#code-flow-with-pkce-using-a-configuration-from-an-http-source-and-silent-renew) - - [Code Flow PKCE with Refresh tokens](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#code-flow-pkce-with-refresh-tokens) - - [Code Flow PKCE Auto login](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#code-flow-pkce-auto-login) - - [Code Flow with PKCE basic with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#code-flow-with-pkce-basic-with-silent-renew) - - [Azure B2C Code Flow PKCE with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#azure-b2c-code-flow-pkce-with-silent-renew) - - [Azure AD Code Flow PKCE with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#azure-ad-oidc-code-flow-with-pkce) - - [Implicit Flow with silent renew (Not recommended)](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#implicit-flow-with-silent-renew-not-recommended) - - [Implicit Flow google (Not recommended)](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#implicit-flow-google-not-recommended) - - [Code flow with a lazy loaded module](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/samples.md#code-flow-with-a-lazy-loaded-module) - -- [Silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/silent-renew.md) - - - [Silent Renew Code Flow with PKCE](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/silent-renew.md#silent-renew-code-flow-with-pkce) - - [Silent Renew Code Flow with PKCE with refresh tokens](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/silent-renew.md#silent-renew-code-flow-with-pkce-with-refresh-tokens) - - [Silent Renew Implicit Flow](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/silent-renew.md#silent-renew-implicit-flow) - - [Secure Token Server CSP and CORS](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/silent-renew.md#secure-token-server-csp-and-cors) - -- [Guards](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/guards.md) -- [Features](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md) - - [Public Events](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md#public-events) - - [Custom Storage](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md#custom-storage) - - [Custom parameters](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md#custom-parameters) - - [Using the OIDC package in a module or a Angular lib](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md#using-the-oidc-package-in-a-module-or-a-angular-lib) - - [Delay the loading or pass an existing AuthWellKnownEndpoints config](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/features.md#delay-the-loading-or-pass-an-existing-well-knownopenid-configuration-configuration) -- [Logout](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/logout.md) -- [Using and revoking the access token](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/using-access-tokens.md) -- [CSP & CORS](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/csp-cors-config.md) -- [Public API](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/public-api.md) -- [Configuration](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/configuration.md) -- [Migration](https://github.com/damienbod/angular-auth-oidc-client/tree/master/docs/migration.md) -- [Changelog](https://github.com/damienbod/angular-auth-oidc-client/tree/master/CHANGELOG.md) +- [Quickstart](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/quickstart.md) +- [Samples](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md) + + - [Code Flow with PKCE Using a configuration from an http source and silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#code-flow-with-pkce-using-a-configuration-from-an-http-source-and-silent-renew) + - [Code Flow PKCE with Refresh tokens](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#code-flow-pkce-with-refresh-tokens) + - [Code Flow PKCE Auto login](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#code-flow-pkce-auto-login) + - [Code Flow with PKCE basic with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#code-flow-with-pkce-basic-with-silent-renew) + - [Azure B2C Code Flow PKCE with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#azure-b2c-code-flow-pkce-with-silent-renew) + - [Azure AD Code Flow PKCE with silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#azure-ad-oidc-code-flow-with-pkce) + - [Implicit Flow with silent renew (Not recommended)](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#implicit-flow-with-silent-renew-not-recommended) + - [Implicit Flow google (Not recommended)](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#implicit-flow-google-not-recommended) + - [Code flow with a lazy loaded module](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#code-flow-with-a-lazy-loaded-module) + - [Code flow with popup](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/samples.md#sample-code-flow-popup) + +- [Silent renew](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/silent-renew.md) + + - [Silent Renew Code Flow with PKCE](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/silent-renew.md#silent-renew-code-flow-with-pkce) + - [Silent Renew Code Flow with PKCE with refresh tokens](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/silent-renew.md#silent-renew-code-flow-with-pkce-with-refresh-tokens) + - [Silent Renew Implicit Flow](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/silent-renew.md#silent-renew-implicit-flow) + - [Secure Token Server CSP and CORS](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/silent-renew.md#secure-token-server-csp-and-cors) + +- [Guards](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/guards.md) +- [Features](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md) + - [Public Events](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md#public-events) + - [Auth with a popup](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/authorizing-popup.md) + - [Custom Storage](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md#custom-storage) + - [Custom parameters](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md#custom-parameters) + - [Using the OIDC package in a module or a Angular lib](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md#using-the-oidc-package-in-a-module-or-a-angular-lib) + - [Delay the loading or pass an existing AuthWellKnownEndpoints config](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/features.md#delay-the-loading-or-pass-an-existing-well-knownopenid-configuration-configuration) +- [Logout](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/logout.md) +- [Using and revoking the access token](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/using-access-tokens.md) +- [CSP & CORS](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/csp-cors-config.md) +- [Public API](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/public-api.md) +- [Configuration](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/configuration.md) +- [Migration](https://github.com/damienbod/angular-auth-oidc-client/tree/main/docs/migration.md) +- [Changelog](https://github.com/damienbod/angular-auth-oidc-client/tree/master/CHANGELOG.md) ## Quickstart @@ -101,36 +103,36 @@ import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-clien // ... export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: '', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'angularClient', - scope: 'openid profile email', - responseType: 'code', - silentRenew: true, - silentRenewUrl: `${window.location.origin}/silent-renew.html`, - logLevel: LogLevel.Debug, - }); + return () => + oidcConfigService.withConfig({ + stsServer: '', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularClient', + scope: 'openid profile email', + responseType: 'code', + silentRenew: true, + silentRenewUrl: `${window.location.origin}/silent-renew.html`, + logLevel: LogLevel.Debug, + }); } @NgModule({ + // ... + imports: [ // ... - imports: [ - // ... - AuthModule.forRoot(), - ], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - // ... + AuthModule.forRoot(), + ], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + // ... }) export class AppModule {} ``` @@ -143,22 +145,22 @@ import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from import { Observable } from 'rxjs'; @Component({ - /**/ + /**/ }) export class AppComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService) {} + constructor(public oidcSecurityService: OidcSecurityService) {} - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe((auth) => console.log('is authenticated', auth)); - } + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe((auth) => console.log('is authenticated', auth)); + } - login() { - this.oidcSecurityService.authorize(); - } + login() { + this.oidcSecurityService.authorize(); + } - logout() { - this.oidcSecurityService.logoff(); - } + logout() { + this.oidcSecurityService.logoff(); + } } ``` @@ -178,9 +180,9 @@ import { HttpHeaders } from '@angular/common/http'; const token = this.oidcSecurityServices.getToken(); const httpOptions = { - headers: new HttpHeaders({ - Authorization: 'Bearer ' + token, - }), + headers: new HttpHeaders({ + Authorization: 'Bearer ' + token, + }), }; ``` diff --git a/angular.json b/angular.json index d815d7613..bfb7fbddc 100644 --- a/angular.json +++ b/angular.json @@ -27,18 +27,13 @@ "main": "projects/angular-auth-oidc-client/src/test.ts", "tsConfig": "projects/angular-auth-oidc-client/tsconfig.spec.json", "karmaConfig": "projects/angular-auth-oidc-client/karma.conf.js", - "codeCoverageExclude": [ - "/**/*mock*.ts" - ] + "codeCoverageExclude": ["/**/*mock*.ts"] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/angular-auth-oidc-client/**/*.ts", - "projects/angular-auth-oidc-client/**/*.html" - ] + "lintFilePatterns": ["projects/angular-auth-oidc-client/**/*.ts", "projects/angular-auth-oidc-client/**/*.html"] } } } @@ -64,9 +59,7 @@ "projects/sample-code-flow/src/silent-renew.html", "projects/sample-code-flow/src/assets" ], - "styles": [ - "projects/sample-code-flow/src/styles.css" - ], + "styles": ["projects/sample-code-flow/src/styles.css"], "scripts": [] }, "configurations": { @@ -126,23 +119,15 @@ "polyfills": "projects/sample-code-flow/src/polyfills.ts", "tsConfig": "projects/sample-code-flow/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow/karma.conf.js", - "assets": [ - "projects/sample-code-flow/src/favicon.ico", - "projects/sample-code-flow/src/assets" - ], - "styles": [ - "projects/sample-code-flow/src/styles.css" - ], + "assets": ["projects/sample-code-flow/src/favicon.ico", "projects/sample-code-flow/src/assets"], + "styles": ["projects/sample-code-flow/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow/**/*.ts", - "projects/sample-code-flow/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow/**/*.ts", "projects/sample-code-flow/**/*.html"] } }, "e2e": { @@ -180,9 +165,7 @@ "projects/sample-code-flow-auto-login/src/silent-renew.html", "projects/sample-code-flow-auto-login/src/assets" ], - "styles": [ - "projects/sample-code-flow-auto-login/src/styles.css" - ], + "styles": ["projects/sample-code-flow-auto-login/src/styles.css"], "scripts": [] }, "configurations": { @@ -242,23 +225,15 @@ "polyfills": "projects/sample-code-flow-auto-login/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-auto-login/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow-auto-login/karma.conf.js", - "assets": [ - "projects/sample-code-flow-auto-login/src/favicon.ico", - "projects/sample-code-flow-auto-login/src/assets" - ], - "styles": [ - "projects/sample-code-flow-auto-login/src/styles.css" - ], + "assets": ["projects/sample-code-flow-auto-login/src/favicon.ico", "projects/sample-code-flow-auto-login/src/assets"], + "styles": ["projects/sample-code-flow-auto-login/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-auto-login/**/*.ts", - "projects/sample-code-flow-auto-login/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-auto-login/**/*.ts", "projects/sample-code-flow-auto-login/**/*.html"] } }, "e2e": { @@ -296,9 +271,7 @@ "projects/sample-code-flow-http-config/src/assets", "projects/sample-code-flow-http-config/src/silent-renew.html" ], - "styles": [ - "projects/sample-code-flow-http-config/src/styles.css" - ], + "styles": ["projects/sample-code-flow-http-config/src/styles.css"], "scripts": [] }, "configurations": { @@ -358,23 +331,15 @@ "polyfills": "projects/sample-code-flow-http-config/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-http-config/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow-http-config/karma.conf.js", - "assets": [ - "projects/sample-code-flow-http-config/src/favicon.ico", - "projects/sample-code-flow-http-config/src/assets" - ], - "styles": [ - "projects/sample-code-flow-http-config/src/styles.css" - ], + "assets": ["projects/sample-code-flow-http-config/src/favicon.ico", "projects/sample-code-flow-http-config/src/assets"], + "styles": ["projects/sample-code-flow-http-config/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-http-config/**/*.ts", - "projects/sample-code-flow-http-config/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-http-config/**/*.ts", "projects/sample-code-flow-http-config/**/*.html"] } }, "e2e": { @@ -407,13 +372,8 @@ "polyfills": "projects/sample-implicit-flow-google/src/polyfills.ts", "tsConfig": "projects/sample-implicit-flow-google/tsconfig.app.json", "aot": true, - "assets": [ - "projects/sample-implicit-flow-google/src/favicon.ico", - "projects/sample-implicit-flow-google/src/assets" - ], - "styles": [ - "projects/sample-implicit-flow-google/src/styles.css" - ], + "assets": ["projects/sample-implicit-flow-google/src/favicon.ico", "projects/sample-implicit-flow-google/src/assets"], + "styles": ["projects/sample-implicit-flow-google/src/styles.css"], "scripts": [] }, "configurations": { @@ -473,23 +433,15 @@ "polyfills": "projects/sample-implicit-flow-google/src/polyfills.ts", "tsConfig": "projects/sample-implicit-flow-google/tsconfig.spec.json", "karmaConfig": "projects/sample-implicit-flow-google/karma.conf.js", - "assets": [ - "projects/sample-implicit-flow-google/src/favicon.ico", - "projects/sample-implicit-flow-google/src/assets" - ], - "styles": [ - "projects/sample-implicit-flow-google/src/styles.css" - ], + "assets": ["projects/sample-implicit-flow-google/src/favicon.ico", "projects/sample-implicit-flow-google/src/assets"], + "styles": ["projects/sample-implicit-flow-google/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-implicit-flow-google/**/*.ts", - "projects/sample-implicit-flow-google/**/*.html" - ] + "lintFilePatterns": ["projects/sample-implicit-flow-google/**/*.ts", "projects/sample-implicit-flow-google/**/*.html"] } }, "e2e": { @@ -527,9 +479,7 @@ "projects/sample-code-flow-azuread/src/assets", "projects/sample-code-flow-azuread/src/silent-renew.html" ], - "styles": [ - "projects/sample-code-flow-azuread/src/styles.css" - ], + "styles": ["projects/sample-code-flow-azuread/src/styles.css"], "scripts": [] }, "configurations": { @@ -594,19 +544,14 @@ "projects/sample-code-flow-azuread/src/assets", "projects/sample-code-flow-azuread/src/silent-renew.html" ], - "styles": [ - "projects/sample-code-flow-azuread/src/styles.css" - ], + "styles": ["projects/sample-code-flow-azuread/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-azuread/**/*.ts", - "projects/sample-code-flow-azuread/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-azuread/**/*.ts", "projects/sample-code-flow-azuread/**/*.html"] } }, "e2e": { @@ -644,9 +589,7 @@ "projects/sample-code-flow-azure-b2c/src/assets", "projects/sample-code-flow-azure-b2c/src/silent-renew.html" ], - "styles": [ - "projects/sample-code-flow-azure-b2c/src/styles.css" - ], + "styles": ["projects/sample-code-flow-azure-b2c/src/styles.css"], "scripts": [] }, "configurations": { @@ -706,23 +649,15 @@ "polyfills": "projects/sample-code-flow-azure-b2c/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-azure-b2c/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow-azure-b2c/karma.conf.js", - "assets": [ - "projects/sample-code-flow-azure-b2c/src/favicon.ico", - "projects/sample-code-flow-azure-b2c/src/assets" - ], - "styles": [ - "projects/sample-code-flow-azure-b2c/src/styles.css" - ], + "assets": ["projects/sample-code-flow-azure-b2c/src/favicon.ico", "projects/sample-code-flow-azure-b2c/src/assets"], + "styles": ["projects/sample-code-flow-azure-b2c/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-azure-b2c/**/*.ts", - "projects/sample-code-flow-azure-b2c/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-azure-b2c/**/*.ts", "projects/sample-code-flow-azure-b2c/**/*.html"] } }, "e2e": { @@ -760,9 +695,7 @@ "projects/sample-implicit-flow-silent-renew/src/assets", "projects/sample-implicit-flow-silent-renew/src/silent-renew.html" ], - "styles": [ - "projects/sample-implicit-flow-silent-renew/src/styles.css" - ], + "styles": ["projects/sample-implicit-flow-silent-renew/src/styles.css"], "scripts": [] }, "configurations": { @@ -826,9 +759,7 @@ "projects/sample-implicit-flow-silent-renew/src/favicon.ico", "projects/sample-implicit-flow-silent-renew/src/assets" ], - "styles": [ - "projects/sample-implicit-flow-silent-renew/src/styles.css" - ], + "styles": ["projects/sample-implicit-flow-silent-renew/src/styles.css"], "scripts": [] } }, @@ -871,13 +802,8 @@ "polyfills": "projects/sample-code-flow-refresh-tokens/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-refresh-tokens/tsconfig.app.json", "aot": true, - "assets": [ - "projects/sample-code-flow-refresh-tokens/src/favicon.ico", - "projects/sample-code-flow-refresh-tokens/src/assets" - ], - "styles": [ - "projects/sample-code-flow-refresh-tokens/src/styles.css" - ], + "assets": ["projects/sample-code-flow-refresh-tokens/src/favicon.ico", "projects/sample-code-flow-refresh-tokens/src/assets"], + "styles": ["projects/sample-code-flow-refresh-tokens/src/styles.css"], "scripts": [] }, "configurations": { @@ -937,23 +863,15 @@ "polyfills": "projects/sample-code-flow-refresh-tokens/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-refresh-tokens/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow-refresh-tokens/karma.conf.js", - "assets": [ - "projects/sample-code-flow-refresh-tokens/src/favicon.ico", - "projects/sample-code-flow-refresh-tokens/src/assets" - ], - "styles": [ - "projects/sample-code-flow-refresh-tokens/src/styles.css" - ], + "assets": ["projects/sample-code-flow-refresh-tokens/src/favicon.ico", "projects/sample-code-flow-refresh-tokens/src/assets"], + "styles": ["projects/sample-code-flow-refresh-tokens/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-refresh-tokens/**/*.ts", - "projects/sample-code-flow-refresh-tokens/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-refresh-tokens/**/*.ts", "projects/sample-code-flow-refresh-tokens/**/*.html"] } }, "e2e": { @@ -986,13 +904,8 @@ "polyfills": "projects/sample-code-flow-lazy-loaded/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-lazy-loaded/tsconfig.app.json", "aot": true, - "assets": [ - "projects/sample-code-flow-lazy-loaded/src/favicon.ico", - "projects/sample-code-flow-lazy-loaded/src/assets" - ], - "styles": [ - "projects/sample-code-flow-lazy-loaded/src/styles.css" - ], + "assets": ["projects/sample-code-flow-lazy-loaded/src/favicon.ico", "projects/sample-code-flow-lazy-loaded/src/assets"], + "styles": ["projects/sample-code-flow-lazy-loaded/src/styles.css"], "scripts": [] }, "configurations": { @@ -1051,23 +964,15 @@ "polyfills": "projects/sample-code-flow-lazy-loaded/src/polyfills.ts", "tsConfig": "projects/sample-code-flow-lazy-loaded/tsconfig.spec.json", "karmaConfig": "projects/sample-code-flow-lazy-loaded/karma.conf.js", - "assets": [ - "projects/sample-code-flow-lazy-loaded/src/favicon.ico", - "projects/sample-code-flow-lazy-loaded/src/assets" - ], - "styles": [ - "projects/sample-code-flow-lazy-loaded/src/styles.css" - ], + "assets": ["projects/sample-code-flow-lazy-loaded/src/favicon.ico", "projects/sample-code-flow-lazy-loaded/src/assets"], + "styles": ["projects/sample-code-flow-lazy-loaded/src/styles.css"], "scripts": [] } }, "lint": { "builder": "@angular-eslint/builder:lint", "options": { - "lintFilePatterns": [ - "projects/sample-code-flow-lazy-loaded/**/*.ts", - "projects/sample-code-flow-lazy-loaded/**/*.html" - ] + "lintFilePatterns": ["projects/sample-code-flow-lazy-loaded/**/*.ts", "projects/sample-code-flow-lazy-loaded/**/*.html"] } }, "e2e": { @@ -1083,6 +988,117 @@ } } } + }, + "sample-code-flow-popup": { + "projectType": "application", + "schematics": {}, + "root": "projects/sample-code-flow-popup", + "sourceRoot": "projects/sample-code-flow-popup/src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/sample-code-flow-popup", + "index": "projects/sample-code-flow-popup/src/index.html", + "main": "projects/sample-code-flow-popup/src/main.ts", + "polyfills": "projects/sample-code-flow-popup/src/polyfills.ts", + "tsConfig": "projects/sample-code-flow-popup/tsconfig.app.json", + "aot": true, + "assets": [ + "projects/sample-code-flow-popup/src/favicon.ico", + "projects/sample-code-flow-popup/src/silent-renew.html", + "projects/sample-code-flow-popup/src/assets" + ], + "styles": ["projects/sample-code-flow-popup/src/styles.css"], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "projects/sample-code-flow-popup/src/environments/environment.ts", + "with": "projects/sample-code-flow-popup/src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "6kb", + "maximumError": "10kb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "sample-code-flow-popup:build", + "sslKey": "certs/dev_localhost.key", + "sslCert": "certs/dev_localhost.pem", + "port": 4205 + }, + "configurations": { + "production": { + "browserTarget": "sample-code-flow-popup:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "sample-code-flow-popup:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "projects/sample-code-flow-popup/src/test.ts", + "polyfills": "projects/sample-code-flow-popup/src/polyfills.ts", + "tsConfig": "projects/sample-code-flow-popup/tsconfig.spec.json", + "karmaConfig": "projects/sample-code-flow-popup/karma.conf.js", + "assets": ["projects/sample-code-flow-popup/src/favicon.ico", "projects/sample-code-flow-popup/src/assets"], + "styles": ["projects/sample-code-flow-popup/src/styles.css"], + "scripts": [] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "projects/sample-code-flow-popup/tsconfig.app.json", + "projects/sample-code-flow-popup/tsconfig.spec.json", + "projects/sample-code-flow-popup/e2e/tsconfig.json" + ], + "exclude": ["**/node_modules/**"] + } + }, + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "projects/sample-code-flow-popup/e2e/protractor.conf.js", + "devServerTarget": "sample-code-flow-popup:serve" + }, + "configurations": { + "production": { + "devServerTarget": "sample-code-flow-popup:serve:production" + } + } + } + } } }, "cli": { diff --git a/docs/authorizing-popup-iframe.md b/docs/authorizing-popup-iframe.md deleted file mode 100644 index 181e18f90..000000000 --- a/docs/authorizing-popup-iframe.md +++ /dev/null @@ -1,14 +0,0 @@ -# Authorizing in a popup or iframe - -You can call the Provider's authorization endpoint in a popup or iframe instead of navigating to it in the app's parent window. -This allows you to have the Provider's consent prompt display in a popup window to avoid unloading and reloading the app, -or to authorize the user silently by loading the endpoint in a hidden iframe if that supported by the Provider. - -To get the fully-formed authorization URL, pass a handler function to `OidcSecurityService.authorize` -(this will also prevent the default behavior of loading the authorization endpoint in the current window): - -```typescript -login() { - this.oidcSecurityService.authorizeWithPopUp(); -} -``` diff --git a/docs/authorizing-popup.md b/docs/authorizing-popup.md new file mode 100644 index 000000000..5f99c4af1 --- /dev/null +++ b/docs/authorizing-popup.md @@ -0,0 +1,35 @@ +# Authentication using a Popup + +You can authenticate with any Open ID Connect identity provider using a popup. + +This allows you to have the provider's consent prompt display in a popup window to avoid unloading and reloading the app. + +## Sample + +```typescript + userData$: Observable; + + isAuthenticated: boolean; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => { + console.log('app authenticated', isAuthenticated); + const at = this.oidcSecurityService.getToken(); + console.log(`Current access token is '${at}'`); + }); + } + + loginWithPopup() { + this.oidcSecurityService.authorizeWithPopUp().subscribe(({ isAuthenticated, userData, accessToken }) => { + console.log(isAuthenticated); + console.log(userData); + console.log(accessToken); + }); + } +``` + +## Sample Application + +[app.component.ts](../projects/sample-code-flow-popup/src/app/app.component.ts) diff --git a/docs/samples.md b/docs/samples.md index b2d9c0107..11f023377 100644 --- a/docs/samples.md +++ b/docs/samples.md @@ -1,14 +1,14 @@ # Samples using this library -- [Code Flow with PKCE Using a configuration from an http source and silent renew](#code-flow-with-pkce-using-a-configuration-from-an-http-source-and-silent-renew) -- [Code Flow PKCE with Refresh tokens](#code-flow-pkce-with-refresh-tokens) -- [Code Flow PKCE Auto login](#code-flow-pkce-auto-login) -- [Code Flow with PKCE basic with silent renew](#code-flow-with-pkce-basic-with-silent-renew) -- [Azure B2C Code Flow PKCE with silent renew](#azure-b2c-code-flow-pkce-with-silent-renew) -- [Azure AD Code Flow PKCE with silent renew](#azure-ad-oidc-code-flow-with-pkce) -- [Implicit Flow with silent renew (Not recommended)](#implicit-flow-with-silent-renew-not-recommended) -- [Implicit Flow google (Not recommended)](#implicit-flow-google-not-recommended) -- [Code flow with a lazy loaded module](#code-flow-with-a-lazy-loaded-module) +- [Code Flow with PKCE Using a configuration from an http source and silent renew](#code-flow-with-pkce-using-a-configuration-from-an-http-source-and-silent-renew) +- [Code Flow PKCE with Refresh tokens](#code-flow-pkce-with-refresh-tokens) +- [Code Flow PKCE Auto login](#code-flow-pkce-auto-login) +- [Code Flow with PKCE basic with silent renew](#code-flow-with-pkce-basic-with-silent-renew) +- [Azure B2C Code Flow PKCE with silent renew](#azure-b2c-code-flow-pkce-with-silent-renew) +- [Azure AD Code Flow PKCE with silent renew](#azure-ad-oidc-code-flow-with-pkce) +- [Implicit Flow with silent renew (Not recommended)](#implicit-flow-with-silent-renew-not-recommended) +- [Implicit Flow google (Not recommended)](#implicit-flow-google-not-recommended) +- [Code flow with a lazy loaded module](#code-flow-with-a-lazy-loaded-module) ## Code Flow with PKCE Using a configuration from an http source and silent renew @@ -127,3 +127,15 @@ The example uses the Code flow with silent renew but you authenticate in a lazy [lazy.component.ts](../projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.ts) [lazy.component.html](../projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.html) + +### [src code](../projects/sample-code-flow-popup) + +[app.module.ts](../projects/sample-code-flow-popup/src/app/app.module.ts) + +[app.component.ts](../projects/sample-code-flow-popup/src/app/app.component.ts) + +[app.component.html](../projects/sample-code-flow-popup/src/app/app.component.html) + +[lazy.component.ts](../projects/sample-code-flow-popup/src/app/lazy/lazy.component.ts) + +[lazy.component.html](../projects/sample-code-flow-popup/src/app/lazy/lazy.component.html) diff --git a/package.json b/package.json index 7e1299896..66df90051 100644 --- a/package.json +++ b/package.json @@ -27,11 +27,12 @@ "copy-readme-to-lib-folder": "ncp README.md ./dist/angular-auth-oidc-client/README.md", "copy-licence-to-lib-folder": "ncp LICENSE ./dist/angular-auth-oidc-client/LICENSE", "check-prettier": "prettier --check \"projects/angular-auth-oidc-client/**/*.*\"", - "fix-prettier": "prettier --write \"projects/angular-auth-oidc-client/**/*.*\"", + "fix-prettier": "prettier --write \"projects/**/*.*\"", "start": "ng serve sample-code-flow --ssl -o", "coveralls": "cat ./coverage/angular-auth-oidc-client/lcov.info | coveralls", "start-sample-code-flow-auto-login": "ng serve sample-code-flow-auto-login --ssl -o", "start-sample-code-flow": "ng serve sample-code-flow --ssl -o", + "start-sample-code-flow-popup": "ng serve sample-code-flow-popup --ssl -o", "start-sample-code-flow-http-config": "ng serve sample-code-flow-http-config --ssl -o", "start-sample-code-flow-refresh-tokens": "ng serve sample-code-flow-refresh-tokens --ssl -o", "start-sample-code-flow-azure-b2c": "ng serve sample-code-flow-azure-b2c --ssl -o", diff --git a/projects/angular-auth-oidc-client/src/lib/auth.module.ts b/projects/angular-auth-oidc-client/src/lib/auth.module.ts index 95318f292..abc0ede25 100644 --- a/projects/angular-auth-oidc-client/src/lib/auth.module.ts +++ b/projects/angular-auth-oidc-client/src/lib/auth.module.ts @@ -4,6 +4,7 @@ import { NgModule } from '@angular/core'; import { DataService } from './api/data.service'; import { HttpBaseService } from './api/http-base.service'; import { AuthStateService } from './authState/auth-state.service'; +import { CheckAuthService } from './check-auth.service'; import { ConfigValidationService } from './config-validation/config-validation.service'; import { AuthWellKnownDataService } from './config/auth-well-known-data.service'; import { AuthWellKnownService } from './config/auth-well-known.service'; @@ -72,6 +73,7 @@ export class AuthModule { DataService, StateValidationService, ConfigValidationService, + CheckAuthService, { provide: AbstractSecurityStorage, useClass: token.storage || BrowserStorageService, diff --git a/projects/angular-auth-oidc-client/src/lib/check-auth.service-mock.ts b/projects/angular-auth-oidc-client/src/lib/check-auth.service-mock.ts new file mode 100644 index 000000000..c0c4788a6 --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/check-auth.service-mock.ts @@ -0,0 +1,13 @@ +import { Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; + +@Injectable() +export class CheckAuthServiceMock { + checkAuth(url?: string): Observable { + return of(null); + } + + checkAuthIncludingServer(): Observable { + return of(null); + } +} diff --git a/projects/angular-auth-oidc-client/src/lib/check-auth.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/check-auth.service.spec.ts new file mode 100644 index 000000000..c826f44c1 --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/check-auth.service.spec.ts @@ -0,0 +1,255 @@ +import { HttpClientModule } from '@angular/common/http'; +import { TestBed, waitForAsync } from '@angular/core/testing'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; +import { of, throwError } from 'rxjs'; +import { AuthModule } from './auth.module'; +import { AuthStateService } from './authState/auth-state.service'; +import { CallbackService } from './callback/callback.service'; +import { PeriodicallyTokenCheckService } from './callback/periodically-token-check.service'; +import { RefreshSessionService } from './callback/refresh-session.service'; +import { ConfigurationProvider } from './config/config.provider'; +import { CheckSessionService } from './iframe/check-session.service'; +import { SilentRenewService } from './iframe/silent-renew.service'; +import { LoggerService } from './logging/logger.service'; +import { LoggerServiceMock } from './logging/logger.service-mock'; +import { PopUpService } from './login/popup.service'; +import { OidcSecurityService } from './oidc.security.service'; +import { UserService } from './userData/user-service'; + +describe('CheckAuthService', () => { + let oidcSecurityService: OidcSecurityService; + let configurationProvider: ConfigurationProvider; + let authStateService: AuthStateService; + let userService: UserService; + let checkSessionService: CheckSessionService; + let callBackService: CallbackService; + let silentRenewService: SilentRenewService; + let periodicallyTokenCheckService: PeriodicallyTokenCheckService; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [BrowserModule, HttpClientModule, RouterTestingModule, AuthModule.forRoot()], + providers: [ + CheckSessionService, + SilentRenewService, + UserService, + { provide: LoggerService, useClass: LoggerServiceMock }, + ConfigurationProvider, + AuthStateService, + CallbackService, + RefreshSessionService, + PeriodicallyTokenCheckService, + PopUpService, + ], + }); + }); + + beforeEach(() => { + oidcSecurityService = TestBed.inject(OidcSecurityService); + configurationProvider = TestBed.inject(ConfigurationProvider); + userService = TestBed.inject(UserService); + authStateService = TestBed.inject(AuthStateService); + checkSessionService = TestBed.inject(CheckSessionService); + callBackService = TestBed.inject(CallbackService); + silentRenewService = TestBed.inject(SilentRenewService); + + periodicallyTokenCheckService = TestBed.inject(PeriodicallyTokenCheckService); + }); + + it('should create', () => { + expect(oidcSecurityService).toBeTruthy(); + }); + + describe('checkAuth', () => { + it( + 'returns false when config is not valid', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(false); + oidcSecurityService.checkAuth().subscribe((result) => expect(result).toBeFalse()); + }) + ); + + it( + 'returns false in case handleCallbackAndFireEvents throws an error', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'isCallback').and.returnValue(true); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + const spy = spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(throwError('ERROR')); + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeFalse(); + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'calls callbackService.handlePossibleStsCallback with current url when callback is true', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'isCallback').and.returnValue(true); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + const spy = spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeTrue(); + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'does NOT call handleCallbackAndFireEvents with current url when callback is false', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'isCallback').and.returnValue(false); + const spy = spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeFalse(); + expect(spy).not.toHaveBeenCalled(); + }); + }) + ); + + it( + 'does fire the auth and user data events when it is not a callback from the sts and is authenticated', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'isCallback').and.returnValue(false); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + + const setAuthorizedAndFireEventSpy = spyOn(authStateService, 'setAuthorizedAndFireEvent'); + const userServiceSpy = spyOn(userService, 'publishUserDataIfExists'); + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeTrue(); + expect(setAuthorizedAndFireEventSpy).toHaveBeenCalled(); + expect(userServiceSpy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'does NOT fire the auth and user data events when it is not a callback from the sts and is NOT authenticated', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'isCallback').and.returnValue(false); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(false); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + + const setAuthorizedAndFireEventSpy = spyOn(authStateService, 'setAuthorizedAndFireEvent'); + const userServiceSpy = spyOn(userService, 'publishUserDataIfExists'); + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeFalse(); + expect(setAuthorizedAndFireEventSpy).not.toHaveBeenCalled(); + expect(userServiceSpy).not.toHaveBeenCalled(); + }); + }) + ); + + it( + 'if authenticated return true', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(result).toBeTrue(); + }); + }) + ); + + it( + 'if authenticated set auth and fires event ', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + const spy = spyOn(authStateService, 'setAuthorizedAndFireEvent'); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'if authenticated publishUserdataIfExists ', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + const spy = spyOn(userService, 'publishUserDataIfExists'); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'if authenticated callbackService startTokenValidationPeriodically', + waitForAsync(() => { + const config = { + stsServer: 'stsServer', + tokenRefreshInSeconds: 7, + }; + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue(config); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + const spy = spyOn(periodicallyTokenCheckService, 'startTokenValidationPeriodically'); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(spy).toHaveBeenCalledWith(7); + }); + }) + ); + + it( + 'if isCheckSessionConfigured call checkSessionService.start()', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + spyOn(checkSessionService, 'isCheckSessionConfigured').and.returnValue(true); + const spy = spyOn(checkSessionService, 'start'); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'if isSilentRenewConfigured call getOrCreateIframe()', + waitForAsync(() => { + spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); + spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); + spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); + spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); + + spyOn(silentRenewService, 'isSilentRenewConfigured').and.returnValue(true); + const spy = spyOn(silentRenewService, 'getOrCreateIframe'); + + oidcSecurityService.checkAuth().subscribe((result) => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); + }); +}); diff --git a/projects/angular-auth-oidc-client/src/lib/check-auth.service.ts b/projects/angular-auth-oidc-client/src/lib/check-auth.service.ts new file mode 100644 index 000000000..f7e7e8c0b --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/check-auth.service.ts @@ -0,0 +1,107 @@ +import { DOCUMENT } from '@angular/common'; +import { Inject, Injectable } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { catchError, map, switchMap } from 'rxjs/operators'; +import { AuthStateService } from './authState/auth-state.service'; +import { CallbackService } from './callback/callback.service'; +import { PeriodicallyTokenCheckService } from './callback/periodically-token-check.service'; +import { RefreshSessionService } from './callback/refresh-session.service'; +import { ConfigurationProvider } from './config/config.provider'; +import { CheckSessionService } from './iframe/check-session.service'; +import { SilentRenewService } from './iframe/silent-renew.service'; +import { LoggerService } from './logging/logger.service'; +import { PopUpService } from './login/popup.service'; +import { UserService } from './userData/user-service'; + +@Injectable() +export class CheckAuthService { + constructor( + @Inject(DOCUMENT) private readonly doc: any, + private checkSessionService: CheckSessionService, + private silentRenewService: SilentRenewService, + private userService: UserService, + private loggerService: LoggerService, + private configurationProvider: ConfigurationProvider, + private authStateService: AuthStateService, + private callbackService: CallbackService, + private refreshSessionService: RefreshSessionService, + private periodicallyTokenCheckService: PeriodicallyTokenCheckService, + private popupService: PopUpService + ) {} + + checkAuth(url?: string): Observable { + if (!this.configurationProvider.hasValidConfig()) { + this.loggerService.logError('Please provide a configuration before setting up the module'); + return of(false); + } + + this.loggerService.logDebug('STS server: ' + this.configurationProvider.openIDConfiguration.stsServer); + + const currentUrl = url || this.doc.defaultView.location.toString(); + + if (this.popupService.isCurrentlyInPopup()) { + this.popupService.sendMessageToMainWindow(currentUrl); + return of(null); + } + + const isCallback = this.callbackService.isCallback(currentUrl); + + this.loggerService.logDebug('currentUrl to check auth with: ', currentUrl); + + const callback$ = isCallback ? this.callbackService.handleCallbackAndFireEvents(currentUrl) : of(null); + + return callback$.pipe( + map(() => { + const isAuthenticated = this.authStateService.areAuthStorageTokensValid(); + if (isAuthenticated) { + this.startCheckSessionAndValidation(); + + if (!isCallback) { + this.authStateService.setAuthorizedAndFireEvent(); + this.userService.publishUserDataIfExists(); + } + } + + this.loggerService.logDebug('checkAuth completed fired events, auth: ' + isAuthenticated); + + return isAuthenticated; + }), + catchError(() => of(false)) + ); + } + + checkAuthIncludingServer(): Observable { + return this.checkAuth().pipe( + switchMap((isAuthenticated) => { + if (isAuthenticated) { + return of(isAuthenticated); + } + + return this.refreshSessionService.forceRefreshSession().pipe( + map((result) => !!result?.idToken && !!result?.accessToken), + switchMap((isAuth) => { + if (isAuth) { + this.startCheckSessionAndValidation(); + } + + return of(isAuth); + }) + ); + }) + ); + } + + private startCheckSessionAndValidation() { + if (this.checkSessionService.isCheckSessionConfigured()) { + this.checkSessionService.start(); + } + + this.periodicallyTokenCheckService.startTokenValidationPeriodically( + this.configurationProvider.openIDConfiguration.tokenRefreshInSeconds + ); + + if (this.silentRenewService.isSilentRenewConfigured()) { + this.silentRenewService.getOrCreateIframe(); + } + } +} diff --git a/projects/angular-auth-oidc-client/src/lib/flows/flows.service.ts b/projects/angular-auth-oidc-client/src/lib/flows/flows.service.ts index f11753582..11854f018 100644 --- a/projects/angular-auth-oidc-client/src/lib/flows/flows.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/flows/flows.service.ts @@ -92,7 +92,7 @@ export class FlowsService { this.loggerService.logDebug('no code in url'); return throwError('no code in url'); } - this.loggerService.logDebug('running validation for callback' + urlToCheck); + this.loggerService.logDebug('running validation for callback', urlToCheck); const initialCallbackContext = { code, @@ -105,6 +105,7 @@ export class FlowsService { validationResult: null, existingIdToken: null, }; + return of(initialCallbackContext); } diff --git a/projects/angular-auth-oidc-client/src/lib/iframe/check-session.service.ts b/projects/angular-auth-oidc-client/src/lib/iframe/check-session.service.ts index 3eca5e7c3..3c1872867 100644 --- a/projects/angular-auth-oidc-client/src/lib/iframe/check-session.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/iframe/check-session.service.ts @@ -20,12 +20,12 @@ export class CheckSessionService { private outstandingMessages = 0; private heartBeatInterval = 3000; private iframeRefreshInterval = 60000; - private checkSessionChangedInternal$ = new BehaviorSubject(false); get checkSessionChanged$() { return this.checkSessionChangedInternal$.asObservable(); } + constructor( private storagePersistanceService: StoragePersistanceService, private loggerService: LoggerService, diff --git a/projects/angular-auth-oidc-client/src/lib/logging/logger.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/logging/logger.service.spec.ts index b9e971585..be96a9d22 100644 --- a/projects/angular-auth-oidc-client/src/lib/logging/logger.service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/logging/logger.service.spec.ts @@ -44,7 +44,7 @@ describe('Logger Service', () => { const spy = spyOn(console, 'error'); loggerService.logError('some message', 'arg1', 'arg2'); - expect(spy).toHaveBeenCalledWith('some message', ['arg1', 'arg2']); + expect(spy).toHaveBeenCalledWith('some message', 'arg1', 'arg2'); }); }); @@ -77,7 +77,7 @@ describe('Logger Service', () => { configProvider.setConfig({ logLevel: LogLevel.Warn }); loggerService.logWarning('some message', 'arg1', 'arg2'); - expect(spy).toHaveBeenCalledWith('some message', ['arg1', 'arg2']); + expect(spy).toHaveBeenCalledWith('some message', 'arg1', 'arg2'); }); it('should log warning when loglevel is Debug', () => { @@ -126,7 +126,7 @@ describe('Logger Service', () => { configProvider.setConfig({ logLevel: LogLevel.Debug }); loggerService.logDebug('some message', 'arg1', 'arg2'); - expect(spy).toHaveBeenCalledWith('some message', ['arg1', 'arg2']); + expect(spy).toHaveBeenCalledWith('some message', 'arg1', 'arg2'); }); it('should not log when loglevel is Warn', () => { diff --git a/projects/angular-auth-oidc-client/src/lib/logging/logger.service.ts b/projects/angular-auth-oidc-client/src/lib/logging/logger.service.ts index 5593c530f..62dc8fd32 100644 --- a/projects/angular-auth-oidc-client/src/lib/logging/logger.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/logging/logger.service.ts @@ -12,7 +12,7 @@ export class LoggerService { } if (!!args && args.length) { - console.error(message, args); + console.error(message, ...args); } else { console.error(message); } @@ -32,7 +32,7 @@ export class LoggerService { } if (!!args && args.length) { - console.warn(message, args); + console.warn(message, ...args); } else { console.warn(message); } @@ -52,7 +52,7 @@ export class LoggerService { } if (!!args && args.length) { - console.log(message, args); + console.log(message, ...args); } else { console.log(message); } diff --git a/projects/angular-auth-oidc-client/src/lib/login/login.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/login/login.service.spec.ts index d55366ef1..1aac1a3b9 100644 --- a/projects/angular-auth-oidc-client/src/lib/login/login.service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/login/login.service.spec.ts @@ -1,23 +1,26 @@ import { CommonModule } from '@angular/common'; import { TestBed, waitForAsync } from '@angular/core/testing'; import { of } from 'rxjs'; +import { AuthStateService } from '../authState/auth-state.service'; +import { AuthStateServiceMock } from '../authState/auth-state.service-mock'; +import { CheckAuthServiceMock } from '../check-auth.service-mock'; import { AuthWellKnownService } from '../config/auth-well-known.service'; import { AuthWellKnownServiceMock } from '../config/auth-well-known.service-mock'; import { ConfigurationProvider } from '../config/config.provider'; import { ConfigurationProviderMock } from '../config/config.provider-mock'; -import { FlowsService } from '../flows/flows.service'; -import { FlowsServiceMock } from '../flows/flows.service-mock'; import { LoggerService } from '../logging/logger.service'; import { LoggerServiceMock } from '../logging/logger.service-mock'; -import { StoragePersistanceService } from '../storage/storage-persistance.service'; -import { StoragePersistanceServiceMock } from '../storage/storage-persistance.service-mock'; import { RedirectService } from '../utils/redirect/redirect.service'; -import { RedirectServiceMock } from '../utils/redirect/redirect.service-mock'; import { UrlService } from '../utils/url/url.service'; import { UrlServiceMock } from '../utils/url/url.service-mock'; import { TokenValidationService } from '../validation/token-validation.service'; import { TokenValidationServiceMock } from '../validation/token-validation.service-mock'; +import { CheckAuthService } from './../check-auth.service'; +import { UserService } from './../userData/user-service'; +import { UserServiceMock } from './../userData/user-service-mock'; import { LoginService } from './login.service'; +import { PopUpService } from './popup.service'; +import { PopUpServiceMock } from './popup.service-mock'; describe('LoginService', () => { let loginService: LoginService; @@ -25,27 +28,28 @@ describe('LoginService', () => { let urlService: UrlService; let loggerService: LoggerService; let tokenValidationService: TokenValidationService; - let flowsService: FlowsService; let redirectService: RedirectService; let authWellKnownService: AuthWellKnownService; + let popupService: PopUpService; + let checkAuthService: CheckAuthService; + let userService: UserService; + let authStateService: AuthStateService; beforeEach(() => { TestBed.configureTestingModule({ imports: [CommonModule], providers: [ - LoginService, - { - provide: StoragePersistanceService, - useClass: StoragePersistanceServiceMock, - }, { provide: LoggerService, useClass: LoggerServiceMock }, - { provide: ConfigurationProvider, useClass: ConfigurationProviderMock }, - { provide: AuthWellKnownService, useClass: AuthWellKnownServiceMock }, { provide: TokenValidationService, useClass: TokenValidationServiceMock }, { provide: UrlService, useClass: UrlServiceMock }, - { provide: FlowsService, useClass: FlowsServiceMock }, - { provide: RedirectService, useClass: RedirectServiceMock }, + RedirectService, + { provide: ConfigurationProvider, useClass: ConfigurationProviderMock }, { provide: AuthWellKnownService, useClass: AuthWellKnownServiceMock }, + { provide: PopUpService, useClass: PopUpServiceMock }, + { provide: CheckAuthService, useClass: CheckAuthServiceMock }, + { provide: UserService, useClass: UserServiceMock }, + { provide: AuthStateService, useClass: AuthStateServiceMock }, + LoginService, ], }); }); @@ -56,9 +60,12 @@ describe('LoginService', () => { urlService = TestBed.inject(UrlService); loggerService = TestBed.inject(LoggerService); tokenValidationService = TestBed.inject(TokenValidationService); - flowsService = TestBed.inject(FlowsService); redirectService = TestBed.inject(RedirectService); authWellKnownService = TestBed.inject(AuthWellKnownService); + popupService = TestBed.inject(PopUpService); + checkAuthService = TestBed.inject(CheckAuthService); + userService = TestBed.inject(UserService); + authStateService = TestBed.inject(AuthStateService); }); it('should create', () => { @@ -89,21 +96,6 @@ describe('LoginService', () => { }) ); - it( - 'calls flowsService.resetAuthorizationData() if everything fits', - waitForAsync(() => { - spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ - authWellknownEndpoint: 'authWellknownEndpoint', - responseType: 'stubValue', - }); - spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); - spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); - spyOn(redirectService, 'redirectTo').and.callFake(() => {}); - const result = loginService.login(); - expect(result).toBeUndefined(); - }) - ); - it( 'calls urlService.getAuthorizeUrl() if everything fits', waitForAsync(() => { @@ -113,7 +105,6 @@ describe('LoginService', () => { }); spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); - spyOn(flowsService, 'resetAuthorizationData').and.callFake(() => {}); const spy = spyOn(urlService, 'getAuthorizeUrl'); spyOn(redirectService, 'redirectTo').and.callFake(() => {}); const result = loginService.login(); @@ -131,17 +122,16 @@ describe('LoginService', () => { }); spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); - spyOn(flowsService, 'resetAuthorizationData').and.callFake(() => {}); spyOn(urlService, 'getAuthorizeUrl').and.returnValue('someUrl'); - const redirectspy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); + const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); const result = loginService.login(); expect(result).toBeUndefined(); - expect(redirectspy).toHaveBeenCalledWith('someUrl'); + expect(redirectSpy).toHaveBeenCalledWith('someUrl'); }) ); it( - 'redirects to url with url handler when urlhandler is given', + 'redirects to url with url handler when urlHandler is given', waitForAsync(() => { spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ authWellknownEndpoint: 'authWellknownEndpoint', @@ -149,9 +139,8 @@ describe('LoginService', () => { }); spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); - spyOn(flowsService, 'resetAuthorizationData').and.callFake(() => {}); spyOn(urlService, 'getAuthorizeUrl').and.returnValue('someUrl'); - const redirectspy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); + const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); const spy = jasmine.createSpy(); const urlHandler = (url) => { spy(url); @@ -159,7 +148,7 @@ describe('LoginService', () => { const result = loginService.login({ urlHandler }); expect(result).toBeUndefined(); expect(spy).toHaveBeenCalledWith('someUrl'); - expect(redirectspy).not.toHaveBeenCalled(); + expect(redirectSpy).not.toHaveBeenCalled(); }) ); @@ -172,15 +161,106 @@ describe('LoginService', () => { }); spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); - spyOn(flowsService, 'resetAuthorizationData').and.callFake(() => {}); const getAuthorizeUrlSpy = spyOn(urlService, 'getAuthorizeUrl').and.returnValue('someUrl'); - const redirectspy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); + const redirectSpy = spyOn(redirectService, 'redirectTo').and.callFake(() => {}); const result = loginService.login({ customParams: { to: 'add', as: 'well' } }); expect(result).toBeUndefined(); - expect(redirectspy).toHaveBeenCalledWith('someUrl'); + expect(redirectSpy).toHaveBeenCalledWith('someUrl'); expect(getAuthorizeUrlSpy).toHaveBeenCalledWith({ to: 'add', as: 'well' }); }) ); }); + + describe('loginWithPopup', () => { + it( + 'does nothing if it has an invalid response type', + waitForAsync(() => { + spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ responseType: 'stubValue' }); + spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(false); + const loggerSpy = spyOn(loggerService, 'logError'); + + const result = loginService.loginWithPopUp(); + + expect(result).toBeUndefined(); + expect(loggerSpy).toHaveBeenCalled(); + }) + ); + + it( + 'does nothing if no well known endpoint is given', + waitForAsync(() => { + spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ responseType: 'stubValue' }); + const spy = spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); + const loggerSpy = spyOn(loggerService, 'logError'); + + const result = loginService.loginWithPopUp(); + + expect(result).toBeUndefined(); + expect(spy).toHaveBeenCalled(); + expect(loggerSpy).toHaveBeenCalled(); + }) + ); + + it( + 'calls urlService.getAuthorizeUrl() if everything fits', + waitForAsync(() => { + spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ + authWellknownEndpoint: 'authWellknownEndpoint', + responseType: 'stubValue', + }); + spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); + spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); + const spy = spyOn(urlService, 'getAuthorizeUrl'); + + loginService.loginWithPopUp().subscribe(() => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'opens popup if everything fits', + waitForAsync(() => { + spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ + authWellknownEndpoint: 'authWellknownEndpoint', + responseType: 'stubValue', + }); + spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); + spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); + spyOn(urlService, 'getAuthorizeUrl'); + const popupSpy = spyOn(popupService, 'openPopUp'); + + loginService.loginWithPopUp().subscribe(() => { + expect(popupSpy).toHaveBeenCalled(); + }); + }) + ); + + it( + 'returns three properties when popupservice received an url', + waitForAsync(() => { + spyOnProperty(configurationProvider, 'openIDConfiguration').and.returnValue({ + authWellknownEndpoint: 'authWellknownEndpoint', + responseType: 'stubValue', + }); + spyOn(tokenValidationService, 'configValidateResponseType').and.returnValue(true); + spyOn(authWellKnownService, 'getAuthWellKnownEndPoints').and.returnValue(of({})); + spyOn(urlService, 'getAuthorizeUrl'); + spyOn(popupService, 'openPopUp'); + const checkAuthSpy = spyOn(checkAuthService, 'checkAuth').and.returnValue(of(true)); + const getUserDataFromStoreSpy = spyOn(userService, 'getUserDataFromStore').and.returnValue({ any: 'userData' }); + const getAccessTokenSpy = spyOn(authStateService, 'getAccessToken').and.returnValue('anyAccessToken'); + spyOnProperty(popupService, 'receivedUrl$').and.returnValue(of('someUrl')); + + loginService.loginWithPopUp().subscribe((result) => { + expect(checkAuthSpy).toHaveBeenCalledWith('someUrl'); + expect(getUserDataFromStoreSpy).toHaveBeenCalledTimes(1); + expect(getAccessTokenSpy).toHaveBeenCalledTimes(1); + + expect(result).toEqual({ isAuthenticated: true, userData: { any: 'userData' }, accessToken: 'anyAccessToken' }); + }); + }) + ); + }); }); diff --git a/projects/angular-auth-oidc-client/src/lib/login/login.service.ts b/projects/angular-auth-oidc-client/src/lib/login/login.service.ts index c980e2aa1..cd215b44d 100644 --- a/projects/angular-auth-oidc-client/src/lib/login/login.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/login/login.service.ts @@ -1,11 +1,17 @@ import { Injectable } from '@angular/core'; +import { map, switchMap } from 'rxjs/operators'; +import { AuthStateService } from '../authState/auth-state.service'; import { AuthWellKnownService } from '../config/auth-well-known.service'; import { ConfigurationProvider } from '../config/config.provider'; import { LoggerService } from '../logging/logger.service'; import { RedirectService } from '../utils/redirect/redirect.service'; import { UrlService } from '../utils/url/url.service'; import { TokenValidationService } from '../validation/token-validation.service'; +import { CheckAuthService } from './../check-auth.service'; +import { UserService } from './../userData/user-service'; import { AuthOptions } from './auth-options'; +import { PopupOptions } from './popup-options'; +import { PopUpService } from './popup.service'; @Injectable() export class LoginService { @@ -15,7 +21,11 @@ export class LoginService { private urlService: UrlService, private redirectService: RedirectService, private configurationProvider: ConfigurationProvider, - private authWellKnownService: AuthWellKnownService + private authWellKnownService: AuthWellKnownService, + private popupService: PopUpService, + private checkAuthService: CheckAuthService, + private userService: UserService, + private authStateService: AuthStateService ) {} login(authOptions?: AuthOptions) { @@ -24,7 +34,7 @@ export class LoginService { return; } - const authWellknownEndpoint = this.configurationProvider.openIDConfiguration?.authWellknownEndpoint; + const authWellknownEndpoint = this.configurationProvider.openIDConfiguration.authWellknownEndpoint; if (!authWellknownEndpoint) { this.loggerService.logError('no authWellknownEndpoint given!'); @@ -50,4 +60,39 @@ export class LoginService { } }); } + + loginWithPopUp(authOptions?: AuthOptions, popupOptions?: PopupOptions) { + if (!this.tokenValidationService.configValidateResponseType(this.configurationProvider.openIDConfiguration.responseType)) { + this.loggerService.logError('Invalid response type!'); + return; + } + + const authWellknownEndpoint = this.configurationProvider.openIDConfiguration.authWellknownEndpoint; + + if (!authWellknownEndpoint) { + this.loggerService.logError('no authWellknownEndpoint given!'); + return; + } + + this.loggerService.logDebug('BEGIN Authorize OIDC Flow with popup, no auth data'); + + return this.authWellKnownService.getAuthWellKnownEndPoints(authWellknownEndpoint).pipe( + switchMap(() => { + const { customParams } = authOptions || {}; + + const authUrl = this.urlService.getAuthorizeUrl(customParams); + + this.popupService.openPopUp(authUrl, popupOptions); + + return this.popupService.receivedUrl$.pipe( + switchMap((url: string) => this.checkAuthService.checkAuth(url)), + map((isAuthenticated) => ({ + isAuthenticated, + userData: this.userService.getUserDataFromStore(), + accessToken: this.authStateService.getAccessToken(), + })) + ); + }) + ); + } } diff --git a/projects/angular-auth-oidc-client/src/lib/login/popup-options.ts b/projects/angular-auth-oidc-client/src/lib/login/popup-options.ts new file mode 100644 index 000000000..9852a4c1c --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/login/popup-options.ts @@ -0,0 +1,6 @@ +export interface PopupOptions { + width?: number; + height?: number; + left?: number; + top?: number; +} diff --git a/projects/angular-auth-oidc-client/src/lib/login/popup.service-mock.ts b/projects/angular-auth-oidc-client/src/lib/login/popup.service-mock.ts new file mode 100644 index 000000000..8fddf454b --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/login/popup.service-mock.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@angular/core'; +import { of } from 'rxjs'; +import { PopupOptions } from './popup-options'; + +@Injectable({ providedIn: 'root' }) +export class PopUpServiceMock { + get receivedUrl$() { + return of(null); + } + + hasPopup() { + return true; + } + + openPopUp(url: string, popupOptions?: PopupOptions) {} + + sendMessageToMainWindow(url: string) {} +} diff --git a/projects/angular-auth-oidc-client/src/lib/login/popup.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/login/popup.service.spec.ts new file mode 100644 index 000000000..9ce661e78 --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/login/popup.service.spec.ts @@ -0,0 +1,110 @@ +import { TestBed, waitForAsync } from '@angular/core/testing'; +import { PopUpService } from './popup.service'; + +describe('PopUpService', () => { + let popUpService: PopUpService; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [PopUpService], + }); + }); + + beforeEach(() => { + popUpService = TestBed.inject(PopUpService); + }); + + it('should create', () => { + expect(popUpService).toBeTruthy(); + }); + + describe('isCurrentlyInPopup', () => { + it('returns true if window has opener and opener does not equal the window', () => { + spyOnProperty(window, 'opener').and.returnValue({ some: 'thing' }); + + const result = popUpService.isCurrentlyInPopup(); + + expect(result).toBe(true); + }); + + it('returns false if there is no opener', () => { + spyOnProperty(window, 'opener').and.returnValue(null); + + const result = popUpService.isCurrentlyInPopup(); + + expect(result).toBe(false); + }); + }); + + describe('receivedUrl$', () => { + it( + 'emits when internal subject is called', + waitForAsync(() => { + popUpService.receivedUrl$.subscribe((result) => { + expect(result).toBe(true); + }); + + (popUpService as any).receivedUrlInternal$.next(true); + }) + ); + }); + + describe('openPopup', () => { + it( + 'popup opens with parameters and defaultoptions', + waitForAsync(() => { + const popupSpy = spyOn(window, 'open').and.callFake(() => null); + popUpService.openPopUp('url'); + + expect(popupSpy).toHaveBeenCalledOnceWith('url', '_blank', 'width=500,height=500,left=50,top=50'); + }) + ); + + it( + 'popup opens with parameters and passed options', + waitForAsync(() => { + const popupSpy = spyOn(window, 'open').and.callFake(() => null); + popUpService.openPopUp('url', { width: 100 }); + + expect(popupSpy).toHaveBeenCalledOnceWith('url', '_blank', 'width=100,height=500,left=50,top=50'); + }) + ); + + it( + 'xxx', + waitForAsync(() => { + const popupSpy = spyOn(window, 'open').and.callFake(() => ({ close: () => {} } as Window)); + popUpService.openPopUp('url', { width: 100 }); + + expect(popupSpy).toHaveBeenCalledOnceWith('url', '_blank', 'width=100,height=500,left=50,top=50'); + }) + ); + }); + + describe('sendMessageToMainWindow', () => { + it( + 'does nothing if window.opener is null', + waitForAsync(() => { + spyOnProperty(window, 'opener').and.returnValue(null); + + const sendMessageSpy = spyOn(popUpService as any, 'sendMessage'); + popUpService.sendMessageToMainWindow(''); + + expect(sendMessageSpy).not.toHaveBeenCalled(); + }) + ); + + it( + 'calls postMessage when window opener is given', + waitForAsync(() => { + spyOnProperty(window, 'opener').and.returnValue({ postMessage: () => {} }); + const sendMessageSpy = spyOn(window.opener, 'postMessage'); + + popUpService.sendMessageToMainWindow('someUrl'); + + expect(sendMessageSpy).toHaveBeenCalledTimes(1); + expect(sendMessageSpy).toHaveBeenCalledWith('someUrl', jasmine.any(String)); + }) + ); + }); +}); diff --git a/projects/angular-auth-oidc-client/src/lib/login/popup.service.ts b/projects/angular-auth-oidc-client/src/lib/login/popup.service.ts new file mode 100644 index 000000000..7b1120962 --- /dev/null +++ b/projects/angular-auth-oidc-client/src/lib/login/popup.service.ts @@ -0,0 +1,63 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; +import { PopupOptions } from './popup-options'; + +@Injectable({ providedIn: 'root' }) +export class PopUpService { + private popUp: Window; + private receivedUrlInternal$ = new Subject(); + + get receivedUrl$() { + return this.receivedUrlInternal$.asObservable(); + } + + isCurrentlyInPopup() { + return !!window.opener && window.opener !== window; + } + + openPopUp(url: string, popupOptions?: PopupOptions) { + const optionsToPass = this.getOptions(popupOptions); + this.popUp = window.open(url, '_blank', optionsToPass); + + const listener = (event: MessageEvent) => { + if (!event?.data || typeof event.data !== 'string') { + return; + } + + this.receivedUrlInternal$.next(event.data); + + this.cleanUp(listener); + }; + + window.addEventListener('message', listener, false); + } + + sendMessageToMainWindow(url: string) { + if (window.opener) { + this.sendMessage(url, window.location.href); + } + } + + private cleanUp(listener: any) { + window.removeEventListener('message', listener, false); + + if (this.popUp) { + this.popUp.close(); + this.popUp = null; + } + } + + private sendMessage(url: string, href: string) { + window.opener.postMessage(url, href); + } + + private getOptions(popupOptions?: PopupOptions) { + const popupDefaultOptions = { width: 500, height: 500, left: 50, top: 50 }; + + const options = { ...popupDefaultOptions, ...(popupOptions || {}) }; + + return Object.entries(options) + .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) + .join(','); + } +} diff --git a/projects/angular-auth-oidc-client/src/lib/oidc.security.service.spec.ts b/projects/angular-auth-oidc-client/src/lib/oidc.security.service.spec.ts index 66509a0a3..c6b0914bd 100644 --- a/projects/angular-auth-oidc-client/src/lib/oidc.security.service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/oidc.security.service.spec.ts @@ -147,29 +147,55 @@ describe('OidcSecurityService', () => { }); describe('authorize', () => { - it('calls loginservice login', () => { + it('calls login service login', () => { const spy = spyOn(loginService, 'login'); oidcSecurityService.authorize(); expect(spy).toHaveBeenCalled(); }); - it('calls loginservice login with params if given', () => { + it('calls login service login with params if given', () => { const spy = spyOn(loginService, 'login'); oidcSecurityService.authorize({ customParams: { any: 'thing' } }); expect(spy).toHaveBeenCalledWith({ customParams: { any: 'thing' } }); }); }); + describe('authorizeWithPopUp', () => { + it( + 'calls login service loginWithPopUp', + waitForAsync(() => { + const spy = spyOn(loginService, 'loginWithPopUp').and.callFake(() => of(null)); + oidcSecurityService.authorizeWithPopUp().subscribe(() => { + expect(spy).toHaveBeenCalledTimes(1); + }); + }) + ); + + it( + 'calls login service loginWithPopUp with params if given', + waitForAsync(() => { + const spy = spyOn(loginService, 'loginWithPopUp').and.callFake(() => of(null)); + oidcSecurityService.authorizeWithPopUp({ customParams: { any: 'thing' } }).subscribe(() => { + expect(spy).toHaveBeenCalledWith({ customParams: { any: 'thing' } }); + }); + }) + ); + }); + describe('isAuthenticated', () => { it('is of type observable', () => { expect(oidcSecurityService.isAuthenticated$).toEqual(jasmine.any(Observable)); }); - it('returns authStateService.authorized$', () => { - const spy = spyOnProperty(authStateService, 'authorized$', 'get'); - oidcSecurityService.isAuthenticated$; - expect(spy).toHaveBeenCalled(); - }); + it( + 'returns authStateService.authorized$', + waitForAsync(() => { + const spy = spyOnProperty(authStateService, 'authorized$', 'get').and.returnValue(of(null)); + oidcSecurityService.isAuthenticated$.subscribe(() => { + expect(spy).toHaveBeenCalled(); + }); + }) + ); }); describe('checkSessionChanged', () => { @@ -177,11 +203,29 @@ describe('OidcSecurityService', () => { expect(oidcSecurityService.checkSessionChanged$).toEqual(jasmine.any(Observable)); }); - it('returns checkSessionService.checkSessionChanged$', () => { - const spy = spyOnProperty(checkSessionService, 'checkSessionChanged$', 'get'); - oidcSecurityService.checkSessionChanged$; - expect(spy).toHaveBeenCalled(); - }); + it( + 'checkSessionChanged emits false initially', + waitForAsync(() => { + spyOnProperty(oidcSecurityService, 'checkSessionChanged$', 'get').and.callThrough(); + oidcSecurityService.checkSessionChanged$.subscribe((result) => { + expect(result).toBe(false); + }); + }) + ); + + it( + 'checkSessionChanged emits false then true when emitted', + waitForAsync(() => { + const expectedResultsInOrder = [false, true]; + let counter = 0; + oidcSecurityService.checkSessionChanged$.subscribe((result) => { + expect(result).toBe(expectedResultsInOrder[counter]); + counter++; + }); + + (checkSessionService as any).checkSessionChangedInternal$.next(true); + }) + ); }); describe('stsCallback', () => { @@ -253,7 +297,7 @@ describe('OidcSecurityService', () => { spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); const setAuthorizedAndFireEventSpy = spyOn(authStateService, 'setAuthorizedAndFireEvent'); - const userServiceSpy = spyOn(userService, 'publishUserdataIfExists'); + const userServiceSpy = spyOn(userService, 'publishUserDataIfExists'); oidcSecurityService.checkAuth().subscribe((result) => { expect(result).toBeTrue(); expect(setAuthorizedAndFireEventSpy).toHaveBeenCalled(); @@ -272,7 +316,7 @@ describe('OidcSecurityService', () => { spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); const setAuthorizedAndFireEventSpy = spyOn(authStateService, 'setAuthorizedAndFireEvent'); - const userServiceSpy = spyOn(userService, 'publishUserdataIfExists'); + const userServiceSpy = spyOn(userService, 'publishUserDataIfExists'); oidcSecurityService.checkAuth().subscribe((result) => { expect(result).toBeFalse(); expect(setAuthorizedAndFireEventSpy).not.toHaveBeenCalled(); @@ -312,14 +356,14 @@ describe('OidcSecurityService', () => { ); it( - 'if authenticated publishUserdataIfExists ', + 'if authenticated publishUserDataIfExists', waitForAsync(() => { spyOn(configurationProvider, 'hasValidConfig').and.returnValue(true); spyOnProperty(configurationProvider, 'openIDConfiguration', 'get').and.returnValue('stsServer'); spyOn(callBackService, 'handleCallbackAndFireEvents').and.returnValue(of(null)); spyOn(authStateService, 'areAuthStorageTokensValid').and.returnValue(true); - const spy = spyOn(userService, 'publishUserdataIfExists'); + const spy = spyOn(userService, 'publishUserDataIfExists'); oidcSecurityService.checkAuth().subscribe((result) => { expect(spy).toHaveBeenCalled(); @@ -517,8 +561,6 @@ describe('OidcSecurityService', () => { ); }); - describe('authorize', () => {}); - describe('logoffAndRevokeTokens', () => { it( 'calls logoffRevocationService.logoffAndRevokeTokens if no urlHandler is given', diff --git a/projects/angular-auth-oidc-client/src/lib/oidc.security.service.ts b/projects/angular-auth-oidc-client/src/lib/oidc.security.service.ts index 73d9d92a6..7df94e3e1 100644 --- a/projects/angular-auth-oidc-client/src/lib/oidc.security.service.ts +++ b/projects/angular-auth-oidc-client/src/lib/oidc.security.service.ts @@ -1,17 +1,13 @@ -import { DOCUMENT } from '@angular/common'; -import { Inject, Injectable } from '@angular/core'; -import { Observable, of } from 'rxjs'; -import { catchError, map, switchMap } from 'rxjs/operators'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; import { AuthStateService } from './authState/auth-state.service'; import { CallbackService } from './callback/callback.service'; -import { PeriodicallyTokenCheckService } from './callback/periodically-token-check.service'; import { RefreshSessionService } from './callback/refresh-session.service'; +import { CheckAuthService } from './check-auth.service'; import { ConfigurationProvider } from './config/config.provider'; import { PublicConfiguration } from './config/public-configuration'; import { FlowsDataService } from './flows/flows-data.service'; import { CheckSessionService } from './iframe/check-session.service'; -import { SilentRenewService } from './iframe/silent-renew.service'; -import { LoggerService } from './logging/logger.service'; import { AuthOptions } from './login/auth-options'; import { LoginService } from './login/login.service'; import { LogoffRevocationService } from './logoffRevoke/logoff-revocation.service'; @@ -45,12 +41,10 @@ export class OidcSecurityService { } constructor( - @Inject(DOCUMENT) private readonly doc: any, private checkSessionService: CheckSessionService, - private silentRenewService: SilentRenewService, + private checkAuthService: CheckAuthService, private userService: UserService, private tokenHelperService: TokenHelperService, - private loggerService: LoggerService, private configurationProvider: ConfigurationProvider, private authStateService: AuthStateService, private flowsDataService: FlowsDataService, @@ -58,64 +52,15 @@ export class OidcSecurityService { private logoffRevocationService: LogoffRevocationService, private loginService: LoginService, private storagePersistanceService: StoragePersistanceService, - private refreshSessionService: RefreshSessionService, - private periodicallyTokenCheckService: PeriodicallyTokenCheckService + private refreshSessionService: RefreshSessionService ) {} checkAuth(url?: string): Observable { - if (!this.configurationProvider.hasValidConfig()) { - this.loggerService.logError('Please provide a configuration before setting up the module'); - return of(false); - } - - this.loggerService.logDebug('STS server: ' + this.configurationProvider.openIDConfiguration.stsServer); - - const currentUrl = url || this.doc.defaultView.location.toString(); - const isCallback = this.callbackService.isCallback(currentUrl); - - this.loggerService.logDebug('currentUrl to check auth with: ', currentUrl); - - const callback$ = isCallback ? this.callbackService.handleCallbackAndFireEvents(currentUrl) : of(null); - - return callback$.pipe( - map(() => { - const isAuthenticated = this.authStateService.areAuthStorageTokensValid(); - if (isAuthenticated) { - this.startCheckSessionAndValidation(); - - if (!isCallback) { - this.authStateService.setAuthorizedAndFireEvent(); - this.userService.publishUserdataIfExists(); - } - } - - this.loggerService.logDebug('checkAuth completed fire events, auth: ' + isAuthenticated); - - return isAuthenticated; - }), - catchError(() => of(false)) - ); + return this.checkAuthService.checkAuth(url); } checkAuthIncludingServer(): Observable { - return this.checkAuth().pipe( - switchMap((isAuthenticated) => { - if (isAuthenticated) { - return of(isAuthenticated); - } - - return this.refreshSessionService.forceRefreshSession().pipe( - map((result) => !!result?.idToken && !!result?.accessToken), - switchMap((isAuth) => { - if (isAuth) { - this.startCheckSessionAndValidation(); - } - - return of(isAuth); - }) - ); - }) - ); + return this.checkAuthService.checkAuthIncludingServer(); } getToken(): string { @@ -146,26 +91,18 @@ export class OidcSecurityService { // Code Flow with PCKE or Implicit Flow authorize(authOptions?: AuthOptions) { if (authOptions?.customParams) { - this.storagePersistanceService.write('storageCustomRequestParams', authOptions?.customParams); + this.storagePersistanceService.write('storageCustomRequestParams', authOptions.customParams); } this.loginService.login(authOptions); } authorizeWithPopUp(authOptions?: AuthOptions) { - const internalUrlHandler = (authUrl) => { - // handle the authorization URL - this.doc.defaultView.open(authUrl, '_blank', 'toolbar=0,location=0,menubar=0'); - }; - - const urlHandler = authOptions?.urlHandler || internalUrlHandler; - - const options = { - urlHandler, - customParams: authOptions?.customParams, - }; + if (authOptions?.customParams) { + this.storagePersistanceService.write('storageCustomRequestParams', authOptions.customParams); + } - this.authorize(options); + return this.loginService.loginWithPopUp(authOptions); } forceRefreshSession(customParams?: { [key: string]: string | number | boolean }) { @@ -211,16 +148,4 @@ export class OidcSecurityService { getEndSessionUrl(): string | null { return this.logoffRevocationService.getEndSessionUrl(); } - - private startCheckSessionAndValidation() { - if (this.checkSessionService.isCheckSessionConfigured()) { - this.checkSessionService.start(); - } - - this.periodicallyTokenCheckService.startTokenValidationPeriodically(this.configuration.configuration.tokenRefreshInSeconds); - - if (this.silentRenewService.isSilentRenewConfigured()) { - this.silentRenewService.getOrCreateIframe(); - } - } } diff --git a/projects/angular-auth-oidc-client/src/lib/userData/user-service.spec.ts b/projects/angular-auth-oidc-client/src/lib/userData/user-service.spec.ts index e34ff231c..2e50d0931 100644 --- a/projects/angular-auth-oidc-client/src/lib/userData/user-service.spec.ts +++ b/projects/angular-auth-oidc-client/src/lib/userData/user-service.spec.ts @@ -306,7 +306,7 @@ describe('User Service', () => { spyOn(userService, 'getUserDataFromStore').and.returnValue(''); const observableSpy = spyOn((userService as any).userDataInternal$, 'next'); const eventSpy = spyOn(eventsService, 'fireEvent'); - userService.publishUserdataIfExists(); + userService.publishUserDataIfExists(); expect(observableSpy).not.toHaveBeenCalled(); expect(eventSpy).not.toHaveBeenCalled(); }); @@ -314,14 +314,14 @@ describe('User Service', () => { it('userDataInternal is fired if userdata exists', () => { spyOn(userService, 'getUserDataFromStore').and.returnValue('something'); const observableSpy = spyOn((userService as any).userDataInternal$, 'next'); - userService.publishUserdataIfExists(); + userService.publishUserDataIfExists(); expect(observableSpy).toHaveBeenCalledWith('something'); }); it('eventservice UserDataChanged is fired if userdata exists', () => { spyOn(userService, 'getUserDataFromStore').and.returnValue('something'); const eventSpy = spyOn(eventsService, 'fireEvent'); - userService.publishUserdataIfExists(); + userService.publishUserDataIfExists(); expect(eventSpy).toHaveBeenCalledWith(EventTypes.UserDataChanged, 'something'); }); }); diff --git a/projects/angular-auth-oidc-client/src/lib/userData/user-service.ts b/projects/angular-auth-oidc-client/src/lib/userData/user-service.ts index 52d04d3b5..836395706 100644 --- a/projects/angular-auth-oidc-client/src/lib/userData/user-service.ts +++ b/projects/angular-auth-oidc-client/src/lib/userData/user-service.ts @@ -24,8 +24,8 @@ export class UserService { private eventService: PublicEventsService, private loggerService: LoggerService, private tokenHelperService: TokenHelperService, - private readonly flowHelper: FlowHelper, - private readonly configurationProvider: ConfigurationProvider + private flowHelper: FlowHelper, + private configurationProvider: ConfigurationProvider ) {} // TODO CHECK PARAMETERS @@ -69,11 +69,11 @@ export class UserService { return this.storagePersistanceService.read('userData') || null; } - publishUserdataIfExists() { - const userdata = this.getUserDataFromStore(); - if (userdata) { - this.userDataInternal$.next(userdata); - this.eventService.fireEvent(EventTypes.UserDataChanged, userdata); + publishUserDataIfExists() { + const userData = this.getUserDataFromStore(); + if (userData) { + this.userDataInternal$.next(userData); + this.eventService.fireEvent(EventTypes.UserDataChanged, userData); } } diff --git a/projects/sample-code-flow-auto-login/.eslintrc.json b/projects/sample-code-flow-auto-login/.eslintrc.json index fe84ae742..a6978621d 100644 --- a/projects/sample-code-flow-auto-login/.eslintrc.json +++ b/projects/sample-code-flow-auto-login/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-auto-login/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-auto-login/e2e/protractor.conf.js b/projects/sample-code-flow-auto-login/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-auto-login/e2e/protractor.conf.js +++ b/projects/sample-code-flow-auto-login/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-auto-login/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-auto-login/e2e/src/app.e2e-spec.ts index 45424dee9..6faa224ae 100644 --- a/projects/sample-code-flow-auto-login/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-auto-login/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-auto-login/e2e/tsconfig.json b/projects/sample-code-flow-auto-login/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-auto-login/e2e/tsconfig.json +++ b/projects/sample-code-flow-auto-login/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-auto-login/karma.conf.js b/projects/sample-code-flow-auto-login/karma.conf.js index 8146c9f2f..768a8d927 100644 --- a/projects/sample-code-flow-auto-login/karma.conf.js +++ b/projects/sample-code-flow-auto-login/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-auto-login'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-auto-login/src/app/app.component.html b/projects/sample-code-flow-auto-login/src/app/app.component.html index e379ac17e..30adf7d55 100644 --- a/projects/sample-code-flow-auto-login/src/app/app.component.html +++ b/projects/sample-code-flow-auto-login/src/app/app.component.html @@ -1,9 +1,9 @@ -
-
-
- -
+
+
+
+
+
diff --git a/projects/sample-code-flow-auto-login/src/app/app.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/app.component.spec.ts index 10351e5d9..efe71810c 100644 --- a/projects/sample-code-flow-auto-login/src/app/app.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/app.component.spec.ts @@ -2,30 +2,30 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'sample-code-flow-auto-login'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('sample-code-flow-auto-login'); - }); + it(`should have as title 'sample-code-flow-auto-login'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('sample-code-flow-auto-login'); + }); - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to sample-code-flow-auto-login!'); - }); + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to sample-code-flow-auto-login!'); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/app.component.ts b/projects/sample-code-flow-auto-login/src/app/app.component.ts index 4c26577ae..73bcc8156 100644 --- a/projects/sample-code-flow-auto-login/src/app/app.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/app.component.ts @@ -3,69 +3,69 @@ import { Router } from '@angular/router'; import { OidcSecurityService } from 'angular-auth-oidc-client'; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'], + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], }) export class AppComponent implements OnInit { - constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} + constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} - ngOnInit() { - this.oidcSecurityService - .checkAuth() + ngOnInit() { + this.oidcSecurityService + .checkAuth() - .subscribe((isAuthenticated) => { - if (!isAuthenticated) { - if ('/autologin' !== window.location.pathname) { - this.write('redirect', window.location.pathname); - this.router.navigate(['/autologin']); - } - } - if (isAuthenticated) { - this.navigateToStoredEndpoint(); - } - }); - } + .subscribe((isAuthenticated) => { + if (!isAuthenticated) { + if ('/autologin' !== window.location.pathname) { + this.write('redirect', window.location.pathname); + this.router.navigate(['/autologin']); + } + } + if (isAuthenticated) { + this.navigateToStoredEndpoint(); + } + }); + } - login() { - console.log('start login'); - this.oidcSecurityService.authorize(); - } + login() { + console.log('start login'); + this.oidcSecurityService.authorize(); + } - refreshSession() { - console.log('start refreshSession'); - this.oidcSecurityService.authorize(); - } + refreshSession() { + console.log('start refreshSession'); + this.oidcSecurityService.authorize(); + } - logout() { - console.log('start logoff'); - this.oidcSecurityService.logoff(); - } + logout() { + console.log('start logoff'); + this.oidcSecurityService.logoff(); + } - private navigateToStoredEndpoint() { - const path = this.read('redirect'); + private navigateToStoredEndpoint() { + const path = this.read('redirect'); - if (this.router.url === path) { - return; - } - - if (path.toString().includes('/unauthorized')) { - this.router.navigate(['/']); - } else { - this.router.navigate([path]); - } + if (this.router.url === path) { + return; } - private read(key: string): any { - const data = localStorage.getItem(key); - if (data) { - return JSON.parse(data); - } - - return; + if (path.toString().includes('/unauthorized')) { + this.router.navigate(['/']); + } else { + this.router.navigate([path]); } + } - private write(key: string, value: any): void { - localStorage.setItem(key, JSON.stringify(value)); + private read(key: string): any { + const data = localStorage.getItem(key); + if (data) { + return JSON.parse(data); } + + return; + } + + private write(key: string, value: any): void { + localStorage.setItem(key, JSON.stringify(value)); + } } diff --git a/projects/sample-code-flow-auto-login/src/app/app.module.ts b/projects/sample-code-flow-auto-login/src/app/app.module.ts index fd9f282c2..3f416ea26 100644 --- a/projects/sample-code-flow-auto-login/src/app/app.module.ts +++ b/projects/sample-code-flow-auto-login/src/app/app.module.ts @@ -11,9 +11,9 @@ import { NavigationComponent } from './navigation/navigation.component'; import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; @NgModule({ - imports: [BrowserModule, routing, HttpClientModule, AuthConfigModule], - declarations: [AppComponent, ForbiddenComponent, HomeComponent, AutoLoginComponent, NavigationComponent, UnauthorizedComponent], - providers: [], - bootstrap: [AppComponent], + imports: [BrowserModule, routing, HttpClientModule, AuthConfigModule], + declarations: [AppComponent, ForbiddenComponent, HomeComponent, AutoLoginComponent, NavigationComponent, UnauthorizedComponent], + providers: [], + bootstrap: [AppComponent], }) export class AppModule {} diff --git a/projects/sample-code-flow-auto-login/src/app/app.routes.ts b/projects/sample-code-flow-auto-login/src/app/app.routes.ts index f9e2785a5..0de64e99a 100644 --- a/projects/sample-code-flow-auto-login/src/app/app.routes.ts +++ b/projects/sample-code-flow-auto-login/src/app/app.routes.ts @@ -1,18 +1,18 @@ -import { RouterModule, Routes } from '@angular/router'; -import { AuthorizationGuard } from './authorization.guard'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { ProtectedComponent } from './protected/protected.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -const appRoutes: Routes = [ - { path: '', pathMatch: 'full', redirectTo: 'home' }, - { path: 'home', component: HomeComponent }, - { path: 'autologin', component: AutoLoginComponent }, - { path: 'forbidden', component: ForbiddenComponent, canActivate: [AuthorizationGuard] }, - { path: 'unauthorized', component: UnauthorizedComponent }, - { path: 'protected', component: ProtectedComponent }, -]; - -export const routing = RouterModule.forRoot(appRoutes); +import { RouterModule, Routes } from '@angular/router'; +import { AuthorizationGuard } from './authorization.guard'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { ProtectedComponent } from './protected/protected.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +const appRoutes: Routes = [ + { path: '', pathMatch: 'full', redirectTo: 'home' }, + { path: 'home', component: HomeComponent }, + { path: 'autologin', component: AutoLoginComponent }, + { path: 'forbidden', component: ForbiddenComponent, canActivate: [AuthorizationGuard] }, + { path: 'unauthorized', component: UnauthorizedComponent }, + { path: 'protected', component: ProtectedComponent }, +]; + +export const routing = RouterModule.forRoot(appRoutes); diff --git a/projects/sample-code-flow-auto-login/src/app/auth-config.module.ts b/projects/sample-code-flow-auto-login/src/app/auth-config.module.ts index de1f9b265..231dff759 100644 --- a/projects/sample-code-flow-auto-login/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-auto-login/src/app/auth-config.module.ts @@ -1,40 +1,40 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://offeringsolutions-sts.azurewebsites.net', - redirectUrl: window.location.origin, - clientId: 'angularJwtClient', - scope: 'openid profile email', - responseType: 'code', - triggerAuthorizationResultEvent: true, - postLogoutRedirectUri: `${window.location.origin}/unauthorized`, - startCheckSession: false, - silentRenew: true, - silentRenewUrl: `${window.location.origin}/silent-renew.html`, - postLoginRoute: '/home', - forbiddenRoute: '/forbidden', - unauthorizedRoute: '/unauthorized', - logLevel: LogLevel.Debug, - historyCleanupOff: true, - // iss_validation_off: false - // disable_iat_offset_validation: true - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + clientId: 'angularJwtClient', + scope: 'openid profile email', + responseType: 'code', + triggerAuthorizationResultEvent: true, + postLogoutRedirectUri: `${window.location.origin}/unauthorized`, + startCheckSession: false, + silentRenew: true, + silentRenewUrl: `${window.location.origin}/silent-renew.html`, + postLoginRoute: '/home', + forbiddenRoute: '/forbidden', + unauthorizedRoute: '/unauthorized', + logLevel: LogLevel.Debug, + historyCleanupOff: true, + // iss_validation_off: false + // disable_iat_offset_validation: true + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-auto-login/src/app/authorization.guard.ts b/projects/sample-code-flow-auto-login/src/app/authorization.guard.ts index d33129526..c1a06da4f 100644 --- a/projects/sample-code-flow-auto-login/src/app/authorization.guard.ts +++ b/projects/sample-code-flow-auto-login/src/app/authorization.guard.ts @@ -1,26 +1,26 @@ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; - -@Injectable({ providedIn: 'root' }) -export class AuthorizationGuard implements CanActivate { - constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} - - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - // return checkAuth() again should be possible - return this.oidcSecurityService.isAuthenticated$.pipe( - map((isAuthorized: boolean) => { - console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); - - if (!isAuthorized) { - this.router.navigate(['/unauthorized']); - return false; - } - - return true; - }) - ); - } -} +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class AuthorizationGuard implements CanActivate { + constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + // return checkAuth() again should be possible + return this.oidcSecurityService.isAuthenticated$.pipe( + map((isAuthorized: boolean) => { + console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); + + if (!isAuthorized) { + this.router.navigate(['/unauthorized']); + return false; + } + + return true; + }) + ); + } +} diff --git a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.html b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.html index da378ebeb..795c64ded 100644 --- a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.html +++ b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.html @@ -1 +1 @@ -
redirecting to login
+
redirecting to login
diff --git a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.spec.ts index 81e597d04..9752eb14d 100644 --- a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { AutoLoginComponent } from './auto-login.component'; describe('AutoLoginComponent', () => { - let component: AutoLoginComponent; - let fixture: ComponentFixture; + let component: AutoLoginComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AutoLoginComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AutoLoginComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(AutoLoginComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AutoLoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.ts b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.ts index e005286ea..0c05d8d93 100644 --- a/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/auto-login/auto-login.component.ts @@ -1,14 +1,14 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-auto-component', - templateUrl: './auto-login.component.html', -}) -export class AutoLoginComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.authorize(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-auto-component', + templateUrl: './auto-login.component.html', +}) +export class AutoLoginComponent implements OnInit { + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.authorize(); + } +} diff --git a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.html b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.html index 9f457a042..2c34bec60 100644 --- a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.html +++ b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.html @@ -1,5 +1,5 @@ -
- Normally you should not see this but your -
authenticated
- is {{ authenticated$ | async }} :-) -
+
+ Normally you should not see this but your +
authenticated
+ is {{ authenticated$ | async }} :-) +
diff --git a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.spec.ts index 314157237..74561b527 100644 --- a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ForbiddenComponent } from './forbidden.component'; describe('ForbiddenComponent', () => { - let component: ForbiddenComponent; - let fixture: ComponentFixture; + let component: ForbiddenComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ForbiddenComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ForbiddenComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ForbiddenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ForbiddenComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.ts b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.ts index c424d8341..ba6de408d 100644 --- a/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/forbidden/forbidden.component.ts @@ -1,17 +1,17 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-forbidden', - templateUrl: 'forbidden.component.html', -}) -export class ForbiddenComponent implements OnInit { - public authenticated$: Observable; - - constructor(private oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.authenticated$ = this.oidcSecurityService.isAuthenticated$; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-forbidden', + templateUrl: 'forbidden.component.html', +}) +export class ForbiddenComponent implements OnInit { + public authenticated$: Observable; + + constructor(private oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.authenticated$ = this.oidcSecurityService.isAuthenticated$; + } +} diff --git a/projects/sample-code-flow-auto-login/src/app/home/home.component.html b/projects/sample-code-flow-auto-login/src/app/home/home.component.html index ba0ebdd2d..58a36167d 100644 --- a/projects/sample-code-flow-auto-login/src/app/home/home.component.html +++ b/projects/sample-code-flow-auto-login/src/app/home/home.component.html @@ -1,5 +1,5 @@ -
Welcome to home Route
- -
-Is Authenticated: {{ isAuthenticated$ | async }} -
{{ userData$ | async | json }}
+
Welcome to home Route
+ +
+Is Authenticated: {{ isAuthenticated$ | async }} +
{{ userData$ | async | json }}
diff --git a/projects/sample-code-flow-auto-login/src/app/home/home.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/home/home.component.spec.ts index 0c4a69378..50ff56b39 100644 --- a/projects/sample-code-flow-auto-login/src/app/home/home.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/home/home.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HomeComponent } from './home.component'; describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; + let component: HomeComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HomeComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/home/home.component.ts b/projects/sample-code-flow-auto-login/src/app/home/home.component.ts index c456dcc38..deb140da9 100644 --- a/projects/sample-code-flow-auto-login/src/app/home/home.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/home/home.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - userData$: Observable; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - this.userData$ = this.oidcSecurityService.userData$; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + userData$: Observable; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + this.userData$ = this.oidcSecurityService.userData$; + } +} diff --git a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.css b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.css index 733dfdbdb..e83c8f87f 100644 --- a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.css +++ b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.css @@ -1,3 +1,3 @@ -li a { - cursor: pointer; -} +li a { + cursor: pointer; +} diff --git a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.html b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.html index 003538ef7..87fcdf884 100644 --- a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.html +++ b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.html @@ -1,24 +1,24 @@ - + diff --git a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.spec.ts index 82a41acef..6b707df7e 100644 --- a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { NavigationComponent } from './navigation.component'; describe('NavigationComponent', () => { - let component: NavigationComponent; - let fixture: ComponentFixture; + let component: NavigationComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [NavigationComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [NavigationComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(NavigationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(NavigationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.ts b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.ts index 241ad6be8..8fab9d5ed 100644 --- a/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/navigation/navigation.component.ts @@ -1,29 +1,29 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-navigation', - templateUrl: 'navigation.component.html', -}) -export class NavigationComponent implements OnInit { - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.authorize(); - } - - logout() { - this.oidcSecurityService.logoff(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-navigation', + templateUrl: 'navigation.component.html', +}) +export class NavigationComponent implements OnInit { + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.authorize(); + } + + logout() { + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.html b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.html index 562486bf5..842979e71 100644 --- a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.html +++ b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.html @@ -1,3 +1 @@ -

- protected works! -

+

protected works!

diff --git a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.spec.ts index f67bd0ec0..6c1942350 100644 --- a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ProtectedComponent } from './protected.component'; describe('ProtectedComponent', () => { - let component: ProtectedComponent; - let fixture: ComponentFixture; + let component: ProtectedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ProtectedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProtectedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ProtectedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ProtectedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.ts b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.ts index 528985f90..024769909 100644 --- a/projects/sample-code-flow-auto-login/src/app/protected/protected.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/protected/protected.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-protected', templateUrl: './protected.component.html', - styleUrls: ['./protected.component.css'] + styleUrls: ['./protected.component.css'], }) export class ProtectedComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.ts index 2d9cf2f88..834791f20 100644 --- a/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow-auto-login/src/app/unauthorized/unauthorized.component.ts @@ -1,19 +1,16 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html' -}) - -export class UnauthorizedComponent implements OnInit { - - public message: string; - public values: any[]; - - constructor() { - this.message = 'UnauthorizedComponent constructor'; - } - - ngOnInit() { - } -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + public message: string; + public values: any[]; + + constructor() { + this.message = 'UnauthorizedComponent constructor'; + } + + ngOnInit() {} +} diff --git a/projects/sample-code-flow-auto-login/src/environments/environment.prod.ts b/projects/sample-code-flow-auto-login/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-auto-login/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-auto-login/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-auto-login/src/environments/environment.ts b/projects/sample-code-flow-auto-login/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-auto-login/src/environments/environment.ts +++ b/projects/sample-code-flow-auto-login/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-auto-login/src/index.html b/projects/sample-code-flow-auto-login/src/index.html index f0b960b9f..14cf19e7b 100644 --- a/projects/sample-code-flow-auto-login/src/index.html +++ b/projects/sample-code-flow-auto-login/src/index.html @@ -1,34 +1,34 @@ - - - Sample Code Flow Auto Login - - - - - - - - - - - + + + Sample Code Flow Auto Login + + + + + + + + + + + diff --git a/projects/sample-code-flow-auto-login/src/main.ts b/projects/sample-code-flow-auto-login/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-auto-login/src/main.ts +++ b/projects/sample-code-flow-auto-login/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-auto-login/src/polyfills.ts b/projects/sample-code-flow-auto-login/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-auto-login/src/polyfills.ts +++ b/projects/sample-code-flow-auto-login/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-auto-login/src/silent-renew.html b/projects/sample-code-flow-auto-login/src/silent-renew.html index fea2b75fc..7aab22f4b 100644 --- a/projects/sample-code-flow-auto-login/src/silent-renew.html +++ b/projects/sample-code-flow-auto-login/src/silent-renew.html @@ -1,22 +1,21 @@ - + - - + + silent-renew - - - - - + + + + diff --git a/projects/sample-code-flow-auto-login/src/test.ts b/projects/sample-code-flow-auto-login/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-auto-login/src/test.ts +++ b/projects/sample-code-flow-auto-login/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-auto-login/tsconfig.app.json b/projects/sample-code-flow-auto-login/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-auto-login/tsconfig.app.json +++ b/projects/sample-code-flow-auto-login/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-auto-login/tsconfig.spec.json b/projects/sample-code-flow-auto-login/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-auto-login/tsconfig.spec.json +++ b/projects/sample-code-flow-auto-login/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-azure-b2c/.eslintrc.json b/projects/sample-code-flow-azure-b2c/.eslintrc.json index 61474751e..ee26bafbf 100644 --- a/projects/sample-code-flow-azure-b2c/.eslintrc.json +++ b/projects/sample-code-flow-azure-b2c/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-azure-b2c/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-azure-b2c/e2e/protractor.conf.js b/projects/sample-code-flow-azure-b2c/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-azure-b2c/e2e/protractor.conf.js +++ b/projects/sample-code-flow-azure-b2c/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-azure-b2c/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-azure-b2c/e2e/src/app.e2e-spec.ts index 2847e3d46..06ae4e6de 100644 --- a/projects/sample-code-flow-azure-b2c/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-azure-b2c/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-azure-b2c/e2e/tsconfig.json b/projects/sample-code-flow-azure-b2c/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-azure-b2c/e2e/tsconfig.json +++ b/projects/sample-code-flow-azure-b2c/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-azure-b2c/karma.conf.js b/projects/sample-code-flow-azure-b2c/karma.conf.js index 92db49e85..1f399ddf8 100644 --- a/projects/sample-code-flow-azure-b2c/karma.conf.js +++ b/projects/sample-code-flow-azure-b2c/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-azure-b2c'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-azure-b2c/src/app/app.component.css b/projects/sample-code-flow-azure-b2c/src/app/app.component.css index ef8c2c02c..33bfcb7a9 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/app.component.css +++ b/projects/sample-code-flow-azure-b2c/src/app/app.component.css @@ -1,6 +1,6 @@ -@media (max-width: 767px) { - /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */ - .body-content { - padding-top: 50px; - } -} +@media (max-width: 767px) { + /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */ + .body-content { + padding-top: 50px; + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/app.component.html b/projects/sample-code-flow-azure-b2c/src/app/app.component.html index 77d25b4a3..7a7f4d20f 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/app.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/app.component.html @@ -1,9 +1,9 @@ - - -
-
-
- -
-
-
+ + +
+
+
+ +
+
+
diff --git a/projects/sample-code-flow-azure-b2c/src/app/app.component.ts b/projects/sample-code-flow-azure-b2c/src/app/app.component.ts index b7ade83e7..02d3f83a9 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/app.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/app.component.ts @@ -1,57 +1,57 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit, OnDestroy { - constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} - - ngOnInit() { - this.oidcSecurityService - .checkAuth() - - .subscribe((isAuthenticated) => { - if (!isAuthenticated) { - if ('/autologin' !== window.location.pathname) { - this.write('redirect', window.location.pathname); - this.router.navigate(['/autologin']); - } - } - if (isAuthenticated) { - this.navigateToStoredEndpoint(); - } - }); - } - - ngOnDestroy(): void {} - - private navigateToStoredEndpoint() { - const path = this.read('redirect'); - - if (this.router.url === path) { - return; - } - - if (path.toString().includes('/unauthorized')) { - this.router.navigate(['/']); - } else { - this.router.navigate([path]); - } - } - - private read(key: string): any { - const data = localStorage.getItem(key); - if (data != null) { - return JSON.parse(data); - } - - return; - } - - private write(key: string, value: any): void { - localStorage.setItem(key, JSON.stringify(value)); - } -} +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit, OnDestroy { + constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} + + ngOnInit() { + this.oidcSecurityService + .checkAuth() + + .subscribe((isAuthenticated) => { + if (!isAuthenticated) { + if ('/autologin' !== window.location.pathname) { + this.write('redirect', window.location.pathname); + this.router.navigate(['/autologin']); + } + } + if (isAuthenticated) { + this.navigateToStoredEndpoint(); + } + }); + } + + ngOnDestroy(): void {} + + private navigateToStoredEndpoint() { + const path = this.read('redirect'); + + if (this.router.url === path) { + return; + } + + if (path.toString().includes('/unauthorized')) { + this.router.navigate(['/']); + } else { + this.router.navigate([path]); + } + } + + private read(key: string): any { + const data = localStorage.getItem(key); + if (data != null) { + return JSON.parse(data); + } + + return; + } + + private write(key: string, value: any): void { + localStorage.setItem(key, JSON.stringify(value)); + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/app.module.ts b/projects/sample-code-flow-azure-b2c/src/app/app.module.ts index 1da465952..d1107ee6d 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/app.module.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/app.module.ts @@ -1,30 +1,30 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { AppComponent } from './app.component'; -import { routing } from './app.routes'; -import { AuthConfigModule } from './auth-config.module'; -import { AuthorizationGuard } from './authorization.guard'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { NavMenuComponent } from './nav-menu/nav-menu.component'; -import { ProtectedComponent } from './protected/protected.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [ - AppComponent, - NavMenuComponent, - HomeComponent, - AutoLoginComponent, - ForbiddenComponent, - UnauthorizedComponent, - ProtectedComponent, - ], - imports: [BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, routing, AuthConfigModule], - providers: [AuthorizationGuard], - bootstrap: [AppComponent], -}) -export class AppModule {} +import { HttpClientModule } from '@angular/common/http'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { routing } from './app.routes'; +import { AuthConfigModule } from './auth-config.module'; +import { AuthorizationGuard } from './authorization.guard'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { NavMenuComponent } from './nav-menu/nav-menu.component'; +import { ProtectedComponent } from './protected/protected.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [ + AppComponent, + NavMenuComponent, + HomeComponent, + AutoLoginComponent, + ForbiddenComponent, + UnauthorizedComponent, + ProtectedComponent, + ], + imports: [BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, routing, AuthConfigModule], + providers: [AuthorizationGuard], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/projects/sample-code-flow-azure-b2c/src/app/app.routes.ts b/projects/sample-code-flow-azure-b2c/src/app/app.routes.ts index 4645a2d64..cb1d58df3 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/app.routes.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/app.routes.ts @@ -1,19 +1,19 @@ -import { Routes, RouterModule } from '@angular/router'; - -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ProtectedComponent } from './protected/protected.component'; -import { AuthorizationGuard } from './authorization.guard'; - -const appRoutes: Routes = [ - { path: '', component: HomeComponent, pathMatch: 'full'}, - { path: 'home', component: HomeComponent, canActivate: [AuthorizationGuard] }, - { path: 'autologin', component: AutoLoginComponent }, - { path: 'forbidden', component: ForbiddenComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - { path: 'protected', component: ProtectedComponent, canActivate: [AuthorizationGuard] } -]; - -export const routing = RouterModule.forRoot(appRoutes); +import { Routes, RouterModule } from '@angular/router'; + +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ProtectedComponent } from './protected/protected.component'; +import { AuthorizationGuard } from './authorization.guard'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent, pathMatch: 'full' }, + { path: 'home', component: HomeComponent, canActivate: [AuthorizationGuard] }, + { path: 'autologin', component: AutoLoginComponent }, + { path: 'forbidden', component: ForbiddenComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + { path: 'protected', component: ProtectedComponent, canActivate: [AuthorizationGuard] }, +]; + +export const routing = RouterModule.forRoot(appRoutes); diff --git a/projects/sample-code-flow-azure-b2c/src/app/auth-config.module.ts b/projects/sample-code-flow-azure-b2c/src/app/auth-config.module.ts index 966e0765b..9e100eeb7 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/auth-config.module.ts @@ -1,40 +1,40 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; - -export function loadConfig(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://login.microsoftonline.com/damienbod.onmicrosoft.com/v2.0', - authWellknownEndpoint: - 'https://damienbod.b2clogin.com/damienbod.onmicrosoft.com/B2C_1_b2cpolicydamien/v2.0/.well-known/openid-configuration', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'f1934a6e-958d-4198-9f36-6127cfc4cdb3', - scope: 'openid https://damienbod.onmicrosoft.com/testapi/demo.read', - responseType: 'code', - silentRenew: true, - autoUserinfo: false, - silentRenewUrl: window.location.origin + '/silent-renew.html', - logLevel: LogLevel.Debug, - renewTimeBeforeTokenExpiresInSeconds: 60, - // useRefreshToken: true, // for refresh renew, but revocation and one time usage is missing from server impl. - // ignoreNonceAfterRefresh: true, - // disableRefreshIdTokenAuthTimeValidation: true, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcSecurityService, - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: loadConfig, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; + +export function loadConfig(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://login.microsoftonline.com/damienbod.onmicrosoft.com/v2.0', + authWellknownEndpoint: + 'https://damienbod.b2clogin.com/damienbod.onmicrosoft.com/B2C_1_b2cpolicydamien/v2.0/.well-known/openid-configuration', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'f1934a6e-958d-4198-9f36-6127cfc4cdb3', + scope: 'openid https://damienbod.onmicrosoft.com/testapi/demo.read', + responseType: 'code', + silentRenew: true, + autoUserinfo: false, + silentRenewUrl: window.location.origin + '/silent-renew.html', + logLevel: LogLevel.Debug, + renewTimeBeforeTokenExpiresInSeconds: 60, + // useRefreshToken: true, // for refresh renew, but revocation and one time usage is missing from server impl. + // ignoreNonceAfterRefresh: true, + // disableRefreshIdTokenAuthTimeValidation: true, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcSecurityService, + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: loadConfig, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-azure-b2c/src/app/authorization.guard.ts b/projects/sample-code-flow-azure-b2c/src/app/authorization.guard.ts index d65af9c76..993f7fb4b 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/authorization.guard.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/authorization.guard.ts @@ -1,25 +1,25 @@ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; - -@Injectable({ providedIn: 'root' }) -export class AuthorizationGuard implements CanActivate { - constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} - - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - return this.oidcSecurityService.isAuthenticated$.pipe( - map((isAuthorized: boolean) => { - console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); - - if (!isAuthorized) { - this.router.navigate(['/unauthorized']); - return false; - } - - return true; - }) - ); - } -} +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class AuthorizationGuard implements CanActivate { + constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + return this.oidcSecurityService.isAuthenticated$.pipe( + map((isAuthorized: boolean) => { + console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); + + if (!isAuthorized) { + this.router.navigate(['/unauthorized']); + return false; + } + + return true; + }) + ); + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.html b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.html index 579fb8a03..795c64ded 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.html @@ -1 +1 @@ -
redirecting to login
\ No newline at end of file +
redirecting to login
diff --git a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.spec.ts b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.spec.ts index 81e597d04..9752eb14d 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.spec.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { AutoLoginComponent } from './auto-login.component'; describe('AutoLoginComponent', () => { - let component: AutoLoginComponent; - let fixture: ComponentFixture; + let component: AutoLoginComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AutoLoginComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AutoLoginComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(AutoLoginComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AutoLoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.ts b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.ts index 170e2a0c0..ea8fa48d0 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/auto-login/auto-login.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-auto-component', - templateUrl: './auto-login.component.html', -}) -export class AutoLoginComponent implements OnInit { - lang: any; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-auto-component', + templateUrl: './auto-login.component.html', +}) +export class AutoLoginComponent implements OnInit { + lang: any; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.html b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.html index dcbbc4381..c30096c8c 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.html @@ -1,3 +1 @@ -

- forbidden works! -

+

forbidden works!

diff --git a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.spec.ts b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.spec.ts index 314157237..74561b527 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.spec.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ForbiddenComponent } from './forbidden.component'; describe('ForbiddenComponent', () => { - let component: ForbiddenComponent; - let fixture: ComponentFixture; + let component: ForbiddenComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ForbiddenComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ForbiddenComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ForbiddenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ForbiddenComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.ts b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.ts index 3dd20c084..b5416954e 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/forbidden/forbidden.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-forbidden', templateUrl: './forbidden.component.html', - styleUrls: ['./forbidden.component.css'] + styleUrls: ['./forbidden.component.css'], }) export class ForbiddenComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azure-b2c/src/app/home/home.component.html b/projects/sample-code-flow-azure-b2c/src/app/home/home.component.html index fc46ff8fe..61532b953 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/home/home.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/home/home.component.html @@ -1,5 +1,5 @@ -
Welcome
- -
-Is Authenticated: {{ isAuthenticated$ | async }} -
{{ userData$ | async | json }}
+
Welcome
+ +
+Is Authenticated: {{ isAuthenticated$ | async }} +
{{ userData$ | async | json }}
diff --git a/projects/sample-code-flow-azure-b2c/src/app/home/home.component.ts b/projects/sample-code-flow-azure-b2c/src/app/home/home.component.ts index c456dcc38..deb140da9 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/home/home.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/home/home.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - userData$: Observable; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - this.userData$ = this.oidcSecurityService.userData$; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + userData$: Observable; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + this.userData$ = this.oidcSecurityService.userData$; + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.css b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.css index f76d03515..9b7f74684 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.css +++ b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.css @@ -1,59 +1,59 @@ -li .glyphicon { - margin-right: 10px; -} - -/* Highlighting rules for nav menu items */ -li.link-active a, -li.link-active a:hover, -li.link-active a:focus { - background-color: #4189C7; - color: white; -} - -/* Keep the nav menu independent of scrolling and on top of other items */ -.main-nav { - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 1; -} - -@media (min-width: 768px) { - /* On small screens, convert the nav menu to a vertical sidebar */ - .main-nav { - height: 100%; - width: calc(25% - 20px); - } - .navbar { - border-radius: 0px; - border-width: 0px; - height: 100%; - } - .navbar-header { - float: none; - } - .navbar-collapse { - border-top: 1px solid #444; - padding: 0px; - } - .navbar ul { - float: none; - } - .navbar li { - float: none; - font-size: 15px; - margin: 6px; - } - .navbar li a { - padding: 10px 16px; - border-radius: 4px; - } - .navbar a { - /* If a menu item's text is too long, truncate it */ - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} +li .glyphicon { + margin-right: 10px; +} + +/* Highlighting rules for nav menu items */ +li.link-active a, +li.link-active a:hover, +li.link-active a:focus { + background-color: #4189c7; + color: white; +} + +/* Keep the nav menu independent of scrolling and on top of other items */ +.main-nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1; +} + +@media (min-width: 768px) { + /* On small screens, convert the nav menu to a vertical sidebar */ + .main-nav { + height: 100%; + width: calc(25% - 20px); + } + .navbar { + border-radius: 0px; + border-width: 0px; + height: 100%; + } + .navbar-header { + float: none; + } + .navbar-collapse { + border-top: 1px solid #444; + padding: 0px; + } + .navbar ul { + float: none; + } + .navbar li { + float: none; + font-size: 15px; + margin: 6px; + } + .navbar li a { + padding: 10px 16px; + border-radius: 4px; + } + .navbar a { + /* If a menu item's text is too long, truncate it */ + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.html b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.html index 2738f39a3..1bb65b23c 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.html @@ -1,30 +1,30 @@ - + diff --git a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.ts b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.ts index 7da5728a9..6bbb2d297 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/nav-menu/nav-menu.component.ts @@ -1,39 +1,39 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-nav-menu', - templateUrl: './nav-menu.component.html', - styleUrls: ['./nav-menu.component.css'], -}) -export class NavMenuComponent implements OnInit { - isExpanded = false; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); - } - - logout() { - this.oidcSecurityService.logoff(); - } - - collapse() { - this.isExpanded = false; - } - - toggle() { - this.isExpanded = !this.isExpanded; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-nav-menu', + templateUrl: './nav-menu.component.html', + styleUrls: ['./nav-menu.component.css'], +}) +export class NavMenuComponent implements OnInit { + isExpanded = false; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } + + collapse() { + this.isExpanded = false; + } + + toggle() { + this.isExpanded = !this.isExpanded; + } +} diff --git a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.html b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.html index 122e8a8f0..842979e71 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.html @@ -1,3 +1 @@ -

- protected works! -

+

protected works!

diff --git a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.spec.ts b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.spec.ts index f67bd0ec0..6c1942350 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.spec.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ProtectedComponent } from './protected.component'; describe('ProtectedComponent', () => { - let component: ProtectedComponent; - let fixture: ComponentFixture; + let component: ProtectedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ProtectedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProtectedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ProtectedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ProtectedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.ts b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.ts index 528985f90..024769909 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/protected/protected.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-protected', templateUrl: './protected.component.html', - styleUrls: ['./protected.component.css'] + styleUrls: ['./protected.component.css'], }) export class ProtectedComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.html index 3f20fd3c9..10fe24be2 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.html @@ -1,3 +1 @@ -

- unauthorized works! -

+

unauthorized works!

diff --git a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.ts index fd9b55b1e..fe06a6912 100644 --- a/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow-azure-b2c/src/app/unauthorized/unauthorized.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-unauthorized', templateUrl: './unauthorized.component.html', - styleUrls: ['./unauthorized.component.css'] + styleUrls: ['./unauthorized.component.css'], }) export class UnauthorizedComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azure-b2c/src/environments/environment.prod.ts b/projects/sample-code-flow-azure-b2c/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-azure-b2c/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-azure-b2c/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-azure-b2c/src/environments/environment.ts b/projects/sample-code-flow-azure-b2c/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-azure-b2c/src/environments/environment.ts +++ b/projects/sample-code-flow-azure-b2c/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-azure-b2c/src/index.html b/projects/sample-code-flow-azure-b2c/src/index.html index c78a1086c..9b9fa1e5a 100644 --- a/projects/sample-code-flow-azure-b2c/src/index.html +++ b/projects/sample-code-flow-azure-b2c/src/index.html @@ -1,34 +1,34 @@ - - - Sample Code Flow Azure B2C with silent renew - - - - - - - - - - - + + + Sample Code Flow Azure B2C with silent renew + + + + + + + + + + + diff --git a/projects/sample-code-flow-azure-b2c/src/main.ts b/projects/sample-code-flow-azure-b2c/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-azure-b2c/src/main.ts +++ b/projects/sample-code-flow-azure-b2c/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-azure-b2c/src/polyfills.ts b/projects/sample-code-flow-azure-b2c/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-azure-b2c/src/polyfills.ts +++ b/projects/sample-code-flow-azure-b2c/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-azure-b2c/src/silent-renew.html b/projects/sample-code-flow-azure-b2c/src/silent-renew.html index 35a8eabe3..7aab22f4b 100644 --- a/projects/sample-code-flow-azure-b2c/src/silent-renew.html +++ b/projects/sample-code-flow-azure-b2c/src/silent-renew.html @@ -1,21 +1,21 @@ - - - - - silent-renew - - - - - + + + + + silent-renew + + + + + diff --git a/projects/sample-code-flow-azure-b2c/src/test.ts b/projects/sample-code-flow-azure-b2c/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-azure-b2c/src/test.ts +++ b/projects/sample-code-flow-azure-b2c/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-azure-b2c/tsconfig.app.json b/projects/sample-code-flow-azure-b2c/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-azure-b2c/tsconfig.app.json +++ b/projects/sample-code-flow-azure-b2c/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-azure-b2c/tsconfig.spec.json b/projects/sample-code-flow-azure-b2c/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-azure-b2c/tsconfig.spec.json +++ b/projects/sample-code-flow-azure-b2c/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-azuread/.eslintrc.json b/projects/sample-code-flow-azuread/.eslintrc.json index fe7b1c6de..e75f56055 100644 --- a/projects/sample-code-flow-azuread/.eslintrc.json +++ b/projects/sample-code-flow-azuread/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-azuread/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-azuread/e2e/protractor.conf.js b/projects/sample-code-flow-azuread/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-azuread/e2e/protractor.conf.js +++ b/projects/sample-code-flow-azuread/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-azuread/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-azuread/e2e/src/app.e2e-spec.ts index bc5777263..f32e1dde5 100644 --- a/projects/sample-code-flow-azuread/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-azuread/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-azuread/e2e/tsconfig.json b/projects/sample-code-flow-azuread/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-azuread/e2e/tsconfig.json +++ b/projects/sample-code-flow-azuread/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-azuread/karma.conf.js b/projects/sample-code-flow-azuread/karma.conf.js index 7e0157aac..f332c6b8b 100644 --- a/projects/sample-code-flow-azuread/karma.conf.js +++ b/projects/sample-code-flow-azuread/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-azuread'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-azuread/src/app/app.component.css b/projects/sample-code-flow-azuread/src/app/app.component.css index ef8c2c02c..33bfcb7a9 100644 --- a/projects/sample-code-flow-azuread/src/app/app.component.css +++ b/projects/sample-code-flow-azuread/src/app/app.component.css @@ -1,6 +1,6 @@ -@media (max-width: 767px) { - /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */ - .body-content { - padding-top: 50px; - } -} +@media (max-width: 767px) { + /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */ + .body-content { + padding-top: 50px; + } +} diff --git a/projects/sample-code-flow-azuread/src/app/app.component.html b/projects/sample-code-flow-azuread/src/app/app.component.html index 77d25b4a3..7a7f4d20f 100644 --- a/projects/sample-code-flow-azuread/src/app/app.component.html +++ b/projects/sample-code-flow-azuread/src/app/app.component.html @@ -1,9 +1,9 @@ - - -
-
-
- -
-
-
+ + +
+
+
+ +
+
+
diff --git a/projects/sample-code-flow-azuread/src/app/app.component.ts b/projects/sample-code-flow-azuread/src/app/app.component.ts index 3d6c1f279..3d16a8f75 100644 --- a/projects/sample-code-flow-azuread/src/app/app.component.ts +++ b/projects/sample-code-flow-azuread/src/app/app.component.ts @@ -1,72 +1,72 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit, OnDestroy { - constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} - - ngOnInit() { - this.oidcSecurityService - .checkAuth() - - .subscribe((isAuthenticated) => { - if (!isAuthenticated) { - if ('/autologin' !== window.location.pathname) { - this.write('redirect', window.location.pathname); - this.router.navigate(['/autologin']); - } - } - if (isAuthenticated) { - this.navigateToStoredEndpoint(); - } - }); - } - - ngOnDestroy(): void {} - - login() { - console.log('start login'); - this.oidcSecurityService.authorize(); - } - - refreshSession() { - console.log('start refreshSession'); - this.oidcSecurityService.authorize(); - } - - logout() { - console.log('start logoff'); - this.oidcSecurityService.logoff(); - } - - private navigateToStoredEndpoint() { - const path = this.read('redirect'); - - if (this.router.url === path) { - return; - } - - if (path.toString().includes('/unauthorized')) { - this.router.navigate(['/']); - } else { - this.router.navigate([path]); - } - } - - private read(key: string): any { - const data = localStorage.getItem(key); - if (data != null) { - return JSON.parse(data); - } - - return; - } - - private write(key: string, value: any): void { - localStorage.setItem(key, JSON.stringify(value)); - } -} +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit, OnDestroy { + constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} + + ngOnInit() { + this.oidcSecurityService + .checkAuth() + + .subscribe((isAuthenticated) => { + if (!isAuthenticated) { + if ('/autologin' !== window.location.pathname) { + this.write('redirect', window.location.pathname); + this.router.navigate(['/autologin']); + } + } + if (isAuthenticated) { + this.navigateToStoredEndpoint(); + } + }); + } + + ngOnDestroy(): void {} + + login() { + console.log('start login'); + this.oidcSecurityService.authorize(); + } + + refreshSession() { + console.log('start refreshSession'); + this.oidcSecurityService.authorize(); + } + + logout() { + console.log('start logoff'); + this.oidcSecurityService.logoff(); + } + + private navigateToStoredEndpoint() { + const path = this.read('redirect'); + + if (this.router.url === path) { + return; + } + + if (path.toString().includes('/unauthorized')) { + this.router.navigate(['/']); + } else { + this.router.navigate([path]); + } + } + + private read(key: string): any { + const data = localStorage.getItem(key); + if (data != null) { + return JSON.parse(data); + } + + return; + } + + private write(key: string, value: any): void { + localStorage.setItem(key, JSON.stringify(value)); + } +} diff --git a/projects/sample-code-flow-azuread/src/app/app.module.ts b/projects/sample-code-flow-azuread/src/app/app.module.ts index 1da465952..d1107ee6d 100644 --- a/projects/sample-code-flow-azuread/src/app/app.module.ts +++ b/projects/sample-code-flow-azuread/src/app/app.module.ts @@ -1,30 +1,30 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { AppComponent } from './app.component'; -import { routing } from './app.routes'; -import { AuthConfigModule } from './auth-config.module'; -import { AuthorizationGuard } from './authorization.guard'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { NavMenuComponent } from './nav-menu/nav-menu.component'; -import { ProtectedComponent } from './protected/protected.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [ - AppComponent, - NavMenuComponent, - HomeComponent, - AutoLoginComponent, - ForbiddenComponent, - UnauthorizedComponent, - ProtectedComponent, - ], - imports: [BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, routing, AuthConfigModule], - providers: [AuthorizationGuard], - bootstrap: [AppComponent], -}) -export class AppModule {} +import { HttpClientModule } from '@angular/common/http'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { routing } from './app.routes'; +import { AuthConfigModule } from './auth-config.module'; +import { AuthorizationGuard } from './authorization.guard'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { NavMenuComponent } from './nav-menu/nav-menu.component'; +import { ProtectedComponent } from './protected/protected.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [ + AppComponent, + NavMenuComponent, + HomeComponent, + AutoLoginComponent, + ForbiddenComponent, + UnauthorizedComponent, + ProtectedComponent, + ], + imports: [BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }), HttpClientModule, FormsModule, routing, AuthConfigModule], + providers: [AuthorizationGuard], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/projects/sample-code-flow-azuread/src/app/app.routes.ts b/projects/sample-code-flow-azuread/src/app/app.routes.ts index 4645a2d64..cb1d58df3 100644 --- a/projects/sample-code-flow-azuread/src/app/app.routes.ts +++ b/projects/sample-code-flow-azuread/src/app/app.routes.ts @@ -1,19 +1,19 @@ -import { Routes, RouterModule } from '@angular/router'; - -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ProtectedComponent } from './protected/protected.component'; -import { AuthorizationGuard } from './authorization.guard'; - -const appRoutes: Routes = [ - { path: '', component: HomeComponent, pathMatch: 'full'}, - { path: 'home', component: HomeComponent, canActivate: [AuthorizationGuard] }, - { path: 'autologin', component: AutoLoginComponent }, - { path: 'forbidden', component: ForbiddenComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - { path: 'protected', component: ProtectedComponent, canActivate: [AuthorizationGuard] } -]; - -export const routing = RouterModule.forRoot(appRoutes); +import { Routes, RouterModule } from '@angular/router'; + +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ProtectedComponent } from './protected/protected.component'; +import { AuthorizationGuard } from './authorization.guard'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent, pathMatch: 'full' }, + { path: 'home', component: HomeComponent, canActivate: [AuthorizationGuard] }, + { path: 'autologin', component: AutoLoginComponent }, + { path: 'forbidden', component: ForbiddenComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + { path: 'protected', component: ProtectedComponent, canActivate: [AuthorizationGuard] }, +]; + +export const routing = RouterModule.forRoot(appRoutes); diff --git a/projects/sample-code-flow-azuread/src/app/auth-config.module.ts b/projects/sample-code-flow-azuread/src/app/auth-config.module.ts index 8ab99f1fb..85f0c6ca3 100644 --- a/projects/sample-code-flow-azuread/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-azuread/src/app/auth-config.module.ts @@ -1,39 +1,39 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; - -export function loadConfig(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://login.microsoftonline.com/7ff95b15-dc21-4ba6-bc92-824856578fc1/v2.0', - authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', - redirectUrl: window.location.origin, - clientId: 'e38ea64a-2962-4cde-bfe7-dd2822fdab32', - scope: 'openid profile email api://e38ea64a-2962-4cde-bfe7-dd2822fdab32/access_as_user', - responseType: 'code', - silentRenew: true, - maxIdTokenIatOffsetAllowedInSeconds: 600, - issValidationOff: true, - autoUserinfo: false, - silentRenewUrl: window.location.origin + '/silent-renew.html', - logLevel: LogLevel.Debug, - customParams: { - prompt: 'consent', // login, consent - }, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcSecurityService, - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: loadConfig, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; + +export function loadConfig(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://login.microsoftonline.com/7ff95b15-dc21-4ba6-bc92-824856578fc1/v2.0', + authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', + redirectUrl: window.location.origin, + clientId: 'e38ea64a-2962-4cde-bfe7-dd2822fdab32', + scope: 'openid profile email api://e38ea64a-2962-4cde-bfe7-dd2822fdab32/access_as_user', + responseType: 'code', + silentRenew: true, + maxIdTokenIatOffsetAllowedInSeconds: 600, + issValidationOff: true, + autoUserinfo: false, + silentRenewUrl: window.location.origin + '/silent-renew.html', + logLevel: LogLevel.Debug, + customParams: { + prompt: 'consent', // login, consent + }, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcSecurityService, + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: loadConfig, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-azuread/src/app/authorization.guard.ts b/projects/sample-code-flow-azuread/src/app/authorization.guard.ts index d65af9c76..993f7fb4b 100644 --- a/projects/sample-code-flow-azuread/src/app/authorization.guard.ts +++ b/projects/sample-code-flow-azuread/src/app/authorization.guard.ts @@ -1,25 +1,25 @@ -import { Injectable } from '@angular/core'; -import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; - -@Injectable({ providedIn: 'root' }) -export class AuthorizationGuard implements CanActivate { - constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} - - canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { - return this.oidcSecurityService.isAuthenticated$.pipe( - map((isAuthorized: boolean) => { - console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); - - if (!isAuthorized) { - this.router.navigate(['/unauthorized']); - return false; - } - - return true; - }) - ); - } -} +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +@Injectable({ providedIn: 'root' }) +export class AuthorizationGuard implements CanActivate { + constructor(private oidcSecurityService: OidcSecurityService, private router: Router) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { + return this.oidcSecurityService.isAuthenticated$.pipe( + map((isAuthorized: boolean) => { + console.log('AuthorizationGuard, canActivate isAuthorized: ' + isAuthorized); + + if (!isAuthorized) { + this.router.navigate(['/unauthorized']); + return false; + } + + return true; + }) + ); + } +} diff --git a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.html b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.html index 579fb8a03..795c64ded 100644 --- a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.html +++ b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.html @@ -1 +1 @@ -
redirecting to login
\ No newline at end of file +
redirecting to login
diff --git a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.spec.ts b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.spec.ts index 81e597d04..9752eb14d 100644 --- a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.spec.ts +++ b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { AutoLoginComponent } from './auto-login.component'; describe('AutoLoginComponent', () => { - let component: AutoLoginComponent; - let fixture: ComponentFixture; + let component: AutoLoginComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AutoLoginComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AutoLoginComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(AutoLoginComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(AutoLoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.ts b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.ts index 170e2a0c0..ea8fa48d0 100644 --- a/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.ts +++ b/projects/sample-code-flow-azuread/src/app/auto-login/auto-login.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-auto-component', - templateUrl: './auto-login.component.html', -}) -export class AutoLoginComponent implements OnInit { - lang: any; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-auto-component', + templateUrl: './auto-login.component.html', +}) +export class AutoLoginComponent implements OnInit { + lang: any; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); + } +} diff --git a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.html b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.html index dcbbc4381..c30096c8c 100644 --- a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.html +++ b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.html @@ -1,3 +1 @@ -

- forbidden works! -

+

forbidden works!

diff --git a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.spec.ts b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.spec.ts index 314157237..74561b527 100644 --- a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.spec.ts +++ b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ForbiddenComponent } from './forbidden.component'; describe('ForbiddenComponent', () => { - let component: ForbiddenComponent; - let fixture: ComponentFixture; + let component: ForbiddenComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ForbiddenComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ForbiddenComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ForbiddenComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ForbiddenComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.ts b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.ts index 3dd20c084..b5416954e 100644 --- a/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.ts +++ b/projects/sample-code-flow-azuread/src/app/forbidden/forbidden.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-forbidden', templateUrl: './forbidden.component.html', - styleUrls: ['./forbidden.component.css'] + styleUrls: ['./forbidden.component.css'], }) export class ForbiddenComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azuread/src/app/home/home.component.html b/projects/sample-code-flow-azuread/src/app/home/home.component.html index fc46ff8fe..61532b953 100644 --- a/projects/sample-code-flow-azuread/src/app/home/home.component.html +++ b/projects/sample-code-flow-azuread/src/app/home/home.component.html @@ -1,5 +1,5 @@ -
Welcome
- -
-Is Authenticated: {{ isAuthenticated$ | async }} -
{{ userData$ | async | json }}
+
Welcome
+ +
+Is Authenticated: {{ isAuthenticated$ | async }} +
{{ userData$ | async | json }}
diff --git a/projects/sample-code-flow-azuread/src/app/home/home.component.ts b/projects/sample-code-flow-azuread/src/app/home/home.component.ts index c456dcc38..deb140da9 100644 --- a/projects/sample-code-flow-azuread/src/app/home/home.component.ts +++ b/projects/sample-code-flow-azuread/src/app/home/home.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - userData$: Observable; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - this.userData$ = this.oidcSecurityService.userData$; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + userData$: Observable; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + this.userData$ = this.oidcSecurityService.userData$; + } +} diff --git a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.css b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.css index f76d03515..9b7f74684 100644 --- a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.css +++ b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.css @@ -1,59 +1,59 @@ -li .glyphicon { - margin-right: 10px; -} - -/* Highlighting rules for nav menu items */ -li.link-active a, -li.link-active a:hover, -li.link-active a:focus { - background-color: #4189C7; - color: white; -} - -/* Keep the nav menu independent of scrolling and on top of other items */ -.main-nav { - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 1; -} - -@media (min-width: 768px) { - /* On small screens, convert the nav menu to a vertical sidebar */ - .main-nav { - height: 100%; - width: calc(25% - 20px); - } - .navbar { - border-radius: 0px; - border-width: 0px; - height: 100%; - } - .navbar-header { - float: none; - } - .navbar-collapse { - border-top: 1px solid #444; - padding: 0px; - } - .navbar ul { - float: none; - } - .navbar li { - float: none; - font-size: 15px; - margin: 6px; - } - .navbar li a { - padding: 10px 16px; - border-radius: 4px; - } - .navbar a { - /* If a menu item's text is too long, truncate it */ - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -} +li .glyphicon { + margin-right: 10px; +} + +/* Highlighting rules for nav menu items */ +li.link-active a, +li.link-active a:hover, +li.link-active a:focus { + background-color: #4189c7; + color: white; +} + +/* Keep the nav menu independent of scrolling and on top of other items */ +.main-nav { + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1; +} + +@media (min-width: 768px) { + /* On small screens, convert the nav menu to a vertical sidebar */ + .main-nav { + height: 100%; + width: calc(25% - 20px); + } + .navbar { + border-radius: 0px; + border-width: 0px; + height: 100%; + } + .navbar-header { + float: none; + } + .navbar-collapse { + border-top: 1px solid #444; + padding: 0px; + } + .navbar ul { + float: none; + } + .navbar li { + float: none; + font-size: 15px; + margin: 6px; + } + .navbar li a { + padding: 10px 16px; + border-radius: 4px; + } + .navbar a { + /* If a menu item's text is too long, truncate it */ + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} diff --git a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.html b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.html index 35e282cf7..de9599a9f 100644 --- a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.html +++ b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.html @@ -1,30 +1,30 @@ - + diff --git a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.ts b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.ts index 1613fee02..c77319625 100644 --- a/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.ts +++ b/projects/sample-code-flow-azuread/src/app/nav-menu/nav-menu.component.ts @@ -1,38 +1,38 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-nav-menu', - templateUrl: './nav-menu.component.html', - styleUrls: ['./nav-menu.component.css'], -}) -export class NavMenuComponent implements OnInit { - isExpanded = false; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); - } - - logout() { - this.oidcSecurityService.logoff(); - } - collapse() { - this.isExpanded = false; - } - - toggle() { - this.isExpanded = !this.isExpanded; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-nav-menu', + templateUrl: './nav-menu.component.html', + styleUrls: ['./nav-menu.component.css'], +}) +export class NavMenuComponent implements OnInit { + isExpanded = false; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } + collapse() { + this.isExpanded = false; + } + + toggle() { + this.isExpanded = !this.isExpanded; + } +} diff --git a/projects/sample-code-flow-azuread/src/app/protected/protected.component.html b/projects/sample-code-flow-azuread/src/app/protected/protected.component.html index 122e8a8f0..842979e71 100644 --- a/projects/sample-code-flow-azuread/src/app/protected/protected.component.html +++ b/projects/sample-code-flow-azuread/src/app/protected/protected.component.html @@ -1,3 +1 @@ -

- protected works! -

+

protected works!

diff --git a/projects/sample-code-flow-azuread/src/app/protected/protected.component.spec.ts b/projects/sample-code-flow-azuread/src/app/protected/protected.component.spec.ts index f67bd0ec0..6c1942350 100644 --- a/projects/sample-code-flow-azuread/src/app/protected/protected.component.spec.ts +++ b/projects/sample-code-flow-azuread/src/app/protected/protected.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ProtectedComponent } from './protected.component'; describe('ProtectedComponent', () => { - let component: ProtectedComponent; - let fixture: ComponentFixture; + let component: ProtectedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [ProtectedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [ProtectedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(ProtectedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(ProtectedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azuread/src/app/protected/protected.component.ts b/projects/sample-code-flow-azuread/src/app/protected/protected.component.ts index 528985f90..024769909 100644 --- a/projects/sample-code-flow-azuread/src/app/protected/protected.component.ts +++ b/projects/sample-code-flow-azuread/src/app/protected/protected.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-protected', templateUrl: './protected.component.html', - styleUrls: ['./protected.component.css'] + styleUrls: ['./protected.component.css'], }) export class ProtectedComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.html index 3f20fd3c9..10fe24be2 100644 --- a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.html @@ -1,3 +1 @@ -

- unauthorized works! -

+

unauthorized works!

diff --git a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.ts index fd9b55b1e..fe06a6912 100644 --- a/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow-azuread/src/app/unauthorized/unauthorized.component.ts @@ -3,13 +3,10 @@ import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-unauthorized', templateUrl: './unauthorized.component.html', - styleUrls: ['./unauthorized.component.css'] + styleUrls: ['./unauthorized.component.css'], }) export class UnauthorizedComponent implements OnInit { + constructor() {} - constructor() { } - - ngOnInit() { - } - + ngOnInit() {} } diff --git a/projects/sample-code-flow-azuread/src/environments/environment.prod.ts b/projects/sample-code-flow-azuread/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-azuread/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-azuread/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-azuread/src/environments/environment.ts b/projects/sample-code-flow-azuread/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-azuread/src/environments/environment.ts +++ b/projects/sample-code-flow-azuread/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-azuread/src/index.html b/projects/sample-code-flow-azuread/src/index.html index b0338933f..41028b33e 100644 --- a/projects/sample-code-flow-azuread/src/index.html +++ b/projects/sample-code-flow-azuread/src/index.html @@ -1,34 +1,34 @@ - - - Sample Azure OIDC Code Flow with PKCE - - - - - - - - - - - + + + Sample Azure OIDC Code Flow with PKCE + + + + + + + + + + + diff --git a/projects/sample-code-flow-azuread/src/main.ts b/projects/sample-code-flow-azuread/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-azuread/src/main.ts +++ b/projects/sample-code-flow-azuread/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-azuread/src/polyfills.ts b/projects/sample-code-flow-azuread/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-azuread/src/polyfills.ts +++ b/projects/sample-code-flow-azuread/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-azuread/src/silent-renew.html b/projects/sample-code-flow-azuread/src/silent-renew.html index 35a8eabe3..7aab22f4b 100644 --- a/projects/sample-code-flow-azuread/src/silent-renew.html +++ b/projects/sample-code-flow-azuread/src/silent-renew.html @@ -1,21 +1,21 @@ - - - - - silent-renew - - - - - + + + + + silent-renew + + + + + diff --git a/projects/sample-code-flow-azuread/src/test.ts b/projects/sample-code-flow-azuread/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-azuread/src/test.ts +++ b/projects/sample-code-flow-azuread/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-azuread/tsconfig.app.json b/projects/sample-code-flow-azuread/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-azuread/tsconfig.app.json +++ b/projects/sample-code-flow-azuread/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-azuread/tsconfig.spec.json b/projects/sample-code-flow-azuread/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-azuread/tsconfig.spec.json +++ b/projects/sample-code-flow-azuread/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-http-config/.eslintrc.json b/projects/sample-code-flow-http-config/.eslintrc.json index 60373e651..f686f9f78 100644 --- a/projects/sample-code-flow-http-config/.eslintrc.json +++ b/projects/sample-code-flow-http-config/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-http-config/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-http-config/e2e/protractor.conf.js b/projects/sample-code-flow-http-config/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-http-config/e2e/protractor.conf.js +++ b/projects/sample-code-flow-http-config/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-http-config/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-http-config/e2e/src/app.e2e-spec.ts index 10c024658..c8046c819 100644 --- a/projects/sample-code-flow-http-config/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-http-config/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-http-config/e2e/tsconfig.json b/projects/sample-code-flow-http-config/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-http-config/e2e/tsconfig.json +++ b/projects/sample-code-flow-http-config/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-http-config/karma.conf.js b/projects/sample-code-flow-http-config/karma.conf.js index 8848c98bc..b75bd81f5 100644 --- a/projects/sample-code-flow-http-config/karma.conf.js +++ b/projects/sample-code-flow-http-config/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-http-config'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-http-config/src/app/app.component.spec.ts b/projects/sample-code-flow-http-config/src/app/app.component.spec.ts index fc041501b..846c4af9b 100644 --- a/projects/sample-code-flow-http-config/src/app/app.component.spec.ts +++ b/projects/sample-code-flow-http-config/src/app/app.component.spec.ts @@ -2,30 +2,30 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'testSts'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('testSts'); - }); + it(`should have as title 'testSts'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('testSts'); + }); - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); - }); + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); + }); }); diff --git a/projects/sample-code-flow-http-config/src/app/app.component.ts b/projects/sample-code-flow-http-config/src/app/app.component.ts index 39bf7c63f..49f55691d 100644 --- a/projects/sample-code-flow-http-config/src/app/app.component.ts +++ b/projects/sample-code-flow-http-config/src/app/app.component.ts @@ -1,20 +1,20 @@ -import { Component, OnInit } from '@angular/core'; -import { EventTypes, OidcSecurityService, PublicEventsService } from 'angular-auth-oidc-client'; -import { filter } from 'rxjs/operators'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService, private eventService: PublicEventsService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); - - this.eventService - .registerForEvents() - .pipe(filter((notification) => notification.type === EventTypes.CheckSessionReceived)) - .subscribe((value) => console.log('CheckSessionReceived with value from app', value)); - } -} +import { Component, OnInit } from '@angular/core'; +import { EventTypes, OidcSecurityService, PublicEventsService } from 'angular-auth-oidc-client'; +import { filter } from 'rxjs/operators'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit { + constructor(public oidcSecurityService: OidcSecurityService, private eventService: PublicEventsService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); + + this.eventService + .registerForEvents() + .pipe(filter((notification) => notification.type === EventTypes.CheckSessionReceived)) + .subscribe((value) => console.log('CheckSessionReceived with value from app', value)); + } +} diff --git a/projects/sample-code-flow-http-config/src/app/app.module.ts b/projects/sample-code-flow-http-config/src/app/app.module.ts index f51ef8310..8f2305c94 100644 --- a/projects/sample-code-flow-http-config/src/app/app.module.ts +++ b/projects/sample-code-flow-http-config/src/app/app.module.ts @@ -1,24 +1,24 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { RouterModule } from '@angular/router'; -import { AppComponent } from './app.component'; -import { AuthConfigModule } from './auth-config.module'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [AppComponent, HomeComponent, UnauthorizedComponent], - imports: [ - BrowserModule, - RouterModule.forRoot([ - { path: '', redirectTo: 'home', pathMatch: 'full' }, - { path: 'home', component: HomeComponent }, - { path: 'forbidden', component: UnauthorizedComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - ]), - AuthConfigModule, - ], - providers: [], - bootstrap: [AppComponent], -}) -export class AppModule {} +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { AppComponent } from './app.component'; +import { AuthConfigModule } from './auth-config.module'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [AppComponent, HomeComponent, UnauthorizedComponent], + imports: [ + BrowserModule, + RouterModule.forRoot([ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { path: 'home', component: HomeComponent }, + { path: 'forbidden', component: UnauthorizedComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + ]), + AuthConfigModule, + ], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/projects/sample-code-flow-http-config/src/app/auth-config.module.ts b/projects/sample-code-flow-http-config/src/app/auth-config.module.ts index 94667bf06..4e8e56b49 100644 --- a/projects/sample-code-flow-http-config/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-http-config/src/app/auth-config.module.ts @@ -1,48 +1,48 @@ -import { HttpClient } from '@angular/common/http'; -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; -import { map, switchMap } from 'rxjs/operators'; - -export function configureAuth(oidcConfigService: OidcConfigService, httpClient: HttpClient) { - const setupAction$ = httpClient.get(`https://offeringsolutions-sts.azurewebsites.net/api/ClientAppSettings`).pipe( - map((customConfig) => { - return { - stsServer: customConfig.stsServer, - redirectUrl: customConfig.redirect_url, - clientId: customConfig.client_id, - responseType: customConfig.response_type, - scope: customConfig.scope, - postLogoutRedirectUri: customConfig.post_logout_redirect_uri, - startCheckSession: customConfig.start_checksession, - silentRenew: customConfig.silent_renew, - silentRenewUrl: customConfig.redirect_url + '/silent-renew.html', - postLoginRoute: customConfig.startup_route, - forbiddenRoute: customConfig.forbidden_route, - unauthorizedRoute: customConfig.unauthorized_route, - logLevel: customConfig.logLevel, // LogLevel.Debug, - maxIdTokenIatOffsetAllowedInSeconds: customConfig.max_id_token_iat_offset_allowed_in_seconds, - historyCleanupOff: true, - // autoUserinfo: false, - }; - }), - switchMap((config) => oidcConfigService.withConfig(config)) - ); - - return () => setupAction$.toPromise(); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcSecurityService, - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService, HttpClient], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { HttpClient } from '@angular/common/http'; +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; +import { map, switchMap } from 'rxjs/operators'; + +export function configureAuth(oidcConfigService: OidcConfigService, httpClient: HttpClient) { + const setupAction$ = httpClient.get(`https://offeringsolutions-sts.azurewebsites.net/api/ClientAppSettings`).pipe( + map((customConfig) => { + return { + stsServer: customConfig.stsServer, + redirectUrl: customConfig.redirect_url, + clientId: customConfig.client_id, + responseType: customConfig.response_type, + scope: customConfig.scope, + postLogoutRedirectUri: customConfig.post_logout_redirect_uri, + startCheckSession: customConfig.start_checksession, + silentRenew: customConfig.silent_renew, + silentRenewUrl: customConfig.redirect_url + '/silent-renew.html', + postLoginRoute: customConfig.startup_route, + forbiddenRoute: customConfig.forbidden_route, + unauthorizedRoute: customConfig.unauthorized_route, + logLevel: customConfig.logLevel, // LogLevel.Debug, + maxIdTokenIatOffsetAllowedInSeconds: customConfig.max_id_token_iat_offset_allowed_in_seconds, + historyCleanupOff: true, + // autoUserinfo: false, + }; + }), + switchMap((config) => oidcConfigService.withConfig(config)) + ); + + return () => setupAction$.toPromise(); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcSecurityService, + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService, HttpClient], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-http-config/src/app/home/home.component.html b/projects/sample-code-flow-http-config/src/app/home/home.component.html index 31263c768..cec85eef5 100644 --- a/projects/sample-code-flow-http-config/src/app/home/home.component.html +++ b/projects/sample-code-flow-http-config/src/app/home/home.component.html @@ -1,27 +1,27 @@ -
Welcome to home Route
- - - -
- - -
- -
- - Is Authenticated: {{ isAuthenticated }} - -
- userData -
{{ userData$ | async | json }}
- {{ checkSessionChanged }} -
-
- - - -
-
- -Configuration loaded: -
{{ configuration | json }}
+
Welcome to home Route
+ + + +
+ + +
+ +
+ + Is Authenticated: {{ isAuthenticated }} + +
+ userData +
{{ userData$ | async | json }}
+ {{ checkSessionChanged }} +
+
+ + + +
+
+ +Configuration loaded: +
{{ configuration | json }}
diff --git a/projects/sample-code-flow-http-config/src/app/home/home.component.spec.ts b/projects/sample-code-flow-http-config/src/app/home/home.component.spec.ts index 0c4a69378..50ff56b39 100644 --- a/projects/sample-code-flow-http-config/src/app/home/home.component.spec.ts +++ b/projects/sample-code-flow-http-config/src/app/home/home.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HomeComponent } from './home.component'; describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; + let component: HomeComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HomeComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-http-config/src/app/home/home.component.ts b/projects/sample-code-flow-http-config/src/app/home/home.component.ts index cfeaaa47b..65d7cd9fa 100644 --- a/projects/sample-code-flow-http-config/src/app/home/home.component.ts +++ b/projects/sample-code-flow-http-config/src/app/home/home.component.ts @@ -1,37 +1,37 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - configuration: PublicConfiguration; - userDataChanged$: Observable>; - userData$: Observable; - isAuthenticated$: Observable; - checkSessionChanged$: Observable; - checkSessionChanged: any; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.configuration = this.oidcSecurityService.configuration; - this.userData$ = this.oidcSecurityService.userData$; - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - this.checkSessionChanged$ = this.oidcSecurityService.checkSessionChanged$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); - } - - logout() { - this.oidcSecurityService.logoff(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + configuration: PublicConfiguration; + userDataChanged$: Observable>; + userData$: Observable; + isAuthenticated$: Observable; + checkSessionChanged$: Observable; + checkSessionChanged: any; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.configuration = this.oidcSecurityService.configuration; + this.userData$ = this.oidcSecurityService.userData$; + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + this.checkSessionChanged$ = this.oidcSecurityService.checkSessionChanged$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.ts index 1249768a3..dbe965047 100644 --- a/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow-http-config/src/app/unauthorized/unauthorized.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html', -}) -export class UnauthorizedComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/projects/sample-code-flow-http-config/src/environments/environment.prod.ts b/projects/sample-code-flow-http-config/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-http-config/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-http-config/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-http-config/src/environments/environment.ts b/projects/sample-code-flow-http-config/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-http-config/src/environments/environment.ts +++ b/projects/sample-code-flow-http-config/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-http-config/src/index.html b/projects/sample-code-flow-http-config/src/index.html index a3f98a2ef..dc49fd283 100644 --- a/projects/sample-code-flow-http-config/src/index.html +++ b/projects/sample-code-flow-http-config/src/index.html @@ -1,13 +1,13 @@ - - - Sample Code Flow HttpConfig - - - - - - - + + + Sample Code Flow HttpConfig + + + + + + + diff --git a/projects/sample-code-flow-http-config/src/main.ts b/projects/sample-code-flow-http-config/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-http-config/src/main.ts +++ b/projects/sample-code-flow-http-config/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-http-config/src/polyfills.ts b/projects/sample-code-flow-http-config/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-http-config/src/polyfills.ts +++ b/projects/sample-code-flow-http-config/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-http-config/src/silent-renew.html b/projects/sample-code-flow-http-config/src/silent-renew.html index 35a8eabe3..7aab22f4b 100644 --- a/projects/sample-code-flow-http-config/src/silent-renew.html +++ b/projects/sample-code-flow-http-config/src/silent-renew.html @@ -1,21 +1,21 @@ - - - - - silent-renew - - - - - + + + + + silent-renew + + + + + diff --git a/projects/sample-code-flow-http-config/src/test.ts b/projects/sample-code-flow-http-config/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-http-config/src/test.ts +++ b/projects/sample-code-flow-http-config/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-http-config/tsconfig.app.json b/projects/sample-code-flow-http-config/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-http-config/tsconfig.app.json +++ b/projects/sample-code-flow-http-config/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-http-config/tsconfig.spec.json b/projects/sample-code-flow-http-config/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-http-config/tsconfig.spec.json +++ b/projects/sample-code-flow-http-config/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-lazy-loaded/.eslintrc.json b/projects/sample-code-flow-lazy-loaded/.eslintrc.json index 2bfbb566f..44247b1b3 100644 --- a/projects/sample-code-flow-lazy-loaded/.eslintrc.json +++ b/projects/sample-code-flow-lazy-loaded/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-lazy-loaded/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-lazy-loaded/e2e/protractor.conf.js b/projects/sample-code-flow-lazy-loaded/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-lazy-loaded/e2e/protractor.conf.js +++ b/projects/sample-code-flow-lazy-loaded/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-lazy-loaded/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-lazy-loaded/e2e/src/app.e2e-spec.ts index 1ad10b15e..e012194a7 100644 --- a/projects/sample-code-flow-lazy-loaded/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-lazy-loaded/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-lazy-loaded/e2e/tsconfig.json b/projects/sample-code-flow-lazy-loaded/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-lazy-loaded/e2e/tsconfig.json +++ b/projects/sample-code-flow-lazy-loaded/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-lazy-loaded/karma.conf.js b/projects/sample-code-flow-lazy-loaded/karma.conf.js index e2d388021..4b6c52892 100644 --- a/projects/sample-code-flow-lazy-loaded/karma.conf.js +++ b/projects/sample-code-flow-lazy-loaded/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-lazy-loaded'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-lazy-loaded/src/app/app-routing.module.ts b/projects/sample-code-flow-lazy-loaded/src/app/app-routing.module.ts index bc7de19fd..897ab66b0 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/app-routing.module.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/app-routing.module.ts @@ -4,7 +4,7 @@ import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [{ path: 'lazy', loadChildren: () => import('./lazy/lazy.module').then((m) => m.LazyModule) }]; @NgModule({ - imports: [RouterModule.forRoot(routes)], - exports: [RouterModule], + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule], }) export class AppRoutingModule {} diff --git a/projects/sample-code-flow-lazy-loaded/src/app/app.component.spec.ts b/projects/sample-code-flow-lazy-loaded/src/app/app.component.spec.ts index 5c583ac18..a796c6e39 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/app.component.spec.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/app.component.spec.ts @@ -3,31 +3,31 @@ import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [RouterTestingModule], - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'sample-code-flow-lazy-loaded'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('sample-code-flow-lazy-loaded'); - }); + it(`should have as title 'sample-code-flow-lazy-loaded'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('sample-code-flow-lazy-loaded'); + }); - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain('sample-code-flow-lazy-loaded app is running!'); - }); + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(compiled.querySelector('.content span').textContent).toContain('sample-code-flow-lazy-loaded app is running!'); + }); }); diff --git a/projects/sample-code-flow-lazy-loaded/src/app/app.component.ts b/projects/sample-code-flow-lazy-loaded/src/app/app.component.ts index ab5fd7a74..eecfcd45e 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/app.component.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/app.component.ts @@ -2,14 +2,14 @@ import { Component } from '@angular/core'; import { OidcSecurityService } from 'angular-auth-oidc-client'; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.css'], + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], }) export class AppComponent { - title = 'sample-code-flow-lazy-loaded'; + title = 'sample-code-flow-lazy-loaded'; - constructor(public oidcSecurityService: OidcSecurityService) { - this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); - } + constructor(public oidcSecurityService: OidcSecurityService) { + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); + } } diff --git a/projects/sample-code-flow-lazy-loaded/src/app/app.module.ts b/projects/sample-code-flow-lazy-loaded/src/app/app.module.ts index 272b5cf92..f9edda165 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/app.module.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/app.module.ts @@ -6,8 +6,8 @@ import { AppComponent } from './app.component'; import { AuthConfigModule } from './auth-config.module'; @NgModule({ - declarations: [AppComponent], - imports: [BrowserModule, AppRoutingModule, AuthConfigModule, HttpClientModule], - bootstrap: [AppComponent], + declarations: [AppComponent], + imports: [BrowserModule, AppRoutingModule, AuthConfigModule, HttpClientModule], + bootstrap: [AppComponent], }) export class AppModule {} diff --git a/projects/sample-code-flow-lazy-loaded/src/app/auth-config.module.ts b/projects/sample-code-flow-lazy-loaded/src/app/auth-config.module.ts index ae60747fd..39c88a245 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/auth-config.module.ts @@ -1,32 +1,32 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://offeringsolutions-sts.azurewebsites.net', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'angularCodeRefreshTokens', - scope: 'openid profile email offline_access', - responseType: 'code', - silentRenew: true, - useRefreshToken: true, - logLevel: LogLevel.Debug, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularCodeRefreshTokens', + scope: 'openid profile email offline_access', + responseType: 'code', + silentRenew: true, + useRefreshToken: true, + logLevel: LogLevel.Debug, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy-routing.module.ts b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy-routing.module.ts index 201422394..cc5ae3067 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy-routing.module.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy-routing.module.ts @@ -7,6 +7,6 @@ const routes: Routes = [{ path: '', component: LazyComponent }]; @NgModule({ imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + exports: [RouterModule], }) -export class LazyRoutingModule { } +export class LazyRoutingModule {} diff --git a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.html b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.html index cdb8e58d3..0c87593da 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.html +++ b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.html @@ -7,5 +7,5 @@
- +
diff --git a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.spec.ts b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.spec.ts index 583e3da36..4a3e7d8d5 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.spec.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { LazyComponent } from './lazy.component'; describe('LazyComponent', () => { - let component: LazyComponent; - let fixture: ComponentFixture; + let component: LazyComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [LazyComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [LazyComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(LazyComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(LazyComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.ts b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.ts index 859efe5a2..878a7f056 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.component.ts @@ -3,23 +3,23 @@ import { OidcSecurityService } from 'angular-auth-oidc-client'; import { Observable } from 'rxjs'; @Component({ - selector: 'app-lazy', - templateUrl: './lazy.component.html', - styleUrls: ['./lazy.component.css'], + selector: 'app-lazy', + templateUrl: './lazy.component.html', + styleUrls: ['./lazy.component.css'], }) export class LazyComponent implements OnInit { - isAuthenticated$: Observable; - constructor(public oidcSecurityService: OidcSecurityService) {} + isAuthenticated$: Observable; + constructor(public oidcSecurityService: OidcSecurityService) {} - ngOnInit(): void { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } + ngOnInit(): void { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } - login() { - this.oidcSecurityService.authorize(); - } + login() { + this.oidcSecurityService.authorize(); + } - logout() { - this.oidcSecurityService.logoff(); - } + logout() { + this.oidcSecurityService.logoff(); + } } diff --git a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.module.ts b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.module.ts index 61dc8fddf..e6b8a70dc 100644 --- a/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.module.ts +++ b/projects/sample-code-flow-lazy-loaded/src/app/lazy/lazy.module.ts @@ -4,9 +4,9 @@ import { LazyRoutingModule } from './lazy-routing.module'; import { LazyComponent } from './lazy.component'; @NgModule({ - declarations: [LazyComponent], - imports: [CommonModule, LazyRoutingModule], + declarations: [LazyComponent], + imports: [CommonModule, LazyRoutingModule], }) export class LazyModule { - constructor() {} + constructor() {} } diff --git a/projects/sample-code-flow-lazy-loaded/src/environments/environment.prod.ts b/projects/sample-code-flow-lazy-loaded/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-lazy-loaded/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-lazy-loaded/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-lazy-loaded/src/environments/environment.ts b/projects/sample-code-flow-lazy-loaded/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-lazy-loaded/src/environments/environment.ts +++ b/projects/sample-code-flow-lazy-loaded/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-lazy-loaded/src/index.html b/projects/sample-code-flow-lazy-loaded/src/index.html index ae2413674..c66f846ce 100644 --- a/projects/sample-code-flow-lazy-loaded/src/index.html +++ b/projects/sample-code-flow-lazy-loaded/src/index.html @@ -1,13 +1,13 @@ - + - - - SampleCodeFlowLazyLoaded - - - - - - - + + + SampleCodeFlowLazyLoaded + + + + + + + diff --git a/projects/sample-code-flow-lazy-loaded/src/main.ts b/projects/sample-code-flow-lazy-loaded/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-lazy-loaded/src/main.ts +++ b/projects/sample-code-flow-lazy-loaded/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-lazy-loaded/src/polyfills.ts b/projects/sample-code-flow-lazy-loaded/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-lazy-loaded/src/polyfills.ts +++ b/projects/sample-code-flow-lazy-loaded/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-lazy-loaded/src/test.ts b/projects/sample-code-flow-lazy-loaded/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-lazy-loaded/src/test.ts +++ b/projects/sample-code-flow-lazy-loaded/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-lazy-loaded/tsconfig.app.json b/projects/sample-code-flow-lazy-loaded/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-lazy-loaded/tsconfig.app.json +++ b/projects/sample-code-flow-lazy-loaded/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-lazy-loaded/tsconfig.spec.json b/projects/sample-code-flow-lazy-loaded/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-lazy-loaded/tsconfig.spec.json +++ b/projects/sample-code-flow-lazy-loaded/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-popup/.browserslistrc b/projects/sample-code-flow-popup/.browserslistrc new file mode 100644 index 000000000..427441dc9 --- /dev/null +++ b/projects/sample-code-flow-popup/.browserslistrc @@ -0,0 +1,17 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/projects/sample-code-flow-popup/e2e/protractor.conf.js b/projects/sample-code-flow-popup/e2e/protractor.conf.js new file mode 100644 index 000000000..2e47d856e --- /dev/null +++ b/projects/sample-code-flow-popup/e2e/protractor.conf.js @@ -0,0 +1,37 @@ +// @ts-check +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); + +/** + * @type { import("protractor").Config } + */ +exports.config = { + allScriptsTimeout: 11000, + specs: ['./src/**/*.e2e-spec.ts'], + capabilities: { + browserName: 'chrome', + }, + directConnect: true, + SELENIUM_PROMISE_MANAGER: false, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function () {}, + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.json'), + }); + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-popup/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-popup/e2e/src/app.e2e-spec.ts new file mode 100644 index 000000000..e62912fea --- /dev/null +++ b/projects/sample-code-flow-popup/e2e/src/app.e2e-spec.ts @@ -0,0 +1,25 @@ +import { AppPage } from './app.po'; +import { browser, logging } from 'protractor'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', async () => { + await page.navigateTo(); + expect(await page.getTitleText()).toEqual('sample-code-flow-popup app is running!'); + }); + + afterEach(async () => { + // Assert that there are no errors emitted from the browser + const logs = await browser.manage().logs().get(logging.Type.BROWSER); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); + }); +}); diff --git a/projects/sample-code-flow-popup/e2e/src/app.po.ts b/projects/sample-code-flow-popup/e2e/src/app.po.ts new file mode 100644 index 000000000..c9c85ab9a --- /dev/null +++ b/projects/sample-code-flow-popup/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + async navigateTo(): Promise { + return browser.get(browser.baseUrl); + } + + async getTitleText(): Promise { + return element(by.css('app-root .content span')).getText(); + } +} diff --git a/projects/sample-code-flow-popup/e2e/tsconfig.json b/projects/sample-code-flow-popup/e2e/tsconfig.json new file mode 100644 index 000000000..38556bc7d --- /dev/null +++ b/projects/sample-code-flow-popup/e2e/tsconfig.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "../../../out-tsc/e2e", + "module": "commonjs", + "target": "es2018", + "types": ["jasmine", "node"] + } +} diff --git a/projects/sample-code-flow-popup/karma.conf.js b/projects/sample-code-flow-popup/karma.conf.js new file mode 100644 index 000000000..8e44a0e75 --- /dev/null +++ b/projects/sample-code-flow-popup/karma.conf.js @@ -0,0 +1,41 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage'), + require('@angular-devkit/build-angular/plugins/karma'), + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false, // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true, // removes the duplicated traces + }, + coverageReporter: { + dir: require('path').join(__dirname, '../../coverage/sample-code-flow-popup'), + subdir: '.', + reporters: [{ type: 'html' }, { type: 'text-summary' }], + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false, + restartOnFileChange: true, + }); +}; diff --git a/projects/sample-code-flow-popup/src/app/app-routing.module.ts b/projects/sample-code-flow-popup/src/app/app-routing.module.ts new file mode 100644 index 000000000..11c2e8407 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/app-routing.module.ts @@ -0,0 +1,10 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +const routes: Routes = []; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule], +}) +export class AppRoutingModule {} diff --git a/projects/sample-code-flow-popup/src/app/app.component.css b/projects/sample-code-flow-popup/src/app/app.component.css new file mode 100644 index 000000000..e69de29bb diff --git a/projects/sample-code-flow-popup/src/app/app.component.html b/projects/sample-code-flow-popup/src/app/app.component.html new file mode 100644 index 000000000..721ae8d80 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/app.component.html @@ -0,0 +1,24 @@ +
+ + +
+ +
+ + Is Authenticated: {{ isAuthenticated }} + +
+ userData +
{{ userData$ | async | json }}
+ +
+
+ + + +
+ You are NOT authenticated +
+ +Configuration loaded: +
{{ configuration | json }}
diff --git a/projects/sample-code-flow-popup/src/app/app.component.spec.ts b/projects/sample-code-flow-popup/src/app/app.component.spec.ts new file mode 100644 index 000000000..6041289c7 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/app.component.spec.ts @@ -0,0 +1,31 @@ +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'sample-code-flow-popup'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('sample-code-flow-popup'); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(compiled.querySelector('.content span').textContent).toContain('sample-code-flow-popup app is running!'); + }); +}); diff --git a/projects/sample-code-flow-popup/src/app/app.component.ts b/projects/sample-code-flow-popup/src/app/app.component.ts new file mode 100644 index 000000000..81578d293 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/app.component.ts @@ -0,0 +1,48 @@ +import { Component } from '@angular/core'; +import { OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], +}) +export class AppComponent { + title = 'sample-code-flow-popup'; + + userData$: Observable; + + configuration: PublicConfiguration; + + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.configuration = this.oidcSecurityService.configuration; + this.userData$ = this.oidcSecurityService.userData$; + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => { + console.log('app authenticated', isAuthenticated); + const at = this.oidcSecurityService.getToken(); + console.log(`Current access token is '${at}'`); + }); + } + + loginWithPopup() { + this.oidcSecurityService.authorizeWithPopUp().subscribe(({ isAuthenticated, userData, accessToken }) => { + console.log(isAuthenticated); + console.log(userData); + console.log(accessToken); + }); + } + + forceRefreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.warn(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-code-flow-popup/src/app/app.module.ts b/projects/sample-code-flow-popup/src/app/app.module.ts new file mode 100644 index 000000000..79bd5fbf5 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/app.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppRoutingModule } from './app-routing.module'; +import { AppComponent } from './app.component'; +import { AuthConfigModule } from './auth-config.module'; + +@NgModule({ + declarations: [AppComponent], + imports: [BrowserModule, AppRoutingModule, AuthConfigModule], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/projects/sample-code-flow-popup/src/app/auth-config.module.ts b/projects/sample-code-flow-popup/src/app/auth-config.module.ts new file mode 100644 index 000000000..36396bc66 --- /dev/null +++ b/projects/sample-code-flow-popup/src/app/auth-config.module.ts @@ -0,0 +1,34 @@ +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; +import { environment } from '../environments/environment'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularClient', + scope: 'openid profile email', + responseType: 'code', + silentRenew: true, + silentRenewUrl: `${window.location.origin}/silent-renew.html`, + renewTimeBeforeTokenExpiresInSeconds: 10, + logLevel: environment.production ? LogLevel.None : LogLevel.Debug, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-popup/src/assets/.gitkeep b/projects/sample-code-flow-popup/src/assets/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/projects/sample-code-flow-popup/src/environments/environment.prod.ts b/projects/sample-code-flow-popup/src/environments/environment.prod.ts new file mode 100644 index 000000000..c9669790b --- /dev/null +++ b/projects/sample-code-flow-popup/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true, +}; diff --git a/projects/sample-code-flow-popup/src/environments/environment.ts b/projects/sample-code-flow-popup/src/environments/environment.ts new file mode 100644 index 000000000..99c3763ca --- /dev/null +++ b/projects/sample-code-flow-popup/src/environments/environment.ts @@ -0,0 +1,16 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/projects/sample-code-flow-popup/src/favicon.ico b/projects/sample-code-flow-popup/src/favicon.ico new file mode 100644 index 000000000..997406ad2 Binary files /dev/null and b/projects/sample-code-flow-popup/src/favicon.ico differ diff --git a/projects/sample-code-flow-popup/src/index.html b/projects/sample-code-flow-popup/src/index.html new file mode 100644 index 000000000..c3d148002 --- /dev/null +++ b/projects/sample-code-flow-popup/src/index.html @@ -0,0 +1,13 @@ + + + + + SampleCodeFlowPopup + + + + + + + + diff --git a/projects/sample-code-flow-popup/src/main.ts b/projects/sample-code-flow-popup/src/main.ts new file mode 100644 index 000000000..d9a2e7e4a --- /dev/null +++ b/projects/sample-code-flow-popup/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-popup/src/polyfills.ts b/projects/sample-code-flow-popup/src/polyfills.ts new file mode 100644 index 000000000..c5f27446d --- /dev/null +++ b/projects/sample-code-flow-popup/src/polyfills.ts @@ -0,0 +1,62 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + */ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/projects/sample-code-flow-popup/src/silent-renew.html b/projects/sample-code-flow-popup/src/silent-renew.html new file mode 100644 index 000000000..7aab22f4b --- /dev/null +++ b/projects/sample-code-flow-popup/src/silent-renew.html @@ -0,0 +1,21 @@ + + + + + + + silent-renew + + + + + + diff --git a/projects/sample-code-flow-popup/src/styles.css b/projects/sample-code-flow-popup/src/styles.css new file mode 100644 index 000000000..90d4ee007 --- /dev/null +++ b/projects/sample-code-flow-popup/src/styles.css @@ -0,0 +1 @@ +/* You can add global styles to this file, and also import other style files */ diff --git a/projects/sample-code-flow-popup/src/test.ts b/projects/sample-code-flow-popup/src/test.ts new file mode 100644 index 000000000..4f56cf522 --- /dev/null +++ b/projects/sample-code-flow-popup/src/test.ts @@ -0,0 +1,23 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + +declare const require: { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { + keys(): string[]; + (id: string): T; + }; +}; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/projects/sample-code-flow-popup/tsconfig.app.json b/projects/sample-code-flow-popup/tsconfig.app.json new file mode 100644 index 000000000..c3c483759 --- /dev/null +++ b/projects/sample-code-flow-popup/tsconfig.app.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/app", + "types": [] + }, + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/projects/sample-code-flow-popup/tsconfig.spec.json b/projects/sample-code-flow-popup/tsconfig.spec.json new file mode 100644 index 000000000..558b74c94 --- /dev/null +++ b/projects/sample-code-flow-popup/tsconfig.spec.json @@ -0,0 +1,10 @@ +/* To learn more about this file see: https://angular.io/config/tsconfig. */ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/projects/sample-code-flow-popup/tslint.json b/projects/sample-code-flow-popup/tslint.json new file mode 100644 index 000000000..8006e74e9 --- /dev/null +++ b/projects/sample-code-flow-popup/tslint.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tslint.json", + "rules": { + "directive-selector": [true, "attribute", "app", "camelCase"], + "component-selector": [true, "element", "app", "kebab-case"] + } +} diff --git a/projects/sample-code-flow-refresh-tokens/.eslintrc.json b/projects/sample-code-flow-refresh-tokens/.eslintrc.json index 37e04ee0e..0e6b3228b 100644 --- a/projects/sample-code-flow-refresh-tokens/.eslintrc.json +++ b/projects/sample-code-flow-refresh-tokens/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow-refresh-tokens/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow-refresh-tokens/e2e/protractor.conf.js b/projects/sample-code-flow-refresh-tokens/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow-refresh-tokens/e2e/protractor.conf.js +++ b/projects/sample-code-flow-refresh-tokens/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow-refresh-tokens/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow-refresh-tokens/e2e/src/app.e2e-spec.ts index 45fa288a0..a283fa691 100644 --- a/projects/sample-code-flow-refresh-tokens/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow-refresh-tokens/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow-refresh-tokens/e2e/tsconfig.json b/projects/sample-code-flow-refresh-tokens/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow-refresh-tokens/e2e/tsconfig.json +++ b/projects/sample-code-flow-refresh-tokens/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow-refresh-tokens/karma.conf.js b/projects/sample-code-flow-refresh-tokens/karma.conf.js index a8eb9bec8..7faeb8e31 100644 --- a/projects/sample-code-flow-refresh-tokens/karma.conf.js +++ b/projects/sample-code-flow-refresh-tokens/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow-refresh-tokens'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow-refresh-tokens/src/app/app.component.spec.ts b/projects/sample-code-flow-refresh-tokens/src/app/app.component.spec.ts index fc041501b..846c4af9b 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/app.component.spec.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/app.component.spec.ts @@ -2,30 +2,30 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'testSts'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('testSts'); - }); + it(`should have as title 'testSts'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('testSts'); + }); - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); - }); + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); + }); }); diff --git a/projects/sample-code-flow-refresh-tokens/src/app/app.component.ts b/projects/sample-code-flow-refresh-tokens/src/app/app.component.ts index 0e5f04172..cdd0959ea 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/app.component.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/app.component.ts @@ -1,14 +1,14 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit { + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); + } +} diff --git a/projects/sample-code-flow-refresh-tokens/src/app/app.module.ts b/projects/sample-code-flow-refresh-tokens/src/app/app.module.ts index 21741f55e..fe20bc8c5 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/app.module.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/app.module.ts @@ -1,35 +1,35 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { RouterModule } from '@angular/router'; -import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; -import { filter } from 'rxjs/operators'; -import { AppComponent } from './app.component'; -import { AuthConfigModule } from './auth-config.module'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [AppComponent, HomeComponent, UnauthorizedComponent], - imports: [ - BrowserModule, - RouterModule.forRoot([ - { path: '', redirectTo: 'home', pathMatch: 'full' }, - { path: 'home', component: HomeComponent }, - { path: 'forbidden', component: UnauthorizedComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - ]), - AuthConfigModule, - ], - providers: [], - bootstrap: [AppComponent], -}) -export class AppModule { - constructor(private readonly eventService: PublicEventsService) { - this.eventService - .registerForEvents() - .pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded)) - .subscribe((config) => { - console.log('ConfigLoaded', config); - }); - } -} +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; +import { filter } from 'rxjs/operators'; +import { AppComponent } from './app.component'; +import { AuthConfigModule } from './auth-config.module'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [AppComponent, HomeComponent, UnauthorizedComponent], + imports: [ + BrowserModule, + RouterModule.forRoot([ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { path: 'home', component: HomeComponent }, + { path: 'forbidden', component: UnauthorizedComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + ]), + AuthConfigModule, + ], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule { + constructor(private readonly eventService: PublicEventsService) { + this.eventService + .registerForEvents() + .pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded)) + .subscribe((config) => { + console.log('ConfigLoaded', config); + }); + } +} diff --git a/projects/sample-code-flow-refresh-tokens/src/app/auth-config.module.ts b/projects/sample-code-flow-refresh-tokens/src/app/auth-config.module.ts index 42338b8b3..1a9453e31 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/auth-config.module.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/auth-config.module.ts @@ -1,32 +1,32 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://offeringsolutions-sts.azurewebsites.net', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'angularCodeRefreshTokens', - scope: 'openid profile email taler_api offline_access', - responseType: 'code', - silentRenew: true, - useRefreshToken: true, - logLevel: LogLevel.Debug, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularCodeRefreshTokens', + scope: 'openid profile email taler_api offline_access', + responseType: 'code', + silentRenew: true, + useRefreshToken: true, + logLevel: LogLevel.Debug, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.html b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.html index cd83b044f..1ffb371a8 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.html +++ b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.html @@ -1,28 +1,28 @@ -
Welcome to home Route
- -
- - - - - -
- -
- - Is Authenticated: {{ isAuthenticated }} - -
- userData -
{{ userData$ | async | json }}
- -
-
- - - -
-
- -Configuration loaded: -
{{ configuration | json }}
+
Welcome to home Route
+ +
+ + + + + +
+ +
+ + Is Authenticated: {{ isAuthenticated }} + +
+ userData +
{{ userData$ | async | json }}
+ +
+
+ + + +
+
+ +Configuration loaded: +
{{ configuration | json }}
diff --git a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.spec.ts b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.spec.ts index 0c4a69378..50ff56b39 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.spec.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HomeComponent } from './home.component'; describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; + let component: HomeComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HomeComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.ts b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.ts index dc3c71cc1..cbcb487b6 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/home/home.component.ts @@ -1,50 +1,50 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - configuration: PublicConfiguration; - userDataChanged$: Observable>; - userData$: Observable; - isAuthenticated = false; - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.configuration = this.oidcSecurityService.configuration; - this.userData$ = this.oidcSecurityService.userData$; - - this.oidcSecurityService.isAuthenticated$.subscribe((authenticated) => { - this.isAuthenticated = authenticated; - - console.warn('authenticated: ', authenticated); - }); - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); - } - - logout() { - this.oidcSecurityService.logoff(); - } - - logoffAndRevokeTokens() { - this.oidcSecurityService.logoffAndRevokeTokens().subscribe((result) => console.log(result)); - } - - revokeRefreshToken() { - this.oidcSecurityService.revokeRefreshToken().subscribe((result) => console.log(result)); - } - - revokeAccessToken() { - this.oidcSecurityService.revokeAccessToken().subscribe((result) => console.log(result)); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + configuration: PublicConfiguration; + userDataChanged$: Observable>; + userData$: Observable; + isAuthenticated = false; + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.configuration = this.oidcSecurityService.configuration; + this.userData$ = this.oidcSecurityService.userData$; + + this.oidcSecurityService.isAuthenticated$.subscribe((authenticated) => { + this.isAuthenticated = authenticated; + + console.warn('authenticated: ', authenticated); + }); + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } + + logoffAndRevokeTokens() { + this.oidcSecurityService.logoffAndRevokeTokens().subscribe((result) => console.log(result)); + } + + revokeRefreshToken() { + this.oidcSecurityService.revokeRefreshToken().subscribe((result) => console.log(result)); + } + + revokeAccessToken() { + this.oidcSecurityService.revokeAccessToken().subscribe((result) => console.log(result)); + } +} diff --git a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.ts index 1249768a3..dbe965047 100644 --- a/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow-refresh-tokens/src/app/unauthorized/unauthorized.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html', -}) -export class UnauthorizedComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/projects/sample-code-flow-refresh-tokens/src/environments/environment.prod.ts b/projects/sample-code-flow-refresh-tokens/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow-refresh-tokens/src/environments/environment.prod.ts +++ b/projects/sample-code-flow-refresh-tokens/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow-refresh-tokens/src/environments/environment.ts b/projects/sample-code-flow-refresh-tokens/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow-refresh-tokens/src/environments/environment.ts +++ b/projects/sample-code-flow-refresh-tokens/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow-refresh-tokens/src/index.html b/projects/sample-code-flow-refresh-tokens/src/index.html index 71266631d..46115dff2 100644 --- a/projects/sample-code-flow-refresh-tokens/src/index.html +++ b/projects/sample-code-flow-refresh-tokens/src/index.html @@ -1,13 +1,13 @@ - - - Sample Code Flow Refresh Tokens - - - - - - - + + + Sample Code Flow Refresh Tokens + + + + + + + diff --git a/projects/sample-code-flow-refresh-tokens/src/main.ts b/projects/sample-code-flow-refresh-tokens/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow-refresh-tokens/src/main.ts +++ b/projects/sample-code-flow-refresh-tokens/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow-refresh-tokens/src/polyfills.ts b/projects/sample-code-flow-refresh-tokens/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow-refresh-tokens/src/polyfills.ts +++ b/projects/sample-code-flow-refresh-tokens/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow-refresh-tokens/src/test.ts b/projects/sample-code-flow-refresh-tokens/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow-refresh-tokens/src/test.ts +++ b/projects/sample-code-flow-refresh-tokens/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow-refresh-tokens/tsconfig.app.json b/projects/sample-code-flow-refresh-tokens/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow-refresh-tokens/tsconfig.app.json +++ b/projects/sample-code-flow-refresh-tokens/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow-refresh-tokens/tsconfig.spec.json b/projects/sample-code-flow-refresh-tokens/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow-refresh-tokens/tsconfig.spec.json +++ b/projects/sample-code-flow-refresh-tokens/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-code-flow/.eslintrc.json b/projects/sample-code-flow/.eslintrc.json index c75b44b43..6dd29b3a0 100644 --- a/projects/sample-code-flow/.eslintrc.json +++ b/projects/sample-code-flow/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-code-flow/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-code-flow/e2e/protractor.conf.js b/projects/sample-code-flow/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-code-flow/e2e/protractor.conf.js +++ b/projects/sample-code-flow/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-code-flow/e2e/src/app.e2e-spec.ts b/projects/sample-code-flow/e2e/src/app.e2e-spec.ts index 681a06a4b..3168a14bd 100644 --- a/projects/sample-code-flow/e2e/src/app.e2e-spec.ts +++ b/projects/sample-code-flow/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-code-flow/e2e/tsconfig.json b/projects/sample-code-flow/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-code-flow/e2e/tsconfig.json +++ b/projects/sample-code-flow/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-code-flow/karma.conf.js b/projects/sample-code-flow/karma.conf.js index 482506532..07a974396 100644 --- a/projects/sample-code-flow/karma.conf.js +++ b/projects/sample-code-flow/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-code-flow'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-code-flow/src/app/app.component.spec.ts b/projects/sample-code-flow/src/app/app.component.spec.ts index fc041501b..846c4af9b 100644 --- a/projects/sample-code-flow/src/app/app.component.spec.ts +++ b/projects/sample-code-flow/src/app/app.component.spec.ts @@ -2,30 +2,30 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'testSts'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('testSts'); - }); + it(`should have as title 'testSts'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('testSts'); + }); - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); - }); + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); + }); }); diff --git a/projects/sample-code-flow/src/app/app.component.ts b/projects/sample-code-flow/src/app/app.component.ts index 3e8188d0d..25b2d291b 100644 --- a/projects/sample-code-flow/src/app/app.component.ts +++ b/projects/sample-code-flow/src/app/app.component.ts @@ -1,18 +1,18 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => { - console.log('app authenticated', isAuthenticated); - const at = this.oidcSecurityService.getToken(); - console.log(`Current access token is '${at}'`); - }); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit { + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe((isAuthenticated) => { + console.log('app authenticated', isAuthenticated); + const at = this.oidcSecurityService.getToken(); + console.log(`Current access token is '${at}'`); + }); + } +} diff --git a/projects/sample-code-flow/src/app/app.module.ts b/projects/sample-code-flow/src/app/app.module.ts index 01649a834..36bab15a6 100644 --- a/projects/sample-code-flow/src/app/app.module.ts +++ b/projects/sample-code-flow/src/app/app.module.ts @@ -1,37 +1,37 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { RouterModule } from '@angular/router'; -import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; -import { filter } from 'rxjs/operators'; -import { AppComponent } from './app.component'; -import { AuthConfigModule } from './auth-config.module'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [AppComponent, HomeComponent, UnauthorizedComponent], - imports: [ - BrowserModule, - RouterModule.forRoot([ - { path: '', redirectTo: 'home', pathMatch: 'full' }, - { path: 'home', component: HomeComponent }, - { path: 'forbidden', component: UnauthorizedComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - ]), - AuthConfigModule, - ], - bootstrap: [AppComponent], -}) -export class AppModule { - constructor(private readonly eventService: PublicEventsService) { - this.eventService - .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)); - } -} +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; +import { filter } from 'rxjs/operators'; +import { AppComponent } from './app.component'; +import { AuthConfigModule } from './auth-config.module'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [AppComponent, HomeComponent, UnauthorizedComponent], + imports: [ + BrowserModule, + RouterModule.forRoot([ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { path: 'home', component: HomeComponent }, + { path: 'forbidden', component: UnauthorizedComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + ]), + AuthConfigModule, + ], + bootstrap: [AppComponent], +}) +export class AppModule { + constructor(private readonly eventService: PublicEventsService) { + this.eventService + .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)); + } +} diff --git a/projects/sample-code-flow/src/app/auth-config.module.ts b/projects/sample-code-flow/src/app/auth-config.module.ts index 37738f79e..36396bc66 100644 --- a/projects/sample-code-flow/src/app/auth-config.module.ts +++ b/projects/sample-code-flow/src/app/auth-config.module.ts @@ -1,34 +1,34 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; -import { environment } from '../environments/environment'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://offeringsolutions-sts.azurewebsites.net', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'angularClient', - scope: 'openid profile email', - responseType: 'code', - silentRenew: true, - silentRenewUrl: `${window.location.origin}/silent-renew.html`, - renewTimeBeforeTokenExpiresInSeconds: 10, - logLevel: environment.production ? LogLevel.None : LogLevel.Debug, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; +import { environment } from '../environments/environment'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularClient', + scope: 'openid profile email', + responseType: 'code', + silentRenew: true, + silentRenewUrl: `${window.location.origin}/silent-renew.html`, + renewTimeBeforeTokenExpiresInSeconds: 10, + logLevel: environment.production ? LogLevel.None : LogLevel.Debug, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-code-flow/src/app/home/home.component.html b/projects/sample-code-flow/src/app/home/home.component.html index f9f731824..a5b55c3c0 100644 --- a/projects/sample-code-flow/src/app/home/home.component.html +++ b/projects/sample-code-flow/src/app/home/home.component.html @@ -1,26 +1,26 @@ -
Welcome to home Route
- -
- - -
- -
- - Is Authenticated: {{ isAuthenticated }} - -
- userData -
{{ userData$ | async | json }}
- -
-
- - - -
- You are NOT authenticated -
- -Configuration loaded: -
{{ configuration | json }}
+
Welcome to home Route
+ +
+ + +
+ +
+ + Is Authenticated: {{ isAuthenticated }} + +
+ userData +
{{ userData$ | async | json }}
+ +
+
+ + + +
+ You are NOT authenticated +
+ +Configuration loaded: +
{{ configuration | json }}
diff --git a/projects/sample-code-flow/src/app/home/home.component.spec.ts b/projects/sample-code-flow/src/app/home/home.component.spec.ts index 0c4a69378..50ff56b39 100644 --- a/projects/sample-code-flow/src/app/home/home.component.spec.ts +++ b/projects/sample-code-flow/src/app/home/home.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HomeComponent } from './home.component'; describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; + let component: HomeComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HomeComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow/src/app/home/home.component.ts b/projects/sample-code-flow/src/app/home/home.component.ts index 28f9023f8..0e94dd5db 100644 --- a/projects/sample-code-flow/src/app/home/home.component.ts +++ b/projects/sample-code-flow/src/app/home/home.component.ts @@ -1,33 +1,34 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - configuration: PublicConfiguration; - userDataChanged$: Observable>; - userData$: Observable; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.configuration = this.oidcSecurityService.configuration; - this.userData$ = this.oidcSecurityService.userData$; - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - forceRefreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.warn(result)); - } - logout() { - this.oidcSecurityService.logoff(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + configuration: PublicConfiguration; + userDataChanged$: Observable>; + userData$: Observable; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.configuration = this.oidcSecurityService.configuration; + this.userData$ = this.oidcSecurityService.userData$; + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + forceRefreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.warn(result)); + } + + logout() { + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.html b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.ts b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.ts index 1249768a3..dbe965047 100644 --- a/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-code-flow/src/app/unauthorized/unauthorized.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html', -}) -export class UnauthorizedComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/projects/sample-code-flow/src/environments/environment.prod.ts b/projects/sample-code-flow/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-code-flow/src/environments/environment.prod.ts +++ b/projects/sample-code-flow/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-code-flow/src/environments/environment.ts b/projects/sample-code-flow/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-code-flow/src/environments/environment.ts +++ b/projects/sample-code-flow/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-code-flow/src/index.html b/projects/sample-code-flow/src/index.html index 263361713..bce46ebbb 100644 --- a/projects/sample-code-flow/src/index.html +++ b/projects/sample-code-flow/src/index.html @@ -1,13 +1,13 @@ - - - Sample Code Flow - - - - - - - + + + Sample Code Flow + + + + + + + diff --git a/projects/sample-code-flow/src/main.ts b/projects/sample-code-flow/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-code-flow/src/main.ts +++ b/projects/sample-code-flow/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-code-flow/src/polyfills.ts b/projects/sample-code-flow/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-code-flow/src/polyfills.ts +++ b/projects/sample-code-flow/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-code-flow/src/silent-renew.html b/projects/sample-code-flow/src/silent-renew.html index 35a8eabe3..7aab22f4b 100644 --- a/projects/sample-code-flow/src/silent-renew.html +++ b/projects/sample-code-flow/src/silent-renew.html @@ -1,21 +1,21 @@ - - - - - silent-renew - - - - - + + + + + silent-renew + + + + + diff --git a/projects/sample-code-flow/src/test.ts b/projects/sample-code-flow/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-code-flow/src/test.ts +++ b/projects/sample-code-flow/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-code-flow/tsconfig.app.json b/projects/sample-code-flow/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-code-flow/tsconfig.app.json +++ b/projects/sample-code-flow/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-code-flow/tsconfig.spec.json b/projects/sample-code-flow/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-code-flow/tsconfig.spec.json +++ b/projects/sample-code-flow/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-implicit-flow-google/.eslintrc.json b/projects/sample-implicit-flow-google/.eslintrc.json index a1687e7cb..fec7890c5 100644 --- a/projects/sample-implicit-flow-google/.eslintrc.json +++ b/projects/sample-implicit-flow-google/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-implicit-flow-google/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-implicit-flow-google/e2e/protractor.conf.js b/projects/sample-implicit-flow-google/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-implicit-flow-google/e2e/protractor.conf.js +++ b/projects/sample-implicit-flow-google/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-implicit-flow-google/e2e/src/app.e2e-spec.ts b/projects/sample-implicit-flow-google/e2e/src/app.e2e-spec.ts index a6175287d..22d806a48 100644 --- a/projects/sample-implicit-flow-google/e2e/src/app.e2e-spec.ts +++ b/projects/sample-implicit-flow-google/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-implicit-flow-google/e2e/tsconfig.json b/projects/sample-implicit-flow-google/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-implicit-flow-google/e2e/tsconfig.json +++ b/projects/sample-implicit-flow-google/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-implicit-flow-google/karma.conf.js b/projects/sample-implicit-flow-google/karma.conf.js index 7fe797443..58728236b 100644 --- a/projects/sample-implicit-flow-google/karma.conf.js +++ b/projects/sample-implicit-flow-google/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-implicit-flow-google'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-implicit-flow-google/src/app/app.component.css b/projects/sample-implicit-flow-google/src/app/app.component.css index 7879a7bae..16282350e 100644 --- a/projects/sample-implicit-flow-google/src/app/app.component.css +++ b/projects/sample-implicit-flow-google/src/app/app.component.css @@ -1,12 +1,12 @@ -body { -padding-top: 0; -} - -.starter-template { -padding: 40px 15px; -text-align: center; -} - -.navigationLinkButton:hover { -cursor: pointer; -} \ No newline at end of file +body { + padding-top: 0; +} + +.starter-template { + padding: 40px 15px; + text-align: center; +} + +.navigationLinkButton:hover { + cursor: pointer; +} diff --git a/projects/sample-implicit-flow-google/src/app/app.component.html b/projects/sample-implicit-flow-google/src/app/app.component.html index 2cb110a36..30adf7d55 100644 --- a/projects/sample-implicit-flow-google/src/app/app.component.html +++ b/projects/sample-implicit-flow-google/src/app/app.component.html @@ -1,9 +1,9 @@ - - -
-
-
- -
-
-
+ + +
+
+
+ +
+
+
diff --git a/projects/sample-implicit-flow-google/src/app/app.component.spec.ts b/projects/sample-implicit-flow-google/src/app/app.component.spec.ts index 78001caac..2ff01c01b 100644 --- a/projects/sample-implicit-flow-google/src/app/app.component.spec.ts +++ b/projects/sample-implicit-flow-google/src/app/app.component.spec.ts @@ -3,31 +3,31 @@ import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [RouterTestingModule], - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'sample-implicit-flow-google'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('sample-implicit-flow-google'); - }); + it(`should have as title 'sample-implicit-flow-google'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('sample-implicit-flow-google'); + }); - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement; - expect(compiled.querySelector('.content span').textContent).toContain('sample-implicit-flow-google app is running!'); - }); + it('should render title', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.nativeElement; + expect(compiled.querySelector('.content span').textContent).toContain('sample-implicit-flow-google app is running!'); + }); }); diff --git a/projects/sample-implicit-flow-google/src/app/app.component.ts b/projects/sample-implicit-flow-google/src/app/app.component.ts index 3d6c1f279..3d16a8f75 100644 --- a/projects/sample-implicit-flow-google/src/app/app.component.ts +++ b/projects/sample-implicit-flow-google/src/app/app.component.ts @@ -1,72 +1,72 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; -import { Router } from '@angular/router'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit, OnDestroy { - constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} - - ngOnInit() { - this.oidcSecurityService - .checkAuth() - - .subscribe((isAuthenticated) => { - if (!isAuthenticated) { - if ('/autologin' !== window.location.pathname) { - this.write('redirect', window.location.pathname); - this.router.navigate(['/autologin']); - } - } - if (isAuthenticated) { - this.navigateToStoredEndpoint(); - } - }); - } - - ngOnDestroy(): void {} - - login() { - console.log('start login'); - this.oidcSecurityService.authorize(); - } - - refreshSession() { - console.log('start refreshSession'); - this.oidcSecurityService.authorize(); - } - - logout() { - console.log('start logoff'); - this.oidcSecurityService.logoff(); - } - - private navigateToStoredEndpoint() { - const path = this.read('redirect'); - - if (this.router.url === path) { - return; - } - - if (path.toString().includes('/unauthorized')) { - this.router.navigate(['/']); - } else { - this.router.navigate([path]); - } - } - - private read(key: string): any { - const data = localStorage.getItem(key); - if (data != null) { - return JSON.parse(data); - } - - return; - } - - private write(key: string, value: any): void { - localStorage.setItem(key, JSON.stringify(value)); - } -} +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit, OnDestroy { + constructor(public oidcSecurityService: OidcSecurityService, private router: Router) {} + + ngOnInit() { + this.oidcSecurityService + .checkAuth() + + .subscribe((isAuthenticated) => { + if (!isAuthenticated) { + if ('/autologin' !== window.location.pathname) { + this.write('redirect', window.location.pathname); + this.router.navigate(['/autologin']); + } + } + if (isAuthenticated) { + this.navigateToStoredEndpoint(); + } + }); + } + + ngOnDestroy(): void {} + + login() { + console.log('start login'); + this.oidcSecurityService.authorize(); + } + + refreshSession() { + console.log('start refreshSession'); + this.oidcSecurityService.authorize(); + } + + logout() { + console.log('start logoff'); + this.oidcSecurityService.logoff(); + } + + private navigateToStoredEndpoint() { + const path = this.read('redirect'); + + if (this.router.url === path) { + return; + } + + if (path.toString().includes('/unauthorized')) { + this.router.navigate(['/']); + } else { + this.router.navigate([path]); + } + } + + private read(key: string): any { + const data = localStorage.getItem(key); + if (data != null) { + return JSON.parse(data); + } + + return; + } + + private write(key: string, value: any): void { + localStorage.setItem(key, JSON.stringify(value)); + } +} diff --git a/projects/sample-implicit-flow-google/src/app/app.module.ts b/projects/sample-implicit-flow-google/src/app/app.module.ts index 6fd14775b..64dda9382 100644 --- a/projects/sample-implicit-flow-google/src/app/app.module.ts +++ b/projects/sample-implicit-flow-google/src/app/app.module.ts @@ -1,19 +1,19 @@ -import { HttpClientModule } from '@angular/common/http'; -import { NgModule } from '@angular/core'; -import { FormsModule } from '@angular/forms'; -import { BrowserModule } from '@angular/platform-browser'; -import { AppComponent } from './app.component'; -import { routing } from './app.routes'; -import { AuthConfigModule } from './auth-config.module'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { NavigationComponent } from './navigation/navigation.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - imports: [BrowserModule, FormsModule, routing, HttpClientModule, AuthConfigModule], - declarations: [AppComponent, ForbiddenComponent, HomeComponent, AutoLoginComponent, NavigationComponent, UnauthorizedComponent], - bootstrap: [AppComponent], -}) -export class AppModule {} +import { HttpClientModule } from '@angular/common/http'; +import { NgModule } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { BrowserModule } from '@angular/platform-browser'; +import { AppComponent } from './app.component'; +import { routing } from './app.routes'; +import { AuthConfigModule } from './auth-config.module'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { NavigationComponent } from './navigation/navigation.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + imports: [BrowserModule, FormsModule, routing, HttpClientModule, AuthConfigModule], + declarations: [AppComponent, ForbiddenComponent, HomeComponent, AutoLoginComponent, NavigationComponent, UnauthorizedComponent], + bootstrap: [AppComponent], +}) +export class AppModule {} diff --git a/projects/sample-implicit-flow-google/src/app/app.routes.ts b/projects/sample-implicit-flow-google/src/app/app.routes.ts index 02bd9242c..fb295205e 100644 --- a/projects/sample-implicit-flow-google/src/app/app.routes.ts +++ b/projects/sample-implicit-flow-google/src/app/app.routes.ts @@ -1,15 +1,15 @@ -import { RouterModule, Routes } from '@angular/router'; -import { AutoLoginComponent } from './auto-login/auto-login.component'; -import { ForbiddenComponent } from './forbidden/forbidden.component'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -const appRoutes: Routes = [ - { path: '', component: HomeComponent }, - { path: 'home', component: HomeComponent }, - { path: 'autologin', component: AutoLoginComponent }, - { path: 'forbidden', component: ForbiddenComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, -]; - -export const routing = RouterModule.forRoot(appRoutes); +import { RouterModule, Routes } from '@angular/router'; +import { AutoLoginComponent } from './auto-login/auto-login.component'; +import { ForbiddenComponent } from './forbidden/forbidden.component'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +const appRoutes: Routes = [ + { path: '', component: HomeComponent }, + { path: 'home', component: HomeComponent }, + { path: 'autologin', component: AutoLoginComponent }, + { path: 'forbidden', component: ForbiddenComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, +]; + +export const routing = RouterModule.forRoot(appRoutes); diff --git a/projects/sample-implicit-flow-google/src/app/auth-config.module.ts b/projects/sample-implicit-flow-google/src/app/auth-config.module.ts index ec437d3a1..6b6d6c300 100644 --- a/projects/sample-implicit-flow-google/src/app/auth-config.module.ts +++ b/projects/sample-implicit-flow-google/src/app/auth-config.module.ts @@ -1,41 +1,41 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://accounts.google.com', - redirectUrl: window.location.origin, - clientId: '188968487735-b1hh7k87nkkh6vv84548sinju2kpr7gn.apps.googleusercontent.com', - responseType: 'id_token token', - scope: 'openid email profile', - triggerAuthorizationResultEvent: true, - postLogoutRedirectUri: window.location.origin + '/unauthorized', - startCheckSession: false, - silentRenew: false, - silentRenewUrl: window.location.origin + '/silent-renew.html', - postLoginRoute: '/home', - forbiddenRoute: '/forbidden', - unauthorizedRoute: '/unauthorized', - logLevel: LogLevel.Debug, - historyCleanupOff: true, - // iss_validation_off: false - // disable_iat_offset_validation: true - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcSecurityService, - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService, OidcSecurityService } from 'angular-auth-oidc-client'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://accounts.google.com', + redirectUrl: window.location.origin, + clientId: '188968487735-b1hh7k87nkkh6vv84548sinju2kpr7gn.apps.googleusercontent.com', + responseType: 'id_token token', + scope: 'openid email profile', + triggerAuthorizationResultEvent: true, + postLogoutRedirectUri: window.location.origin + '/unauthorized', + startCheckSession: false, + silentRenew: false, + silentRenewUrl: window.location.origin + '/silent-renew.html', + postLoginRoute: '/home', + forbiddenRoute: '/forbidden', + unauthorizedRoute: '/unauthorized', + logLevel: LogLevel.Debug, + historyCleanupOff: true, + // iss_validation_off: false + // disable_iat_offset_validation: true + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcSecurityService, + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.html b/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.html index 579fb8a03..795c64ded 100644 --- a/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.html +++ b/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.html @@ -1 +1 @@ -
redirecting to login
\ No newline at end of file +
redirecting to login
diff --git a/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.ts b/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.ts index 170e2a0c0..ea8fa48d0 100644 --- a/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.ts +++ b/projects/sample-implicit-flow-google/src/app/auto-login/auto-login.component.ts @@ -1,16 +1,16 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-auto-component', - templateUrl: './auto-login.component.html', -}) -export class AutoLoginComponent implements OnInit { - lang: any; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-auto-component', + templateUrl: './auto-login.component.html', +}) +export class AutoLoginComponent implements OnInit { + lang: any; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuth().subscribe(() => this.oidcSecurityService.authorize()); + } +} diff --git a/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.html b/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.html index 471e35d96..86768297d 100644 --- a/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.html +++ b/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.html @@ -1 +1 @@ -
403: You have no rights to access this.
\ No newline at end of file +
403: You have no rights to access this.
diff --git a/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.ts b/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.ts index d34d6d4c6..7431c8b3a 100644 --- a/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.ts +++ b/projects/sample-implicit-flow-google/src/app/forbidden/forbidden.component.ts @@ -1,19 +1,16 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-forbidden', - templateUrl: 'forbidden.component.html' -}) - -export class ForbiddenComponent implements OnInit { - - public message: string; - public values: any[]; - - constructor() { - this.message = 'ForbiddenComponent constructor'; - } - - ngOnInit() { - } -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-forbidden', + templateUrl: 'forbidden.component.html', +}) +export class ForbiddenComponent implements OnInit { + public message: string; + public values: any[]; + + constructor() { + this.message = 'ForbiddenComponent constructor'; + } + + ngOnInit() {} +} diff --git a/projects/sample-implicit-flow-google/src/app/home/home.component.html b/projects/sample-implicit-flow-google/src/app/home/home.component.html index fc46ff8fe..61532b953 100644 --- a/projects/sample-implicit-flow-google/src/app/home/home.component.html +++ b/projects/sample-implicit-flow-google/src/app/home/home.component.html @@ -1,5 +1,5 @@ -
Welcome
- -
-Is Authenticated: {{ isAuthenticated$ | async }} -
{{ userData$ | async | json }}
+
Welcome
+ +
+Is Authenticated: {{ isAuthenticated$ | async }} +
{{ userData$ | async | json }}
diff --git a/projects/sample-implicit-flow-google/src/app/home/home.component.ts b/projects/sample-implicit-flow-google/src/app/home/home.component.ts index c456dcc38..deb140da9 100644 --- a/projects/sample-implicit-flow-google/src/app/home/home.component.ts +++ b/projects/sample-implicit-flow-google/src/app/home/home.component.ts @@ -1,19 +1,19 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - userData$: Observable; - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - this.userData$ = this.oidcSecurityService.userData$; - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + userData$: Observable; + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + this.userData$ = this.oidcSecurityService.userData$; + } +} diff --git a/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.html b/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.html index 9eacc7e25..afa39fc16 100644 --- a/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.html +++ b/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.html @@ -1,33 +1,33 @@ - - - - - + + + + + diff --git a/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.ts b/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.ts index 241ad6be8..8fab9d5ed 100644 --- a/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.ts +++ b/projects/sample-implicit-flow-google/src/app/navigation/navigation.component.ts @@ -1,29 +1,29 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-navigation', - templateUrl: 'navigation.component.html', -}) -export class NavigationComponent implements OnInit { - isAuthenticated$: Observable; - - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - - login() { - this.oidcSecurityService.authorize(); - } - - refreshSession() { - this.oidcSecurityService.authorize(); - } - - logout() { - this.oidcSecurityService.logoff(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-navigation', + templateUrl: 'navigation.component.html', +}) +export class NavigationComponent implements OnInit { + isAuthenticated$: Observable; + + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + + login() { + this.oidcSecurityService.authorize(); + } + + refreshSession() { + this.oidcSecurityService.authorize(); + } + + logout() { + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.html b/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.ts b/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.ts index 2d9cf2f88..834791f20 100644 --- a/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-implicit-flow-google/src/app/unauthorized/unauthorized.component.ts @@ -1,19 +1,16 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html' -}) - -export class UnauthorizedComponent implements OnInit { - - public message: string; - public values: any[]; - - constructor() { - this.message = 'UnauthorizedComponent constructor'; - } - - ngOnInit() { - } -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + public message: string; + public values: any[]; + + constructor() { + this.message = 'UnauthorizedComponent constructor'; + } + + ngOnInit() {} +} diff --git a/projects/sample-implicit-flow-google/src/environments/environment.prod.ts b/projects/sample-implicit-flow-google/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-implicit-flow-google/src/environments/environment.prod.ts +++ b/projects/sample-implicit-flow-google/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-implicit-flow-google/src/environments/environment.ts b/projects/sample-implicit-flow-google/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-implicit-flow-google/src/environments/environment.ts +++ b/projects/sample-implicit-flow-google/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-implicit-flow-google/src/index.html b/projects/sample-implicit-flow-google/src/index.html index fded5ab7f..058a5a8dd 100644 --- a/projects/sample-implicit-flow-google/src/index.html +++ b/projects/sample-implicit-flow-google/src/index.html @@ -1,34 +1,34 @@ - - - SampleImplicitFlowGoogle - - - - - - - - - - - + + + SampleImplicitFlowGoogle + + + + + + + + + + + diff --git a/projects/sample-implicit-flow-google/src/main.ts b/projects/sample-implicit-flow-google/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-implicit-flow-google/src/main.ts +++ b/projects/sample-implicit-flow-google/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-implicit-flow-google/src/polyfills.ts b/projects/sample-implicit-flow-google/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-implicit-flow-google/src/polyfills.ts +++ b/projects/sample-implicit-flow-google/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-implicit-flow-google/src/silent-renew.html b/projects/sample-implicit-flow-google/src/silent-renew.html index 6a1b79bc9..e1801e255 100644 --- a/projects/sample-implicit-flow-google/src/silent-renew.html +++ b/projects/sample-implicit-flow-google/src/silent-renew.html @@ -1,22 +1,21 @@ - - - - - - - silent-renew - - - - - - - + + + + + + + silent-renew + + + + + + diff --git a/projects/sample-implicit-flow-google/src/test.ts b/projects/sample-implicit-flow-google/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-implicit-flow-google/src/test.ts +++ b/projects/sample-implicit-flow-google/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-implicit-flow-google/tsconfig.app.json b/projects/sample-implicit-flow-google/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-implicit-flow-google/tsconfig.app.json +++ b/projects/sample-implicit-flow-google/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-implicit-flow-google/tsconfig.spec.json b/projects/sample-implicit-flow-google/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-implicit-flow-google/tsconfig.spec.json +++ b/projects/sample-implicit-flow-google/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/sample-implicit-flow-silent-renew/.eslintrc.json b/projects/sample-implicit-flow-silent-renew/.eslintrc.json index 9d48a2ac2..1187c21f5 100644 --- a/projects/sample-implicit-flow-silent-renew/.eslintrc.json +++ b/projects/sample-implicit-flow-silent-renew/.eslintrc.json @@ -1,13 +1,9 @@ { "extends": "../../.eslintrc.json", - "ignorePatterns": [ - "!**/*" - ], + "ignorePatterns": ["!**/*"], "overrides": [ { - "files": [ - "*.ts" - ], + "files": ["*.ts"], "parserOptions": { "project": [ "projects/sample-implicit-flow-silent-renew/tsconfig.app.json", @@ -36,9 +32,7 @@ } }, { - "files": [ - "*.html" - ], + "files": ["*.html"], "rules": {} } ] diff --git a/projects/sample-implicit-flow-silent-renew/e2e/protractor.conf.js b/projects/sample-implicit-flow-silent-renew/e2e/protractor.conf.js index 361e7f0cd..2e47d856e 100644 --- a/projects/sample-implicit-flow-silent-renew/e2e/protractor.conf.js +++ b/projects/sample-implicit-flow-silent-renew/e2e/protractor.conf.js @@ -9,11 +9,9 @@ const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); */ exports.config = { allScriptsTimeout: 11000, - specs: [ - './src/**/*.e2e-spec.ts' - ], + specs: ['./src/**/*.e2e-spec.ts'], capabilities: { - browserName: 'chrome' + browserName: 'chrome', }, directConnect: true, SELENIUM_PROMISE_MANAGER: false, @@ -22,16 +20,18 @@ exports.config = { jasmineNodeOpts: { showColors: true, defaultTimeoutInterval: 30000, - print: function() {} + print: function () {}, }, onPrepare() { require('ts-node').register({ - project: require('path').join(__dirname, './tsconfig.json') + project: require('path').join(__dirname, './tsconfig.json'), }); - jasmine.getEnv().addReporter(new SpecReporter({ - spec: { - displayStacktrace: StacktraceOption.PRETTY - } - })); - } -}; \ No newline at end of file + jasmine.getEnv().addReporter( + new SpecReporter({ + spec: { + displayStacktrace: StacktraceOption.PRETTY, + }, + }) + ); + }, +}; diff --git a/projects/sample-implicit-flow-silent-renew/e2e/src/app.e2e-spec.ts b/projects/sample-implicit-flow-silent-renew/e2e/src/app.e2e-spec.ts index 902169eec..7d5d7edd5 100644 --- a/projects/sample-implicit-flow-silent-renew/e2e/src/app.e2e-spec.ts +++ b/projects/sample-implicit-flow-silent-renew/e2e/src/app.e2e-spec.ts @@ -16,8 +16,10 @@ describe('workspace-project App', () => { afterEach(async () => { // Assert that there are no errors emitted from the browser const logs = await browser.manage().logs().get(logging.Type.BROWSER); - expect(logs).not.toContain(jasmine.objectContaining({ - level: logging.Level.SEVERE, - } as logging.Entry)); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: logging.Level.SEVERE, + } as logging.Entry) + ); }); }); diff --git a/projects/sample-implicit-flow-silent-renew/e2e/tsconfig.json b/projects/sample-implicit-flow-silent-renew/e2e/tsconfig.json index dacd5c32d..38556bc7d 100644 --- a/projects/sample-implicit-flow-silent-renew/e2e/tsconfig.json +++ b/projects/sample-implicit-flow-silent-renew/e2e/tsconfig.json @@ -5,9 +5,6 @@ "outDir": "../../../out-tsc/e2e", "module": "commonjs", "target": "es2018", - "types": [ - "jasmine", - "node" - ] + "types": ["jasmine", "node"] } } diff --git a/projects/sample-implicit-flow-silent-renew/karma.conf.js b/projects/sample-implicit-flow-silent-renew/karma.conf.js index dac50692a..56772836f 100644 --- a/projects/sample-implicit-flow-silent-renew/karma.conf.js +++ b/projects/sample-implicit-flow-silent-renew/karma.conf.js @@ -10,7 +10,7 @@ module.exports = function (config) { require('karma-chrome-launcher'), require('karma-jasmine-html-reporter'), require('karma-coverage'), - require('@angular-devkit/build-angular/plugins/karma') + require('@angular-devkit/build-angular/plugins/karma'), ], client: { jasmine: { @@ -19,18 +19,15 @@ module.exports = function (config) { // for example, you can disable the random execution with `random: false` // or set a specific seed with `seed: 4321` }, - clearContext: false // leave Jasmine Spec Runner output visible in browser + clearContext: false, // leave Jasmine Spec Runner output visible in browser }, jasmineHtmlReporter: { - suppressAll: true // removes the duplicated traces + suppressAll: true, // removes the duplicated traces }, coverageReporter: { dir: require('path').join(__dirname, '../../coverage/sample-implicit-flow-silent-renew'), subdir: '.', - reporters: [ - { type: 'html' }, - { type: 'text-summary' } - ] + reporters: [{ type: 'html' }, { type: 'text-summary' }], }, reporters: ['progress', 'kjhtml'], port: 9876, @@ -39,6 +36,6 @@ module.exports = function (config) { autoWatch: true, browsers: ['Chrome'], singleRun: false, - restartOnFileChange: true + restartOnFileChange: true, }); }; diff --git a/projects/sample-implicit-flow-silent-renew/src/app/app.component.spec.ts b/projects/sample-implicit-flow-silent-renew/src/app/app.component.spec.ts index fc041501b..846c4af9b 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/app.component.spec.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/app.component.spec.ts @@ -2,30 +2,30 @@ import { TestBed, waitForAsync } from '@angular/core/testing'; import { AppComponent } from './app.component'; describe('AppComponent', () => { - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [AppComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [AppComponent], + }).compileComponents(); + }) + ); - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app).toBeTruthy(); - }); + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); - it(`should have as title 'testSts'`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('testSts'); - }); + it(`should have as title 'testSts'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('testSts'); + }); - it('should render title in a h1 tag', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); - }); + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to testSts!'); + }); }); diff --git a/projects/sample-implicit-flow-silent-renew/src/app/app.component.ts b/projects/sample-implicit-flow-silent-renew/src/app/app.component.ts index ff996f657..d21c9c5c1 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/app.component.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/app.component.ts @@ -1,16 +1,14 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcSecurityService } from 'angular-auth-oidc-client'; - -@Component({ - selector: 'app-root', - templateUrl: 'app.component.html', -}) -export class AppComponent implements OnInit { - constructor(public oidcSecurityService: OidcSecurityService) {} - - ngOnInit() { - this.oidcSecurityService - .checkAuthIncludingServer() - .subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcSecurityService } from 'angular-auth-oidc-client'; + +@Component({ + selector: 'app-root', + templateUrl: 'app.component.html', +}) +export class AppComponent implements OnInit { + constructor(public oidcSecurityService: OidcSecurityService) {} + + ngOnInit() { + this.oidcSecurityService.checkAuthIncludingServer().subscribe((isAuthenticated) => console.log('app authenticated', isAuthenticated)); + } +} diff --git a/projects/sample-implicit-flow-silent-renew/src/app/app.module.ts b/projects/sample-implicit-flow-silent-renew/src/app/app.module.ts index 2c94c8906..7a1fb3741 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/app.module.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/app.module.ts @@ -1,33 +1,33 @@ -import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -import { RouterModule } from '@angular/router'; -import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; -import { filter } from 'rxjs/operators'; -import { AppComponent } from './app.component'; -import { AuthConfigModule } from './auth-config.module'; -import { HomeComponent } from './home/home.component'; -import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; - -@NgModule({ - declarations: [AppComponent, HomeComponent, UnauthorizedComponent], - imports: [ - BrowserModule, - RouterModule.forRoot([ - { path: '', redirectTo: 'home', pathMatch: 'full' }, - { path: 'home', component: HomeComponent }, - { path: 'forbidden', component: UnauthorizedComponent }, - { path: 'unauthorized', component: UnauthorizedComponent }, - ]), - AuthConfigModule, - ], - providers: [], - bootstrap: [AppComponent], -}) -export class AppModule { - constructor(private readonly eventService: PublicEventsService) { - this.eventService - .registerForEvents() - .pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded)) - .subscribe((config) => console.log('ConfigLoaded', config)); - } -} +import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; +import { RouterModule } from '@angular/router'; +import { EventTypes, PublicEventsService } from 'angular-auth-oidc-client'; +import { filter } from 'rxjs/operators'; +import { AppComponent } from './app.component'; +import { AuthConfigModule } from './auth-config.module'; +import { HomeComponent } from './home/home.component'; +import { UnauthorizedComponent } from './unauthorized/unauthorized.component'; + +@NgModule({ + declarations: [AppComponent, HomeComponent, UnauthorizedComponent], + imports: [ + BrowserModule, + RouterModule.forRoot([ + { path: '', redirectTo: 'home', pathMatch: 'full' }, + { path: 'home', component: HomeComponent }, + { path: 'forbidden', component: UnauthorizedComponent }, + { path: 'unauthorized', component: UnauthorizedComponent }, + ]), + AuthConfigModule, + ], + providers: [], + bootstrap: [AppComponent], +}) +export class AppModule { + constructor(private readonly eventService: PublicEventsService) { + this.eventService + .registerForEvents() + .pipe(filter((notification) => notification.type === EventTypes.ConfigLoaded)) + .subscribe((config) => console.log('ConfigLoaded', config)); + } +} diff --git a/projects/sample-implicit-flow-silent-renew/src/app/auth-config.module.ts b/projects/sample-implicit-flow-silent-renew/src/app/auth-config.module.ts index c932f5e79..198f2173a 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/auth-config.module.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/auth-config.module.ts @@ -1,33 +1,33 @@ -import { APP_INITIALIZER, NgModule } from '@angular/core'; -import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; - -export function configureAuth(oidcConfigService: OidcConfigService) { - return () => - oidcConfigService.withConfig({ - stsServer: 'https://offeringsolutions-sts.azurewebsites.net', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'angularImplicitClient', - scope: 'openid profile email', - responseType: 'id_token token', - silentRenewUrl: `${window.location.origin}/silent-renew.html`, - startCheckSession: true, - silentRenew: true, - logLevel: LogLevel.Debug, - }); -} - -@NgModule({ - imports: [AuthModule.forRoot()], - providers: [ - OidcConfigService, - { - provide: APP_INITIALIZER, - useFactory: configureAuth, - deps: [OidcConfigService], - multi: true, - }, - ], - exports: [AuthModule], -}) -export class AuthConfigModule {} +import { APP_INITIALIZER, NgModule } from '@angular/core'; +import { AuthModule, LogLevel, OidcConfigService } from 'angular-auth-oidc-client'; + +export function configureAuth(oidcConfigService: OidcConfigService) { + return () => + oidcConfigService.withConfig({ + stsServer: 'https://offeringsolutions-sts.azurewebsites.net', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'angularImplicitClient', + scope: 'openid profile email', + responseType: 'id_token token', + silentRenewUrl: `${window.location.origin}/silent-renew.html`, + startCheckSession: true, + silentRenew: true, + logLevel: LogLevel.Debug, + }); +} + +@NgModule({ + imports: [AuthModule.forRoot()], + providers: [ + OidcConfigService, + { + provide: APP_INITIALIZER, + useFactory: configureAuth, + deps: [OidcConfigService], + multi: true, + }, + ], + exports: [AuthModule], +}) +export class AuthConfigModule {} diff --git a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.html b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.html index 8feda49fc..46aee9100 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.html +++ b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.html @@ -1,27 +1,27 @@ -
Welcome to home Route
- - - -
- - -
- -
- - Is Authenticated: {{ isAuthenticated }} - -
- userData -
{{ userData$ | async | json }}
- {{ checkSessionChanged }} -
-
- - - -
-
- -Configuration loaded: -
{{ configuration | json }}
+
Welcome to home Route
+ + + +
+ + +
+ +
+ + Is Authenticated: {{ isAuthenticated }} + +
+ userData +
{{ userData$ | async | json }}
+ {{ checkSessionChanged }} +
+
+ + + +
+
+ +Configuration loaded: +
{{ configuration | json }}
diff --git a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.spec.ts b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.spec.ts index 0c4a69378..50ff56b39 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.spec.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { HomeComponent } from './home.component'; describe('HomeComponent', () => { - let component: HomeComponent; - let fixture: ComponentFixture; + let component: HomeComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [HomeComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [HomeComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(HomeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.ts b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.ts index 0d40d748c..0854d95e8 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/home/home.component.ts @@ -1,43 +1,43 @@ -import { Component, OnInit } from '@angular/core'; -import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; -import { Observable } from 'rxjs'; - -@Component({ - selector: 'app-home', - templateUrl: 'home.component.html', -}) -export class HomeComponent implements OnInit { - configuration: PublicConfiguration; - userDataChanged$: Observable>; - userData$: Observable; - isAuthenticated$: Observable; - checkSessionChanged$: Observable; - checkSessionChanged: any; - - constructor(public oidcSecurityService: OidcSecurityService) {} - ngOnInit() { - this.configuration = this.oidcSecurityService.configuration; - this.userData$ = this.oidcSecurityService.userData$; - this.checkSessionChanged$ = this.oidcSecurityService.checkSessionChanged$; - - this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; - } - login() { - console.log('start login'); - this.oidcSecurityService.authorize(); - } - - refreshSessionCheckSession() { - console.log('start refreshSession'); - this.oidcSecurityService.authorize(); - } - - forceRefreshSession() { - this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); - } - - logout() { - console.log('start logoff'); - this.oidcSecurityService.logoff(); - } -} +import { Component, OnInit } from '@angular/core'; +import { OidcClientNotification, OidcSecurityService, PublicConfiguration } from 'angular-auth-oidc-client'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'app-home', + templateUrl: 'home.component.html', +}) +export class HomeComponent implements OnInit { + configuration: PublicConfiguration; + userDataChanged$: Observable>; + userData$: Observable; + isAuthenticated$: Observable; + checkSessionChanged$: Observable; + checkSessionChanged: any; + + constructor(public oidcSecurityService: OidcSecurityService) {} + ngOnInit() { + this.configuration = this.oidcSecurityService.configuration; + this.userData$ = this.oidcSecurityService.userData$; + this.checkSessionChanged$ = this.oidcSecurityService.checkSessionChanged$; + + this.isAuthenticated$ = this.oidcSecurityService.isAuthenticated$; + } + login() { + console.log('start login'); + this.oidcSecurityService.authorize(); + } + + refreshSessionCheckSession() { + console.log('start refreshSession'); + this.oidcSecurityService.authorize(); + } + + forceRefreshSession() { + this.oidcSecurityService.forceRefreshSession().subscribe((result) => console.log(result)); + } + + logout() { + console.log('start logoff'); + this.oidcSecurityService.logoff(); + } +} diff --git a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.html b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.html index 8e50f9167..476c6261f 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.html +++ b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.html @@ -1 +1 @@ -
401: You have no rights to access this. Please Login
\ No newline at end of file +
401: You have no rights to access this. Please Login
diff --git a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.spec.ts b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.spec.ts index 1344d4461..1d4a1029f 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.spec.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.spec.ts @@ -2,24 +2,24 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { UnauthorizedComponent } from './unauthorized.component'; describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture; + let component: UnauthorizedComponent; + let fixture: ComponentFixture; - beforeEach( - waitForAsync(() => { - TestBed.configureTestingModule({ - declarations: [UnauthorizedComponent], - }).compileComponents(); - }) - ); + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + declarations: [UnauthorizedComponent], + }).compileComponents(); + }) + ); - beforeEach(() => { - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); + beforeEach(() => { + fixture = TestBed.createComponent(UnauthorizedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); - it('should create', () => { - expect(component).toBeTruthy(); - }); + it('should create', () => { + expect(component).toBeTruthy(); + }); }); diff --git a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.ts b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.ts index 1249768a3..dbe965047 100644 --- a/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.ts +++ b/projects/sample-implicit-flow-silent-renew/src/app/unauthorized/unauthorized.component.ts @@ -1,11 +1,11 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-unauthorized', - templateUrl: 'unauthorized.component.html', -}) -export class UnauthorizedComponent implements OnInit { - constructor() {} - - ngOnInit() {} -} +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-unauthorized', + templateUrl: 'unauthorized.component.html', +}) +export class UnauthorizedComponent implements OnInit { + constructor() {} + + ngOnInit() {} +} diff --git a/projects/sample-implicit-flow-silent-renew/src/environments/environment.prod.ts b/projects/sample-implicit-flow-silent-renew/src/environments/environment.prod.ts index 3612073bc..c9669790b 100644 --- a/projects/sample-implicit-flow-silent-renew/src/environments/environment.prod.ts +++ b/projects/sample-implicit-flow-silent-renew/src/environments/environment.prod.ts @@ -1,3 +1,3 @@ export const environment = { - production: true + production: true, }; diff --git a/projects/sample-implicit-flow-silent-renew/src/environments/environment.ts b/projects/sample-implicit-flow-silent-renew/src/environments/environment.ts index 7b4f817ad..99c3763ca 100644 --- a/projects/sample-implicit-flow-silent-renew/src/environments/environment.ts +++ b/projects/sample-implicit-flow-silent-renew/src/environments/environment.ts @@ -3,7 +3,7 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, }; /* diff --git a/projects/sample-implicit-flow-silent-renew/src/index.html b/projects/sample-implicit-flow-silent-renew/src/index.html index e628790aa..00c14821b 100644 --- a/projects/sample-implicit-flow-silent-renew/src/index.html +++ b/projects/sample-implicit-flow-silent-renew/src/index.html @@ -1,13 +1,13 @@ - - - Sample Implicit Flow Silent Renew - - - - - - - + + + Sample Implicit Flow Silent Renew + + + + + + + diff --git a/projects/sample-implicit-flow-silent-renew/src/main.ts b/projects/sample-implicit-flow-silent-renew/src/main.ts index c7b673cf4..d9a2e7e4a 100644 --- a/projects/sample-implicit-flow-silent-renew/src/main.ts +++ b/projects/sample-implicit-flow-silent-renew/src/main.ts @@ -8,5 +8,6 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.error(err)); +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.error(err)); diff --git a/projects/sample-implicit-flow-silent-renew/src/polyfills.ts b/projects/sample-implicit-flow-silent-renew/src/polyfills.ts index 9b8f300ef..c5f27446d 100644 --- a/projects/sample-implicit-flow-silent-renew/src/polyfills.ts +++ b/projects/sample-implicit-flow-silent-renew/src/polyfills.ts @@ -55,8 +55,7 @@ /*************************************************************************************************** * Zone JS is required by default for Angular itself. */ -import 'zone.js/dist/zone'; // Included with Angular CLI. - +import 'zone.js/dist/zone'; // Included with Angular CLI. /*************************************************************************************************** * APPLICATION IMPORTS diff --git a/projects/sample-implicit-flow-silent-renew/src/silent-renew.html b/projects/sample-implicit-flow-silent-renew/src/silent-renew.html index 6a1b79bc9..e1801e255 100644 --- a/projects/sample-implicit-flow-silent-renew/src/silent-renew.html +++ b/projects/sample-implicit-flow-silent-renew/src/silent-renew.html @@ -1,22 +1,21 @@ - - - - - - - silent-renew - - - - - - - + + + + + + + silent-renew + + + + + + diff --git a/projects/sample-implicit-flow-silent-renew/src/test.ts b/projects/sample-implicit-flow-silent-renew/src/test.ts index 50193eb0f..4f56cf522 100644 --- a/projects/sample-implicit-flow-silent-renew/src/test.ts +++ b/projects/sample-implicit-flow-silent-renew/src/test.ts @@ -2,23 +2,21 @@ import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { + context( + path: string, + deep?: boolean, + filter?: RegExp + ): { keys(): string[]; (id: string): T; }; }; // First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); // Then we find all the tests. const context = require.context('./', true, /\.spec\.ts$/); // And load the modules. diff --git a/projects/sample-implicit-flow-silent-renew/tsconfig.app.json b/projects/sample-implicit-flow-silent-renew/tsconfig.app.json index fd37f74d7..c3c483759 100644 --- a/projects/sample-implicit-flow-silent-renew/tsconfig.app.json +++ b/projects/sample-implicit-flow-silent-renew/tsconfig.app.json @@ -5,11 +5,6 @@ "outDir": "../../out-tsc/app", "types": [] }, - "files": [ - "src/main.ts", - "src/polyfills.ts" - ], - "include": [ - "src/**/*.d.ts" - ] + "files": ["src/main.ts", "src/polyfills.ts"], + "include": ["src/**/*.d.ts"] } diff --git a/projects/sample-implicit-flow-silent-renew/tsconfig.spec.json b/projects/sample-implicit-flow-silent-renew/tsconfig.spec.json index 923191846..db2ec9b5d 100644 --- a/projects/sample-implicit-flow-silent-renew/tsconfig.spec.json +++ b/projects/sample-implicit-flow-silent-renew/tsconfig.spec.json @@ -1,10 +1,10 @@ /* To learn more about this file see: https://angular.io/config/tsconfig. */ { - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../../out-tsc/spec", - "types": ["jasmine", "node"] - }, - "files": ["src/test.ts", "src/polyfills.ts"], - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "../../out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] } diff --git a/projects/schematics/package.json b/projects/schematics/package.json index 005c76c70..38cf42257 100644 --- a/projects/schematics/package.json +++ b/projects/schematics/package.json @@ -1,20 +1,20 @@ { - "name": "schematics", - "version": "11.4.5", - "description": "A schematic for the Angular Lib for OpenID Connect & OAuth2", - "scripts": { - "build": "tsc -p tsconfig.json", - "test": "npm run build && jasmine src/**/*_spec.js" - }, - "keywords": [ - "schematics" - ], - "author": "", - "license": "MIT", - "schematics": "./src/collection.json", - "dependencies": { - "@angular-devkit/core": "^11.0.5", - "@angular-devkit/schematics": "^11.0.5", - "typescript": "~4.0.2" - } + "name": "schematics", + "version": "11.4.5", + "description": "A schematic for the Angular Lib for OpenID Connect & OAuth2", + "scripts": { + "build": "tsc -p tsconfig.json", + "test": "npm run build && jasmine src/**/*_spec.js" + }, + "keywords": [ + "schematics" + ], + "author": "", + "license": "MIT", + "schematics": "./src/collection.json", + "dependencies": { + "@angular-devkit/core": "^11.0.5", + "@angular-devkit/schematics": "^11.0.5", + "typescript": "~4.0.2" + } } diff --git a/projects/schematics/src/collection.json b/projects/schematics/src/collection.json index 7704c5ea6..1fc5cac4d 100644 --- a/projects/schematics/src/collection.json +++ b/projects/schematics/src/collection.json @@ -1,10 +1,10 @@ { - "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", - "schematics": { - "ng-add": { - "description": "Add angular-auth-oidc-client library to the project.", - "factory": "./ng-add/index#ngAdd", - "schema": "./ng-add/schema.json" - } + "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", + "schematics": { + "ng-add": { + "description": "Add angular-auth-oidc-client library to the project.", + "factory": "./ng-add/index#ngAdd", + "schema": "./ng-add/schema.json" } + } } diff --git a/projects/schematics/src/ng-add/actions/add-dependencies.ts b/projects/schematics/src/ng-add/actions/add-dependencies.ts index f8432272d..fc3e557ff 100644 --- a/projects/schematics/src/ng-add/actions/add-dependencies.ts +++ b/projects/schematics/src/ng-add/actions/add-dependencies.ts @@ -1,32 +1,32 @@ -import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; -import { addPackageJsonDependency, NodeDependency, NodeDependencyType } from '@schematics/angular/utility/dependencies'; - -const dependenciesToAdd = [ - { - name: 'angular-auth-oidc-client', - version: '11.4.5', - }, -]; - -export function addPackageJsonDependencies(): Rule { - return (host: Tree, context: SchematicContext) => { - for (const pack of dependenciesToAdd) { - const nodeDependency = createNodeDependency(pack); - addPackageJsonDependency(host, nodeDependency); - context.logger.info(`✅️ Added "${pack.name}" ${pack.version}`); - } - - return host; - }; -} - -function createNodeDependency(pack: any): NodeDependency { - const { name, version } = pack; - - return { - type: NodeDependencyType.Default, - name, - version, - overwrite: true, - }; -} +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { addPackageJsonDependency, NodeDependency, NodeDependencyType } from '@schematics/angular/utility/dependencies'; + +const dependenciesToAdd = [ + { + name: 'angular-auth-oidc-client', + version: '11.4.5', + }, +]; + +export function addPackageJsonDependencies(): Rule { + return (host: Tree, context: SchematicContext) => { + for (const pack of dependenciesToAdd) { + const nodeDependency = createNodeDependency(pack); + addPackageJsonDependency(host, nodeDependency); + context.logger.info(`✅️ Added "${pack.name}" ${pack.version}`); + } + + return host; + }; +} + +function createNodeDependency(pack: any): NodeDependency { + const { name, version } = pack; + + return { + type: NodeDependencyType.Default, + name, + version, + overwrite: true, + }; +} diff --git a/projects/schematics/src/ng-add/actions/add-module-import.ts b/projects/schematics/src/ng-add/actions/add-module-import.ts index 451ba0d96..7b659d3bc 100644 --- a/projects/schematics/src/ng-add/actions/add-module-import.ts +++ b/projects/schematics/src/ng-add/actions/add-module-import.ts @@ -1,42 +1,42 @@ -import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; -import { addImportToModule } from '@schematics/angular/utility/ast-utils'; -import { InsertChange } from '@schematics/angular/utility/change'; -import { getProject, readIntoSourceFile } from '../../utils/angular-utils'; -import { NgAddOptions } from '../models/ng-add-options'; - -export function addModuleToImports(options: NgAddOptions): Rule { - return (host: Tree, context: SchematicContext) => { - const project = getProject(host); - - const { moduleFileName, moduleName } = options.moduleInfo; - - const modulesToImport = [ - { - target: `${project.sourceRoot}/app/app.module.ts`, - moduleName, - modulePath: `./auth/${moduleFileName}`, - }, - ]; - - modulesToImport.forEach(({ target, moduleName, modulePath }) => { - addImport(host, context, moduleName, modulePath, target); - }); - - context.logger.info(`All imports done, please add the 'RouterModule' as well if you don't have it imported yet.`); - - return host; - }; -} - -function addImport(host: Tree, context: SchematicContext, moduleName: string, source: string, target: string) { - const sourcefile = readIntoSourceFile(host, target); - const importChanges = addImportToModule(sourcefile, source, moduleName, source) as InsertChange[]; - - importChanges.forEach((insertChange) => { - const exportRecorder = host.beginUpdate(target); - exportRecorder.insertLeft(insertChange.pos, insertChange.toAdd); - host.commitUpdate(exportRecorder); - }); - - context.logger.info(`✅️ '${moduleName}' is imported in '${target}'`); -} +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { addImportToModule } from '@schematics/angular/utility/ast-utils'; +import { InsertChange } from '@schematics/angular/utility/change'; +import { getProject, readIntoSourceFile } from '../../utils/angular-utils'; +import { NgAddOptions } from '../models/ng-add-options'; + +export function addModuleToImports(options: NgAddOptions): Rule { + return (host: Tree, context: SchematicContext) => { + const project = getProject(host); + + const { moduleFileName, moduleName } = options.moduleInfo; + + const modulesToImport = [ + { + target: `${project.sourceRoot}/app/app.module.ts`, + moduleName, + modulePath: `./auth/${moduleFileName}`, + }, + ]; + + modulesToImport.forEach(({ target, moduleName, modulePath }) => { + addImport(host, context, moduleName, modulePath, target); + }); + + context.logger.info(`All imports done, please add the 'RouterModule' as well if you don't have it imported yet.`); + + return host; + }; +} + +function addImport(host: Tree, context: SchematicContext, moduleName: string, source: string, target: string) { + const sourcefile = readIntoSourceFile(host, target); + const importChanges = addImportToModule(sourcefile, source, moduleName, source) as InsertChange[]; + + importChanges.forEach((insertChange) => { + const exportRecorder = host.beginUpdate(target); + exportRecorder.insertLeft(insertChange.pos, insertChange.toAdd); + host.commitUpdate(exportRecorder); + }); + + context.logger.info(`✅️ '${moduleName}' is imported in '${target}'`); +} diff --git a/projects/schematics/src/ng-add/actions/adding-entry-to-assets.ts b/projects/schematics/src/ng-add/actions/adding-entry-to-assets.ts index 294bd508f..22187b863 100644 --- a/projects/schematics/src/ng-add/actions/adding-entry-to-assets.ts +++ b/projects/schematics/src/ng-add/actions/adding-entry-to-assets.ts @@ -1,22 +1,22 @@ -import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; -import { getProject, updateProjectInAngularJson } from '../../utils/angular-utils'; -import { NgAddOptions } from '../models/ng-add-options'; - -export function addSilentRenewHtmlToAssetsArrayInAngularJson(ngAddOptions: NgAddOptions): Rule { - return (host: Tree, context: SchematicContext) => { - if (!ngAddOptions.needsSilentRenewHtml) { - context.logger.info(`No silent-renew entry in assets array needed`); - return host; - } - - const project = getProject(host); - - const options = project.architect?.build?.options; - const srcRoot = project.sourceRoot; - options?.assets?.push(`${srcRoot}/silent-renew.html`); - - updateProjectInAngularJson(host, project); - - return host; - }; -} +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { getProject, updateProjectInAngularJson } from '../../utils/angular-utils'; +import { NgAddOptions } from '../models/ng-add-options'; + +export function addSilentRenewHtmlToAssetsArrayInAngularJson(ngAddOptions: NgAddOptions): Rule { + return (host: Tree, context: SchematicContext) => { + if (!ngAddOptions.needsSilentRenewHtml) { + context.logger.info(`No silent-renew entry in assets array needed`); + return host; + } + + const project = getProject(host); + + const options = project.architect?.build?.options; + const srcRoot = project.sourceRoot; + options?.assets?.push(`${srcRoot}/silent-renew.html`); + + updateProjectInAngularJson(host, project); + + return host; + }; +} diff --git a/projects/schematics/src/ng-add/actions/configs.ts b/projects/schematics/src/ng-add/actions/configs.ts index 8a5dbd2d7..fc8ce503d 100644 --- a/projects/schematics/src/ng-add/actions/configs.ts +++ b/projects/schematics/src/ng-add/actions/configs.ts @@ -1,74 +1,74 @@ -const DEFAULT_CONFIG = `{ - stsServer: '', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'please-enter-clientId', - scope: 'please-enter-scopes', // 'openid profile offline_access ' + your scopes - responseType: 'code', - silentRenew: true, - useRefreshToken: true, - renewTimeBeforeTokenExpiresInSeconds: 30, - }`; - -const IFRAME_SILENT_RENEW = `{ - stsServer: '', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'please-enter-clientId', - scope: 'please-enter-scopes', // 'openid profile ' + your scopes - responseType: 'code', - silentRenew: true, - silentRenewUrl: window.location.origin + '/silent-renew.html', - renewTimeBeforeTokenExpiresInSeconds: 10, - }`; - -const AZURE_AD_SILENT_RENEW = `{ - stsServer: 'https://login.microsoftonline.com//v2.0', - authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', - redirectUrl: window.location.origin, - clientId: 'please-enter-clientId', - scope: 'please-enter-scopes', // 'openid profile ' + your scopes - responseType: 'code', - silentRenew: true, - maxIdTokenIatOffsetAllowedInSeconds: 600, - issValidationOff: false, - autoUserinfo: false, - silentRenewUrl: window.location.origin + '/silent-renew.html', - }`; - -const AZURE_AD_REFRESH_TOKENS = `{ - stsServer: 'https://login.microsoftonline.com//v2.0', - authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', - redirectUrl: window.location.origin, - clientId: 'please-enter-clientId', - scope: 'please-enter-scopes', // 'openid profile offline_access ' + your scopes - responseType: 'code', - silentRenew: true, - useRefreshToken: true, - maxIdTokenIatOffsetAllowedInSeconds: 600, - issValidationOff: false, - autoUserinfo: false, - }`; - -const AUTH_0 = `{ - stsServer: '', - redirectUrl: window.location.origin, - clientId: 'please-enter-auth0-clientId', - scope: 'openid profile offline_access', - responseType: 'code', - silentRenew: true, - useRefreshToken: true, - }`; - -const OIDC_PLAIN = `{ - stsServer: '', - redirectUrl: window.location.origin, - postLogoutRedirectUri: window.location.origin, - clientId: 'please-enter-clientId', - scope: 'please-enter-scopes', // 'openid profile ' + your scopes - responseType: 'code', - silentRenew: false, - renewTimeBeforeTokenExpiresInSeconds: 10, - }`; - -export { DEFAULT_CONFIG, AZURE_AD_SILENT_RENEW, IFRAME_SILENT_RENEW, AZURE_AD_REFRESH_TOKENS, OIDC_PLAIN, AUTH_0 }; +const DEFAULT_CONFIG = `{ + stsServer: '', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'please-enter-clientId', + scope: 'please-enter-scopes', // 'openid profile offline_access ' + your scopes + responseType: 'code', + silentRenew: true, + useRefreshToken: true, + renewTimeBeforeTokenExpiresInSeconds: 30, + }`; + +const IFRAME_SILENT_RENEW = `{ + stsServer: '', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'please-enter-clientId', + scope: 'please-enter-scopes', // 'openid profile ' + your scopes + responseType: 'code', + silentRenew: true, + silentRenewUrl: window.location.origin + '/silent-renew.html', + renewTimeBeforeTokenExpiresInSeconds: 10, + }`; + +const AZURE_AD_SILENT_RENEW = `{ + stsServer: 'https://login.microsoftonline.com//v2.0', + authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', + redirectUrl: window.location.origin, + clientId: 'please-enter-clientId', + scope: 'please-enter-scopes', // 'openid profile ' + your scopes + responseType: 'code', + silentRenew: true, + maxIdTokenIatOffsetAllowedInSeconds: 600, + issValidationOff: false, + autoUserinfo: false, + silentRenewUrl: window.location.origin + '/silent-renew.html', + }`; + +const AZURE_AD_REFRESH_TOKENS = `{ + stsServer: 'https://login.microsoftonline.com//v2.0', + authWellknownEndpoint: 'https://login.microsoftonline.com/common/v2.0', + redirectUrl: window.location.origin, + clientId: 'please-enter-clientId', + scope: 'please-enter-scopes', // 'openid profile offline_access ' + your scopes + responseType: 'code', + silentRenew: true, + useRefreshToken: true, + maxIdTokenIatOffsetAllowedInSeconds: 600, + issValidationOff: false, + autoUserinfo: false, + }`; + +const AUTH_0 = `{ + stsServer: '', + redirectUrl: window.location.origin, + clientId: 'please-enter-auth0-clientId', + scope: 'openid profile offline_access', + responseType: 'code', + silentRenew: true, + useRefreshToken: true, + }`; + +const OIDC_PLAIN = `{ + stsServer: '', + redirectUrl: window.location.origin, + postLogoutRedirectUri: window.location.origin, + clientId: 'please-enter-clientId', + scope: 'please-enter-scopes', // 'openid profile ' + your scopes + responseType: 'code', + silentRenew: false, + renewTimeBeforeTokenExpiresInSeconds: 10, + }`; + +export { DEFAULT_CONFIG, AZURE_AD_SILENT_RENEW, IFRAME_SILENT_RENEW, AZURE_AD_REFRESH_TOKENS, OIDC_PLAIN, AUTH_0 }; diff --git a/projects/schematics/src/ng-add/actions/copy-module-file.ts b/projects/schematics/src/ng-add/actions/copy-module-file.ts index 92f7b7070..bf84b4a84 100644 --- a/projects/schematics/src/ng-add/actions/copy-module-file.ts +++ b/projects/schematics/src/ng-add/actions/copy-module-file.ts @@ -1,101 +1,101 @@ -import { normalize } from '@angular-devkit/core'; -import { - apply, - chain, - mergeWith, - move, - Rule, - SchematicContext, - SchematicsException, - template, - Tree, - url, -} from '@angular-devkit/schematics'; -import { getProject } from '../../utils/angular-utils'; -import { NgAddOptions } from '../models/ng-add-options'; -import { FlowType } from '../schema'; -import { AUTH_0, AZURE_AD_REFRESH_TOKENS, AZURE_AD_SILENT_RENEW, DEFAULT_CONFIG, IFRAME_SILENT_RENEW, OIDC_PLAIN } from './configs'; - -export function copyModuleFile(options: NgAddOptions): Rule { - return (host: Tree, context: SchematicContext) => { - const project = getProject(host); - - const { moduleFileName, moduleFolder } = options.moduleInfo; - - const filePath = `${project.sourceRoot}/app/auth/${moduleFileName}.ts`; - if (host.exists(filePath)) { - context.logger.info(`✅️ "${filePath}" already existing - skipping file create`); - return host; - } - - const templateConfig = getTemplateConfig(options); - - context.logger.info(`✅️ "${filePath}" will be created`); - - const templateSource = apply(url(`./files/${moduleFolder}`), [ - template(templateConfig), - move(normalize(`${project.sourceRoot}/app/auth`)), - ]); - - return chain([mergeWith(templateSource)]); - }; -} - -function getTemplateConfig(options: NgAddOptions) { - const { stsUrlOrTenantId, flowType } = options; - - if (options.isHttpOption) { - return { ts: 'ts', stsUrlOrTenantId }; - } - - const authConfig = getConfig(flowType, stsUrlOrTenantId); - - return { ts: 'ts', authConfig }; -} - -function getConfig(flowType: FlowType, stsUrlOrTenantId: string) { - let config = DEFAULT_CONFIG; - - switch (flowType) { - case FlowType.OidcCodeFlowPkceAzureAdUsingIframeSilentRenew: { - config = AZURE_AD_SILENT_RENEW; - break; - } - - case FlowType.OidcCodeFlowPkceAzureAdUsingRefreshTokens: { - config = AZURE_AD_REFRESH_TOKENS; - break; - } - - case FlowType.OidcCodeFlowPkceUsingIframeSilentRenew: { - config = IFRAME_SILENT_RENEW; - break; - } - - case FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp: { - throw new SchematicsException(`With HTTP another module is used. No config but another module`); - } - - case FlowType.OIDCCodeFlowPkce: { - config = OIDC_PLAIN; - break; - } - - case FlowType.Auth0: { - config = AUTH_0; - break; - } - - case FlowType.OidcCodeFlowPkceUsingRefreshTokens: - case FlowType.DefaultConfig: { - config = DEFAULT_CONFIG; - break; - } - - default: { - throw new SchematicsException(`Could not parse flowType '${flowType}'`); - } - } - - return config.replace('', stsUrlOrTenantId); -} +import { normalize } from '@angular-devkit/core'; +import { + apply, + chain, + mergeWith, + move, + Rule, + SchematicContext, + SchematicsException, + template, + Tree, + url, +} from '@angular-devkit/schematics'; +import { getProject } from '../../utils/angular-utils'; +import { NgAddOptions } from '../models/ng-add-options'; +import { FlowType } from '../schema'; +import { AUTH_0, AZURE_AD_REFRESH_TOKENS, AZURE_AD_SILENT_RENEW, DEFAULT_CONFIG, IFRAME_SILENT_RENEW, OIDC_PLAIN } from './configs'; + +export function copyModuleFile(options: NgAddOptions): Rule { + return (host: Tree, context: SchematicContext) => { + const project = getProject(host); + + const { moduleFileName, moduleFolder } = options.moduleInfo; + + const filePath = `${project.sourceRoot}/app/auth/${moduleFileName}.ts`; + if (host.exists(filePath)) { + context.logger.info(`✅️ "${filePath}" already existing - skipping file create`); + return host; + } + + const templateConfig = getTemplateConfig(options); + + context.logger.info(`✅️ "${filePath}" will be created`); + + const templateSource = apply(url(`./files/${moduleFolder}`), [ + template(templateConfig), + move(normalize(`${project.sourceRoot}/app/auth`)), + ]); + + return chain([mergeWith(templateSource)]); + }; +} + +function getTemplateConfig(options: NgAddOptions) { + const { stsUrlOrTenantId, flowType } = options; + + if (options.isHttpOption) { + return { ts: 'ts', stsUrlOrTenantId }; + } + + const authConfig = getConfig(flowType, stsUrlOrTenantId); + + return { ts: 'ts', authConfig }; +} + +function getConfig(flowType: FlowType, stsUrlOrTenantId: string) { + let config = DEFAULT_CONFIG; + + switch (flowType) { + case FlowType.OidcCodeFlowPkceAzureAdUsingIframeSilentRenew: { + config = AZURE_AD_SILENT_RENEW; + break; + } + + case FlowType.OidcCodeFlowPkceAzureAdUsingRefreshTokens: { + config = AZURE_AD_REFRESH_TOKENS; + break; + } + + case FlowType.OidcCodeFlowPkceUsingIframeSilentRenew: { + config = IFRAME_SILENT_RENEW; + break; + } + + case FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp: { + throw new SchematicsException(`With HTTP another module is used. No config but another module`); + } + + case FlowType.OIDCCodeFlowPkce: { + config = OIDC_PLAIN; + break; + } + + case FlowType.Auth0: { + config = AUTH_0; + break; + } + + case FlowType.OidcCodeFlowPkceUsingRefreshTokens: + case FlowType.DefaultConfig: { + config = DEFAULT_CONFIG; + break; + } + + default: { + throw new SchematicsException(`Could not parse flowType '${flowType}'`); + } + } + + return config.replace('', stsUrlOrTenantId); +} diff --git a/projects/schematics/src/ng-add/actions/copy-silent-renew-html.ts b/projects/schematics/src/ng-add/actions/copy-silent-renew-html.ts index 4b452b833..76be8f5d8 100644 --- a/projects/schematics/src/ng-add/actions/copy-silent-renew-html.ts +++ b/projects/schematics/src/ng-add/actions/copy-silent-renew-html.ts @@ -1,18 +1,18 @@ -import { normalize } from '@angular-devkit/core'; -import { apply, chain, mergeWith, move, Rule, SchematicContext, Tree, url } from '@angular-devkit/schematics'; -import { getProject } from '../../utils/angular-utils'; -import { NgAddOptions } from '../models/ng-add-options'; - -export function copySilentRenewHtmlToRoot(options: NgAddOptions): Rule { - return (host: Tree, context: SchematicContext) => { - if (!options.needsSilentRenewHtml) { - context.logger.info(`No silent-renew.html needed`); - return host; - } - - const project = getProject(host); - const templateSource = apply(url(`./files/silent-renew`), [move(normalize(`${project.sourceRoot}`))]); - - return chain([mergeWith(templateSource)]); - }; -} +import { normalize } from '@angular-devkit/core'; +import { apply, chain, mergeWith, move, Rule, SchematicContext, Tree, url } from '@angular-devkit/schematics'; +import { getProject } from '../../utils/angular-utils'; +import { NgAddOptions } from '../models/ng-add-options'; + +export function copySilentRenewHtmlToRoot(options: NgAddOptions): Rule { + return (host: Tree, context: SchematicContext) => { + if (!options.needsSilentRenewHtml) { + context.logger.info(`No silent-renew.html needed`); + return host; + } + + const project = getProject(host); + const templateSource = apply(url(`./files/silent-renew`), [move(normalize(`${project.sourceRoot}`))]); + + return chain([mergeWith(templateSource)]); + }; +} diff --git a/projects/schematics/src/ng-add/actions/index.ts b/projects/schematics/src/ng-add/actions/index.ts index 6be57d21e..8d5779532 100644 --- a/projects/schematics/src/ng-add/actions/index.ts +++ b/projects/schematics/src/ng-add/actions/index.ts @@ -1,20 +1,20 @@ -import { Schema } from '../schema'; -import { addPackageJsonDependencies } from './add-dependencies'; -import { addModuleToImports } from './add-module-import'; -import { addSilentRenewHtmlToAssetsArrayInAngularJson } from './adding-entry-to-assets'; -import { copyModuleFile } from './copy-module-file'; -import { copySilentRenewHtmlToRoot } from './copy-silent-renew-html'; -import { installPackageJsonDependencies } from './install-dependencies'; -import { parseSchema } from './schema-parser'; - -export function getAllActions(options: Schema) { - const ngAddOptions = parseSchema(options); - return [ - addPackageJsonDependencies(), - installPackageJsonDependencies(), - copyModuleFile(ngAddOptions), - addModuleToImports(ngAddOptions), - addSilentRenewHtmlToAssetsArrayInAngularJson(ngAddOptions), - copySilentRenewHtmlToRoot(ngAddOptions), - ]; -} +import { Schema } from '../schema'; +import { addPackageJsonDependencies } from './add-dependencies'; +import { addModuleToImports } from './add-module-import'; +import { addSilentRenewHtmlToAssetsArrayInAngularJson } from './adding-entry-to-assets'; +import { copyModuleFile } from './copy-module-file'; +import { copySilentRenewHtmlToRoot } from './copy-silent-renew-html'; +import { installPackageJsonDependencies } from './install-dependencies'; +import { parseSchema } from './schema-parser'; + +export function getAllActions(options: Schema) { + const ngAddOptions = parseSchema(options); + return [ + addPackageJsonDependencies(), + installPackageJsonDependencies(), + copyModuleFile(ngAddOptions), + addModuleToImports(ngAddOptions), + addSilentRenewHtmlToAssetsArrayInAngularJson(ngAddOptions), + copySilentRenewHtmlToRoot(ngAddOptions), + ]; +} diff --git a/projects/schematics/src/ng-add/actions/install-dependencies.ts b/projects/schematics/src/ng-add/actions/install-dependencies.ts index 25e373c12..43c55af22 100644 --- a/projects/schematics/src/ng-add/actions/install-dependencies.ts +++ b/projects/schematics/src/ng-add/actions/install-dependencies.ts @@ -1,12 +1,12 @@ -import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; - -export function installPackageJsonDependencies(): Rule { - return (host: Tree, context: SchematicContext) => { - context.logger.info(`🔍 Installing packages...`); - context.addTask(new NodePackageInstallTask()); - context.logger.info(`✅️ Installed`); - - return host; - }; -} +import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; + +export function installPackageJsonDependencies(): Rule { + return (host: Tree, context: SchematicContext) => { + context.logger.info(`🔍 Installing packages...`); + context.addTask(new NodePackageInstallTask()); + context.logger.info(`✅️ Installed`); + + return host; + }; +} diff --git a/projects/schematics/src/ng-add/actions/schema-parser.ts b/projects/schematics/src/ng-add/actions/schema-parser.ts index 0a37ce156..d59300256 100644 --- a/projects/schematics/src/ng-add/actions/schema-parser.ts +++ b/projects/schematics/src/ng-add/actions/schema-parser.ts @@ -1,41 +1,41 @@ -import { NgAddOptions } from '../models/ng-add-options'; -import { FlowType, Schema } from '../schema'; - -const AUTH_CONFIG_MODULE = { moduleFileName: 'auth-config.module', moduleName: 'AuthConfigModule', moduleFolder: 'auth-config' }; -const AUTH_HTTP_CONFIG_MODULE = { - moduleFileName: 'auth-http-config.module', - moduleName: 'AuthHttpConfigModule', - moduleFolder: 'auth-http-config', -}; - -function needsHttp(flowType: FlowType) { - return flowType === FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp; -} - -function needsSilentRenewHtml(flowType: FlowType) { - const optionsWithSilentRenewHtml = [ - FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp, - FlowType.OidcCodeFlowPkceAzureAdUsingIframeSilentRenew, - FlowType.OidcCodeFlowPkceUsingIframeSilentRenew, - ]; - - return optionsWithSilentRenewHtml.includes(flowType); -} - -function getModuleInfo(flowType: FlowType) { - if (needsHttp(flowType)) { - return AUTH_HTTP_CONFIG_MODULE; - } - - return AUTH_CONFIG_MODULE; -} - -export function parseSchema(options: Schema): NgAddOptions { - const { flowType } = options; - return { - ...options, - moduleInfo: getModuleInfo(flowType), - isHttpOption: needsHttp(flowType), - needsSilentRenewHtml: needsSilentRenewHtml(flowType), - }; -} +import { NgAddOptions } from '../models/ng-add-options'; +import { FlowType, Schema } from '../schema'; + +const AUTH_CONFIG_MODULE = { moduleFileName: 'auth-config.module', moduleName: 'AuthConfigModule', moduleFolder: 'auth-config' }; +const AUTH_HTTP_CONFIG_MODULE = { + moduleFileName: 'auth-http-config.module', + moduleName: 'AuthHttpConfigModule', + moduleFolder: 'auth-http-config', +}; + +function needsHttp(flowType: FlowType) { + return flowType === FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp; +} + +function needsSilentRenewHtml(flowType: FlowType) { + const optionsWithSilentRenewHtml = [ + FlowType.OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp, + FlowType.OidcCodeFlowPkceAzureAdUsingIframeSilentRenew, + FlowType.OidcCodeFlowPkceUsingIframeSilentRenew, + ]; + + return optionsWithSilentRenewHtml.includes(flowType); +} + +function getModuleInfo(flowType: FlowType) { + if (needsHttp(flowType)) { + return AUTH_HTTP_CONFIG_MODULE; + } + + return AUTH_CONFIG_MODULE; +} + +export function parseSchema(options: Schema): NgAddOptions { + const { flowType } = options; + return { + ...options, + moduleInfo: getModuleInfo(flowType), + isHttpOption: needsHttp(flowType), + needsSilentRenewHtml: needsSilentRenewHtml(flowType), + }; +} diff --git a/projects/schematics/src/ng-add/files/silent-renew/silent-renew.html b/projects/schematics/src/ng-add/files/silent-renew/silent-renew.html index 35a8eabe3..7aab22f4b 100644 --- a/projects/schematics/src/ng-add/files/silent-renew/silent-renew.html +++ b/projects/schematics/src/ng-add/files/silent-renew/silent-renew.html @@ -1,21 +1,21 @@ - - - - - silent-renew - - - - - + + + + + silent-renew + + + + + diff --git a/projects/schematics/src/ng-add/index.ts b/projects/schematics/src/ng-add/index.ts index 6d65b69e6..2535b0f14 100644 --- a/projects/schematics/src/ng-add/index.ts +++ b/projects/schematics/src/ng-add/index.ts @@ -3,6 +3,6 @@ import { getAllActions } from './actions'; import { Schema } from './schema'; export function ngAdd(options: Schema): Rule { - const allActions = getAllActions(options); - return chain(allActions); + const allActions = getAllActions(options); + return chain(allActions); } diff --git a/projects/schematics/src/ng-add/models/ng-add-options.ts b/projects/schematics/src/ng-add/models/ng-add-options.ts index d55d0572a..c7b0abd25 100644 --- a/projects/schematics/src/ng-add/models/ng-add-options.ts +++ b/projects/schematics/src/ng-add/models/ng-add-options.ts @@ -1,15 +1,15 @@ -import { FlowType } from '../schema'; - -export interface ModuleInfo { - moduleFileName: string; - moduleName: string; - moduleFolder: string; -} - -export interface NgAddOptions { - stsUrlOrTenantId: string; - flowType: FlowType; - isHttpOption: boolean; - needsSilentRenewHtml: boolean; - moduleInfo: ModuleInfo; -} +import { FlowType } from '../schema'; + +export interface ModuleInfo { + moduleFileName: string; + moduleName: string; + moduleFolder: string; +} + +export interface NgAddOptions { + stsUrlOrTenantId: string; + flowType: FlowType; + isHttpOption: boolean; + needsSilentRenewHtml: boolean; + moduleInfo: ModuleInfo; +} diff --git a/projects/schematics/src/ng-add/schema.json b/projects/schematics/src/ng-add/schema.json index 55e347397..280f69ccd 100644 --- a/projects/schematics/src/ng-add/schema.json +++ b/projects/schematics/src/ng-add/schema.json @@ -1,28 +1,28 @@ -{ - "$schema": "http://json-schema.org/schema", - "id": "SchematicsMyService", - "title": "My Service Schema", - "type": "object", - "properties": { - "flowType": { - "description": "The flow the user wants to configure", - "x-prompt": "What flow to use?", - "enum": [ - "OIDC Code Flow PKCE Azure AD using refresh tokens", - "OIDC Code Flow PKCE Azure AD using iframe silent renew", - "OIDC Code Flow PKCE using refresh tokens", - "OIDC Code Flow PKCE using iframe silent renew", - "OIDC Code Flow PKCE using iframe silent renew getting config from http", - "OIDC Code Flow PKCE (no renew)", - "Auth0", - "Default config" - ] - }, - "stsUrlOrTenantId": { - "description": "Please enter your STS URL or Azure tenant id or Http config URL", - "type": "string", - "x-prompt": "Please enter your STS URL or Azure tenant id or Http config URL" - } - }, - "required": ["stsUrlOrTenantId", "flowType"] -} +{ + "$schema": "http://json-schema.org/schema", + "id": "SchematicsMyService", + "title": "My Service Schema", + "type": "object", + "properties": { + "flowType": { + "description": "The flow the user wants to configure", + "x-prompt": "What flow to use?", + "enum": [ + "OIDC Code Flow PKCE Azure AD using refresh tokens", + "OIDC Code Flow PKCE Azure AD using iframe silent renew", + "OIDC Code Flow PKCE using refresh tokens", + "OIDC Code Flow PKCE using iframe silent renew", + "OIDC Code Flow PKCE using iframe silent renew getting config from http", + "OIDC Code Flow PKCE (no renew)", + "Auth0", + "Default config" + ] + }, + "stsUrlOrTenantId": { + "description": "Please enter your STS URL or Azure tenant id or Http config URL", + "type": "string", + "x-prompt": "Please enter your STS URL or Azure tenant id or Http config URL" + } + }, + "required": ["stsUrlOrTenantId", "flowType"] +} diff --git a/projects/schematics/src/ng-add/schema.ts b/projects/schematics/src/ng-add/schema.ts index fe1b8572e..6f77a2f57 100644 --- a/projects/schematics/src/ng-add/schema.ts +++ b/projects/schematics/src/ng-add/schema.ts @@ -1,15 +1,15 @@ -export interface Schema { - stsUrlOrTenantId: string; - flowType: FlowType; -} - -export enum FlowType { - OidcCodeFlowPkceAzureAdUsingRefreshTokens = 'OIDC Code Flow PKCE Azure AD using refresh tokens', - OidcCodeFlowPkceAzureAdUsingIframeSilentRenew = 'OIDC Code Flow PKCE Azure AD using iframe silent renew', - OidcCodeFlowPkceUsingRefreshTokens = 'OIDC Code Flow PKCE using refresh tokens', - OidcCodeFlowPkceUsingIframeSilentRenew = 'OIDC Code Flow PKCE using iframe silent renew', - OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp = 'OIDC Code Flow PKCE using iframe silent renew getting config from http', - OIDCCodeFlowPkce = 'OIDC Code Flow PKCE (no renew)', - Auth0 = 'Auth0', - DefaultConfig = 'Default config', -} +export interface Schema { + stsUrlOrTenantId: string; + flowType: FlowType; +} + +export enum FlowType { + OidcCodeFlowPkceAzureAdUsingRefreshTokens = 'OIDC Code Flow PKCE Azure AD using refresh tokens', + OidcCodeFlowPkceAzureAdUsingIframeSilentRenew = 'OIDC Code Flow PKCE Azure AD using iframe silent renew', + OidcCodeFlowPkceUsingRefreshTokens = 'OIDC Code Flow PKCE using refresh tokens', + OidcCodeFlowPkceUsingIframeSilentRenew = 'OIDC Code Flow PKCE using iframe silent renew', + OidcCodeFlowPkceUsingIframeSilentRenewGettingConfigFromHttp = 'OIDC Code Flow PKCE using iframe silent renew getting config from http', + OIDCCodeFlowPkce = 'OIDC Code Flow PKCE (no renew)', + Auth0 = 'Auth0', + DefaultConfig = 'Default config', +} diff --git a/projects/schematics/src/utils/angular-utils.ts b/projects/schematics/src/utils/angular-utils.ts index 85a7ae80e..92da0ddde 100644 --- a/projects/schematics/src/utils/angular-utils.ts +++ b/projects/schematics/src/utils/angular-utils.ts @@ -1,62 +1,62 @@ -import { SchematicsException, Tree } from '@angular-devkit/schematics'; -import { WorkspaceProject, WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; -import ts = require('@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'); -export const ANGULAR_JSON_FILENAME = 'angular.json'; - -export function getAngularWorkspace(tree: Tree): WorkspaceSchema { - const workspaceContent = getAngularJsonContent(tree); - const workspace = JSON.parse(workspaceContent); - - return workspace as WorkspaceSchema; -} - -export function updateProjectInAngularJson(tree: Tree, content: WorkspaceProject, projectName?: string) { - projectName = projectName || getDefaultProjectName(tree); - - if (!projectName) { - throw new SchematicsException(`project '${projectName}' could not be found and no default project is given in workspace`); - } - - const workspaceContent = getAngularJsonContent(tree); - const workspace = JSON.parse(workspaceContent); - workspace['projects'][projectName] = content; - tree.overwrite(ANGULAR_JSON_FILENAME, JSON.stringify(workspace, null, 2)); -} - -export function getProject(tree: Tree, projectName?: string): WorkspaceProject { - const workspace = getAngularWorkspace(tree); - const hasProjectName = !!projectName; - const hasDefaultProject = !!workspace.defaultProject; - - if (hasProjectName) { - return workspace.projects[projectName as string] || null; - } else if (hasDefaultProject) { - return workspace.projects[workspace.defaultProject as string]; - } - - throw new SchematicsException(`project '${projectName}' could not be found and no default project is given in workspace`); -} - -export function readIntoSourceFile(host: Tree, fileName: string): ts.SourceFile { - const buffer = host.read(fileName); - if (buffer === null) { - throw new SchematicsException(`File ${fileName} does not exist.`); - } - - return ts.createSourceFile(fileName, buffer.toString('utf-8'), ts.ScriptTarget.Latest, true); -} - -function getAngularJsonContent(tree: Tree) { - const workspaceConfig = tree.read(ANGULAR_JSON_FILENAME); - - if (!workspaceConfig) { - throw new SchematicsException('Could not find Angular workspace configuration'); - } - - return workspaceConfig.toString(); -} - -function getDefaultProjectName(tree: Tree) { - const workspace = getAngularWorkspace(tree); - return workspace.defaultProject; -} +import { SchematicsException, Tree } from '@angular-devkit/schematics'; +import { WorkspaceProject, WorkspaceSchema } from '@schematics/angular/utility/workspace-models'; +import ts = require('@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript'); +export const ANGULAR_JSON_FILENAME = 'angular.json'; + +export function getAngularWorkspace(tree: Tree): WorkspaceSchema { + const workspaceContent = getAngularJsonContent(tree); + const workspace = JSON.parse(workspaceContent); + + return workspace as WorkspaceSchema; +} + +export function updateProjectInAngularJson(tree: Tree, content: WorkspaceProject, projectName?: string) { + projectName = projectName || getDefaultProjectName(tree); + + if (!projectName) { + throw new SchematicsException(`project '${projectName}' could not be found and no default project is given in workspace`); + } + + const workspaceContent = getAngularJsonContent(tree); + const workspace = JSON.parse(workspaceContent); + workspace['projects'][projectName] = content; + tree.overwrite(ANGULAR_JSON_FILENAME, JSON.stringify(workspace, null, 2)); +} + +export function getProject(tree: Tree, projectName?: string): WorkspaceProject { + const workspace = getAngularWorkspace(tree); + const hasProjectName = !!projectName; + const hasDefaultProject = !!workspace.defaultProject; + + if (hasProjectName) { + return workspace.projects[projectName as string] || null; + } else if (hasDefaultProject) { + return workspace.projects[workspace.defaultProject as string]; + } + + throw new SchematicsException(`project '${projectName}' could not be found and no default project is given in workspace`); +} + +export function readIntoSourceFile(host: Tree, fileName: string): ts.SourceFile { + const buffer = host.read(fileName); + if (buffer === null) { + throw new SchematicsException(`File ${fileName} does not exist.`); + } + + return ts.createSourceFile(fileName, buffer.toString('utf-8'), ts.ScriptTarget.Latest, true); +} + +function getAngularJsonContent(tree: Tree) { + const workspaceConfig = tree.read(ANGULAR_JSON_FILENAME); + + if (!workspaceConfig) { + throw new SchematicsException('Could not find Angular workspace configuration'); + } + + return workspaceConfig.toString(); +} + +function getDefaultProjectName(tree: Tree) { + const workspace = getAngularWorkspace(tree); + return workspace.defaultProject; +} diff --git a/projects/schematics/tsconfig.json b/projects/schematics/tsconfig.json index 7d8e87db0..168ec9147 100644 --- a/projects/schematics/tsconfig.json +++ b/projects/schematics/tsconfig.json @@ -1,25 +1,25 @@ { - "compilerOptions": { - "baseUrl": "tsconfig", - "lib": ["es2018", "dom"], - "declaration": true, - "module": "commonjs", - "moduleResolution": "node", - "noEmitOnError": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": true, - "noImplicitThis": true, - "noUnusedParameters": false, - "noUnusedLocals": true, - "rootDir": "src/", - "skipDefaultLibCheck": true, - "skipLibCheck": true, - "sourceMap": true, - "strictNullChecks": true, - "target": "es6", - "outDir": "../../dist/angular-auth-oidc-client/schematics", - "types": ["jasmine", "node"] - }, - "include": ["src/**/*"], - "exclude": ["src/*/files/**/*"] + "compilerOptions": { + "baseUrl": "tsconfig", + "lib": ["es2018", "dom"], + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "noEmitOnError": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUnusedParameters": false, + "noUnusedLocals": true, + "rootDir": "src/", + "skipDefaultLibCheck": true, + "skipLibCheck": true, + "sourceMap": true, + "strictNullChecks": true, + "target": "es6", + "outDir": "../../dist/angular-auth-oidc-client/schematics", + "types": ["jasmine", "node"] + }, + "include": ["src/**/*"], + "exclude": ["src/*/files/**/*"] }