import { Injectable } from '@angular/core'; import { CanActivate, CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router'; import { Observable, of } from 'rxjs'; import { map, take, tap } from 'rxjs/operators'; import { AuthService } from '../services/auth.service'; @Injectable({ providedIn: 'root' }) export class AuthGuard implements CanActivate, CanActivateChild { constructor( private authService: AuthService, private router: Router ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable { return this.checkAuth(route, state.url); } canActivateChild( childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable { return this.canActivate(childRoute, state); } private checkAuth(route: ActivatedRouteSnapshot, redirectUrl: string): Observable { return this.authService.isAuthenticated$.pipe( take(1), map(isAuthenticated => { if (isAuthenticated) { // Check for required scopes if specified const requiredScopes = route.data?.['requiredScopes'] as string[]; if (requiredScopes && requiredScopes.length > 0) { const hasScopes = route.data?.['requireAllScopes'] ? this.authService.hasAllScopes(requiredScopes) : this.authService.hasAnyScope(requiredScopes); if (!hasScopes) { this.handleUnauthorized(route.data?.['unauthorizedRedirect']); return false; } } return true; } else { this.handleUnauthenticated(redirectUrl, route.data?.['loginRedirect']); return false; } }) ); } private handleUnauthenticated(redirectUrl: string, customLoginPath?: string): void { const loginPath = customLoginPath || '/login'; this.router.navigate([loginPath], { queryParams: { returnUrl: redirectUrl } }); } private handleUnauthorized(customUnauthorizedPath?: string): void { const unauthorizedPath = customUnauthorizedPath || '/unauthorized'; this.router.navigate([unauthorizedPath]); } }