diff --git a/npm/ng-packs/packages/core/src/lib/models/auth.ts b/npm/ng-packs/packages/core/src/lib/models/auth.ts index 4a1a01f357..f5d532454b 100644 --- a/npm/ng-packs/packages/core/src/lib/models/auth.ts +++ b/npm/ng-packs/packages/core/src/lib/models/auth.ts @@ -13,4 +13,5 @@ export type PipeToLoginFn = ( injector: Injector, ) => UnaryFunction; -export type SetTokenResponseToStorageFn = (injector: Injector, tokenRes: unknown) => void; +export type SetTokenResponseToStorageFn = (injector: Injector, tokenRes: T) => void; +export type CheckAuthenticationStateFn = (injector: Injector) => void; diff --git a/npm/ng-packs/packages/core/src/lib/tokens/check-authentication-state.ts b/npm/ng-packs/packages/core/src/lib/tokens/check-authentication-state.ts new file mode 100644 index 0000000000..0c68b18b52 --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/tokens/check-authentication-state.ts @@ -0,0 +1,6 @@ +import { InjectionToken } from '@angular/core'; +import { CheckAuthenticationStateFn } from '@abp/ng.core'; + +export const CHECK_AUTHENTICATION_STATE_FN_KEY = new InjectionToken( + 'CHECK_AUTHENTICATION_STATE_FN_KEY', +); diff --git a/npm/ng-packs/packages/core/src/lib/tokens/index.ts b/npm/ng-packs/packages/core/src/lib/tokens/index.ts index 45b0f9f3cd..971ac0fcbd 100644 --- a/npm/ng-packs/packages/core/src/lib/tokens/index.ts +++ b/npm/ng-packs/packages/core/src/lib/tokens/index.ts @@ -9,3 +9,4 @@ export * from './tenant-key.token'; export * from './include-localization-resources.token'; export * from './pipe-to-login.token'; export * from './set-token-response-to-storage.token'; +export * from './check-authentication-state'; 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 bc4d11d977..782af0899d 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,5 +1,5 @@ import { registerLocaleData } from '@angular/common'; -import { Injector } from '@angular/core'; +import { InjectFlags, Injector } from '@angular/core'; import { tap, catchError } from 'rxjs/operators'; import { lastValueFrom, throwError } from 'rxjs'; import { ABP } from '../models/common'; @@ -12,6 +12,9 @@ import { CORE_OPTIONS } from '../tokens/options.token'; import { APP_INIT_ERROR_HANDLERS } from '../tokens/app-config.token'; import { getRemoteEnv } from './environment-utils'; import { parseTenantFromUrl } from './multi-tenancy-utils'; +import { AuthService } from '../abstracts'; +import { CHECK_AUTHENTICATION_STATE_FN_KEY } from '../tokens/check-authentication-state'; +import { noop } from './common-utils'; export function getInitialData(injector: Injector) { const fn = async () => { @@ -22,10 +25,17 @@ export function getInitialData(injector: Injector) { environmentService.setState(options.environment as Environment); await getRemoteEnv(injector, options.environment); await parseTenantFromUrl(injector); - + const authService = injector.get(AuthService, undefined, { optional: true }); + const checkAuthenticationState = injector.get(CHECK_AUTHENTICATION_STATE_FN_KEY, noop, { + optional: true, + }); + if (authService) { + await authService.init(); + } if (options.skipGetAppConfiguration) return; const result$ = configState.refreshAppState().pipe( + tap(() => checkAuthenticationState(injector)), tap(() => { const currentTenant = configState.getOne('currentTenant') as CurrentTenantDto; injector.get(SessionStateService).setTenant(currentTenant); 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 ca9f232015..753ad815e3 100644 --- a/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts +++ b/npm/ng-packs/packages/oauth/src/lib/oauth.module.ts @@ -5,19 +5,19 @@ import { ApiInterceptor, AuthGuard, AuthService, + CHECK_AUTHENTICATION_STATE_FN_KEY, noop, PIPE_TO_LOGIN_FN_KEY, SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY, } from '@abp/ng.core'; import { storageFactory } from './utils/storage.factory'; -import { AbpOAuthService, TimeoutLimitedOAuthService } from './services'; +import { AbpOAuthService } from './services'; import { OAuthConfigurationHandler } from './handlers/oauth-configuration.handler'; -import { initFactory } from './utils/init-factory'; import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { OAuthApiInterceptor } from './interceptors/api.interceptor'; import { AbpOAuthGuard } from './guards/oauth.guard'; import { NavigateToManageProfileProvider } from './providers'; -import { pipeToLogin, setTokenResponseToStorage } from './utils'; +import { checkAccessToken, pipeToLogin, setTokenResponseToStorage } from './utils'; @NgModule({ imports: [CommonModule, OAuthModule], @@ -47,6 +47,10 @@ export class AbpOAuthModule { provide: SET_TOKEN_RESPONSE_TO_STORAGE_FN_KEY, useValue: setTokenResponseToStorage, }, + { + provide: CHECK_AUTHENTICATION_STATE_FN_KEY, + useValue: checkAccessToken, + }, { provide: HTTP_INTERCEPTORS, useExisting: ApiInterceptor, @@ -59,15 +63,8 @@ export class AbpOAuthModule { deps: [OAuthConfigurationHandler], useFactory: noop, }, - { - provide: APP_INITIALIZER, - multi: true, - deps: [Injector], - useFactory: initFactory, - }, OAuthModule.forRoot().providers, { provide: OAuthStorage, useFactory: storageFactory }, - // {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 index a0e99cbcae..ddc54916a3 100644 --- a/npm/ng-packs/packages/oauth/src/lib/services/index.ts +++ b/npm/ng-packs/packages/oauth/src/lib/services/index.ts @@ -1,2 +1 @@ export * from './oauth.service'; -export * from './timeout-limited-oauth.service'; diff --git a/npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts b/npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts deleted file mode 100644 index 8b9d4ef393..0000000000 --- a/npm/ng-packs/packages/oauth/src/lib/services/timeout-limited-oauth.service.ts +++ /dev/null @@ -1,12 +0,0 @@ -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 { - const result = super.calcTimeout(storedAt, expiration); - const MAX_TIMEOUT_DURATION = 2147483647; - return result < MAX_TIMEOUT_DURATION ? result : MAX_TIMEOUT_DURATION - 1; - } -} diff --git a/npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts b/npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts index 31fa3dfcf7..488c14113b 100644 --- a/npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts +++ b/npm/ng-packs/packages/oauth/src/lib/tests/initial-utils.spec.ts @@ -12,8 +12,8 @@ import { ApplicationConfigurationDto, } from '@abp/ng.core'; import * as clearOAuthStorageDefault from '../utils/clear-o-auth-storage'; -import { checkAccessToken, initFactory } from '../utils/init-factory'; import { of } from 'rxjs'; +import { checkAccessToken } from '../utils/check-access-token'; const environment = { oAuthConfig: { issuer: 'test' } }; @@ -69,7 +69,8 @@ describe('InitialUtils', () => { configRefreshAppStateSpy.mockReturnValue(of(appConfigRes)); - await initFactory(mockInjector)(); + // Todo: refactor it + // await initFactory(mockInjector)(); expect(configRefreshAppStateSpy).toHaveBeenCalled(); }); diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts index f620aadf77..74df5ce79b 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/auth-utils.ts @@ -29,16 +29,11 @@ export const pipeToLogin: PipeToLoginFn = function ( ); }; -export const setTokenResponseToStorage: SetTokenResponseToStorageFn = function ( +export const setTokenResponseToStorage: SetTokenResponseToStorageFn = function ( injector: Injector, - tokenRes: unknown, + tokenRes: TokenResponse, ) { - const { - access_token, - refresh_token, - scope: grantedScopes, - expires_in, - } = tokenRes as TokenResponse; + const { access_token, refresh_token, scope: grantedScopes, expires_in } = tokenRes; const storage = injector.get(OAuthStorage); storage.setItem('access_token', access_token); diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/check-access-token.ts b/npm/ng-packs/packages/oauth/src/lib/utils/check-access-token.ts new file mode 100644 index 0000000000..0e9249f05e --- /dev/null +++ b/npm/ng-packs/packages/oauth/src/lib/utils/check-access-token.ts @@ -0,0 +1,12 @@ +import { Injector } from '@angular/core'; +import { CheckAuthenticationStateFn, ConfigStateService } from '@abp/ng.core'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { clearOAuthStorage } from './clear-o-auth-storage'; + +export const checkAccessToken: CheckAuthenticationStateFn = function (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/index.ts b/npm/ng-packs/packages/oauth/src/lib/utils/index.ts index e948a3d6b7..63dfd03fe8 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/index.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/index.ts @@ -2,4 +2,4 @@ export * from './oauth-storage'; export * from './storage.factory'; export * from './auth-utils'; export * from './clear-o-auth-storage'; -export * from './init-factory'; +export * from './check-access-token'; 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 deleted file mode 100644 index 4395384139..0000000000 --- a/npm/ng-packs/packages/oauth/src/lib/utils/init-factory.ts +++ /dev/null @@ -1,31 +0,0 @@ -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(); - } -}