From 05c5a4a0adadb4d1ffa0b8fdbff3dcd7d40a0b86 Mon Sep 17 00:00:00 2001 From: Mahmut Gundogdu Date: Wed, 21 Dec 2022 13:58:20 +0300 Subject: [PATCH] Move auth logic to ng-oauth packages --- npm/ng-packs/angular.json | 285 ++++++------------ .../apps/dev-app/src/app/app.module.ts | 2 + .../dev-app/src/app/home/home.component.ts | 4 +- npm/ng-packs/package.json | 12 +- .../core/src/lib/abstracts/auth.guard.ts | 15 + .../core/src/lib/abstracts/auth.service.ts | 59 ++++ .../packages/core/src/lib/abstracts/index.ts | 2 + .../packages/core/src/lib/core.module.ts | 31 +- .../packages/core/src/lib/guards/index.ts | 1 - .../packages/core/src/lib/handlers/index.ts | 1 - .../packages/core/src/lib/models/index.ts | 2 +- .../core/src/lib/services/auth.service.ts | 52 ---- .../packages/core/src/lib/services/index.ts | 2 - .../src/lib/strategies/auth-flow.strategy.ts | 262 ---------------- .../packages/core/src/lib/utils/index.ts | 1 - .../core/src/lib/utils/initial-utils.ts | 45 +-- npm/ng-packs/packages/core/src/public-api.ts | 1 - npm/ng-packs/packages/oauth/ng-package.json | 6 +- npm/ng-packs/packages/oauth/package.json | 3 +- .../packages/oauth/src/lib/guards/index.ts | 1 + .../src/lib/guards/oauth.guard.ts} | 4 +- .../packages/oauth/src/lib/handlers/index.ts | 1 + .../handlers/oauth-configuration.handler.ts | 4 +- .../src/lib/interceptors/api.interceptor.ts | 4 +- .../src/lib/interceptors/index.ts | 0 .../packages/oauth/src/lib/oauth.module.ts | 50 ++- .../packages/oauth/src/lib/services/index.ts | 2 + .../oauth/src/lib/services/oauth.service.ts | 57 ++++ .../services/timeout-limited-oauth.service.ts | 3 +- .../src/lib/strategies/auth-flow-strategy.ts | 17 +- .../strategies/auth-password-flow-strategy.ts | 6 +- .../oauth/src/lib/tests/sample.spec.ts | 5 + .../src/lib/tokens/ auth-flow-strategy.ts | 12 + .../packages/oauth/src/lib/tokens/index.ts | 1 + .../src/lib/utils/auth-utils.ts | 3 +- .../src/lib/utils/clear-o-auth-storage.ts | 21 ++ .../packages/oauth/src/lib/utils/index.ts | 5 + .../oauth/src/lib/utils/init-factory.ts | 31 ++ .../oauth/src/lib/utils/oauth-storage.ts | 1 + .../oauth/src/lib/utils/storage.factory.ts | 6 + npm/ng-packs/packages/oauth/src/public-api.ts | 8 + .../packages/schematics/collection.json | 40 +++ .../packages/theme-shared/ng-package.json | 3 +- .../src/lib/handlers/error.handler.ts | 4 +- npm/ng-packs/tsconfig.base.json | 3 +- 45 files changed, 468 insertions(+), 610 deletions(-) create mode 100644 npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts create mode 100644 npm/ng-packs/packages/core/src/lib/abstracts/auth.service.ts delete mode 100644 npm/ng-packs/packages/core/src/lib/services/auth.service.ts delete mode 100644 npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/guards/index.ts rename npm/ng-packs/packages/{core/src/lib/guards/auth.guard.ts => oauth/src/lib/guards/oauth.guard.ts} (82%) create mode 100644 npm/ng-packs/packages/oauth/src/lib/handlers/index.ts rename npm/ng-packs/packages/{core => oauth}/src/lib/handlers/oauth-configuration.handler.ts (83%) rename npm/ng-packs/packages/{core => oauth}/src/lib/interceptors/api.interceptor.ts (88%) rename npm/ng-packs/packages/{core => oauth}/src/lib/interceptors/index.ts (100%) create mode 100644 npm/ng-packs/packages/oauth/src/lib/services/index.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts rename npm/ng-packs/packages/{core => oauth}/src/lib/services/timeout-limited-oauth.service.ts (70%) create mode 100644 npm/ng-packs/packages/oauth/src/lib/tests/sample.spec.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/tokens/ auth-flow-strategy.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/tokens/index.ts rename npm/ng-packs/packages/{core => oauth}/src/lib/utils/auth-utils.ts (93%) create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/clear-o-auth-storage.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/index.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/init-factory.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/oauth-storage.ts create mode 100644 npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts create mode 100644 npm/ng-packs/packages/schematics/collection.json diff --git a/npm/ng-packs/angular.json b/npm/ng-packs/angular.json index cd9029142c..01e482cd85 100644 --- a/npm/ng-packs/angular.json +++ b/npm/ng-packs/angular.json @@ -10,9 +10,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/account" - ], + "outputs": ["{workspaceRoot}/dist/packages/account"], "options": { "project": "packages/account/ng-package.json" }, @@ -28,9 +26,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/account" - ], + "outputs": ["{workspaceRoot}/coverage/packages/account"], "options": { "jestConfig": "packages/account/jest.config.ts", "passWithNoTests": true @@ -39,22 +35,13 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "packages/account/src/**/*.ts", - "packages/account/src/**/*.html" - ] + "lintFilePatterns": ["packages/account/src/**/*.ts", "packages/account/src/**/*.html"] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared", - "account-core" - ] + "implicitDependencies": ["core", "theme-shared", "account-core"] }, "account-core": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -65,9 +52,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/account-core" - ], + "outputs": ["{workspaceRoot}/dist/packages/account-core"], "options": { "project": "packages/account-core/ng-package.json" }, @@ -83,9 +68,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/account-core" - ], + "outputs": ["{workspaceRoot}/coverage/packages/account-core"], "options": { "jestConfig": "packages/account-core/jest.config.ts", "passWithNoTests": true @@ -99,16 +82,11 @@ "packages/account-core/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared" - ] + "implicitDependencies": ["core", "theme-shared"] }, "components": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -119,9 +97,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/components" - ], + "outputs": ["{workspaceRoot}/dist/packages/components"], "options": { "project": "packages/components/ng-package.json" }, @@ -137,9 +113,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/components" - ], + "outputs": ["{workspaceRoot}/coverage/packages/components"], "options": { "jestConfig": "packages/components/jest.config.ts", "passWithNoTests": true @@ -153,16 +127,11 @@ "packages/components/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared" - ] + "implicitDependencies": ["core", "theme-shared"] }, "core": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -173,9 +142,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/core" - ], + "outputs": ["{workspaceRoot}/dist/packages/core"], "options": { "project": "packages/core/ng-package.json" }, @@ -191,9 +158,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/core" - ], + "outputs": ["{workspaceRoot}/coverage/packages/core"], "options": { "jestConfig": "packages/core/jest.config.ts", "passWithNoTests": true @@ -202,14 +167,9 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "packages/core/src/**/*.ts", - "packages/core/src/**/*.html" - ] + "lintFilePatterns": ["packages/core/src/**/*.ts", "packages/core/src/**/*.html"] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [] @@ -223,9 +183,7 @@ "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", - "outputs": [ - "{options.outputPath}" - ], + "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/dev-app", "index": "apps/dev-app/src/index.html", @@ -233,14 +191,8 @@ "polyfills": "apps/dev-app/src/polyfills.ts", "tsConfig": "apps/dev-app/tsconfig.app.json", "inlineStyleLanguage": "scss", - "allowedCommonJsDependencies": [ - "chart.js", - "js-sha256" - ], - "assets": [ - "apps/dev-app/src/favicon.ico", - "apps/dev-app/src/assets" - ], + "allowedCommonJsDependencies": ["chart.js", "js-sha256"], + "assets": ["apps/dev-app/src/favicon.ico", "apps/dev-app/src/assets"], "styles": [ { "input": "node_modules/bootstrap/dist/css/bootstrap.rtl.min.css", @@ -341,17 +293,12 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/dev-app/src/**/*.ts", - "apps/dev-app/src/**/*.html" - ] + "lintFilePatterns": ["apps/dev-app/src/**/*.ts", "apps/dev-app/src/**/*.html"] } }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/apps/dev-app" - ], + "outputs": ["{workspaceRoot}/coverage/apps/dev-app"], "options": { "jestConfig": "apps/dev-app/jest.config.ts", "passWithNoTests": true @@ -381,19 +328,13 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "apps/dev-app-e2e/**/*.{js,ts}" - ] + "lintFilePatterns": ["apps/dev-app-e2e/**/*.{js,ts}"] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "dev-app" - ] + "implicitDependencies": ["dev-app"] }, "feature-management": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -404,9 +345,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/feature-management" - ], + "outputs": ["{workspaceRoot}/dist/packages/feature-management"], "options": { "project": "packages/feature-management/ng-package.json" }, @@ -422,9 +361,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/feature-management" - ], + "outputs": ["{workspaceRoot}/coverage/packages/feature-management"], "options": { "jestConfig": "packages/feature-management/jest.config.ts", "passWithNoTests": true @@ -438,16 +375,11 @@ "packages/feature-management/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared" - ] + "implicitDependencies": ["core", "theme-shared"] }, "identity": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -458,9 +390,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/identity" - ], + "outputs": ["{workspaceRoot}/dist/packages/identity"], "options": { "project": "packages/identity/ng-package.json" }, @@ -476,9 +406,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/identity" - ], + "outputs": ["{workspaceRoot}/coverage/packages/identity"], "options": { "jestConfig": "packages/identity/jest.config.ts", "passWithNoTests": true @@ -487,22 +415,54 @@ "lint": { "builder": "@nrwl/linter:eslint", "options": { - "lintFilePatterns": [ - "packages/identity/src/**/*.ts", - "packages/identity/src/**/*.html" - ] + "lintFilePatterns": ["packages/identity/src/**/*.ts", "packages/identity/src/**/*.html"] + }, + "outputs": ["{options.outputFile}"] + } + }, + "tags": [], + "implicitDependencies": ["core", "theme-shared", "permission-management"] + }, + "oauth": { + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "projectType": "library", + "root": "packages/oauth", + "sourceRoot": "packages/oauth/src", + "prefix": "abp", + "architect": { + "build": { + "builder": "@nrwl/angular:package", + "outputs": ["{workspaceRoot}/dist/packages/oauth"], + "options": { + "project": "packages/oauth/ng-package.json" }, - "outputs": [ - "{options.outputFile}" - ] + "configurations": { + "production": { + "tsConfig": "packages/oauth/tsconfig.lib.prod.json" + }, + "development": { + "tsConfig": "packages/oauth/tsconfig.lib.json" + } + }, + "defaultConfiguration": "production" + }, + "test": { + "builder": "@nrwl/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/oauth/jest.config.ts", + "passWithNoTests": true + } + }, + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": ["packages/oauth/**/*.ts", "packages/oauth/**/*.html"] + } } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared", - "permission-management" - ] + "implicitDependencies": ["core"] }, "permission-management": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -513,9 +473,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/permission-management" - ], + "outputs": ["{workspaceRoot}/dist/packages/permission-management"], "options": { "project": "packages/permission-management/ng-package.json" }, @@ -531,9 +489,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/permission-management" - ], + "outputs": ["{workspaceRoot}/coverage/packages/permission-management"], "options": { "jestConfig": "packages/permission-management/jest.config.ts", "passWithNoTests": true @@ -547,16 +503,11 @@ "packages/permission-management/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared" - ] + "implicitDependencies": ["core", "theme-shared"] }, "schematics": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -567,9 +518,7 @@ "architect": { "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/schematics" - ], + "outputs": ["{workspaceRoot}/coverage/packages/schematics"], "options": { "jestConfig": "packages/schematics/jest.config.ts", "passWithNoTests": true @@ -583,9 +532,7 @@ "packages/schematics/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [] @@ -599,9 +546,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/setting-management" - ], + "outputs": ["{workspaceRoot}/dist/packages/setting-management"], "options": { "project": "packages/setting-management/ng-package.json" }, @@ -617,9 +562,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/setting-management" - ], + "outputs": ["{workspaceRoot}/coverage/packages/setting-management"], "options": { "jestConfig": "packages/setting-management/jest.config.ts", "passWithNoTests": true @@ -633,17 +576,11 @@ "packages/setting-management/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared", - "components" - ] + "implicitDependencies": ["core", "theme-shared", "components"] }, "tenant-management": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -654,9 +591,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/tenant-management" - ], + "outputs": ["{workspaceRoot}/dist/packages/tenant-management"], "options": { "project": "packages/tenant-management/ng-package.json" }, @@ -672,9 +607,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/tenant-management" - ], + "outputs": ["{workspaceRoot}/coverage/packages/tenant-management"], "options": { "jestConfig": "packages/tenant-management/jest.config.ts", "passWithNoTests": true @@ -688,17 +621,11 @@ "packages/tenant-management/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared", - "feature-management" - ] + "implicitDependencies": ["core", "theme-shared", "feature-management"] }, "theme-basic": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -709,9 +636,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/theme-basic" - ], + "outputs": ["{workspaceRoot}/dist/packages/theme-basic"], "options": { "project": "packages/theme-basic/ng-package.json" }, @@ -727,9 +652,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/theme-basic" - ], + "outputs": ["{workspaceRoot}/coverage/packages/theme-basic"], "options": { "jestConfig": "packages/theme-basic/jest.config.ts", "passWithNoTests": true @@ -743,17 +666,11 @@ "packages/theme-basic/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core", - "theme-shared", - "account-core" - ] + "implicitDependencies": ["core", "theme-shared", "account-core"] }, "theme-shared": { "$schema": "../../node_modules/nx/schemas/project-schema.json", @@ -764,9 +681,7 @@ "architect": { "build": { "builder": "@nrwl/angular:package", - "outputs": [ - "{workspaceRoot}/dist/packages/theme-shared" - ], + "outputs": ["{workspaceRoot}/dist/packages/theme-shared"], "options": { "project": "packages/theme-shared/ng-package.json" }, @@ -782,9 +697,7 @@ }, "test": { "builder": "@nrwl/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/packages/theme-shared" - ], + "outputs": ["{workspaceRoot}/coverage/packages/theme-shared"], "options": { "jestConfig": "packages/theme-shared/jest.config.ts", "passWithNoTests": true @@ -798,15 +711,11 @@ "packages/theme-shared/src/**/*.html" ] }, - "outputs": [ - "{options.outputFile}" - ] + "outputs": ["{options.outputFile}"] } }, "tags": [], - "implicitDependencies": [ - "core" - ] + "implicitDependencies": ["core","oauth"] } } } diff --git a/npm/ng-packs/apps/dev-app/src/app/app.module.ts b/npm/ng-packs/apps/dev-app/src/app/app.module.ts index cff75b7bfa..52ebd38362 100644 --- a/npm/ng-packs/apps/dev-app/src/app/app.module.ts +++ b/npm/ng-packs/apps/dev-app/src/app/app.module.ts @@ -14,6 +14,7 @@ import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { APP_ROUTE_PROVIDER } from './route.provider'; import { FeatureManagementModule } from '@abp/ng.feature-management'; +import { AbpOAuthModule } from '@abp/ng.oauth'; @NgModule({ imports: [ @@ -26,6 +27,7 @@ import { FeatureManagementModule } from '@abp/ng.feature-management'; sendNullsAsQueryParam: false, skipGetAppConfiguration: false, }), + AbpOAuthModule.forRoot(), ThemeSharedModule.forRoot(), AccountConfigModule.forRoot(), IdentityConfigModule.forRoot(), diff --git a/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts b/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts index c0b4602ee2..c48187728c 100644 --- a/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts +++ b/npm/ng-packs/apps/dev-app/src/app/home/home.component.ts @@ -8,10 +8,10 @@ import { OAuthService } from 'angular-oauth2-oidc'; }) export class HomeComponent { get hasLoggedIn(): boolean { - return this.oAuthService.hasValidAccessToken(); + return this.authService.isAuthenticated; } - constructor(private oAuthService: OAuthService, private authService: AuthService) {} + constructor(private authService: AuthService) {} login() { this.authService.navigateToLogin(); diff --git a/npm/ng-packs/package.json b/npm/ng-packs/package.json index b44f13bbc9..ce78984581 100644 --- a/npm/ng-packs/package.json +++ b/npm/ng-packs/package.json @@ -86,8 +86,8 @@ "@popperjs/core": "~2.11.2", "@schematics/angular": "~15.0.1", "@swimlane/ngx-datatable": "^20.0.0", - "@types/jest": "28.1.8", - "@types/node": "14.14.33", + "@types/jest": "28.1.1", + "@types/node": "16.11.7", "@typescript-eslint/eslint-plugin": "5.44.0", "@typescript-eslint/parser": "5.44.0", "angular-oauth2-oidc": "^15.0.1", @@ -99,7 +99,7 @@ "eslint-config-prettier": "8.1.0", "eslint-plugin-cypress": "^2.10.3", "got": "^11.5.2", - "jest": "28.1.3", + "jest": "28.1.1", "jest-canvas-mock": "^2.3.1", "jest-environment-jsdom": "28.1.1", "jest-preset-angular": "12.2.2", @@ -119,18 +119,18 @@ "protractor": "~7.0.0", "rxjs": "7.5.6", "should-quote": "^1.0.0", - "ts-jest": "28.0.8", + "ts-jest": "28.0.5", "ts-node": "10.9.1", "ts-toolbelt": "6.15.4", "tsickle": "^0.39.1", - "tslib": "^2.0.0", + "tslib": "^2.3.0", "tslint": "~6.1.0", "typescript": "4.8.4", "zone.js": "0.11.4" }, "dependencies": {}, "lint-staged": { - "**/*.{js,jsx,ts,tsx}":[ + "**/*.{js,jsx,ts,tsx}": [ "npx prettier --write --config .prettierrc " ] } diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts new file mode 100644 index 0000000000..023b8110dc --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/abstracts/auth.guard.ts @@ -0,0 +1,15 @@ +import { CanActivate, UrlTree } from '@angular/router'; +import { Observable } from 'rxjs'; +import { Injectable } from '@angular/core'; +@Injectable({ + providedIn: 'root', +}) +export class AuthGuard implements CanActivate, IAuthGuard { + canActivate(): Observable | boolean | UrlTree { + console.error('You should add @abp/ng-oauth packages or create your own auth packages.'); + return false; + } +} +export interface IAuthGuard { + canActivate(): Observable | boolean | UrlTree; +} diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/auth.service.ts b/npm/ng-packs/packages/core/src/lib/abstracts/auth.service.ts new file mode 100644 index 0000000000..97bf0b7b24 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/abstracts/auth.service.ts @@ -0,0 +1,59 @@ +import { Injectable } from '@angular/core'; +import { Params } from '@angular/router'; +import { Observable, of } from 'rxjs'; +import { LoginParams } from '../models/auth'; + +/** + * Abstract service for Authentication. + */ +@Injectable({ + providedIn: 'root', +}) +export class AuthService implements IAuthService { + constructor() {} + + private warningMessage() { + console.error('You should add @abp/ng-oauth packages or create your own auth packages.'); + } + + init(): Promise { + this.warningMessage(); + return Promise.resolve(undefined); + } + + login(params: LoginParams): Observable { + this.warningMessage(); + return of(undefined); + } + + logout(queryParams?: Params): Observable { + this.warningMessage(); + return of(undefined); + } + + navigateToLogin(queryParams?: Params): void {} + + get isInternalAuth() { + throw new Error('not implemented'); + return false; + } + + get isAuthenticated(): boolean { + this.warningMessage(); + return false; + } +} + +export interface IAuthService { + get isInternalAuth(): boolean; + + get isAuthenticated(): boolean; + + init(): Promise; + + logout(queryParams?: Params): Observable; + + navigateToLogin(queryParams?: Params): void; + + login(params: LoginParams): Observable; +} diff --git a/npm/ng-packs/packages/core/src/lib/abstracts/index.ts b/npm/ng-packs/packages/core/src/lib/abstracts/index.ts index a4e501a850..6a32fcf8eb 100644 --- a/npm/ng-packs/packages/core/src/lib/abstracts/index.ts +++ b/npm/ng-packs/packages/core/src/lib/abstracts/index.ts @@ -1 +1,3 @@ export * from './ng-model.component'; +export * from './auth.guard'; +export * from './auth.service'; diff --git a/npm/ng-packs/packages/core/src/lib/core.module.ts b/npm/ng-packs/packages/core/src/lib/core.module.ts index 212bf02654..4cf289a240 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -1,9 +1,8 @@ import { CommonModule } from '@angular/common'; -import { HTTP_INTERCEPTORS, HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; +import { HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; -import { OAuthModule, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; import { AbstractNgModelComponent } from './abstracts/ng-model.component'; import { DynamicLayoutComponent } from './components/dynamic-layout.component'; import { ReplaceableRouteContainerComponent } from './components/replaceable-route-container.component'; @@ -16,9 +15,7 @@ import { InitDirective } from './directives/init.directive'; import { PermissionDirective } from './directives/permission.directive'; import { ReplaceableTemplateDirective } from './directives/replaceable-template.directive'; import { StopPropagationDirective } from './directives/stop-propagation.directive'; -import { OAuthConfigurationHandler } from './handlers/oauth-configuration.handler'; import { RoutesHandler } from './handlers/routes.handler'; -import { ApiInterceptor } from './interceptors/api.interceptor'; import { LocalizationModule } from './localization.module'; import { ABP } from './models/common'; import { LocalizationPipe } from './pipes/localization.pipe'; @@ -27,7 +24,6 @@ import { ToInjectorPipe } from './pipes/to-injector.pipe'; import { CookieLanguageProvider } from './providers/cookie-language.provider'; import { LocaleProvider } from './providers/locale.provider'; import { LocalizationService } from './services/localization.service'; -import { oAuthStorage } from './strategies/auth-flow.strategy'; import { localizationContributor, LOCALIZATIONS } from './tokens/localization.token'; import { CORE_OPTIONS, coreOptionsFactory } from './tokens/options.token'; import { TENANT_KEY } from './tokens/tenant-key.token'; @@ -37,12 +33,8 @@ import { getInitialData, localeInitializer } from './utils/initial-utils'; import { ShortDateTimePipe } from './pipes/short-date-time.pipe'; import { ShortTimePipe } from './pipes/short-time.pipe'; import { ShortDatePipe } from './pipes/short-date.pipe'; -import { TimeoutLimitedOAuthService } from './services/timeout-limited-oauth.service'; import { IncludeLocalizationResourcesProvider } from './providers/include-localization-resources.provider'; - -export function storageFactory(): OAuthStorage { - return oAuthStorage; -} +import { AuthGuard } from './abstracts/auth.guard'; /** * BaseCoreModule is the module that holds @@ -77,7 +69,6 @@ export function storageFactory(): OAuthStorage { ShortDatePipe, ], imports: [ - OAuthModule, CommonModule, HttpClientModule, FormsModule, @@ -117,7 +108,6 @@ export class BaseCoreModule {} imports: [ BaseCoreModule, LocalizationModule, - OAuthModule, HttpClientXsrfModule.withOptions({ cookieName: 'XSRF-TOKEN', headerName: 'RequestVerificationToken', @@ -138,7 +128,6 @@ export class CoreModule { return { ngModule: RootCoreModule, providers: [ - OAuthModule.forRoot().providers, LocaleProvider, CookieLanguageProvider, { @@ -150,17 +139,6 @@ export class CoreModule { useFactory: coreOptionsFactory, deps: ['CORE_OPTIONS'], }, - { - provide: HTTP_INTERCEPTORS, - useExisting: ApiInterceptor, - multi: true, - }, - { - provide: APP_INITIALIZER, - multi: true, - deps: [OAuthConfigurationHandler], - useFactory: noop, - }, { provide: APP_INITIALIZER, multi: true, @@ -185,8 +163,7 @@ export class CoreModule { deps: [RoutesHandler], useFactory: noop, }, - { provide: OAuthStorage, useFactory: storageFactory }, - { provide: OAuthService, useClass: TimeoutLimitedOAuthService }, + { provide: TENANT_KEY, useValue: options.tenantKey || '__tenant' }, { provide: LOCALIZATIONS, @@ -194,7 +171,7 @@ export class CoreModule { useValue: localizationContributor(options.localizations), deps: [LocalizationService], }, - IncludeLocalizationResourcesProvider + IncludeLocalizationResourcesProvider, ], }; } diff --git a/npm/ng-packs/packages/core/src/lib/guards/index.ts b/npm/ng-packs/packages/core/src/lib/guards/index.ts index 6d31d6bf14..566b7d166d 100644 --- a/npm/ng-packs/packages/core/src/lib/guards/index.ts +++ b/npm/ng-packs/packages/core/src/lib/guards/index.ts @@ -1,2 +1 @@ -export * from './auth.guard'; export * from './permission.guard'; diff --git a/npm/ng-packs/packages/core/src/lib/handlers/index.ts b/npm/ng-packs/packages/core/src/lib/handlers/index.ts index e11b317f45..b666218d93 100644 --- a/npm/ng-packs/packages/core/src/lib/handlers/index.ts +++ b/npm/ng-packs/packages/core/src/lib/handlers/index.ts @@ -1,2 +1 @@ -export * from './oauth-configuration.handler'; export * from './routes.handler'; diff --git a/npm/ng-packs/packages/core/src/lib/models/index.ts b/npm/ng-packs/packages/core/src/lib/models/index.ts index 67e1c4ed38..0549dd0128 100644 --- a/npm/ng-packs/packages/core/src/lib/models/index.ts +++ b/npm/ng-packs/packages/core/src/lib/models/index.ts @@ -1,4 +1,3 @@ -export * from './auth'; export * from './common'; export * from './dtos'; export * from './environment'; @@ -7,3 +6,4 @@ export * from './replaceable-components'; export * from './rest'; export * from './session'; export * from './utility'; +export * from './auth'; diff --git a/npm/ng-packs/packages/core/src/lib/services/auth.service.ts b/npm/ng-packs/packages/core/src/lib/services/auth.service.ts deleted file mode 100644 index aa920c1633..0000000000 --- a/npm/ng-packs/packages/core/src/lib/services/auth.service.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Injectable, Injector } from '@angular/core'; -import { Params } from '@angular/router'; -import { from, Observable } from 'rxjs'; -import { filter, map, switchMap, take, tap } from 'rxjs/operators'; -import { LoginParams } from '../models/auth'; -import { AuthFlowStrategy, AUTH_FLOW_STRATEGY } from '../strategies/auth-flow.strategy'; -import { EnvironmentService } from './environment.service'; - -@Injectable({ - providedIn: 'root', -}) -export class AuthService { - private strategy: AuthFlowStrategy; - - get isInternalAuth() { - return this.strategy.isInternalAuth; - } - - constructor(protected injector: Injector) {} - - async init() { - const environmentService = this.injector.get(EnvironmentService); - - return environmentService - .getEnvironment$() - .pipe( - map(env => env?.oAuthConfig), - filter(oAuthConfig => !!oAuthConfig), - tap(oAuthConfig => { - this.strategy = - oAuthConfig.responseType === 'code' - ? AUTH_FLOW_STRATEGY.Code(this.injector) - : AUTH_FLOW_STRATEGY.Password(this.injector); - }), - switchMap(() => from(this.strategy.init())), - take(1), - ) - .toPromise(); - } - - logout(queryParams?: Params): Observable { - return this.strategy.logout(queryParams); - } - - navigateToLogin(queryParams?: Params) { - this.strategy.navigateToLogin(queryParams); - } - - login(params: LoginParams) { - return this.strategy.login(params); - } -} diff --git a/npm/ng-packs/packages/core/src/lib/services/index.ts b/npm/ng-packs/packages/core/src/lib/services/index.ts index 7584316db0..209d2a881e 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -1,4 +1,3 @@ -export * from './auth.service'; export * from './config-state.service'; export * from './content-projection.service'; export * from './dom-insertion.service'; @@ -19,4 +18,3 @@ export * from './routes.service'; export * from './session-state.service'; export * from './subscription.service'; export * from './track-by.service'; -export * from './timeout-limited-oauth.service'; diff --git a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts b/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts deleted file mode 100644 index 9ac9283b5d..0000000000 --- a/npm/ng-packs/packages/core/src/lib/strategies/auth-flow.strategy.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { HttpHeaders } from '@angular/common/http'; -import { Injector } from '@angular/core'; -import { Params, Router } from '@angular/router'; -import { - AuthConfig, - OAuthErrorEvent, - OAuthInfoEvent, - OAuthService, - OAuthStorage -} from 'angular-oauth2-oidc'; -import { from, Observable, of, pipe } from 'rxjs'; -import { filter, switchMap, tap } from 'rxjs/operators'; -import { LoginParams } from '../models/auth'; -import { ConfigStateService } from '../services/config-state.service'; -import { EnvironmentService } from '../services/environment.service'; -import { HttpErrorReporterService } from '../services/http-error-reporter.service'; -import { SessionStateService } from '../services/session-state.service'; -import { TENANT_KEY } from '../tokens/tenant-key.token'; -import { removeRememberMe, setRememberMe } from '../utils/auth-utils'; -import { noop } from '../utils/common-utils'; - -export const oAuthStorage = localStorage; - -export abstract class AuthFlowStrategy { - abstract readonly isInternalAuth: boolean; - - protected httpErrorReporter: HttpErrorReporterService; - protected environment: EnvironmentService; - protected configState: ConfigStateService; - protected oAuthService: OAuthService; - protected oAuthConfig: AuthConfig; - protected sessionState: SessionStateService; - protected tenantKey: string; - - abstract checkIfInternalAuth(queryParams?: Params): boolean; - abstract navigateToLogin(queryParams?: Params): void; - abstract logout(queryParams?: Params): Observable; - abstract login(params?: LoginParams | Params): Observable; - - private catchError = err => { - this.httpErrorReporter.reportError(err); - return of(null); - }; - - constructor(protected injector: Injector) { - this.httpErrorReporter = injector.get(HttpErrorReporterService); - this.environment = injector.get(EnvironmentService); - this.configState = injector.get(ConfigStateService); - this.oAuthService = injector.get(OAuthService); - this.sessionState = injector.get(SessionStateService); - this.oAuthConfig = this.environment.getEnvironment().oAuthConfig; - this.tenantKey = injector.get(TENANT_KEY); - - this.listenToOauthErrors(); - } - - async init(): Promise { - const shouldClear = shouldStorageClear( - this.environment.getEnvironment().oAuthConfig.clientId, - oAuthStorage, - ); - if (shouldClear) clearOAuthStorage(oAuthStorage); - - this.oAuthService.configure(this.oAuthConfig); - - this.oAuthService.events - .pipe(filter(event => event.type === 'token_refresh_error')) - .subscribe(() => this.navigateToLogin()); - - return this.oAuthService - .loadDiscoveryDocument() - .then(() => { - if (this.oAuthService.hasValidAccessToken() || !this.oAuthService.getRefreshToken()) { - return Promise.resolve(); - } - - return this.refreshToken(); - }) - .catch(this.catchError); - } - - protected refreshToken() { - return this.oAuthService.refreshToken().catch(() => clearOAuthStorage()); - } - - protected listenToOauthErrors() { - this.oAuthService.events - .pipe( - filter(event => event instanceof OAuthErrorEvent), - tap(() => clearOAuthStorage()), - switchMap(() => this.configState.refreshAppState()), - ) - .subscribe(); - } -} - -export class AuthCodeFlowStrategy extends AuthFlowStrategy { - readonly isInternalAuth = false; - - async init() { - return super - .init() - .then(() => this.oAuthService.tryLogin().catch(noop)) - .then(() => this.oAuthService.setupAutomaticSilentRefresh({}, 'access_token')); - } - - navigateToLogin(queryParams?: Params) { - this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams)); - } - - checkIfInternalAuth(queryParams?: Params) { - this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams)); - return false; - } - - logout(queryParams?: Params) { - return from(this.oAuthService.revokeTokenAndLogout(this.getCultureParams(queryParams))); - } - - login(queryParams?: Params) { - this.oAuthService.initCodeFlow('', this.getCultureParams(queryParams)); - return of(null); - } - - private getCultureParams(queryParams?: Params) { - const lang = this.sessionState.getLanguage(); - const culture = { culture: lang, 'ui-culture': lang }; - return { ...(lang && culture), ...queryParams }; - } -} - -export class AuthPasswordFlowStrategy extends AuthFlowStrategy { - readonly isInternalAuth = true; - private cookieKey = 'rememberMe'; - private storageKey = 'passwordFlow'; - - private listenToTokenExpiration() { - this.oAuthService.events - .pipe( - filter( - event => - event instanceof OAuthInfoEvent && - event.type === 'token_expires' && - event.info === 'access_token', - ), - ) - .subscribe(() => { - if (this.oAuthService.getRefreshToken()) { - this.refreshToken(); - } else { - this.oAuthService.logOut(); - removeRememberMe(); - this.configState.refreshAppState().subscribe(); - } - }); - } - - async init() { - if (!getCookieValueByName(this.cookieKey) && localStorage.getItem(this.storageKey)) { - this.oAuthService.logOut(); - } - - return super.init().then(() => this.listenToTokenExpiration()); - } - - navigateToLogin(queryParams?: Params) { - const router = this.injector.get(Router); - router.navigate(['/account/login'], { queryParams }); - } - - checkIfInternalAuth() { - return true; - } - - login(params: LoginParams): Observable { - const tenant = this.sessionState.getTenant(); - - return from( - this.oAuthService.fetchTokenUsingPasswordFlow( - params.username, - params.password, - new HttpHeaders({ ...(tenant && tenant.id && { [this.tenantKey]: tenant.id }) }), - ), - ).pipe(this.pipeToLogin(params)); - } - - pipeToLogin(params: Pick) { - const router = this.injector.get(Router); - - return pipe( - switchMap(() => this.configState.refreshAppState()), - tap(() => { - setRememberMe(params.rememberMe); - if (params.redirectUrl) router.navigate([params.redirectUrl]); - }), - ); - } - - logout(queryParams?: Params) { - const router = this.injector.get(Router); - - return from(this.oAuthService.revokeTokenAndLogout(queryParams)).pipe( - switchMap(() => this.configState.refreshAppState()), - tap(() => { - router.navigateByUrl('/'); - removeRememberMe(); - }), - ); - } - - protected refreshToken() { - return this.oAuthService.refreshToken().catch(() => { - clearOAuthStorage(); - removeRememberMe(); - }); - } -} - -export const AUTH_FLOW_STRATEGY = { - Code(injector: Injector) { - return new AuthCodeFlowStrategy(injector); - }, - Password(injector: Injector) { - return new AuthPasswordFlowStrategy(injector); - }, -}; - -export function clearOAuthStorage(storage: OAuthStorage = oAuthStorage) { - const keys = [ - 'access_token', - 'id_token', - 'refresh_token', - 'nonce', - 'PKCE_verifier', - 'expires_at', - 'id_token_claims_obj', - 'id_token_expires_at', - 'id_token_stored_at', - 'access_token_stored_at', - 'granted_scopes', - 'session_state', - ]; - - keys.forEach(key => storage.removeItem(key)); -} - -function shouldStorageClear(clientId: string, storage: OAuthStorage): boolean { - const key = 'abpOAuthClientId'; - if (!storage.getItem(key)) { - storage.setItem(key, clientId); - return false; - } - - const shouldClear = storage.getItem(key) !== clientId; - if (shouldClear) storage.setItem(key, clientId); - return shouldClear; -} - -function getCookieValueByName(name: string) { - const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); - return match ? match[2] : ''; -} diff --git a/npm/ng-packs/packages/core/src/lib/utils/index.ts b/npm/ng-packs/packages/core/src/lib/utils/index.ts index 56378f664f..a50b6ef731 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/index.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/index.ts @@ -1,5 +1,4 @@ export * from './array-utils'; -export * from './auth-utils'; export * from './common-utils'; export * from './date-utils'; export * from './environment-utils'; diff --git a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts index 9c14d14b6d..bc4d11d977 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts +++ b/npm/ng-packs/packages/core/src/lib/utils/initial-utils.ts @@ -1,16 +1,13 @@ import { registerLocaleData } from '@angular/common'; import { Injector } from '@angular/core'; -import { OAuthService } from 'angular-oauth2-oidc'; import { tap, catchError } from 'rxjs/operators'; -import { throwError } from 'rxjs'; +import { lastValueFrom, throwError } from 'rxjs'; import { ABP } from '../models/common'; import { Environment } from '../models/environment'; import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; -import { AuthService } from '../services/auth.service'; import { ConfigStateService } from '../services/config-state.service'; import { EnvironmentService } from '../services/environment.service'; import { SessionStateService } from '../services/session-state.service'; -import { clearOAuthStorage } from '../strategies/auth-flow.strategy'; import { CORE_OPTIONS } from '../tokens/options.token'; import { APP_INIT_ERROR_HANDLERS } from '../tokens/app-config.token'; import { getRemoteEnv } from './environment-utils'; @@ -25,41 +22,29 @@ export function getInitialData(injector: Injector) { environmentService.setState(options.environment as Environment); await getRemoteEnv(injector, options.environment); await parseTenantFromUrl(injector); - await injector.get(AuthService).init(); if (options.skipGetAppConfiguration) return; - return configState - .refreshAppState() - .pipe( - tap(() => checkAccessToken(injector)), - tap(() => { - const currentTenant = configState.getOne('currentTenant') as CurrentTenantDto; - injector.get(SessionStateService).setTenant(currentTenant); - }), - catchError(error => { - const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS, null); - if (appInitErrorHandlers && appInitErrorHandlers.length) { - appInitErrorHandlers.forEach(func => func(error)); - } + const result$ = configState.refreshAppState().pipe( + tap(() => { + const currentTenant = configState.getOne('currentTenant') as CurrentTenantDto; + injector.get(SessionStateService).setTenant(currentTenant); + }), + catchError(error => { + const appInitErrorHandlers = injector.get(APP_INIT_ERROR_HANDLERS, null); + if (appInitErrorHandlers && appInitErrorHandlers.length) { + appInitErrorHandlers.forEach(func => func(error)); + } - return throwError(error); - }), - ) - .toPromise(); + return throwError(error); + }), + ); + await lastValueFrom(result$); }; return fn; } -export function checkAccessToken(injector: Injector) { - const configState = injector.get(ConfigStateService); - const oAuth = injector.get(OAuthService); - if (oAuth.hasValidAccessToken() && !configState.getDeep('currentUser.id')) { - clearOAuthStorage(); - } -} - export function localeInitializer(injector: Injector) { const fn = () => { const sessionState = injector.get(SessionStateService); diff --git a/npm/ng-packs/packages/core/src/public-api.ts b/npm/ng-packs/packages/core/src/public-api.ts index a5cbd78e4e..20dec1308b 100644 --- a/npm/ng-packs/packages/core/src/public-api.ts +++ b/npm/ng-packs/packages/core/src/public-api.ts @@ -6,7 +6,6 @@ export * from './lib/core.module'; export * from './lib/directives'; export * from './lib/enums'; export * from './lib/guards'; -export * from './lib/interceptors'; export * from './lib/localization.module'; export * from './lib/models'; export * from './lib/pipes'; diff --git a/npm/ng-packs/packages/oauth/ng-package.json b/npm/ng-packs/packages/oauth/ng-package.json index 2e78d8fbe5..f9cb029dc0 100644 --- a/npm/ng-packs/packages/oauth/ng-package.json +++ b/npm/ng-packs/packages/oauth/ng-package.json @@ -1,12 +1,14 @@ { "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", - "dest": "../../dist/packages/core", + "dest": "../../dist/packages/oauth", "lib": { "entryFile": "src/public-api.ts" }, "allowedNonPeerDependencies": [ "@abp/utils", "@abp/ng.core", - "angular-oauth2-oidc" + "angular-oauth2-oidc", + "just-clone", + "just-compare" ] } diff --git a/npm/ng-packs/packages/oauth/package.json b/npm/ng-packs/packages/oauth/package.json index 9f127e7701..e945d95272 100644 --- a/npm/ng-packs/packages/oauth/package.json +++ b/npm/ng-packs/packages/oauth/package.json @@ -1,5 +1,5 @@ { - "name": "@abp/ng.core", + "name": "@abp/ng.oauth", "version": "7.0.0-rc.4", "homepage": "https://abp.io", "repository": { @@ -12,7 +12,6 @@ "angular-oauth2-oidc": "^15.0.1", "just-clone": "^6.1.1", "just-compare": "^1.4.0", - "ts-toolbelt": "6.15.4", "tslib": "^2.0.0" }, "publishConfig": { diff --git a/npm/ng-packs/packages/oauth/src/lib/guards/index.ts b/npm/ng-packs/packages/oauth/src/lib/guards/index.ts new file mode 100644 index 0000000000..b746a80626 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/guards/index.ts @@ -0,0 +1 @@ +export * from './oauth.guard'; diff --git a/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts similarity index 82% rename from npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts rename to npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts index f1e73ab805..357e861ba0 100644 --- a/npm/ng-packs/packages/core/src/lib/guards/auth.guard.ts +++ b/npm/ng-packs/packages/oauth/src/lib/guards/oauth.guard.ts @@ -2,12 +2,12 @@ import { Injectable } from '@angular/core'; import { CanActivate, UrlTree } from '@angular/router'; import { OAuthService } from 'angular-oauth2-oidc'; import { Observable } from 'rxjs'; -import { AuthService } from '../services/auth.service'; +import { AuthService, IAuthGuard } from '@abp/ng.core'; @Injectable({ providedIn: 'root', }) -export class AuthGuard implements CanActivate { +export class AbpOAuthGuard implements CanActivate, IAuthGuard { constructor(private oauthService: OAuthService, private authService: AuthService) {} canActivate(): Observable | boolean | UrlTree { diff --git a/npm/ng-packs/packages/oauth/src/lib/handlers/index.ts b/npm/ng-packs/packages/oauth/src/lib/handlers/index.ts new file mode 100644 index 0000000000..0faec9db66 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/handlers/index.ts @@ -0,0 +1 @@ +export * from './oauth-configuration.handler'; diff --git a/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts b/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts similarity index 83% rename from npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts rename to npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts index f82e382fe7..7e4cce28e4 100644 --- a/npm/ng-packs/packages/core/src/lib/handlers/oauth-configuration.handler.ts +++ b/npm/ng-packs/packages/oauth/src/lib/handlers/oauth-configuration.handler.ts @@ -2,9 +2,7 @@ import { Inject, Injectable } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import compare from 'just-compare'; import { filter, map } from 'rxjs/operators'; -import { ABP } from '../models/common'; -import { EnvironmentService } from '../services/environment.service'; -import { CORE_OPTIONS } from '../tokens/options.token'; +import { ABP, EnvironmentService, CORE_OPTIONS } from '@abp/ng.core'; @Injectable({ providedIn: 'root', diff --git a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts similarity index 88% rename from npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts rename to npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts index d3dbe19ec0..91666b12a9 100644 --- a/npm/ng-packs/packages/core/src/lib/interceptors/api.interceptor.ts +++ b/npm/ng-packs/packages/oauth/src/lib/interceptors/api.interceptor.ts @@ -2,9 +2,7 @@ import { HttpHandler, HttpHeaders, HttpInterceptor, HttpRequest } from '@angular import { Inject, Injectable } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; import { finalize } from 'rxjs/operators'; -import { SessionStateService } from '../services/session-state.service'; -import { HttpWaitService } from '../services/http-wait.service'; -import { TENANT_KEY } from '../tokens/tenant-key.token'; +import { SessionStateService, HttpWaitService, TENANT_KEY } from '@abp/ng.core'; @Injectable({ providedIn: 'root', diff --git a/npm/ng-packs/packages/core/src/lib/interceptors/index.ts b/npm/ng-packs/packages/oauth/src/lib/interceptors/index.ts similarity index 100% rename from npm/ng-packs/packages/core/src/lib/interceptors/index.ts rename to npm/ng-packs/packages/oauth/src/lib/interceptors/index.ts diff --git a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts index 471e4e3d78..ea2874c2f9 100644 --- a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts +++ b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts @@ -1,20 +1,52 @@ -import { ModuleWithProviders, NgModule } from '@angular/core'; +import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { OAuthModule as OAuthModule2, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; -import { TimeoutLimitedOAuthService } from '@abp/ng.core'; +import { OAuthModule, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; +import { AuthGuard, AuthService, noop } from '@abp/ng.core'; import { storageFactory } from './utils/storage.factory'; +import { AbpOAuthService, TimeoutLimitedOAuthService } from './services'; +import { OAuthConfigurationHandler } from './handlers/oauth-configuration.handler'; +import { initFactory } from './utils/init-factory'; +import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import { ApiInterceptor } from './interceptors/api.interceptor'; +import { AbpOAuthGuard } from './guards/oauth.guard'; @NgModule({ - imports: [CommonModule, OAuthModule2], + imports: [CommonModule, OAuthModule], }) -export class OAuthModule { - static forRoot(): ModuleWithProviders { +export class AbpOAuthModule { + static forRoot(): ModuleWithProviders { return { - ngModule: OAuthModule, + ngModule: AbpOAuthModule, providers: [ - OAuthModule2.forRoot().providers, + { + provide: AuthService, + useClass: AbpOAuthService, + }, + { + provide: AuthGuard, + useClass: AbpOAuthGuard, + }, + { + provide: HTTP_INTERCEPTORS, + useExisting: ApiInterceptor, + multi: true, + }, + { + provide: APP_INITIALIZER, + multi: true, + deps: [OAuthConfigurationHandler], + useFactory: noop, + }, + { + provide: APP_INITIALIZER, + multi: true, + deps: [Injector], + useFactory: initFactory, + }, + + OAuthModule.forRoot().providers, { provide: OAuthStorage, useFactory: storageFactory }, - { provide: OAuthService, useClass: TimeoutLimitedOAuthService }, + // {provide: OAuthService, useClass: TimeoutLimitedOAuthService} ], }; } diff --git a/npm/ng-packs/packages/oauth/src/lib/services/index.ts b/npm/ng-packs/packages/oauth/src/lib/services/index.ts new file mode 100644 index 0000000000..a0e99cbcae --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/services/index.ts @@ -0,0 +1,2 @@ +export * from './oauth.service'; +export * from './timeout-limited-oauth.service'; diff --git a/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts new file mode 100644 index 0000000000..9588fef305 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/services/oauth.service.ts @@ -0,0 +1,57 @@ +import { Injectable, Injector } from '@angular/core'; +import { Params } from '@angular/router'; +import { from, Observable, lastValueFrom } from 'rxjs'; +import { filter, map, switchMap, take, tap } from 'rxjs/operators'; +import { IAuthService, LoginParams } from '@abp/ng.core'; +import { AuthFlowStrategy } from '../strategies'; +import { EnvironmentService } from '@abp/ng.core'; +import { AUTH_FLOW_STRATEGY } from '../tokens/ auth-flow-strategy'; +import { OAuthService } from 'angular-oauth2-oidc'; + +@Injectable({ + providedIn: 'root', +}) +export class AbpOAuthService implements IAuthService { + private strategy: AuthFlowStrategy; + + get isInternalAuth() { + return this.strategy.isInternalAuth; + } + + constructor(protected injector: Injector, private oAuthService: OAuthService) {} + + async init() { + const environmentService = this.injector.get(EnvironmentService); + + const result$ = environmentService.getEnvironment$().pipe( + map(env => env?.oAuthConfig), + filter(oAuthConfig => !!oAuthConfig), + tap(oAuthConfig => { + this.strategy = + oAuthConfig.responseType === 'code' + ? AUTH_FLOW_STRATEGY.Code(this.injector) + : AUTH_FLOW_STRATEGY.Password(this.injector); + }), + switchMap(() => from(this.strategy.init())), + take(1), + ); + + return await lastValueFrom(result$); + } + + logout(queryParams?: Params): Observable { + return this.strategy.logout(queryParams); + } + + navigateToLogin(queryParams?: Params) { + this.strategy.navigateToLogin(queryParams); + } + + login(params: LoginParams) { + return this.strategy.login(params); + } + + get isAuthenticated(): boolean { + return this.oAuthService.hasValidAccessToken(); + } +} diff --git a/npm/ng-packs/packages/core/src/lib/services/timeout-limited-oauth.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts similarity index 70% rename from npm/ng-packs/packages/core/src/lib/services/timeout-limited-oauth.service.ts rename to npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts index bdce294968..8b9d4ef393 100644 --- a/npm/ng-packs/packages/core/src/lib/services/timeout-limited-oauth.service.ts +++ b/npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts @@ -1,6 +1,7 @@ -import { Injectable, NgZone, Optional } from '@angular/core'; +import { Injectable } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; +/** * @deprecated No need to override official service. It should be fixed in 15 or never version of angular-oauth2-oidc*/ @Injectable() export class TimeoutLimitedOAuthService extends OAuthService { protected override calcTimeout(storedAt: number, expiration: number): number { diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts index f74a223fbd..3b5c89d4ac 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-flow-strategy.ts @@ -1,18 +1,23 @@ import { Injector } from '@angular/core'; import { Params } from '@angular/router'; -import { AuthConfig, OAuthErrorEvent, OAuthService, OAuthStorage } from 'angular-oauth2-oidc'; +import { + AuthConfig, + OAuthErrorEvent, + OAuthService as OAuthService2, + OAuthStorage, +} from 'angular-oauth2-oidc'; import { Observable, of } from 'rxjs'; import { filter, switchMap, tap } from 'rxjs/operators'; -import { LoginParams } from '../models/auth'; import { + LoginParams, ConfigStateService, EnvironmentService, HttpErrorReporterService, SessionStateService, TENANT_KEY, } from '@abp/ng.core'; -import { oAuthStorage } from './oauth-storage'; -import { clearOAuthStorage } from './clear-o-auth-storage'; +import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; +import { oAuthStorage } from '../utils/oauth-storage'; export abstract class AuthFlowStrategy { abstract readonly isInternalAuth: boolean; @@ -20,7 +25,7 @@ export abstract class AuthFlowStrategy { protected httpErrorReporter: HttpErrorReporterService; protected environment: EnvironmentService; protected configState: ConfigStateService; - protected oAuthService: OAuthService; + protected oAuthService: OAuthService2; protected oAuthConfig: AuthConfig; protected sessionState: SessionStateService; protected tenantKey: string; @@ -42,7 +47,7 @@ export abstract class AuthFlowStrategy { this.httpErrorReporter = injector.get(HttpErrorReporterService); this.environment = injector.get(EnvironmentService); this.configState = injector.get(ConfigStateService); - this.oAuthService = injector.get(OAuthService); + this.oAuthService = injector.get(OAuthService2); this.sessionState = injector.get(SessionStateService); this.oAuthConfig = this.environment.getEnvironment().oAuthConfig; this.tenantKey = injector.get(TENANT_KEY); diff --git a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts index 703042956d..ff795fc38d 100644 --- a/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts +++ b/npm/ng-packs/packages/oauth/src/lib/strategies/auth-password-flow-strategy.ts @@ -4,9 +4,9 @@ import { Params, Router } from '@angular/router'; import { from, Observable, pipe } from 'rxjs'; import { HttpHeaders } from '@angular/common/http'; import { AuthFlowStrategy } from './auth-flow-strategy'; -import { removeRememberMe, setRememberMe } from './auth-utils'; -import { LoginParams } from '../models'; -import { clearOAuthStorage } from './clear-o-auth-storage'; +import { removeRememberMe, setRememberMe } from '../utils/auth-utils'; +import { LoginParams } from '@abp/ng.core'; +import { clearOAuthStorage } from '../utils/clear-o-auth-storage'; function getCookieValueByName(name: string) { const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)')); diff --git a/npm/ng-packs/packages/oauth/src/lib/tests/sample.spec.ts b/npm/ng-packs/packages/oauth/src/lib/tests/sample.spec.ts new file mode 100644 index 0000000000..83925bb9c0 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/tests/sample.spec.ts @@ -0,0 +1,5 @@ +describe('Test', () => { + it('should be passed', () => { + expect(true).toBe(true); + }); +}); diff --git a/npm/ng-packs/packages/oauth/src/lib/tokens/ auth-flow-strategy.ts b/npm/ng-packs/packages/oauth/src/lib/tokens/ auth-flow-strategy.ts new file mode 100644 index 0000000000..a2c8aa1624 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/tokens/ auth-flow-strategy.ts @@ -0,0 +1,12 @@ +import { Injector } from '@angular/core'; +import { AuthCodeFlowStrategy } from '../strategies/auth-code-flow-strategy'; +import { AuthPasswordFlowStrategy } from '../strategies/auth-password-flow-strategy'; + +export const AUTH_FLOW_STRATEGY = { + Code(injector: Injector) { + return new AuthCodeFlowStrategy(injector); + }, + Password(injector: Injector) { + return new AuthPasswordFlowStrategy(injector); + }, +}; diff --git a/npm/ng-packs/packages/oauth/src/lib/tokens/index.ts b/npm/ng-packs/packages/oauth/src/lib/tokens/index.ts new file mode 100644 index 0000000000..2ee0bf7fde --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/tokens/index.ts @@ -0,0 +1 @@ +export * from './ auth-flow-strategy'; diff --git a/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts similarity index 93% rename from npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts rename to npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index 10fe1e1177..2ac24abf22 100644 --- a/npm/ng-packs/packages/core/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -3,8 +3,7 @@ import { Router } from '@angular/router'; import { OAuthStorage, TokenResponse } from 'angular-oauth2-oidc'; import { pipe } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; -import { LoginParams } from '../models/auth'; -import { ConfigStateService } from '../services/config-state.service'; +import { ConfigStateService, LoginParams } from '@abp/ng.core'; const cookieKey = 'rememberMe'; const storageKey = 'passwordFlow'; diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/clear-o-auth-storage.ts b/npm/ng-packs/packages/oauth/src/lib/utils/clear-o-auth-storage.ts new file mode 100644 index 0000000000..d9b662c833 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/clear-o-auth-storage.ts @@ -0,0 +1,21 @@ +import { OAuthStorage } from 'angular-oauth2-oidc'; +import { oAuthStorage } from './oauth-storage'; + +export function clearOAuthStorage(storage: OAuthStorage = oAuthStorage) { + const keys = [ + 'access_token', + 'id_token', + 'refresh_token', + 'nonce', + 'PKCE_verifier', + 'expires_at', + 'id_token_claims_obj', + 'id_token_expires_at', + 'id_token_stored_at', + 'access_token_stored_at', + 'granted_scopes', + 'session_state', + ]; + + keys.forEach(key => storage.removeItem(key)); +} diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/index.ts b/npm/ng-packs/packages/oauth/src/lib/utils/index.ts new file mode 100644 index 0000000000..e948a3d6b7 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/index.ts @@ -0,0 +1,5 @@ +export * from './oauth-storage'; +export * from './storage.factory'; +export * from './auth-utils'; +export * from './clear-o-auth-storage'; +export * from './init-factory'; diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/init-factory.ts b/npm/ng-packs/packages/oauth/src/lib/utils/init-factory.ts new file mode 100644 index 0000000000..4395384139 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/init-factory.ts @@ -0,0 +1,31 @@ +import { ABP, AuthService, ConfigStateService, CORE_OPTIONS } from '@abp/ng.core'; +import { Injector } from '@angular/core'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { clearOAuthStorage } from './clear-o-auth-storage'; +import { lastValueFrom } from 'rxjs'; +import { tap } from 'rxjs/operators'; + +export function initFactory(injector: Injector): () => Promise { + return async () => { + const authService = injector.get(AuthService); + await authService.init(); + const configState = injector.get(ConfigStateService); + + const options = injector.get(CORE_OPTIONS) as ABP.Root; + + if (options.skipGetAppConfiguration) { + return; + } + + const result$ = configState.refreshAppState().pipe(tap(() => checkAccessToken(injector))); + await lastValueFrom(result$); + }; +} + +export function checkAccessToken(injector: Injector) { + const configState = injector.get(ConfigStateService); + const oAuth = injector.get(OAuthService); + if (oAuth.hasValidAccessToken() && !configState.getDeep('currentUser.id')) { + clearOAuthStorage(); + } +} diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/oauth-storage.ts b/npm/ng-packs/packages/oauth/src/lib/utils/oauth-storage.ts new file mode 100644 index 0000000000..9fb591e1c7 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/oauth-storage.ts @@ -0,0 +1 @@ +export const oAuthStorage = localStorage; diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts b/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts new file mode 100644 index 0000000000..5d76ecf244 --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts @@ -0,0 +1,6 @@ +import { OAuthStorage } from 'angular-oauth2-oidc'; +import { oAuthStorage } from './oauth-storage'; + +export function storageFactory(): OAuthStorage { + return oAuthStorage; +} diff --git a/npm/ng-packs/packages/oauth/src/public-api.ts b/npm/ng-packs/packages/oauth/src/public-api.ts index e69de29bb2..d6154d0883 100644 --- a/npm/ng-packs/packages/oauth/src/public-api.ts +++ b/npm/ng-packs/packages/oauth/src/public-api.ts @@ -0,0 +1,8 @@ +export * from './lib/oauth.module'; +export * from './lib/utils'; +export * from './lib/tokens'; +export * from './lib/services'; +export * from './lib/strategies'; +export * from './lib/handlers'; +export * from './lib/interceptors'; +export * from './lib/guards'; diff --git a/npm/ng-packs/packages/schematics/collection.json b/npm/ng-packs/packages/schematics/collection.json new file mode 100644 index 0000000000..16f148d78a --- /dev/null +++ b/npm/ng-packs/packages/schematics/collection.json @@ -0,0 +1,40 @@ +{ + "schematics": { + "proxy-add": { + "description": "ABP Proxy Generator Add Schematics", + "factory": "./commands/proxy-add", + "schema": "./commands/proxy-add/schema.json" + }, + "proxy-index": { + "description": "ABP Proxy Generator Index Schematics", + "factory": "./commands/proxy-index", + "schema": "./commands/proxy-index/schema.json" + }, + "proxy-refresh": { + "description": "ABP Proxy Generator Refresh Schematics", + "factory": "./commands/proxy-refresh", + "schema": "./commands/proxy-refresh/schema.json" + }, + "proxy-remove": { + "description": "ABP Proxy Generator Remove Schematics", + "factory": "./commands/proxy-remove", + "schema": "./commands/proxy-remove/schema.json" + }, + "api": { + "description": "ABP API Generator Schematics", + "factory": "./commands/api", + "schema": "./commands/api/schema.json" + }, + "create-lib": { + "description": "ABP Create Library Schematics", + "factory": "./commands/create-lib", + "schema": "./commands/create-lib/schema.json" + }, + "change-theme": { + "description": "ABP Change Styles of Theme Schematics", + "factory": "./commands/change-theme", + "schema": "./commands/change-theme/schema.json" + + } + } +} diff --git a/npm/ng-packs/packages/theme-shared/ng-package.json b/npm/ng-packs/packages/theme-shared/ng-package.json index bc84e15a22..8082dca0c9 100644 --- a/npm/ng-packs/packages/theme-shared/ng-package.json +++ b/npm/ng-packs/packages/theme-shared/ng-package.json @@ -11,6 +11,7 @@ "@ngx-validate/core", "@swimlane/ngx-datatable", "bootstrap", - "@popperjs/core" + "@popperjs/core", + "@abp/ng.oauth" ] } diff --git a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts index a3db3d2017..ce5647bccd 100644 --- a/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts +++ b/npm/ng-packs/packages/theme-shared/src/lib/handlers/error.handler.ts @@ -83,6 +83,7 @@ export class ErrorHandler { protected cfRes: ComponentFactoryResolver; protected rendererFactory: RendererFactory2; protected httpErrorConfig: HttpErrorConfig; + private authService: AuthService; constructor(protected injector: Injector) { this.httpErrorReporter = injector.get(HttpErrorReporterService); @@ -91,6 +92,7 @@ export class ErrorHandler { this.cfRes = injector.get(ComponentFactoryResolver); this.rendererFactory = injector.get(RendererFactory2); this.httpErrorConfig = injector.get('HTTP_ERROR_CONFIG'); + this.authService = this.injector.get(AuthService); this.listenToRestError(); this.listenToRouterError(); @@ -284,7 +286,7 @@ export class ErrorHandler { } private navigateToLogin() { - this.injector.get(AuthService).navigateToLogin(); + this.authService.navigateToLogin(); } createErrorComponent(instance: Partial) { diff --git a/npm/ng-packs/tsconfig.base.json b/npm/ng-packs/tsconfig.base.json index e9cd6ac6b6..ac29fd53ad 100644 --- a/npm/ng-packs/tsconfig.base.json +++ b/npm/ng-packs/tsconfig.base.json @@ -43,7 +43,8 @@ "@abp/ng.theme.basic/testing": ["packages/theme-basic/testing/src/public-api.ts"], "@abp/ng.theme.shared": ["packages/theme-shared/src/public-api.ts"], "@abp/ng.theme.shared/extensions": ["packages/theme-shared/extensions/src/public-api.ts"], - "@abp/ng.theme.shared/testing": ["packages/theme-shared/testing/src/public-api.ts"] + "@abp/ng.theme.shared/testing": ["packages/theme-shared/testing/src/public-api.ts"], + "@abp/ng.oauth": ["packages/oauth/src/public-api.ts"] } }, "exclude": ["node_modules", "tmp"]