UNPKG

ngx-permissions

Version:

Permission and roles based access control for your angular(angular 2,4,5,6,7,8+) applications(AOT, lazy modules compatible)

979 lines (961 loc) 47.2 kB
import * as i0 from '@angular/core'; import { Injectable, InjectionToken, Inject, EventEmitter, inject, ViewContainerRef, ChangeDetectorRef, TemplateRef, Directive, Input, Output, NgModule } from '@angular/core'; import { BehaviorSubject, of, from, merge, forkJoin } from 'rxjs'; import { map, switchMap, catchError, mergeAll, first, mergeMap, every, skip, take, tap } from 'rxjs/operators'; import * as i3 from '@angular/router'; import { RouterStateSnapshot } from '@angular/router'; const NgxPermissionsPredefinedStrategies = { REMOVE: 'remove', SHOW: 'show' }; class NgxPermissionsConfigurationStore { constructor() { this.strategiesSource = new BehaviorSubject({}); this.strategies$ = this.strategiesSource.asObservable(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationStore }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationStore, decorators: [{ type: Injectable }] }); const USE_CONFIGURATION_STORE = new InjectionToken('USE_CONFIGURATION_STORE'); class NgxPermissionsConfigurationService { constructor(isolate = false, configurationStore) { this.isolate = isolate; this.configurationStore = configurationStore; this.strategiesSource = this.isolate ? new BehaviorSubject({}) : this.configurationStore.strategiesSource; this.strategies$ = this.strategiesSource.asObservable(); this.onAuthorisedDefaultStrategy = this.isolate ? undefined : this.configurationStore.onAuthorisedDefaultStrategy; this.onUnAuthorisedDefaultStrategy = this.isolate ? undefined : this.configurationStore.onUnAuthorisedDefaultStrategy; } setDefaultOnAuthorizedStrategy(name) { if (this.isolate) { this.onAuthorisedDefaultStrategy = this.getDefinedStrategy(name); } else { this.configurationStore.onAuthorisedDefaultStrategy = this.getDefinedStrategy(name); this.onAuthorisedDefaultStrategy = this.configurationStore.onAuthorisedDefaultStrategy; } } setDefaultOnUnauthorizedStrategy(name) { if (this.isolate) { this.onUnAuthorisedDefaultStrategy = this.getDefinedStrategy(name); } else { this.configurationStore.onUnAuthorisedDefaultStrategy = this.getDefinedStrategy(name); this.onUnAuthorisedDefaultStrategy = this.configurationStore.onUnAuthorisedDefaultStrategy; } } addPermissionStrategy(key, func) { this.strategiesSource.value[key] = func; } getStrategy(key) { return this.strategiesSource.value[key]; } getAllStrategies() { return this.strategiesSource.value; } getDefinedStrategy(name) { if (this.strategiesSource.value[name] || this.isPredefinedStrategy(name)) { return name; } else { throw new Error(`No ' ${name} ' strategy is found please define one`); } } isPredefinedStrategy(strategy) { return strategy === NgxPermissionsPredefinedStrategies.SHOW || strategy === NgxPermissionsPredefinedStrategies.REMOVE; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationService, deps: [{ token: USE_CONFIGURATION_STORE }, { token: NgxPermissionsConfigurationStore }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsConfigurationService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [USE_CONFIGURATION_STORE] }] }, { type: NgxPermissionsConfigurationStore }] }); function isFunction(value) { return typeof value === 'function'; } function isPlainObject(value) { if (Object.prototype.toString.call(value) !== '[object Object]') { return false; } else { const prototype = Object.getPrototypeOf(value); return prototype === null || prototype === Object.prototype; } } function isString(value) { return !!value && typeof value === 'string'; } function isBoolean(value) { return typeof value === 'boolean'; } function isPromise(promise) { return Object.prototype.toString.call(promise) === '[object Promise]'; } function notEmptyValue(value) { if (Array.isArray(value)) { return value.length > 0; } return !!value; } function transformStringToArray(value) { if (isString(value)) { return [value]; } return value; } class NgxPermissionsStore { constructor() { this.permissionsSource = new BehaviorSubject({}); this.permissions$ = this.permissionsSource.asObservable(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsStore }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsStore, decorators: [{ type: Injectable }] }); const USE_PERMISSIONS_STORE = new InjectionToken('USE_PERMISSIONS_STORE'); class NgxPermissionsService { constructor(isolate = false, permissionsStore) { this.isolate = isolate; this.permissionsStore = permissionsStore; this.permissionsSource = this.isolate ? new BehaviorSubject({}) : this.permissionsStore.permissionsSource; this.permissions$ = this.permissionsSource.asObservable(); } /** * Remove all permissions from permissions source */ flushPermissions() { this.permissionsSource.next({}); } hasPermission(permission) { if (!permission || (Array.isArray(permission) && permission.length === 0)) { return Promise.resolve(true); } permission = transformStringToArray(permission); return this.hasArrayPermission(permission); } loadPermissions(permissions, validationFunction) { const newPermissions = permissions.reduce((source, name) => this.reducePermission(source, name, validationFunction), {}); this.permissionsSource.next(newPermissions); } addPermission(permission, validationFunction) { if (Array.isArray(permission)) { const permissions = permission.reduce((source, name) => this.reducePermission(source, name, validationFunction), this.permissionsSource.value); this.permissionsSource.next(permissions); } else { const permissions = this.reducePermission(this.permissionsSource.value, permission, validationFunction); this.permissionsSource.next(permissions); } } removePermission(permissionName) { const permissions = { ...this.permissionsSource.value }; delete permissions[permissionName]; this.permissionsSource.next(permissions); } getPermission(name) { return this.permissionsSource.value[name]; } getPermissions() { return this.permissionsSource.value; } reducePermission(source, name, validationFunction) { if (!!validationFunction && isFunction(validationFunction)) { return { ...source, [name]: { name, validationFunction } }; } return { ...source, [name]: { name } }; } hasArrayPermission(permissions) { const promises = permissions.map(key => { if (this.hasPermissionValidationFunction(key)) { const validationFunction = this.permissionsSource.value[key].validationFunction; const immutableValue = { ...this.permissionsSource.value }; return of(null).pipe(map(() => validationFunction(key, immutableValue)), switchMap((promise) => isBoolean(promise) ? of(promise) : promise), catchError(() => of(false))); } // check for name of the permission if there is no validation function return of(!!this.permissionsSource.value[key]); }); return from(promises).pipe(mergeAll(), first((data) => data !== false, false), map((data) => data !== false)).toPromise().then((data) => data); } hasPermissionValidationFunction(key) { return !!this.permissionsSource.value[key] && !!this.permissionsSource.value[key].validationFunction && isFunction(this.permissionsSource.value[key].validationFunction); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsService, deps: [{ token: USE_PERMISSIONS_STORE }, { token: NgxPermissionsStore }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [USE_PERMISSIONS_STORE] }] }, { type: NgxPermissionsStore }] }); class NgxRolesStore { constructor() { this.rolesSource = new BehaviorSubject({}); this.roles$ = this.rolesSource.asObservable(); } } const USE_ROLES_STORE = new InjectionToken('USE_ROLES_STORE'); class NgxRolesService { constructor(isolate = false, rolesStore, permissionsService) { this.isolate = isolate; this.rolesStore = rolesStore; this.permissionsService = permissionsService; this.rolesSource = this.isolate ? new BehaviorSubject({}) : this.rolesStore.rolesSource; this.roles$ = this.rolesSource.asObservable(); } addRole(name, validationFunction) { const roles = { ...this.rolesSource.value, [name]: { name, validationFunction } }; this.rolesSource.next(roles); } addRoleWithPermissions(name, permissions) { this.permissionsService.addPermission(permissions); this.addRole(name, permissions); } addRoles(rolesObj) { Object.keys(rolesObj).forEach((key, index) => { this.addRole(key, rolesObj[key]); }); } addRolesWithPermissions(rolesObj) { Object.keys(rolesObj).forEach((key, index) => { this.addRoleWithPermissions(key, rolesObj[key]); }); } flushRoles() { this.rolesSource.next({}); } flushRolesAndPermissions() { this.flushRoles(); this.permissionsService.flushPermissions(); } removeRole(roleName) { const roles = { ...this.rolesSource.value }; delete roles[roleName]; this.rolesSource.next(roles); } getRoles() { return this.rolesSource.value; } getRole(name) { return this.rolesSource.value[name]; } hasOnlyRoles(names) { const isNamesEmpty = !names || (Array.isArray(names) && names.length === 0); if (isNamesEmpty) { return Promise.resolve(true); } names = transformStringToArray(names); return Promise.all([this.hasRoleKey(names), this.hasRolePermission(this.rolesSource.value, names)]) .then(([hasRoles, hasPermissions]) => { return hasRoles || hasPermissions; }); } hasRoleKey(roleName) { const promises = roleName.map((key) => { const hasValidationFunction = !!this.rolesSource.value[key] && !!this.rolesSource.value[key].validationFunction && isFunction(this.rolesSource.value[key].validationFunction); if (hasValidationFunction && !isPromise(this.rolesSource.value[key].validationFunction)) { const validationFunction = this.rolesSource.value[key].validationFunction; const immutableValue = { ...this.rolesSource.value }; return of(null).pipe(map(() => validationFunction(key, immutableValue)), switchMap((promise) => isBoolean(promise) ? of(promise) : promise), catchError(() => of(false))); } return of(false); }); return from(promises).pipe(mergeAll(), first((data) => data !== false, false), map((data) => data !== false)).toPromise().then((data) => data); } hasRolePermission(roles, roleNames) { return from(roleNames).pipe(mergeMap((key) => { if (roles[key] && Array.isArray(roles[key].validationFunction)) { return from(roles[key].validationFunction).pipe(mergeMap((permission) => this.permissionsService.hasPermission(permission)), every(hasPermission => hasPermission === true)); } return of(false); }), first(hasPermission => hasPermission === true, false)).toPromise(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxRolesService, deps: [{ token: USE_ROLES_STORE }, { token: NgxRolesStore }, { token: NgxPermissionsService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxRolesService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxRolesService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Inject, args: [USE_ROLES_STORE] }] }, { type: NgxRolesStore }, { type: NgxPermissionsService }] }); class NgxPermissionsDirective { constructor() { this.permissionsAuthorized = new EventEmitter(); this.permissionsUnauthorized = new EventEmitter(); // skip first run cause merge will fire twice this.firstMergeUnusedRun = 1; this.permissionsService = inject(NgxPermissionsService); this.configurationService = inject(NgxPermissionsConfigurationService); this.rolesService = inject(NgxRolesService); this.viewContainer = inject(ViewContainerRef); this.changeDetector = inject(ChangeDetectorRef); this.templateRef = inject((TemplateRef)); } ngOnInit() { this.viewContainer.clear(); this.initPermissionSubscription = this.validateExceptOnlyPermissions(); } ngOnChanges(changes) { const onlyChanges = changes['ngxPermissionsOnly']; const exceptChanges = changes['ngxPermissionsExcept']; if (onlyChanges || exceptChanges) { // Due to bug when you pass empty array if (onlyChanges && onlyChanges.firstChange) { return; } if (exceptChanges && exceptChanges.firstChange) { return; } merge(this.permissionsService.permissions$, this.rolesService.roles$) .pipe(skip(this.firstMergeUnusedRun), take(1)) .subscribe(() => { if (notEmptyValue(this.ngxPermissionsExcept)) { this.validateExceptAndOnlyPermissions(); return; } if (notEmptyValue(this.ngxPermissionsOnly)) { this.validateOnlyPermissions(); return; } this.handleAuthorisedPermission(this.getAuthorisedTemplates()); }); } } ngOnDestroy() { if (this.initPermissionSubscription) { this.initPermissionSubscription.unsubscribe(); } } validateExceptOnlyPermissions() { return merge(this.permissionsService.permissions$, this.rolesService.roles$) .pipe(skip(this.firstMergeUnusedRun)) .subscribe(() => { if (notEmptyValue(this.ngxPermissionsExcept)) { this.validateExceptAndOnlyPermissions(); return; } if (notEmptyValue(this.ngxPermissionsOnly)) { this.validateOnlyPermissions(); return; } this.handleAuthorisedPermission(this.getAuthorisedTemplates()); }); } validateExceptAndOnlyPermissions() { Promise .all([ this.permissionsService.hasPermission(this.ngxPermissionsExcept), this.rolesService.hasOnlyRoles(this.ngxPermissionsExcept) ]) .then(([hasPermission, hasRole]) => { if (hasPermission || hasRole) { this.handleUnauthorisedPermission(this.ngxPermissionsExceptElse || this.ngxPermissionsElse); return; } if (!!this.ngxPermissionsOnly) { throw false; } this.handleAuthorisedPermission(this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef); }) .catch(() => { if (!!this.ngxPermissionsOnly) { this.validateOnlyPermissions(); } else { this.handleAuthorisedPermission(this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef); } }); } validateOnlyPermissions() { Promise .all([this.permissionsService.hasPermission(this.ngxPermissionsOnly), this.rolesService.hasOnlyRoles(this.ngxPermissionsOnly)]) .then(([hasPermissions, hasRoles]) => { if (hasPermissions || hasRoles) { this.handleAuthorisedPermission(this.ngxPermissionsOnlyThen || this.ngxPermissionsThen || this.templateRef); } else { this.handleUnauthorisedPermission(this.ngxPermissionsOnlyElse || this.ngxPermissionsElse); } }) .catch(() => { this.handleUnauthorisedPermission(this.ngxPermissionsOnlyElse || this.ngxPermissionsElse); }); } handleUnauthorisedPermission(template) { if (isBoolean(this.currentAuthorizedState) && !this.currentAuthorizedState) { return; } this.currentAuthorizedState = false; this.permissionsUnauthorized.emit(); if (this.getUnAuthorizedStrategyInput()) { this.applyStrategyAccordingToStrategyType(this.getUnAuthorizedStrategyInput()); return; } if (this.configurationService.onUnAuthorisedDefaultStrategy && !this.elseBlockDefined()) { this.applyStrategy(this.configurationService.onUnAuthorisedDefaultStrategy); } else { this.showTemplateBlockInView(template); } } handleAuthorisedPermission(template) { if (isBoolean(this.currentAuthorizedState) && this.currentAuthorizedState) { return; } this.currentAuthorizedState = true; this.permissionsAuthorized.emit(); if (this.getAuthorizedStrategyInput()) { this.applyStrategyAccordingToStrategyType(this.getAuthorizedStrategyInput()); return; } if (this.configurationService.onAuthorisedDefaultStrategy && !this.thenBlockDefined()) { this.applyStrategy(this.configurationService.onAuthorisedDefaultStrategy); } else { this.showTemplateBlockInView(template); } } applyStrategyAccordingToStrategyType(strategy) { if (isString(strategy)) { this.applyStrategy(strategy); return; } if (isFunction(strategy)) { this.showTemplateBlockInView(this.templateRef); strategy(this.templateRef); return; } } showTemplateBlockInView(template) { this.viewContainer.clear(); if (!template) { return; } this.viewContainer.createEmbeddedView(template); this.changeDetector.markForCheck(); } getAuthorisedTemplates() { return this.ngxPermissionsOnlyThen || this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef; } elseBlockDefined() { return !!this.ngxPermissionsExceptElse || !!this.ngxPermissionsElse; } thenBlockDefined() { return !!this.ngxPermissionsExceptThen || !!this.ngxPermissionsThen; } getAuthorizedStrategyInput() { return this.ngxPermissionsOnlyAuthorisedStrategy || this.ngxPermissionsExceptAuthorisedStrategy || this.ngxPermissionsAuthorisedStrategy; } getUnAuthorizedStrategyInput() { return this.ngxPermissionsOnlyUnauthorisedStrategy || this.ngxPermissionsExceptUnauthorisedStrategy || this.ngxPermissionsUnauthorisedStrategy; } applyStrategy(name) { if (name === NgxPermissionsPredefinedStrategies.SHOW) { this.showTemplateBlockInView(this.templateRef); return; } if (name === NgxPermissionsPredefinedStrategies.REMOVE) { this.viewContainer.clear(); return; } const strategy = this.configurationService.getStrategy(name); this.showTemplateBlockInView(this.templateRef); strategy(this.templateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: NgxPermissionsDirective, isStandalone: false, selector: "[ngxPermissionsOnly],[ngxPermissionsExcept]", inputs: { ngxPermissionsOnly: "ngxPermissionsOnly", ngxPermissionsOnlyThen: "ngxPermissionsOnlyThen", ngxPermissionsOnlyElse: "ngxPermissionsOnlyElse", ngxPermissionsExcept: "ngxPermissionsExcept", ngxPermissionsExceptElse: "ngxPermissionsExceptElse", ngxPermissionsExceptThen: "ngxPermissionsExceptThen", ngxPermissionsThen: "ngxPermissionsThen", ngxPermissionsElse: "ngxPermissionsElse", ngxPermissionsOnlyAuthorisedStrategy: "ngxPermissionsOnlyAuthorisedStrategy", ngxPermissionsOnlyUnauthorisedStrategy: "ngxPermissionsOnlyUnauthorisedStrategy", ngxPermissionsExceptUnauthorisedStrategy: "ngxPermissionsExceptUnauthorisedStrategy", ngxPermissionsExceptAuthorisedStrategy: "ngxPermissionsExceptAuthorisedStrategy", ngxPermissionsUnauthorisedStrategy: "ngxPermissionsUnauthorisedStrategy", ngxPermissionsAuthorisedStrategy: "ngxPermissionsAuthorisedStrategy" }, outputs: { permissionsAuthorized: "permissionsAuthorized", permissionsUnauthorized: "permissionsUnauthorized" }, usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsDirective, decorators: [{ type: Directive, args: [{ selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]', standalone: false }] }], propDecorators: { ngxPermissionsOnly: [{ type: Input }], ngxPermissionsOnlyThen: [{ type: Input }], ngxPermissionsOnlyElse: [{ type: Input }], ngxPermissionsExcept: [{ type: Input }], ngxPermissionsExceptElse: [{ type: Input }], ngxPermissionsExceptThen: [{ type: Input }], ngxPermissionsThen: [{ type: Input }], ngxPermissionsElse: [{ type: Input }], ngxPermissionsOnlyAuthorisedStrategy: [{ type: Input }], ngxPermissionsOnlyUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptAuthorisedStrategy: [{ type: Input }], ngxPermissionsUnauthorisedStrategy: [{ type: Input }], ngxPermissionsAuthorisedStrategy: [{ type: Input }], permissionsAuthorized: [{ type: Output }], permissionsUnauthorized: [{ type: Output }] } }); const DEFAULT_REDIRECT_KEY = 'default'; const ngxPermissionsGuard = (route, state) => { const permissionsGuard = inject(NgxPermissionsGuard); if (state instanceof RouterStateSnapshot) { return permissionsGuard.hasPermissions(route, state); } return permissionsGuard.hasPermissions(route); }; /** * @deprecated Use {@link ngxPermissionsGuard} instead */ class NgxPermissionsGuard { constructor(permissionsService, rolesService, router) { this.permissionsService = permissionsService; this.rolesService = rolesService; this.router = router; } canActivate(route, state) { return this.hasPermissions(route, state); } canActivateChild(childRoute, state) { return this.hasPermissions(childRoute, state); } canLoad(route) { return this.hasPermissions(route); } canMatch(route) { return this.hasPermissions(route); } hasPermissions(route, state) { const routeDataPermissions = !!route && route.data ? route.data['permissions'] : {}; const permissions = this.transformPermission(routeDataPermissions, route, state); if (this.isParameterAvailable(permissions.except)) { return this.passingExceptPermissionsValidation(permissions, route, state); } if (this.isParameterAvailable(permissions.only)) { return this.passingOnlyPermissionsValidation(permissions, route, state); } return true; } transformPermission(permissions, route, state) { const only = isFunction(permissions.only) ? permissions.only(route, state) : transformStringToArray(permissions.only); const except = isFunction(permissions.except) ? permissions.except(route, state) : transformStringToArray(permissions.except); const redirectTo = permissions.redirectTo; return { only, except, redirectTo }; } isParameterAvailable(permission) { return !!permission && permission.length > 0; } passingExceptPermissionsValidation(permissions, route, state) { if (!!permissions.redirectTo && ((isFunction(permissions.redirectTo)) || (isPlainObject(permissions.redirectTo) && !this.isRedirectionWithParameters(permissions.redirectTo)))) { let failedPermission = ''; return from(permissions.except) .pipe(mergeMap(permissionsExcept => { return forkJoin([ this.permissionsService.hasPermission(permissionsExcept), this.rolesService.hasOnlyRoles(permissionsExcept) ]).pipe(tap(hasPermissions => { const dontHavePermissions = hasPermissions.every(hasPermission => hasPermission === false); if (!dontHavePermissions) { failedPermission = permissionsExcept; } })); }), first(hasPermissions => hasPermissions.some(hasPermission => hasPermission === true), false), mergeMap(isAllFalse => { if (!!failedPermission) { this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state); return of(false); } if (!isAllFalse && permissions.only) { return this.onlyRedirectCheck(permissions, route, state); } return of(!isAllFalse); })) .toPromise(); } return Promise.all([ this.permissionsService.hasPermission(permissions.except), this.rolesService.hasOnlyRoles(permissions.except) ]).then(([hasPermission, hasRoles]) => { if (hasPermission || hasRoles) { if (permissions.redirectTo) { this.redirectToAnotherRoute(permissions.redirectTo, route, state); } return false; } if (permissions.only) { return this.checkOnlyPermissions(permissions, route, state); } return true; }); } redirectToAnotherRoute(permissionRedirectTo, route, state, failedPermissionName) { const redirectTo = isFunction(permissionRedirectTo) ? permissionRedirectTo(failedPermissionName, route, state) : permissionRedirectTo; if (this.isRedirectionWithParameters(redirectTo)) { redirectTo.navigationCommands = this.transformNavigationCommands(redirectTo.navigationCommands, route, state); redirectTo.navigationExtras = this.transformNavigationExtras(redirectTo.navigationExtras, route, state); this.router.navigate(redirectTo.navigationCommands, redirectTo.navigationExtras); return; } if (Array.isArray(redirectTo)) { this.router.navigate(redirectTo); } else { this.router.navigate([redirectTo]); } } isRedirectionWithParameters(object) { return (isPlainObject(object) && (!!object.navigationCommands || !!object.navigationExtras)); } transformNavigationCommands(navigationCommands, route, state) { return isFunction(navigationCommands) ? navigationCommands(route, state) : navigationCommands; } transformNavigationExtras(navigationExtras, route, state) { return isFunction(navigationExtras) ? navigationExtras(route, state) : navigationExtras; } onlyRedirectCheck(permissions, route, state) { let failedPermission = ''; return from(permissions.only) .pipe(mergeMap(permissionsOnly => { return forkJoin([ this.permissionsService.hasPermission(permissionsOnly), this.rolesService.hasOnlyRoles(permissionsOnly) ]).pipe(tap(hasPermissions => { const failed = hasPermissions.every(hasPermission => hasPermission === false); if (failed) { failedPermission = permissionsOnly; } })); }), first(hasPermissions => { if (isFunction(permissions.redirectTo)) { return hasPermissions.some(hasPermission => hasPermission === true); } return hasPermissions.every(hasPermission => hasPermission === false); }, false), mergeMap((pass) => { if (isFunction(permissions.redirectTo)) { if (pass) { return of(true); } else { this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state); return of(false); } } else { if (!!failedPermission) { this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state); } return of(!pass); } })) .toPromise(); } handleRedirectOfFailedPermission(permissions, failedPermission, route, state) { if (this.isFailedPermissionPropertyOfRedirectTo(permissions, failedPermission)) { this.redirectToAnotherRoute(permissions.redirectTo[failedPermission], route, state, failedPermission); } else { if (isFunction(permissions.redirectTo)) { this.redirectToAnotherRoute(permissions.redirectTo, route, state, failedPermission); } else { this.redirectToAnotherRoute(permissions.redirectTo[DEFAULT_REDIRECT_KEY], route, state, failedPermission); } } } isFailedPermissionPropertyOfRedirectTo(permissions, failedPermission) { return (!!permissions.redirectTo && permissions.redirectTo[failedPermission]); } checkOnlyPermissions(purePermissions, route, state) { const permissions = { ...purePermissions }; return Promise.all([ this.permissionsService.hasPermission(permissions.only), this.rolesService.hasOnlyRoles(permissions.only) ]).then(([hasPermission, hasRole]) => { if (hasPermission || hasRole) { return true; } if (permissions.redirectTo) { this.redirectToAnotherRoute(permissions.redirectTo, route, state); } return false; }); } passingOnlyPermissionsValidation(permissions, route, state) { if ((isFunction(permissions.redirectTo) || isPlainObject(permissions.redirectTo) && !this.isRedirectionWithParameters(permissions.redirectTo))) { return this.onlyRedirectCheck(permissions, route, state); } return this.checkOnlyPermissions(permissions, route, state); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsGuard, deps: [{ token: NgxPermissionsService }, { token: NgxRolesService }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsGuard }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsGuard, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: NgxPermissionsService }, { type: NgxRolesService }, { type: i3.Router }] }); class NgxPermissionsAllowStubDirective { constructor() { this.permissionsAuthorized = new EventEmitter(); this.permissionsUnauthorized = new EventEmitter(); this.viewContainer = inject(ViewContainerRef); this.templateRef = inject((TemplateRef)); } ngOnInit() { this.viewContainer.clear(); this.viewContainer.createEmbeddedView(this.getAuthorizedTemplate()); this.permissionsAuthorized.emit(); } getAuthorizedTemplate() { return (this.ngxPermissionsOnlyThen || this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: NgxPermissionsAllowStubDirective, isStandalone: true, selector: "[ngxPermissionsOnly],[ngxPermissionsExcept]", inputs: { ngxPermissionsOnly: "ngxPermissionsOnly", ngxPermissionsOnlyThen: "ngxPermissionsOnlyThen", ngxPermissionsOnlyElse: "ngxPermissionsOnlyElse", ngxPermissionsExcept: "ngxPermissionsExcept", ngxPermissionsExceptElse: "ngxPermissionsExceptElse", ngxPermissionsExceptThen: "ngxPermissionsExceptThen", ngxPermissionsThen: "ngxPermissionsThen", ngxPermissionsElse: "ngxPermissionsElse", ngxPermissionsOnlyAuthorisedStrategy: "ngxPermissionsOnlyAuthorisedStrategy", ngxPermissionsOnlyUnauthorisedStrategy: "ngxPermissionsOnlyUnauthorisedStrategy", ngxPermissionsExceptUnauthorisedStrategy: "ngxPermissionsExceptUnauthorisedStrategy", ngxPermissionsExceptAuthorisedStrategy: "ngxPermissionsExceptAuthorisedStrategy", ngxPermissionsUnauthorisedStrategy: "ngxPermissionsUnauthorisedStrategy", ngxPermissionsAuthorisedStrategy: "ngxPermissionsAuthorisedStrategy" }, outputs: { permissionsAuthorized: "permissionsAuthorized", permissionsUnauthorized: "permissionsUnauthorized" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]', }] }], propDecorators: { ngxPermissionsOnly: [{ type: Input }], ngxPermissionsOnlyThen: [{ type: Input }], ngxPermissionsOnlyElse: [{ type: Input }], ngxPermissionsExcept: [{ type: Input }], ngxPermissionsExceptElse: [{ type: Input }], ngxPermissionsExceptThen: [{ type: Input }], ngxPermissionsThen: [{ type: Input }], ngxPermissionsElse: [{ type: Input }], ngxPermissionsOnlyAuthorisedStrategy: [{ type: Input }], ngxPermissionsOnlyUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptAuthorisedStrategy: [{ type: Input }], ngxPermissionsUnauthorisedStrategy: [{ type: Input }], ngxPermissionsAuthorisedStrategy: [{ type: Input }], permissionsAuthorized: [{ type: Output }], permissionsUnauthorized: [{ type: Output }] } }); class NgxPermissionsRestrictStubDirective { constructor() { this.permissionsAuthorized = new EventEmitter(); this.permissionsUnauthorized = new EventEmitter(); this.viewContainer = inject(ViewContainerRef); } ngOnInit() { this.viewContainer.clear(); if (this.getUnAuthorizedTemplate()) { this.viewContainer.createEmbeddedView(this.getUnAuthorizedTemplate()); } this.permissionsUnauthorized.emit(); } getUnAuthorizedTemplate() { return (this.ngxPermissionsOnlyElse || this.ngxPermissionsExceptElse || this.ngxPermissionsElse); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: NgxPermissionsRestrictStubDirective, isStandalone: true, selector: "[ngxPermissionsOnly],[ngxPermissionsExcept]", inputs: { ngxPermissionsOnly: "ngxPermissionsOnly", ngxPermissionsOnlyThen: "ngxPermissionsOnlyThen", ngxPermissionsOnlyElse: "ngxPermissionsOnlyElse", ngxPermissionsExcept: "ngxPermissionsExcept", ngxPermissionsExceptElse: "ngxPermissionsExceptElse", ngxPermissionsExceptThen: "ngxPermissionsExceptThen", ngxPermissionsThen: "ngxPermissionsThen", ngxPermissionsElse: "ngxPermissionsElse", ngxPermissionsOnlyAuthorisedStrategy: "ngxPermissionsOnlyAuthorisedStrategy", ngxPermissionsOnlyUnauthorisedStrategy: "ngxPermissionsOnlyUnauthorisedStrategy", ngxPermissionsExceptUnauthorisedStrategy: "ngxPermissionsExceptUnauthorisedStrategy", ngxPermissionsExceptAuthorisedStrategy: "ngxPermissionsExceptAuthorisedStrategy", ngxPermissionsUnauthorisedStrategy: "ngxPermissionsUnauthorisedStrategy", ngxPermissionsAuthorisedStrategy: "ngxPermissionsAuthorisedStrategy" }, outputs: { permissionsAuthorized: "permissionsAuthorized", permissionsUnauthorized: "permissionsUnauthorized" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubDirective, decorators: [{ type: Directive, args: [{ standalone: true, selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]', }] }], propDecorators: { ngxPermissionsOnly: [{ type: Input }], ngxPermissionsOnlyThen: [{ type: Input }], ngxPermissionsOnlyElse: [{ type: Input }], ngxPermissionsExcept: [{ type: Input }], ngxPermissionsExceptElse: [{ type: Input }], ngxPermissionsExceptThen: [{ type: Input }], ngxPermissionsThen: [{ type: Input }], ngxPermissionsElse: [{ type: Input }], ngxPermissionsOnlyAuthorisedStrategy: [{ type: Input }], ngxPermissionsOnlyUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptUnauthorisedStrategy: [{ type: Input }], ngxPermissionsExceptAuthorisedStrategy: [{ type: Input }], ngxPermissionsUnauthorisedStrategy: [{ type: Input }], ngxPermissionsAuthorisedStrategy: [{ type: Input }], permissionsAuthorized: [{ type: Output }], permissionsUnauthorized: [{ type: Output }] } }); class NgxPermissionsModule { static forRoot(config = {}) { return { ngModule: NgxPermissionsModule, providers: [ NgxPermissionsStore, NgxRolesStore, NgxPermissionsConfigurationStore, NgxPermissionsService, NgxPermissionsGuard, NgxRolesService, NgxPermissionsConfigurationService, { provide: USE_PERMISSIONS_STORE, useValue: config.permissionsIsolate }, { provide: USE_ROLES_STORE, useValue: config.rolesIsolate }, { provide: USE_CONFIGURATION_STORE, useValue: config.configurationIsolate }, ] }; } static forChild(config = {}) { return { ngModule: NgxPermissionsModule, providers: [ { provide: USE_PERMISSIONS_STORE, useValue: config.permissionsIsolate }, { provide: USE_ROLES_STORE, useValue: config.rolesIsolate }, { provide: USE_CONFIGURATION_STORE, useValue: config.configurationIsolate }, NgxPermissionsConfigurationService, NgxPermissionsService, NgxRolesService, NgxPermissionsGuard ] }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsModule, declarations: [NgxPermissionsDirective], exports: [NgxPermissionsDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsModule, decorators: [{ type: NgModule, args: [{ imports: [], declarations: [ NgxPermissionsDirective ], exports: [ NgxPermissionsDirective ] }] }] }); class NgxPermissionsAllowStubModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubModule, imports: [NgxPermissionsAllowStubDirective], exports: [NgxPermissionsAllowStubDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsAllowStubModule, decorators: [{ type: NgModule, args: [{ imports: [NgxPermissionsAllowStubDirective], declarations: [], exports: [ NgxPermissionsAllowStubDirective ] }] }] }); class NgxPermissionsRestrictStubModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubModule, imports: [NgxPermissionsRestrictStubDirective], exports: [NgxPermissionsRestrictStubDirective] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgxPermissionsRestrictStubModule, decorators: [{ type: NgModule, args: [{ imports: [NgxPermissionsRestrictStubDirective], declarations: [], exports: [ NgxPermissionsRestrictStubDirective ] }] }] }); /* * Public API Surface of ngx-permissions */ /** * Generated bundle index. Do not edit. */ export { DEFAULT_REDIRECT_KEY, NgxPermissionsAllowStubDirective, NgxPermissionsAllowStubModule, NgxPermissionsConfigurationService, NgxPermissionsConfigurationStore, NgxPermissionsDirective, NgxPermissionsGuard, NgxPermissionsModule, NgxPermissionsPredefinedStrategies, NgxPermissionsRestrictStubDirective, NgxPermissionsRestrictStubModule, NgxPermissionsService, NgxPermissionsStore, NgxRolesService, NgxRolesStore, USE_CONFIGURATION_STORE, USE_PERMISSIONS_STORE, USE_ROLES_STORE, ngxPermissionsGuard }; //# sourceMappingURL=ngx-permissions.mjs.map