Updated auth config
All checks were successful
Gitea/swiss-client/pipeline/head This commit looks good

This commit is contained in:
2025-10-08 21:36:13 +02:00
parent 0fd693aa42
commit 8083e7fc5f
13 changed files with 225 additions and 62 deletions

View File

@@ -0,0 +1,22 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {AuthService} from './auth.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {
}
public canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
if (this.authService.isLoggedIn() && this.authService.isUserInRole(next.routeConfig?.data?.['role'])) {
return true;
} else {
// this.router.navigateByUrl("/login");
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}
}

View File

@@ -0,0 +1,35 @@
import {Injectable} from '@angular/core';
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {catchError, Observable, throwError} from 'rxjs';
import {Router} from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let token = sessionStorage.getItem("app.token");
if (token) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
},
});
}
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => this.handleErrorRes(error))
);
}
private handleErrorRes(error: HttpErrorResponse): Observable<never> {
if (error.status === 401) {
this.router.navigateByUrl("/login", {replaceUrl: true});
}
return throwError(() => error);
}
}

View File

@@ -0,0 +1,86 @@
import {Inject, Injectable, PLATFORM_ID} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';
import {environment} from "../../environments/environment";
import {isPlatformBrowser} from "@angular/common";
import {jwtDecode, JwtPayload} from "jwt-decode";
@Injectable({
providedIn: 'root'
})
export class AuthService {
private readonly authUrl: string
constructor(private http: HttpClient,
@Inject(PLATFORM_ID) private platformId: Object) {
this.authUrl = `${environment.backendUrl}/api/auth`;
}
private get isBrowser(): boolean {
return isPlatformBrowser(this.platformId);
}
isLoggedIn(): boolean {
if (!this.isBrowser) return false;
return sessionStorage.getItem("app.token") != null;
}
login(username: string, password: string): Observable<string> {
if (!this.isBrowser) {
throw new Error('Login can only be performed in browser');
}
const credentials = btoa(`${username}:${password}`);
const httpOptions = {
headers: {
'Authorization': `Basic ${credentials}`,
'Content-Type': 'application/json'
},
responseType: 'text' as 'text',
};
return this.http.post(this.authUrl, null, httpOptions);
}
logout() {
if (!this.isBrowser) return;
sessionStorage.removeItem("app.token");
sessionStorage.removeItem("app.roles");
}
isUserInRole(roleFromRoute: string) {
if (!this.isBrowser) return false;
const roles = sessionStorage.getItem("app.roles");
if (roles!.includes(",")) {
if (roles === roleFromRoute) {
return true;
}
} else {
const roleArray = roles!.split(",");
for (let role of roleArray) {
if (role === roleFromRoute) {
return true;
}
}
}
return false;
}
getUsername(): string | null {
if (!this.isBrowser) return null;
const token = sessionStorage.getItem("app.token");
if (!token) return null;
try {
const decodedToken = jwtDecode<JwtPayload>(token);
return decodedToken.sub || null; // 'sub' is the standard JWT claim for subject/username
} catch (error) {
console.error('Error decoding token:', error);
return null;
}
}
}