ng-secure-access
Version:
Librairie Angular pour la gestion des permissions d'accès aux routes et l'affichage conditionnel basé sur les permissions utilisateur
153 lines (146 loc) • 6.68 kB
JavaScript
import * as i0 from '@angular/core';
import { signal, computed, Injectable, Directive, Input, inject } from '@angular/core';
import { Router } from '@angular/router';
class PermissionService {
// Signaux privés
permissions = signal([]);
permissionsLoaded = signal(false);
// Signaux publics computed (readonly)
permissions$ = computed(() => this.permissions());
permissionsLoaded$ = computed(() => this.permissionsLoaded());
// Charger les permissions
loadPermissions(permissions) {
this.permissions.set(permissions);
this.permissionsLoaded.set(true);
}
// Vérifier si l'utilisateur possède AU MOINS une des permissions (OU logique)
hasPermission(requiredPermissions) {
if (!requiredPermissions || requiredPermissions.length === 0) {
return true;
}
return requiredPermissions.some(permission => this.permissions().includes(permission));
}
// Obtenir toutes les permissions
getPermissions() {
return this.permissions();
}
// Vérifier si les permissions sont chargées
arePermissionsLoaded() {
return this.permissionsLoaded();
}
// Effacer les permissions (déconnexion)
clearPermissions() {
this.permissions.set([]);
this.permissionsLoaded.set(false);
}
// Ajouter une permission dynamiquement
addPermission(permission) {
if (!this.permissions().includes(permission)) {
this.permissions.update(perms => [...perms, permission]);
}
}
// Retirer une permission
removePermission(permission) {
this.permissions.update(perms => perms.filter(p => p !== permission));
}
// Vérifier une permission spécifique
hasSpecificPermission(permission) {
return this.permissions().includes(permission);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionService, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
class HasPermissionDirective {
templateRef;
viewContainer;
permissionService;
permissionsRequired = [];
constructor(templateRef, viewContainer, permissionService) {
this.templateRef = templateRef;
this.viewContainer = viewContainer;
this.permissionService = permissionService;
}
set hasPermission(permissions) {
this.permissionsRequired = permissions;
this.updateView();
}
updateView() {
if (this.checkPermissions()) {
// Affiche l'élément si au moins une permission est présente
this.viewContainer.createEmbeddedView(this.templateRef);
}
else {
// Masque l'élément
this.viewContainer.clear();
}
}
checkPermissions() {
// Vérifie si l'utilisateur a au moins une des permissions requises
return this.permissionService.hasPermission(this.permissionsRequired);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: PermissionService }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.8", type: HasPermissionDirective, isStandalone: true, selector: "[hasPermission]", inputs: { hasPermission: "hasPermission" }, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: HasPermissionDirective, decorators: [{
type: Directive,
args: [{
selector: '[hasPermission]',
standalone: true
}]
}], ctorParameters: () => [{ type: i0.TemplateRef }, { type: i0.ViewContainerRef }, { type: PermissionService }], propDecorators: { hasPermission: [{
type: Input
}] } });
class PermissionGuard {
permissionService = inject(PermissionService);
router = inject(Router);
canActivate(route, state) {
const requiredPermissions = route.data['permissions'];
const redirectTo = route.data['redirectTo'] || '/access-denied';
// Vérifier si des permissions sont spécifiées
if (!requiredPermissions || requiredPermissions.length === 0) {
console.warn('[PermissionGuard] Aucune permission requise pour cette route:', state.url);
return true;
}
// Vérifier si les permissions sont chargées
if (!this.permissionService.arePermissionsLoaded()) {
console.error('[PermissionGuard] Les permissions ne sont pas encore chargées');
this.router.navigate([redirectTo], {
queryParams: { returnUrl: state.url }
});
return false;
}
// Vérifier les permissions (OU logique : au moins une permission requise)
if (this.permissionService.hasPermission(requiredPermissions)) {
return true;
}
// Log de l'accès refusé
console.warn('[PermissionGuard] Accès refusé à:', state.url, '\nPermissions requises (au moins une):', requiredPermissions, '\nPermissions utilisateur:', this.permissionService.getPermissions());
// Redirection avec l'URL de retour
this.router.navigate([redirectTo], {
queryParams: { returnUrl: state.url }
});
return false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionGuard, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionGuard, providedIn: 'root' });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: PermissionGuard, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}] });
/*
* Public API Surface of ng-secure-access
*/
/**
* Generated bundle index. Do not edit.
*/
export { HasPermissionDirective, PermissionGuard, PermissionService };
//# sourceMappingURL=ng-secure-access.mjs.map