import { Injectable, inject } from '@outposts/injection-js'; import type { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import type { AuthOptions } from '../auth-options'; import { AuthStateService } from '../auth-state/auth-state.service'; import { ConfigurationService } from '../config/config.service'; import { injectAbstractType } from '../injection'; import { LoginService } from '../login/login.service'; import { AbstractRouter, type ActivatedRouteSnapshot, type RouterStateSnapshot, } from '../router'; import { AutoLoginService } from './auto-login.service'; @Injectable() export class AutoLoginPartialRoutesGuard { private readonly autoLoginService = inject(AutoLoginService); private readonly authStateService = inject(AuthStateService); private readonly loginService = inject(LoginService); private readonly configurationService = inject(ConfigurationService); private readonly router = injectAbstractType(AbstractRouter); canLoad(): Observable { const url = this.router .getCurrentNavigation() ?.extractedUrl.toString() .substring(1) ?? ''; return checkAuth( url, this.configurationService, this.authStateService, this.autoLoginService, this.loginService ); } canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable { const authOptions: AuthOptions | undefined = route?.data ? { customParams: route.data } : undefined; return checkAuth( state.url, this.configurationService, this.authStateService, this.autoLoginService, this.loginService, authOptions ); } canActivateChild( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable { const authOptions: AuthOptions | undefined = route?.data ? { customParams: route.data } : undefined; return checkAuth( state.url, this.configurationService, this.authStateService, this.autoLoginService, this.loginService, authOptions ); } } export function autoLoginPartialRoutesGuard( route?: ActivatedRouteSnapshot, _state?: RouterStateSnapshot, configId?: string ): Observable { const configurationService = inject(ConfigurationService); const authStateService = inject(AuthStateService); const loginService = inject(LoginService); const autoLoginService = inject(AutoLoginService); const router = injectAbstractType(AbstractRouter); const authOptions: AuthOptions | undefined = route?.data ? { customParams: route.data } : undefined; const url = router.getCurrentNavigation()?.extractedUrl.toString().substring(1) ?? ''; return checkAuth( url, configurationService, authStateService, autoLoginService, loginService, authOptions, configId ); } export function autoLoginPartialRoutesGuardWithConfig( configId: string ): ( route?: ActivatedRouteSnapshot, state?: RouterStateSnapshot ) => Observable { return (route?: ActivatedRouteSnapshot, state?: RouterStateSnapshot) => autoLoginPartialRoutesGuard(route, state, configId); } function checkAuth( url: string, configurationService: ConfigurationService, authStateService: AuthStateService, autoLoginService: AutoLoginService, loginService: LoginService, authOptions?: AuthOptions, configId?: string ): Observable { return configurationService.getOpenIDConfiguration(configId).pipe( map((configuration) => { const isAuthenticated = authStateService.areAuthStorageTokensValid(configuration); if (isAuthenticated) { autoLoginService.checkSavedRedirectRouteAndNavigate(configuration); } if (!isAuthenticated) { autoLoginService.saveRedirectRoute(configuration, url); if (authOptions) { loginService.login(configuration, authOptions); } else { loginService.login(configuration); } } return isAuthenticated; }) ); }