import {Injectable} from '@angular/core'; import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree} from '@angular/router'; import {from, isObservable, map, Observable, of, switchMap} from 'rxjs'; import {AuthService} from '@services/auth.service'; import {MatDialog} from '@angular/material/dialog'; import {LoginDialogComponent} from '@shared-components/login/login.component'; import {catchError} from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate { constructor( private authService: AuthService, private router: Router, private dialog: MatDialog ) { } canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable | Promise | boolean | UrlTree { const code = route.paramMap.get('code'); if (code) { return this.authService.login(code).pipe( switchMap(() => { const result = this.canActivateInternal(route, state); return isObservable(result) ? result : result instanceof Promise ? from(result) : of(result); }), catchError(() => of(this.router.createUrlTree(['/']))) ); } return this.canActivateInternal(route, state); } private canActivateInternal(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | boolean | UrlTree { if (!this.authService.isAuthenticated$()) { this.router.createUrlTree(['/']); const dialogRef = this.dialog.open(LoginDialogComponent, { width: '400px', }) return dialogRef.afterClosed().pipe( map(result => { if (result) { return this.router.createUrlTree([state.url]); } return this.router.createUrlTree(['/']); }) ); } const requiredAuthorizations = route.data['requiredAuthorizations'] as string[]; if (!requiredAuthorizations || requiredAuthorizations.length === 0) { return true; } const userAuthorizations = this.authService.getUserAuthorizations(); const hasAccess = requiredAuthorizations.some(auth => userAuthorizations.includes(auth)); if (!hasAccess) { return this.router.createUrlTree(['/']); } return true; } }