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
JavaScript
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