import { IFASAdminConfigInitializer } from '../../shared/models/fas-admin-models'; import { CanActivate, ActivatedRouteSnapshot, Router } from '@angular/router'; import { FAS_LIB_CONFIG } from '../../shared/tokens/fas-lib-config.token'; import { Injectable, Inject } from '@angular/core'; import jwtDecode from 'jwt-decode'; /** * FasAccessGuard is an Angular route guard that ensures users can only * access routes they are authorized to based on their role. * * Configuration for access rules is provided via FAS_LIB_CONFIG, which * must include `accessRules` defining allowed routes per role. * * Usage: * - Ensure that `accessRules` is correctly set in the configuration object. * - Token must be stored in `localStorage` under the key `authToken`. */ @Injectable({ providedIn: 'root', }) export class FasAccessGuard implements CanActivate { constructor( private router: Router, @Inject(FAS_LIB_CONFIG) private config: IFASAdminConfigInitializer ) {} /** * Determines whether the current user can activate a route based on * their role and the configured access rules. * * @param route The activated route snapshot * @returns `true` if access is allowed, otherwise `false` */ canActivate(route: ActivatedRouteSnapshot): boolean { // Retrieve the auth token from localStorage const token = localStorage.getItem('authToken'); if (!token) { console.error('AccessGuard: No token found. Redirecting to login.'); this.router.navigate(['/']); return false; } // Decode the token to extract the user role const decodedToken: any = jwtDecode(token); const currentUserRole = decodedToken.Roles; // Find access rules for the current user role const accessRules = this.config.accessRules?.find((rule) => rule.role === currentUserRole) ?? null; if (!accessRules) { console.error( `AccessGuard: Missing access rule for role ${currentUserRole}. Contant with app administrator.` ); this.router.navigate(['/']); return false; } // Check if the current route is in the access list for the role const routePath = route.routeConfig?.path; if (routePath && accessRules.access.includes(routePath)) { return true; } // Deny access if the route is not in the access list console.error( `AccessGuard: Access denied for role: ${currentUserRole} to path: ${routePath}` ); this.router.navigate(['/']); return false; } }