Compare commits

...

3 Commits

Author SHA1 Message Date
Cristiano cf53e4c8ef Merge remote-tracking branch 'origin/develop' into develop 2026-05-30 15:00:14 +02:00
Cristiano 9b898432c0 Mask user for employee on navbar 2026-05-29 14:17:45 +02:00
Cristiano d0e98482b9 Added guards for auth and role 2026-05-29 14:07:42 +02:00
6 changed files with 80 additions and 13 deletions
+19 -8
View File
@@ -1,4 +1,6 @@
import {Routes} from '@angular/router'; import {Routes} from '@angular/router';
import {authGuard} from "./guards/auth.guard";
import {roleGuard} from "./guards/role.guard";
export const routes: Routes = [ export const routes: Routes = [
{ {
@@ -22,35 +24,44 @@ export const routes: Routes = [
}, },
{ {
path: 'dashboard', path: 'dashboard',
loadComponent: () => import('./pages/dashboard/dashboard').then(m => m.Dashboard) loadComponent: () => import('./pages/dashboard/dashboard').then(m => m.Dashboard),
canActivate: [authGuard]
}, },
{ {
path: 'stock', path: 'stock',
loadComponent: () => import('./pages/stock/stock').then(m => m.Stock) loadComponent: () => import('./pages/stock/stock').then(m => m.Stock),
canActivate: [authGuard]
}, },
{ {
path: 'supplier', path: 'supplier',
loadComponent: () => import('./pages/supplier/supplier').then(m => m.Supplier) loadComponent: () => import('./pages/supplier/supplier').then(m => m.Supplier),
canActivate: [authGuard]
}, },
{ {
path: 'deliverer', path: 'deliverer',
loadComponent: () => import('./pages/deliverer/deliverer').then(m => m.Deliverer) loadComponent: () => import('./pages/deliverer/deliverer').then(m => m.Deliverer),
canActivate: [authGuard]
}, },
{ {
path: 'quotation', path: 'quotation',
loadComponent: () => import('./pages/quotation/quotation').then(m => m.Quotation) loadComponent: () => import('./pages/quotation/quotation').then(m => m.Quotation),
canActivate: [authGuard]
}, },
{ {
path: 'purchase-order', path: 'purchase-order',
loadComponent: () => import('./pages/purchase-order/purchase-order').then(m => m.PurchaseOrder) loadComponent: () => import('./pages/purchase-order/purchase-order').then(m => m.PurchaseOrder),
canActivate: [authGuard]
}, },
{ {
path: 'delivery-note', path: 'delivery-note',
loadComponent: () => import('./pages/delivery-note/delivery-note').then(m => m.DeliveryNote) loadComponent: () => import('./pages/delivery-note/delivery-note').then(m => m.DeliveryNote),
canActivate: [authGuard]
}, },
{ {
path: 'user', path: 'user',
loadComponent: () => import('./pages/user/user').then(m => m.User) loadComponent: () => import('./pages/user/user').then(m => m.User),
canActivate: [authGuard, roleGuard],
data: {roles: ['Admin']},
}, },
{ {
path: '**', path: '**',
+2
View File
@@ -60,10 +60,12 @@
</ul> </ul>
</li> </li>
<li nz-menu-item routerLinkActive="ant-menu-item-selected"> <li nz-menu-item routerLinkActive="ant-menu-item-selected">
@if (authService.hasRole(['ADMIN'])) {
<a routerLink="/user"> <a routerLink="/user">
<nz-icon nzType="user"></nz-icon> <nz-icon nzType="user"></nz-icon>
<span>Utilisateur</span> <span>Utilisateur</span>
</a> </a>
}
</li> </li>
</ul> </ul>
+1 -1
View File
@@ -29,7 +29,7 @@ import {AuthService} from "../../services/auth.service";
styleUrl: './layout.css', styleUrl: './layout.css',
}) })
export class Layout { export class Layout {
private authService = inject(AuthService); protected authService = inject(AuthService);
private router = inject(Router); private router = inject(Router);
async disconnect() { async disconnect() {
+10
View File
@@ -0,0 +1,10 @@
import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService} from "../services/auth.service";
export const authGuard = () => {
const auth = inject(AuthService);
const router = inject(Router);
return auth.isLoggedIn() ? true : router.parseUrl('/login');
};
+12
View File
@@ -0,0 +1,12 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, Router } from '@angular/router';
import { AuthService} from "../services/auth.service";
export const roleGuard = (route: ActivatedRouteSnapshot) => {
const auth = inject(AuthService);
const router = inject(Router);
const requiredRoles: string[] = route.data['roles'];
return auth.hasRole(requiredRoles) ? true : router.parseUrl('/dashboard');
};
+32
View File
@@ -34,4 +34,36 @@ export class AuthService {
localStorage.removeItem('jwt'); localStorage.removeItem('jwt');
} }
decodeToken(): { sub?: string; role?: string; exp?: number } | null {
const token = this.getToken();
if (!token) return null;
try {
const payload = token.split('.')[1];
return JSON.parse(atob(payload));
} catch {
return null;
}
}
isLoggedIn(): boolean {
const token = this.getToken();
if (!token) return false;
const decoded = this.decodeToken();
if (!decoded?.exp) return true;
return decoded.exp * 1000 > Date.now();
}
getRole(): string | null {
return this.decodeToken()?.role ?? null;
}
hasRole(requiredRoles: string[]): boolean {
const role = this.getRole();
if (!role) return false;
return requiredRoles.includes(role);
}
} }