diff --git a/npm/ng-packs/packages/account/src/lib/services/authentication.service.ts b/npm/ng-packs/packages/account/src/lib/services/authentication.service.ts index 8348d07d51..beca24c2ef 100644 --- a/npm/ng-packs/packages/account/src/lib/services/authentication.service.ts +++ b/npm/ng-packs/packages/account/src/lib/services/authentication.service.ts @@ -48,7 +48,7 @@ export class AuthenticationService { this.router.navigate([redirectUrl]); - const strategy = this.authService.activeAuthFlowStrategy; + const strategy = this.authService.strategy; if (strategy instanceof AuthPasswordFlowStrategy) strategy.setRememberMe(remember); }), ); 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 36d59c929b..9fba623b39 100644 --- a/npm/ng-packs/packages/core/src/lib/core.module.ts +++ b/npm/ng-packs/packages/core/src/lib/core.module.ts @@ -1,5 +1,5 @@ import { CommonModule } from '@angular/common'; -import { HTTP_INTERCEPTORS, HttpClientModule, HttpClientXsrfModule } from '@angular/common/http'; +import { HttpClientModule, HttpClientXsrfModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { APP_INITIALIZER, Injector, ModuleWithProviders, NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; @@ -26,10 +26,11 @@ import { ABP } from './models/common'; import { LocalizationPipe } from './pipes/localization.pipe'; import { SortPipe } from './pipes/sort.pipe'; import { LocaleProvider } from './providers/locale.provider'; +import { AuthFlowInitializerService } from './services/auth-flow-initializer.service'; import { LocalizationService } from './services/localization.service'; import { ProfileState } from './states/profile.state'; import { oAuthStorage } from './strategies/auth-flow.strategy'; -import { CORE_OPTIONS, coreOptionsFactory } from './tokens/options.token'; +import { coreOptionsFactory, CORE_OPTIONS } from './tokens/options.token'; import { noop } from './utils/common-utils'; import './utils/date-extensions'; import { getInitialData, localeInitializer } from './utils/initial-utils'; @@ -178,6 +179,7 @@ export class CoreModule { useFactory: noop, }, { provide: OAuthStorage, useFactory: storageFactory }, + AuthFlowInitializerService, ], }; } diff --git a/npm/ng-packs/packages/core/src/lib/services/auth-flow-initializer.service.ts b/npm/ng-packs/packages/core/src/lib/services/auth-flow-initializer.service.ts new file mode 100644 index 0000000000..2b8609c85e --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/services/auth-flow-initializer.service.ts @@ -0,0 +1,33 @@ +import { Injectable, Injector } from '@angular/core'; +import { from } from 'rxjs'; +import { filter, map, switchMap, take, tap } from 'rxjs/operators'; +import { AUTH_FLOW_STRATEGY } from '../strategies/auth-flow.strategy'; +import { AuthService } from './auth.service'; +import { EnvironmentService } from './environment.service'; + +@Injectable() +export class AuthFlowInitializerService { + constructor( + protected injector: Injector, + protected environmentService: EnvironmentService, + protected authService: AuthService, + ) {} + + init(): Promise { + return this.environmentService + .getEnvironment$() + .pipe( + map(env => env?.oAuthConfig), + filter(oAuthConfig => !!oAuthConfig), + tap(oAuthConfig => { + this.authService.strategy = + oAuthConfig.responseType === 'code' + ? AUTH_FLOW_STRATEGY.Code(this.injector) + : AUTH_FLOW_STRATEGY.Password(this.injector); + }), + switchMap(() => from(this.authService.init())), + take(1), + ) + .toPromise(); + } +} 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 index 47ccc01184..3a24bd1538 100644 --- a/npm/ng-packs/packages/core/src/lib/services/auth.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/auth.service.ts @@ -12,38 +12,19 @@ import { EnvironmentService } from './environment.service'; providedIn: 'root', }) export class AuthService { - private flow: string; - private strategy: AuthFlowStrategy; + private _strategy: AuthFlowStrategy; - get isInternalAuth() { - return this.strategy.isInternalAuth; - } - - get activeAuthFlowStrategy() { - return this.strategy as AuthCodeFlowStrategy | AuthPasswordFlowStrategy; + set strategy(strategy: AuthFlowStrategy) { + if (this.strategy) this.strategy.destroy(); + this._strategy = strategy; } - constructor(private environment: EnvironmentService, private injector: Injector) { - this.setStrategy(); - this.listenToSetEnvironment(); + get strategy() { + return this._strategy; } - private setStrategy = () => { - const flow = - this.environment.getEnvironment().oAuthConfig.responseType === 'code' ? 'code' : 'password'; - if (this.flow === flow) return; - - if (this.strategy) this.strategy.destroy(); - - this.flow = flow; - this.strategy = - flow === 'code' - ? AUTH_FLOW_STRATEGY.Code(this.injector) - : AUTH_FLOW_STRATEGY.Password(this.injector); - }; - - private listenToSetEnvironment() { - this.environment.createOnUpdateStream(state => state.oAuthConfig).subscribe(this.setStrategy); + get isInternalAuth() { + return this.strategy.isInternalAuth; } async init() { 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 55000edde1..093c4dece9 100644 --- a/npm/ng-packs/packages/core/src/lib/services/index.ts +++ b/npm/ng-packs/packages/core/src/lib/services/index.ts @@ -1,5 +1,6 @@ export * from './application-configuration.service'; export * from './auth.service'; +export * from './auth-flow-initializer.service'; export * from './config-state.service'; export * from './content-projection.service'; export * from './dom-insertion.service'; 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 d37200c9c8..c1bfdab95d 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,14 +1,12 @@ import { registerLocaleData } from '@angular/common'; import { Injector } from '@angular/core'; -import { Store } from '@ngxs/store'; import { OAuthService } from 'angular-oauth2-oidc'; import { tap } from 'rxjs/operators'; -import { ApplicationConfiguration } from '../models/application-configuration'; import { ABP } from '../models/common'; import { Environment } from '../models/environment'; import { AbpApplicationConfigurationService } from '../proxy/volo/abp/asp-net-core/mvc/application-configurations/abp-application-configuration.service'; import { CurrentTenantDto } from '../proxy/volo/abp/asp-net-core/mvc/multi-tenancy/models'; -import { AuthService } from '../services/auth.service'; +import { AuthFlowInitializerService } from '../services/auth-flow-initializer.service'; import { ConfigStateService } from '../services/config-state.service'; import { EnvironmentService } from '../services/environment.service'; import { SessionStateService } from '../services/session-state.service'; @@ -27,7 +25,7 @@ export function getInitialData(injector: Injector) { environmentService.setState(options.environment as Environment); await getRemoteEnv(injector, options.environment); await parseTenantFromUrl(injector); - await injector.get(AuthService).init(); + await injector.get(AuthFlowInitializerService).init(); if (options.skipGetAppConfiguration) return;