import {Injectable} from '@angular/core'; import {LoginService} from '@api'; import {BehaviorSubject, Observable, throwError} from 'rxjs'; import {catchError, tap} from 'rxjs/operators'; import {MatSnackBar} from '@angular/material/snack-bar'; import {JwtHelperService} from '@auth0/angular-jwt'; import {JwtClaims} from '@custom-types/jwt_interface' @Injectable({ providedIn: 'root' }) export class AuthService { private isAuthenticatedSubject = new BehaviorSubject(false); public isAuthenticated$ = this.isAuthenticatedSubject.asObservable(); private userClaimsSubject = new BehaviorSubject(null); public userClaims$ = this.userClaimsSubject.asObservable(); private jwtHelper = new JwtHelperService(); constructor( private loginService: LoginService, private snackBar: MatSnackBar ) { // Check if user is already logged in on service initialization this.checkAuthStatus(); } /** * Attempt to login with the provided code */ public login(code: string): Observable { return this.loginService.login(code).pipe( tap(jwt => { this.saveJwt(jwt); this.isAuthenticatedSubject.next(true); }), catchError(error => { this.snackBar.open('Login failed', '', {duration: 2000}); return throwError(() => error); }) ); } /** * Log the user out by removing the JWT */ public logout(): void { localStorage.removeItem('jwt'); this.isAuthenticatedSubject.next(false); this.userClaimsSubject.next(null); } /** * Check if the user is authenticated */ public checkAuthStatus(): boolean { const jwt = this.getJwt(); if (jwt) { try { // Check if token is expired if (this.jwtHelper.isTokenExpired(jwt)) { this.logout(); return false; } const claims = this.extractJwtClaims(jwt); console.log("User claims: ", claims); this.userClaimsSubject.next(claims); this.isAuthenticatedSubject.next(true); return true; } catch (e) { this.logout(); } } return false; } /** * Get the JWT from localStorage */ public getJwt(): string | null { return localStorage.getItem('jwt'); } /** * Save the JWT to localStorage */ private saveJwt(jwt: string): void { localStorage.setItem('jwt', jwt); const claims = this.extractJwtClaims(jwt); console.log("User claims: ", claims); this.userClaimsSubject.next(claims); } /** * Extract claims from JWT */ private extractJwtClaims(jwt: string): JwtClaims { return this.jwtHelper.decodeToken(jwt); } /** * Get user authorizations from claims */ public getUserAuthorizations(): string[] { const claims = this.userClaimsSubject.getValue(); return claims?.authorities || []; } public hasAccess(requiredAuthorizations: string[]): boolean { const userAuthorizations = this.getUserAuthorizations(); return requiredAuthorizations.some(auth => userAuthorizations.includes(auth)); } }