ngx-permissions
Version:
Permission and roles based access control for your angular(angular 2,4,5,6,7,8+) applications(AOT, lazy modules compatible)
1 lines • 81 kB
Source Map (JSON)
{"version":3,"file":"ngx-permissions.mjs","sources":["../../../projects/ngx-permissions/src/lib/enums/predefined-strategies.enum.ts","../../../projects/ngx-permissions/src/lib/store/configuration.store.ts","../../../projects/ngx-permissions/src/lib/service/configuration.service.ts","../../../projects/ngx-permissions/src/lib/utils/utils.ts","../../../projects/ngx-permissions/src/lib/store/permissions.store.ts","../../../projects/ngx-permissions/src/lib/service/permissions.service.ts","../../../projects/ngx-permissions/src/lib/store/roles.store.ts","../../../projects/ngx-permissions/src/lib/service/roles.service.ts","../../../projects/ngx-permissions/src/lib/directive/permissions.directive.ts","../../../projects/ngx-permissions/src/lib/model/permissions-router-data.model.ts","../../../projects/ngx-permissions/src/lib/router/permissions-guard.service.ts","../../../projects/ngx-permissions/src/lib/testing/permissions-allow.directive.stub.ts","../../../projects/ngx-permissions/src/lib/testing/permissions-restrict.directive.stub.ts","../../../projects/ngx-permissions/src/lib/index.ts","../../../projects/ngx-permissions/src/public-api.ts","../../../projects/ngx-permissions/src/ngx-permissions.ts"],"sourcesContent":["export const NgxPermissionsPredefinedStrategies = {\n REMOVE: 'remove',\n SHOW: 'show'\n} as const;\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { Strategy } from '../service/configuration.service';\n\n@Injectable()\nexport class NgxPermissionsConfigurationStore {\n\n public strategiesSource: BehaviorSubject<Strategy> = new BehaviorSubject<Strategy>({});\n public strategies$: Observable<Strategy> = this.strategiesSource.asObservable();\n\n public onAuthorisedDefaultStrategy: string | undefined;\n public onUnAuthorisedDefaultStrategy: string | undefined;\n\n}\n","import { Inject, Injectable, InjectionToken, TemplateRef } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { NgxPermissionsPredefinedStrategies } from '../enums/predefined-strategies.enum';\nimport { NgxPermissionsConfigurationStore } from '../store/configuration.store';\n\nexport type StrategyFunction = (templateRef?: TemplateRef<any>) => void;\n\nexport interface Strategy {\n [key: string]: StrategyFunction;\n}\n\nexport const USE_CONFIGURATION_STORE = new InjectionToken('USE_CONFIGURATION_STORE');\n\n@Injectable()\nexport class NgxPermissionsConfigurationService {\n\n private strategiesSource: BehaviorSubject<Strategy>;\n public strategies$: Observable<Strategy>;\n public onAuthorisedDefaultStrategy: string | undefined;\n public onUnAuthorisedDefaultStrategy: string | undefined;\n\n constructor(\n @Inject(USE_CONFIGURATION_STORE) private isolate: boolean = false,\n private configurationStore: NgxPermissionsConfigurationStore\n ) {\n this.strategiesSource = this.isolate ? new BehaviorSubject<Strategy>({}) : this.configurationStore.strategiesSource;\n this.strategies$ = this.strategiesSource.asObservable();\n\n this.onAuthorisedDefaultStrategy = this.isolate ? undefined : this.configurationStore.onAuthorisedDefaultStrategy;\n this.onUnAuthorisedDefaultStrategy = this.isolate ? undefined : this.configurationStore.onUnAuthorisedDefaultStrategy;\n\n }\n\n public setDefaultOnAuthorizedStrategy(name: string | 'remove' | 'show'): void {\n if (this.isolate) {\n this.onAuthorisedDefaultStrategy = this.getDefinedStrategy(name);\n } else {\n this.configurationStore.onAuthorisedDefaultStrategy = this.getDefinedStrategy(name);\n this.onAuthorisedDefaultStrategy = this.configurationStore.onAuthorisedDefaultStrategy;\n }\n }\n\n public setDefaultOnUnauthorizedStrategy(name: string | 'remove' | 'show'): void {\n if (this.isolate) {\n this.onUnAuthorisedDefaultStrategy = this.getDefinedStrategy(name);\n } else {\n this.configurationStore.onUnAuthorisedDefaultStrategy = this.getDefinedStrategy(name);\n this.onUnAuthorisedDefaultStrategy = this.configurationStore.onUnAuthorisedDefaultStrategy;\n }\n }\n\n public addPermissionStrategy(key: string, func: StrategyFunction): void {\n this.strategiesSource.value[key] = func;\n }\n\n public getStrategy(key: string) {\n return this.strategiesSource.value[key];\n }\n\n public getAllStrategies() {\n return this.strategiesSource.value;\n }\n\n private getDefinedStrategy(name: string | 'remove' | 'show') {\n if (this.strategiesSource.value[name] || this.isPredefinedStrategy(name)) {\n return name;\n } else {\n throw new Error(`No ' ${name} ' strategy is found please define one`);\n }\n }\n\n private isPredefinedStrategy(strategy: string): boolean {\n return strategy === NgxPermissionsPredefinedStrategies.SHOW || strategy === NgxPermissionsPredefinedStrategies.REMOVE;\n }\n\n}\n","export function isFunction<T>(value: any): value is T {\n return typeof value === 'function';\n}\n\nexport function isPlainObject(value: any): boolean {\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n } else {\n const prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n }\n}\n\nexport function isString(value: any): value is string {\n return !!value && typeof value === 'string';\n}\n\nexport function isBoolean(value: any): value is boolean {\n return typeof value === 'boolean';\n}\n\nexport function isPromise(promise: any) {\n return Object.prototype.toString.call(promise) === '[object Promise]';\n}\n\nexport function notEmptyValue(value: string | string[]): boolean {\n if (Array.isArray(value)) {\n return value.length > 0;\n }\n return !!value;\n}\n\nexport function transformStringToArray(value: string | string[]): string[] {\n if (isString(value)) {\n return [value];\n }\n return value;\n}\n","import { Injectable } from '@angular/core';\nimport { BehaviorSubject, Observable } from 'rxjs';\n\n@Injectable()\nexport class NgxPermissionsStore {\n\n public permissionsSource = new BehaviorSubject<{}>({});\n public permissions$: Observable<{}> = this.permissionsSource.asObservable();\n\n}\n","import { Inject, Injectable, InjectionToken } from '@angular/core';\n\nimport { BehaviorSubject, from, Observable, ObservableInput, of } from 'rxjs';\nimport { catchError, first, map, mergeAll, switchMap } from 'rxjs/operators';\n\nimport { NgxPermission } from '../model/permission.model';\nimport { ValidationFn } from '../model/permissions-router-data.model';\nimport { NgxPermissionsStore } from '../store/permissions.store';\n\nimport { isBoolean, isFunction, transformStringToArray } from '../utils/utils';\n\nexport interface NgxPermissionsObject {\n [name: string]: NgxPermission;\n}\n\nexport const USE_PERMISSIONS_STORE = new InjectionToken('USE_PERMISSIONS_STORE');\n\n@Injectable()\nexport class NgxPermissionsService {\n\n private permissionsSource: BehaviorSubject<NgxPermissionsObject>;\n public permissions$: Observable<NgxPermissionsObject>;\n\n constructor(\n @Inject(USE_PERMISSIONS_STORE) private isolate: boolean = false,\n private permissionsStore: NgxPermissionsStore\n ) {\n this.permissionsSource = this.isolate ? new BehaviorSubject<NgxPermissionsObject>({}) : this.permissionsStore.permissionsSource;\n this.permissions$ = this.permissionsSource.asObservable();\n }\n\n /**\n * Remove all permissions from permissions source\n */\n public flushPermissions(): void {\n this.permissionsSource.next({});\n }\n\n public hasPermission(permission: string | string[]): Promise<boolean> {\n if (!permission || (Array.isArray(permission) && permission.length === 0)) {\n return Promise.resolve(true);\n }\n\n permission = transformStringToArray(permission);\n return this.hasArrayPermission(permission);\n }\n\n public loadPermissions(permissions: string[], validationFunction?: ValidationFn): void {\n const newPermissions = permissions.reduce(\n (source, name) => this.reducePermission(source, name, validationFunction), {}\n );\n this.permissionsSource.next(newPermissions);\n }\n\n public addPermission(permission: string | string[], validationFunction?: ValidationFn): void {\n if (Array.isArray(permission)) {\n const permissions = permission.reduce(\n (source, name) => this.reducePermission(source, name, validationFunction), this.permissionsSource.value\n );\n\n this.permissionsSource.next(permissions);\n } else {\n const permissions = this.reducePermission(this.permissionsSource.value, permission, validationFunction);\n\n this.permissionsSource.next(permissions);\n }\n }\n\n public removePermission(permissionName: string): void {\n const permissions = {\n ...this.permissionsSource.value\n };\n delete permissions[permissionName];\n this.permissionsSource.next(permissions);\n }\n\n public getPermission(name: string): NgxPermission | undefined {\n return this.permissionsSource.value[name];\n }\n\n public getPermissions(): NgxPermissionsObject {\n return this.permissionsSource.value;\n }\n\n private reducePermission(source: NgxPermissionsObject, name: string, validationFunction?: ValidationFn): NgxPermissionsObject {\n if (!!validationFunction && isFunction(validationFunction)) {\n return {\n ...source,\n [name]: {name, validationFunction}\n };\n }\n return {\n ...source,\n [name]: {name}\n };\n }\n\n private hasArrayPermission(permissions: string[]): Promise<boolean> {\n const promises: Observable<boolean>[] = permissions.map(key => {\n if (this.hasPermissionValidationFunction(key)) {\n const validationFunction = this.permissionsSource.value[key].validationFunction;\n const immutableValue = {...this.permissionsSource.value};\n\n return of(null).pipe(\n map(() => validationFunction(key, immutableValue)),\n switchMap((promise: Promise<boolean> | boolean): ObservableInput<boolean> => isBoolean(promise) ?\n of(promise as boolean) : promise as Promise<boolean>),\n catchError(() => of(false))\n );\n }\n\n // check for name of the permission if there is no validation function\n return of(!!this.permissionsSource.value[key]);\n });\n\n return from(promises).pipe(\n mergeAll(),\n first((data) => data !== false, false),\n map((data) => data !== false)\n ).toPromise().then((data: any) => data);\n }\n\n private hasPermissionValidationFunction(key: string): boolean {\n return !!this.permissionsSource.value[key] &&\n !!this.permissionsSource.value[key].validationFunction &&\n isFunction(this.permissionsSource.value[key].validationFunction);\n }\n\n}\n","import { BehaviorSubject, Observable } from 'rxjs';\n\nexport class NgxRolesStore {\n\n public rolesSource = new BehaviorSubject<{}>({});\n\n public roles$: Observable<{}> = this.rolesSource.asObservable();\n\n}\n","import { Inject, Injectable, InjectionToken } from '@angular/core';\n\nimport { BehaviorSubject, from, Observable, ObservableInput, of } from 'rxjs';\nimport { catchError, every, first, map, mergeAll, mergeMap, switchMap } from 'rxjs/operators';\nimport { ValidationFn } from '../model/permissions-router-data.model';\n\nimport { NgxRole } from '../model/role.model';\nimport { NgxRolesStore } from '../store/roles.store';\nimport { isBoolean, isFunction, isPromise, transformStringToArray } from '../utils/utils';\nimport { NgxPermissionsService } from './permissions.service';\n\nexport const USE_ROLES_STORE = new InjectionToken('USE_ROLES_STORE');\n\nexport interface NgxRolesObject {\n [name: string]: NgxRole;\n}\n\n@Injectable()\nexport class NgxRolesService {\n\n private rolesSource: BehaviorSubject<NgxRolesObject>;\n\n public roles$: Observable<NgxRolesObject>;\n\n constructor(\n @Inject(USE_ROLES_STORE) private isolate: boolean = false,\n private rolesStore: NgxRolesStore,\n private permissionsService: NgxPermissionsService\n ) {\n this.rolesSource = this.isolate ? new BehaviorSubject<NgxRolesObject>({}) : this.rolesStore.rolesSource;\n this.roles$ = this.rolesSource.asObservable();\n }\n\n public addRole(name: string, validationFunction: ValidationFn | string[]) {\n const roles = {\n ...this.rolesSource.value,\n [name]: {name, validationFunction}\n };\n this.rolesSource.next(roles);\n }\n\n public addRoleWithPermissions(name: string, permissions: string[]) {\n this.permissionsService.addPermission(permissions);\n this.addRole(name, permissions);\n }\n\n public addRoles(rolesObj: { [name: string]: ValidationFn | string[] }) {\n Object.keys(rolesObj).forEach((key, index) => {\n this.addRole(key, rolesObj[key]);\n });\n }\n\n public addRolesWithPermissions(rolesObj: { [name: string]: string[] }) {\n Object.keys(rolesObj).forEach((key, index) => {\n this.addRoleWithPermissions(key, rolesObj[key]);\n });\n }\n\n public flushRoles() {\n this.rolesSource.next({});\n }\n\n public flushRolesAndPermissions() {\n this.flushRoles();\n this.permissionsService.flushPermissions();\n }\n\n public removeRole(roleName: string) {\n const roles = {\n ...this.rolesSource.value\n };\n delete roles[roleName];\n this.rolesSource.next(roles);\n }\n\n public getRoles(): NgxRolesObject {\n return this.rolesSource.value;\n }\n\n public getRole(name: string): NgxRole | undefined {\n return this.rolesSource.value[name];\n }\n\n public hasOnlyRoles(names: string | string[]): Promise<boolean> {\n const isNamesEmpty = !names || (Array.isArray(names) && names.length === 0);\n\n if (isNamesEmpty) {\n return Promise.resolve(true);\n }\n\n names = transformStringToArray(names);\n\n return Promise.all([this.hasRoleKey(names), this.hasRolePermission(this.rolesSource.value, names)])\n .then(([hasRoles, hasPermissions]: [boolean, boolean]) => {\n return hasRoles || hasPermissions;\n });\n }\n\n private hasRoleKey(roleName: string[]): Promise<boolean> {\n const promises: Observable<boolean>[] = roleName.map((key) => {\n const hasValidationFunction = !!this.rolesSource.value[key] &&\n !!this.rolesSource.value[key].validationFunction &&\n isFunction(this.rolesSource.value[key].validationFunction);\n\n if (hasValidationFunction && !isPromise(this.rolesSource.value[key].validationFunction)) {\n const validationFunction = this.rolesSource.value[key].validationFunction as ValidationFn;\n const immutableValue = {...this.rolesSource.value};\n\n return of(null).pipe(\n map(() => validationFunction(key, immutableValue)),\n switchMap((promise: Promise<boolean> | boolean): ObservableInput<boolean> => isBoolean(promise) ?\n of(promise as boolean) : promise as Promise<boolean>),\n catchError(() => of(false))\n );\n }\n\n return of(false);\n });\n\n return from(promises).pipe(\n mergeAll(),\n first((data: any) => data !== false, false),\n map((data) => data !== false)\n ).toPromise().then((data: any) => data);\n }\n\n private hasRolePermission(roles: NgxRolesObject, roleNames: string[]): Promise<boolean> {\n return from(roleNames).pipe(\n mergeMap((key) => {\n if (roles[key] && Array.isArray(roles[key].validationFunction)) {\n return from(<string[]>roles[key].validationFunction).pipe(\n mergeMap((permission) => this.permissionsService.hasPermission(permission)),\n every(hasPermission => hasPermission === true)\n );\n }\n\n return of(false);\n }),\n first(hasPermission => hasPermission === true, false)\n ).toPromise();\n }\n\n}\n","import {\n ChangeDetectorRef,\n Directive,\n EventEmitter,\n inject,\n Input,\n OnChanges,\n OnDestroy,\n OnInit,\n Output,\n SimpleChanges,\n TemplateRef,\n ViewContainerRef\n} from '@angular/core';\n\nimport { merge, Subscription } from 'rxjs';\nimport { skip, take } from 'rxjs/operators';\n\nimport { NgxPermissionsPredefinedStrategies } from '../enums/predefined-strategies.enum';\nimport { NgxPermissionsConfigurationService, StrategyFunction } from '../service/configuration.service';\nimport { NgxPermissionsService } from '../service/permissions.service';\nimport { NgxRolesService } from '../service/roles.service';\nimport { isBoolean, isFunction, isString, notEmptyValue } from '../utils/utils';\n\n@Directive({\n selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]',\n standalone: false\n})\nexport class NgxPermissionsDirective implements OnInit, OnDestroy, OnChanges {\n\n @Input() ngxPermissionsOnly: string | string[];\n @Input() ngxPermissionsOnlyThen: TemplateRef<any>;\n @Input() ngxPermissionsOnlyElse: TemplateRef<any>;\n\n @Input() ngxPermissionsExcept: string | string[];\n @Input() ngxPermissionsExceptElse: TemplateRef<any>;\n @Input() ngxPermissionsExceptThen: TemplateRef<any>;\n\n @Input() ngxPermissionsThen: TemplateRef<any>;\n @Input() ngxPermissionsElse: TemplateRef<any>;\n\n @Input() ngxPermissionsOnlyAuthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsOnlyUnauthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsExceptUnauthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsExceptAuthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsUnauthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsAuthorisedStrategy: string | StrategyFunction;\n\n @Output() permissionsAuthorized = new EventEmitter();\n @Output() permissionsUnauthorized = new EventEmitter();\n\n private initPermissionSubscription: Subscription;\n // skip first run cause merge will fire twice\n private firstMergeUnusedRun = 1;\n private currentAuthorizedState: boolean;\n\n private readonly permissionsService = inject(NgxPermissionsService);\n private readonly configurationService = inject(NgxPermissionsConfigurationService);\n private readonly rolesService = inject(NgxRolesService);\n private readonly viewContainer = inject(ViewContainerRef);\n private readonly changeDetector = inject(ChangeDetectorRef);\n private readonly templateRef = inject(TemplateRef<any>);\n\n ngOnInit(): void {\n this.viewContainer.clear();\n this.initPermissionSubscription = this.validateExceptOnlyPermissions();\n }\n\n\n ngOnChanges(changes: SimpleChanges): void {\n const onlyChanges = changes['ngxPermissionsOnly'];\n const exceptChanges = changes['ngxPermissionsExcept'];\n if (onlyChanges || exceptChanges) {\n // Due to bug when you pass empty array\n if (onlyChanges && onlyChanges.firstChange) {\n return;\n }\n if (exceptChanges && exceptChanges.firstChange) {\n return;\n }\n\n merge(this.permissionsService.permissions$, this.rolesService.roles$)\n .pipe(skip(this.firstMergeUnusedRun), take(1))\n .subscribe(() => {\n if (notEmptyValue(this.ngxPermissionsExcept)) {\n this.validateExceptAndOnlyPermissions();\n return;\n }\n\n if (notEmptyValue(this.ngxPermissionsOnly)) {\n this.validateOnlyPermissions();\n return;\n }\n\n this.handleAuthorisedPermission(this.getAuthorisedTemplates());\n });\n }\n }\n\n ngOnDestroy(): void {\n if (this.initPermissionSubscription) {\n this.initPermissionSubscription.unsubscribe();\n }\n }\n\n private validateExceptOnlyPermissions(): Subscription {\n return merge(this.permissionsService.permissions$, this.rolesService.roles$)\n .pipe(skip(this.firstMergeUnusedRun))\n .subscribe(() => {\n if (notEmptyValue(this.ngxPermissionsExcept)) {\n this.validateExceptAndOnlyPermissions();\n return;\n }\n\n if (notEmptyValue(this.ngxPermissionsOnly)) {\n this.validateOnlyPermissions();\n return;\n }\n this.handleAuthorisedPermission(this.getAuthorisedTemplates());\n });\n }\n\n private validateExceptAndOnlyPermissions(): void {\n Promise\n .all([\n this.permissionsService.hasPermission(this.ngxPermissionsExcept),\n this.rolesService.hasOnlyRoles(this.ngxPermissionsExcept)\n ])\n .then(([hasPermission, hasRole]) => {\n if (hasPermission || hasRole) {\n this.handleUnauthorisedPermission(this.ngxPermissionsExceptElse || this.ngxPermissionsElse);\n return;\n }\n\n if (!!this.ngxPermissionsOnly) {\n throw false;\n }\n\n this.handleAuthorisedPermission(this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef);\n })\n .catch(() => {\n if (!!this.ngxPermissionsOnly) {\n this.validateOnlyPermissions();\n } else {\n this.handleAuthorisedPermission(this.ngxPermissionsExceptThen || this.ngxPermissionsThen || this.templateRef);\n }\n });\n }\n\n private validateOnlyPermissions(): void {\n Promise\n .all([this.permissionsService.hasPermission(this.ngxPermissionsOnly), this.rolesService.hasOnlyRoles(this.ngxPermissionsOnly)])\n .then(([hasPermissions, hasRoles]) => {\n if (hasPermissions || hasRoles) {\n this.handleAuthorisedPermission(this.ngxPermissionsOnlyThen || this.ngxPermissionsThen || this.templateRef);\n } else {\n this.handleUnauthorisedPermission(this.ngxPermissionsOnlyElse || this.ngxPermissionsElse);\n }\n })\n .catch(() => {\n this.handleUnauthorisedPermission(this.ngxPermissionsOnlyElse || this.ngxPermissionsElse);\n });\n }\n\n private handleUnauthorisedPermission(template: TemplateRef<any>): void {\n if (isBoolean(this.currentAuthorizedState) && !this.currentAuthorizedState) {\n return;\n }\n\n this.currentAuthorizedState = false;\n this.permissionsUnauthorized.emit();\n\n if (this.getUnAuthorizedStrategyInput()) {\n this.applyStrategyAccordingToStrategyType(this.getUnAuthorizedStrategyInput());\n return;\n }\n\n if (this.configurationService.onUnAuthorisedDefaultStrategy && !this.elseBlockDefined()) {\n this.applyStrategy(this.configurationService.onUnAuthorisedDefaultStrategy);\n } else {\n this.showTemplateBlockInView(template);\n }\n\n }\n\n private handleAuthorisedPermission(template: TemplateRef<any>): void {\n if (isBoolean(this.currentAuthorizedState) && this.currentAuthorizedState) {\n return;\n }\n\n this.currentAuthorizedState = true;\n this.permissionsAuthorized.emit();\n\n if (this.getAuthorizedStrategyInput()) {\n this.applyStrategyAccordingToStrategyType(this.getAuthorizedStrategyInput());\n return;\n }\n\n if (this.configurationService.onAuthorisedDefaultStrategy && !this.thenBlockDefined()) {\n this.applyStrategy(this.configurationService.onAuthorisedDefaultStrategy);\n } else {\n this.showTemplateBlockInView(template);\n }\n }\n\n private applyStrategyAccordingToStrategyType(strategy: string | StrategyFunction): void {\n if (isString(strategy)) {\n this.applyStrategy(strategy);\n return;\n }\n\n if (isFunction(strategy)) {\n this.showTemplateBlockInView(this.templateRef);\n (strategy as StrategyFunction)(this.templateRef);\n return;\n }\n }\n\n private showTemplateBlockInView(template: TemplateRef<any>): void {\n this.viewContainer.clear();\n if (!template) {\n return;\n }\n\n this.viewContainer.createEmbeddedView(template);\n this.changeDetector.markForCheck();\n }\n\n private getAuthorisedTemplates(): TemplateRef<any> {\n return this.ngxPermissionsOnlyThen\n || this.ngxPermissionsExceptThen\n || this.ngxPermissionsThen\n || this.templateRef;\n }\n\n private elseBlockDefined(): boolean {\n return !!this.ngxPermissionsExceptElse || !!this.ngxPermissionsElse;\n }\n\n private thenBlockDefined() {\n return !!this.ngxPermissionsExceptThen || !!this.ngxPermissionsThen;\n }\n\n private getAuthorizedStrategyInput() {\n return this.ngxPermissionsOnlyAuthorisedStrategy ||\n this.ngxPermissionsExceptAuthorisedStrategy ||\n this.ngxPermissionsAuthorisedStrategy;\n }\n\n private getUnAuthorizedStrategyInput() {\n return this.ngxPermissionsOnlyUnauthorisedStrategy ||\n this.ngxPermissionsExceptUnauthorisedStrategy ||\n this.ngxPermissionsUnauthorisedStrategy;\n }\n\n private applyStrategy(name: string) {\n if (name === NgxPermissionsPredefinedStrategies.SHOW) {\n this.showTemplateBlockInView(this.templateRef);\n return;\n }\n\n if (name === NgxPermissionsPredefinedStrategies.REMOVE) {\n this.viewContainer.clear();\n return;\n }\n const strategy = this.configurationService.getStrategy(name);\n this.showTemplateBlockInView(this.templateRef);\n strategy(this.templateRef);\n }\n}\n","import { ActivatedRouteSnapshot, NavigationExtras, Route, RouterStateSnapshot } from '@angular/router';\n\nexport interface NgxPermissionsRouterData {\n only?: string | string[] | OnlyFn;\n except?: string | string[] | ExceptFn;\n redirectTo?: RedirectTo | RedirectToFn;\n}\n\nexport interface NgxRedirectToNavigationParameters {\n navigationCommands: any[] | NavigationCommandsFn;\n navigationExtras?: NavigationExtras | NavigationExtrasFn;\n}\n\nexport declare type OnlyFn = (route: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) => string | string[];\nexport declare type ExceptFn = (route: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) => string | string[];\n\nexport declare type RedirectTo =\n string\n | { [name: string]: NgxRedirectToNavigationParameters | string | RedirectToFn }\n | NgxRedirectToNavigationParameters;\nexport declare type RedirectToFn =\n (rejectedPermissionName?: string, route?: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) => RedirectTo;\n\nexport declare type NavigationCommandsFn = (route: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) => any[];\nexport declare type NavigationExtrasFn = (route: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) => NavigationExtras;\nexport declare type ValidationFn = ((name?: string, store?: any) => Promise<void | string | boolean> | boolean | string[]);\n\nexport const DEFAULT_REDIRECT_KEY = 'default';\n","import { inject, Injectable } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivateChildFn,\n CanActivateFn,\n CanMatchFn,\n NavigationExtras,\n Route,\n Router,\n RouterStateSnapshot,\n UrlSegment\n} from '@angular/router';\n\nimport { forkJoin, from, Observable, of } from 'rxjs';\nimport { first, mergeMap, tap } from 'rxjs/operators';\n\nimport {\n DEFAULT_REDIRECT_KEY,\n ExceptFn,\n NavigationCommandsFn,\n NavigationExtrasFn,\n NgxPermissionsRouterData,\n NgxRedirectToNavigationParameters,\n OnlyFn,\n RedirectTo,\n RedirectToFn\n} from '../model/permissions-router-data.model';\nimport { NgxPermissionsService } from '../service/permissions.service';\nimport { NgxRolesService } from '../service/roles.service';\nimport { isFunction, isPlainObject, transformStringToArray } from '../utils/utils';\n\nexport interface NgxPermissionsData {\n only?: string | string[];\n except?: string | string[];\n redirectTo?: RedirectTo | RedirectToFn;\n}\n\nexport const ngxPermissionsGuard: CanActivateFn | CanActivateChildFn | CanMatchFn = (route: ActivatedRouteSnapshot | Route, state: RouterStateSnapshot | UrlSegment[]) => {\n const permissionsGuard = inject(NgxPermissionsGuard);\n if (state instanceof RouterStateSnapshot) {\n return permissionsGuard.hasPermissions(route, state);\n }\n return permissionsGuard.hasPermissions(route);\n}\n\n/**\n * @deprecated Use {@link ngxPermissionsGuard} instead\n */\n@Injectable()\nexport class NgxPermissionsGuard {\n\n constructor(private permissionsService: NgxPermissionsService, private rolesService: NgxRolesService, private router: Router) {\n }\n\n canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> | boolean {\n return this.hasPermissions(route, state);\n }\n\n canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {\n return this.hasPermissions(childRoute, state);\n }\n\n canLoad(route: Route): boolean | Observable<boolean> | Promise<boolean> {\n return this.hasPermissions(route);\n }\n\n canMatch(route: Route): boolean | Observable<boolean> | Promise<boolean> {\n return this.hasPermissions(route);\n }\n\n hasPermissions(route: ActivatedRouteSnapshot | Route, state?: RouterStateSnapshot) {\n const routeDataPermissions = !!route && route.data ? (route.data['permissions'] as NgxPermissionsRouterData) : {};\n const permissions = this.transformPermission(routeDataPermissions, route, state);\n\n if (this.isParameterAvailable(permissions.except)) {\n return this.passingExceptPermissionsValidation(permissions, route, state);\n }\n\n if (this.isParameterAvailable(permissions.only)) {\n return this.passingOnlyPermissionsValidation(permissions, route, state);\n }\n\n return true;\n }\n\n private transformPermission(\n permissions: NgxPermissionsRouterData,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): NgxPermissionsData {\n const only = isFunction<OnlyFn>(permissions.only)\n ? permissions.only(route, state)\n : transformStringToArray(permissions.only);\n const except = isFunction<ExceptFn>(permissions.except)\n ? permissions.except(route, state)\n : transformStringToArray(permissions.except);\n const redirectTo = permissions.redirectTo;\n\n\n return {\n only,\n except,\n redirectTo\n };\n }\n\n private isParameterAvailable(permission: string | string[]) {\n return !!permission && permission.length > 0;\n }\n\n private passingExceptPermissionsValidation(\n permissions: NgxPermissionsData,\n route: ActivatedRouteSnapshot | Route,\n state: RouterStateSnapshot\n ): Promise<boolean> {\n if (\n !!permissions.redirectTo\n && (\n (isFunction<RedirectToFn>(permissions.redirectTo))\n || (isPlainObject(permissions.redirectTo) && !this.isRedirectionWithParameters(permissions.redirectTo))\n )\n ) {\n let failedPermission = '';\n\n return from(permissions.except)\n .pipe(\n mergeMap(permissionsExcept => {\n return forkJoin([\n this.permissionsService.hasPermission(permissionsExcept),\n this.rolesService.hasOnlyRoles(permissionsExcept)\n ]).pipe(\n tap(hasPermissions => {\n const dontHavePermissions = hasPermissions.every(hasPermission => hasPermission === false);\n\n if (!dontHavePermissions) {\n failedPermission = permissionsExcept;\n }\n })\n );\n }),\n first(hasPermissions => hasPermissions.some(hasPermission => hasPermission === true), false),\n mergeMap(isAllFalse => {\n if (!!failedPermission) {\n this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state);\n\n return of(false);\n }\n\n if (!isAllFalse && permissions.only) {\n return this.onlyRedirectCheck(permissions, route, state);\n }\n\n return of(!isAllFalse);\n })\n )\n .toPromise();\n }\n\n return Promise.all([\n this.permissionsService.hasPermission(permissions.except),\n this.rolesService.hasOnlyRoles(permissions.except)\n ]).then(([hasPermission, hasRoles]) => {\n if (hasPermission || hasRoles) {\n if (permissions.redirectTo) {\n this.redirectToAnotherRoute(\n permissions.redirectTo,\n route,\n state\n );\n }\n\n return false;\n }\n\n if (permissions.only) {\n return this.checkOnlyPermissions(permissions, route, state);\n }\n return true;\n });\n }\n\n private redirectToAnotherRoute(\n permissionRedirectTo: RedirectTo | RedirectToFn,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot,\n failedPermissionName?: string\n ): void {\n\n const redirectTo = isFunction<RedirectToFn>(permissionRedirectTo)\n ? permissionRedirectTo(failedPermissionName, route, state)\n : permissionRedirectTo;\n\n if (this.isRedirectionWithParameters(redirectTo)) {\n redirectTo.navigationCommands = this.transformNavigationCommands(redirectTo.navigationCommands, route, state);\n redirectTo.navigationExtras = this.transformNavigationExtras(redirectTo.navigationExtras, route, state);\n this.router.navigate(redirectTo.navigationCommands, redirectTo.navigationExtras);\n return;\n }\n\n if (Array.isArray(redirectTo)) {\n this.router.navigate(redirectTo);\n } else {\n this.router.navigate([redirectTo]);\n }\n }\n\n private isRedirectionWithParameters(object: any | NgxRedirectToNavigationParameters): object is NgxRedirectToNavigationParameters {\n return (isPlainObject(object) && (!!object.navigationCommands || !!object.navigationExtras));\n }\n\n private transformNavigationCommands(\n navigationCommands: any[] | NavigationCommandsFn,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): any[] {\n return isFunction<NavigationCommandsFn>(navigationCommands)\n ? navigationCommands(route, state)\n : navigationCommands;\n }\n\n private transformNavigationExtras(\n navigationExtras: NavigationExtras | NavigationExtrasFn,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): NavigationExtras {\n return isFunction<NavigationExtrasFn>(navigationExtras)\n ? navigationExtras(route, state)\n : navigationExtras;\n }\n\n private onlyRedirectCheck(\n permissions: NgxPermissionsData,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): Promise<boolean> {\n let failedPermission = '';\n\n return from(permissions.only)\n .pipe(\n mergeMap(permissionsOnly => {\n return forkJoin([\n this.permissionsService.hasPermission(permissionsOnly),\n this.rolesService.hasOnlyRoles(permissionsOnly)\n ]).pipe(\n tap(hasPermissions => {\n const failed = hasPermissions.every(hasPermission => hasPermission === false);\n\n if (failed) {\n failedPermission = permissionsOnly;\n }\n })\n );\n }),\n first(hasPermissions => {\n if (isFunction<RedirectToFn>(permissions.redirectTo)) {\n return hasPermissions.some(hasPermission => hasPermission === true);\n }\n\n return hasPermissions.every(hasPermission => hasPermission === false);\n },\n false),\n mergeMap(\n (pass: boolean): Observable<boolean> => {\n if (isFunction<RedirectToFn>(permissions.redirectTo)) {\n if (pass) {\n return of(true);\n } else {\n this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state);\n return of(false);\n }\n } else {\n if (!!failedPermission) {\n this.handleRedirectOfFailedPermission(permissions, failedPermission, route, state);\n }\n return of(!pass);\n }\n }\n )\n )\n .toPromise();\n }\n\n private handleRedirectOfFailedPermission(\n permissions: NgxPermissionsData,\n failedPermission: string,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ) {\n if (this.isFailedPermissionPropertyOfRedirectTo(permissions, failedPermission)) {\n this.redirectToAnotherRoute(permissions.redirectTo[failedPermission], route, state, failedPermission);\n } else {\n if (isFunction<RedirectToFn>(permissions.redirectTo)) {\n this.redirectToAnotherRoute(permissions.redirectTo, route, state, failedPermission);\n } else {\n this.redirectToAnotherRoute(permissions.redirectTo[DEFAULT_REDIRECT_KEY], route, state, failedPermission);\n }\n }\n }\n\n private isFailedPermissionPropertyOfRedirectTo(permissions: NgxPermissionsData, failedPermission: string): boolean {\n return (!!permissions.redirectTo && permissions.redirectTo[failedPermission]);\n }\n\n private checkOnlyPermissions(\n purePermissions: NgxPermissionsData,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): Promise<boolean> {\n const permissions: NgxPermissionsData = {\n ...purePermissions\n };\n\n return Promise.all([\n this.permissionsService.hasPermission(permissions.only),\n this.rolesService.hasOnlyRoles(permissions.only)\n ]).then(([hasPermission, hasRole]) => {\n if (hasPermission || hasRole) {\n return true;\n }\n\n if (permissions.redirectTo) {\n this.redirectToAnotherRoute(permissions.redirectTo, route, state);\n }\n\n return false;\n });\n }\n\n private passingOnlyPermissionsValidation(\n permissions: NgxPermissionsData,\n route: ActivatedRouteSnapshot | Route,\n state?: RouterStateSnapshot\n ): Promise<boolean> {\n if (\n (isFunction<RedirectToFn>(permissions.redirectTo)\n || isPlainObject(permissions.redirectTo) && !this.isRedirectionWithParameters(permissions.redirectTo))\n ) {\n return this.onlyRedirectCheck(permissions, route, state);\n }\n return this.checkOnlyPermissions(permissions, route, state);\n }\n}\n","import { Directive, EventEmitter, inject, Input, OnInit, Output, TemplateRef, ViewContainerRef } from '@angular/core';\nimport { StrategyFunction } from '../service/configuration.service';\n\n@Directive({\n standalone: true,\n selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]',\n})\nexport class NgxPermissionsAllowStubDirective implements OnInit {\n @Input() ngxPermissionsOnly: string | string[];\n @Input() ngxPermissionsOnlyThen: TemplateRef<any>;\n @Input() ngxPermissionsOnlyElse: TemplateRef<any>;\n\n @Input() ngxPermissionsExcept: string | string[];\n @Input() ngxPermissionsExceptElse: TemplateRef<any>;\n @Input() ngxPermissionsExceptThen: TemplateRef<any>;\n\n @Input() ngxPermissionsThen: TemplateRef<any>;\n @Input() ngxPermissionsElse: TemplateRef<any>;\n\n @Input() ngxPermissionsOnlyAuthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsOnlyUnauthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsExceptUnauthorisedStrategy:\n | string\n | StrategyFunction;\n @Input() ngxPermissionsExceptAuthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsUnauthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsAuthorisedStrategy: string | StrategyFunction;\n\n @Output() permissionsAuthorized = new EventEmitter();\n @Output() permissionsUnauthorized = new EventEmitter();\n\n private viewContainer = inject(ViewContainerRef);\n private templateRef = inject(TemplateRef<any>);\n\n ngOnInit(): void {\n this.viewContainer.clear();\n this.viewContainer.createEmbeddedView(this.getAuthorizedTemplate());\n this.permissionsAuthorized.emit();\n }\n\n private getAuthorizedTemplate() {\n return (\n this.ngxPermissionsOnlyThen ||\n this.ngxPermissionsExceptThen ||\n this.ngxPermissionsThen ||\n this.templateRef\n );\n }\n}\n","import { Directive, EventEmitter, inject, Input, OnInit, Output, TemplateRef, ViewContainerRef } from '@angular/core';\nimport { StrategyFunction } from '../service/configuration.service';\n\n@Directive({\n standalone: true,\n selector: '[ngxPermissionsOnly],[ngxPermissionsExcept]',\n})\nexport class NgxPermissionsRestrictStubDirective implements OnInit {\n @Input() ngxPermissionsOnly: string | string[];\n @Input() ngxPermissionsOnlyThen: TemplateRef<any>;\n @Input() ngxPermissionsOnlyElse: TemplateRef<any>;\n\n @Input() ngxPermissionsExcept: string | string[];\n @Input() ngxPermissionsExceptElse: TemplateRef<any>;\n @Input() ngxPermissionsExceptThen: TemplateRef<any>;\n\n @Input() ngxPermissionsThen: TemplateRef<any>;\n @Input() ngxPermissionsElse: TemplateRef<any>;\n\n @Input() ngxPermissionsOnlyAuthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsOnlyUnauthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsExceptUnauthorisedStrategy:\n | string\n | StrategyFunction;\n @Input() ngxPermissionsExceptAuthorisedStrategy: string | StrategyFunction;\n\n @Input() ngxPermissionsUnauthorisedStrategy: string | StrategyFunction;\n @Input() ngxPermissionsAuthorisedStrategy: string | StrategyFunction;\n\n @Output() permissionsAuthorized = new EventEmitter();\n @Output() permissionsUnauthorized = new EventEmitter();\n\n private viewContainer = inject(ViewContainerRef);\n\n ngOnInit(): void {\n this.viewContainer.clear();\n if (this.getUnAuthorizedTemplate()) {\n this.viewContainer.createEmbeddedView(\n this.getUnAuthorizedTemplate()\n );\n }\n this.permissionsUnauthorized.emit();\n }\n\n private getUnAuthorizedTemplate() {\n return (\n this.ngxPermissionsOnlyElse ||\n this.ngxPermissionsExceptElse ||\n this.ngxPermissionsElse\n );\n }\n}\n","import { NgModule, ModuleWithProviders } from '@angular/core';\nimport { NgxPermissionsDirective } from './directive/permissions.directive';\nimport { NgxPermissionsService, USE_PERMISSIONS_STORE } from './service/permissions.service';\nimport { NgxPermissionsGuard } from './router/permissions-guard.service';\nimport { NgxRolesService, USE_ROLES_STORE } from './service/roles.service';\nimport { NgxPermissionsStore } from './store/permissions.store';\nimport { NgxRolesStore } from './store/roles.store';\nimport { NgxPermissionsAllowStubDirective } from './testing/permissions-allow.directive.stub';\nimport { NgxPermissionsRestrictStubDirective } from './testing/permissions-restrict.directive.stub';\nimport { NgxPermissionsConfigurationService, USE_CONFIGURATION_STORE } from './service/configuration.service';\nimport { NgxPermissionsConfigurationStore } from './store/configuration.store';\n\nexport * from './store/roles.store';\nexport * from './store/permissions.store';\nexport * from './store/configuration.store';\n\nexport * from './directive/permissions.directive';\n\nexport * from './service/permissions.service';\nexport * from './service/roles.service';\nexport * from './service/configuration.service';\n\nexport * from './router/permissions-guard.service';\n\nexport * from './model/permissions-router-data.model';\nexport * from './model/role.model';\n\nexport * from './testing/permissions-allow.directive.stub';\nexport * from './testing/permissions-restrict.directive.stub';\n\nexport * from './enums/predefined-strategies.enum';\n\nexport interface NgxPermissionsModuleConfig {\n // isolate the service instance, only works for lazy loaded modules or components with the \"providers\" property\n rolesIsolate?: boolean;\n permissionsIsolate?: boolean;\n configurationIsolate?: boolean;\n}\n\n\n@NgModule({\n imports: [],\n declarations: [\n NgxPermissionsDirective\n ],\n exports: [\n NgxPermissionsDirective\n ]\n})\nexport class NgxPermissionsModule {\n static forRoot(config: NgxPermissionsModuleConfig = {}): ModuleWithProviders<NgxPermissionsModule> {\n return {\n ngModule: NgxPermissionsModule,\n providers: [\n NgxPermissionsStore,\n NgxRolesStore,\n NgxPermissionsConfigurationStore,\n NgxPermissionsService,\n NgxPermissionsGuard,\n NgxRolesService,\n NgxPermissionsConfigurationService,\n {provide: USE_PERMISSIONS_STORE, useValue: config.permissionsIsolate},\n {provide: USE_ROLES_STORE, useValue: config.rolesIsolate},\n {provide: USE_CONFIGURATION_STORE, useValue: config.configurationIsolate},\n ]\n };\n }\n\n static forChild(config: NgxPermissionsModuleConfig = {}): ModuleWithProviders<NgxPermissionsModule> {\n return {\n ngModule: NgxPermissionsModule,\n providers: [\n {provide: USE_PERMISSIONS_STORE, useValue: config.permissionsIsolate},\n {provide: USE_ROLES_STORE, useValue: config.rolesIsolate},\n {provide: USE_CONFIGURATION_STORE, useValue: config.configurationIsolate},\n NgxPermissionsConfigurationService,\n NgxPermissionsService,\n NgxRolesService,\n NgxPermissionsGuard\n ]\n };\n }\n}\n\n@NgModule({\n imports: [NgxPermissionsAllowStubDirective],\n declarations: [],\n exports: [\n NgxPermissionsAllowStubDirective\n ]\n})\nexport class NgxPermissionsAllowStubModule {\n}\n\n\n@NgModule({\n imports: [NgxPermissionsRestrictStubDirective],\n declarations: [],\n exports: [\n NgxPermissionsRestrictStubDirective\n ]\n})\nexport class NgxPermissionsRestrictStubModule {\n}\n\n\n","/*\n * Public API Surface of ngx-permissions\n */\n\nexport * from './lib/index';\n","/**\n * Generated bundle index. Do not edit.\n */\n\n