import { Injectable } from '@angular/core'; import { Router } from '@angular/router'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { filter, map, switchMap, tap } from 'rxjs/operators'; import * as actions from './oidc.actions'; import * as userActions from './user.actions'; import { environment } from 'projects/core/src//environment'; import { MwAuthService } from '../services/auth.service'; import { MwCompanyGuard } from '../services/guards/company.guard'; export const OIDC_STORAGE_KEY = 'mw-redirect'; @Injectable() export class OIDCEffects { checkAuth$ = createEffect(() => this.actions$.pipe( ofType(actions.checkAuth), switchMap(() => this.authService.checkAuth()), map(({ isAuthenticated }) => isAuthenticated ? actions.authorizationSucceeded() : actions.authorize() ) ) ); authorize$ = createEffect( () => this.actions$.pipe( ofType(actions.authorize), map(() => (this.router as any).location._platformLocation._doc.URL), filter((url) => { const skipRoutes = ['unauthorized', 'autologin'].concat( environment.skipAuthRoutes ); const skip = skipRoutes.some((skipRoute) => url.includes(skipRoute)); return !skip; }), tap((url) => { OIDCEffects.saveStoredRedirectRoute(url.split('#')[1] || ''); this.authService.authorize(); }) ), { dispatch: false } ); configLoaded$ = createEffect(() => this.actions$.pipe( ofType(actions.configLoaded), map(() => actions.checkAuth()) ) ); setUserProfile$ = createEffect( () => this.actions$.pipe( ofType(userActions.setUserProfile), tap((action) => { const hasAccess = action.userApiProfile?.hasAccessToModule === true; const storedRoute = OIDCEffects.getStoredRedirectRoute(); if ( storedRoute && (hasAccess || !MwCompanyGuard.isCompanyProtectedRoute()) ) { this.deleteStoredRedirectRoute(); this.router.navigateByUrl(storedRoute); } }) ), { dispatch: false } ); authorizationSucceeded$ = createEffect(() => this.actions$.pipe( ofType(actions.authorizationSucceeded), switchMap(() => this.authService.userData$), filter((userData) => userData), switchMap((userData) => [ actions.userDataReceived({ companyId: +userData['mw-company-id'], language: userData['mw-language'], companyNotRequired: userData['mw-company-not-required'] === 'true', }), ]) ) ); logInByGuid$ = createEffect( () => this.actions$.pipe( ofType(actions.logInByGuid), tap((action) => { this.authService.authorizeByGuid(action.guid); }) ), { dispatch: false } ); constructor( private readonly actions$: Actions, private readonly authService: MwAuthService, private readonly router: Router ) {} static getStoredRedirectRoute(): string { return localStorage.getItem(OIDC_STORAGE_KEY) || ''; } static saveStoredRedirectRoute(url: string): void { localStorage.setItem(OIDC_STORAGE_KEY, url); } deleteStoredRedirectRoute(): void { localStorage.removeItem(OIDC_STORAGE_KEY); } }