{"id":13495768,"url":"https://github.com/AlexKhymenko/ngx-permissions","last_synced_at":"2025-03-28T16:33:18.609Z","repository":{"id":24056900,"uuid":"100498112","full_name":"AlexKhymenko/ngx-permissions","owner":"AlexKhymenko","description":"Permission and roles based access control for your angular(angular 2,4,5,6,7,9+) applications(AOT, lazy modules compatible","archived":false,"fork":false,"pushed_at":"2025-02-05T13:29:03.000Z","size":4762,"stargazers_count":947,"open_issues_count":30,"forks_count":129,"subscribers_count":24,"default_branch":"master","last_synced_at":"2025-03-22T08:01:37.543Z","etag":null,"topics":["access","access-control","acl","angular","angular-permissions","angular2","angular2-permission","angular2-permissions","angular4","angular5","ng-permission","ng2-permissions","ngx-permission","ngx-permissions","permissions","rbac","roles"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexKhymenko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-16T14:26:45.000Z","updated_at":"2025-03-15T07:06:22.000Z","dependencies_parsed_at":"2023-11-30T06:28:39.328Z","dependency_job_id":"3b50a3b1-713a-41ed-8408-293ae2f64ac0","html_url":"https://github.com/AlexKhymenko/ngx-permissions","commit_stats":{"total_commits":383,"total_committers":12,"mean_commits":"31.916666666666668","dds":"0.18537859007832902","last_synced_commit":"c0548903a00a4111576350a9afacbb70fb1f9600"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexKhymenko%2Fngx-permissions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexKhymenko%2Fngx-permissions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexKhymenko%2Fngx-permissions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexKhymenko%2Fngx-permissions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexKhymenko","download_url":"https://codeload.github.com/AlexKhymenko/ngx-permissions/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246063219,"owners_count":20717773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access","access-control","acl","angular","angular-permissions","angular2","angular2-permission","angular2-permissions","angular4","angular5","ng-permission","ng2-permissions","ngx-permission","ngx-permissions","permissions","rbac","roles"],"created_at":"2024-07-31T19:01:38.008Z","updated_at":"2025-03-28T16:33:18.474Z","avatar_url":"https://github.com/AlexKhymenko.png","language":"TypeScript","funding_links":["https://patreon.com/alexKhymenko","https://www.buymeacoffee.com/alexKhymenko"],"categories":["Uncategorized","Security and Authentication","TypeScript","Awesome Angular [![Awesome TipeIO](https://img.shields.io/badge/Awesome%20Angular-@TipeIO-6C6AE7.svg)](https://github.com/gdi2290/awesome-angular) [![Awesome devarchy.com](https://img.shields.io/badge/Awesome%20Angular-@devarchy.com-86BDC1.svg)](https://github.com/brillout/awesome-angular-components)","Dependencies"],"sub_categories":["Uncategorized","Role-Based Access Control","Angular \u003ca id=\"angular\"\u003e\u003c/a\u003e","Modules"],"readme":"# ngx-permissions\n\nPermission and roles based access control for your angular(angular 2,4,5,6,7,8+) applications(AOT, lazy modules compatible)\n\n## Disclaimer\n```diff\n- This library is PROHIBITED to use with russians projects or russians or belarusians \n```\nWe are against any forms of discrimination. We respect sanctions. We don’t support agressors\n\nreason https://9gag.com/gag/a41zRvw and many more\n\nIf You can help Ukrainian army https://bank.gov.ua/en/about/support-the-armed-forces\n\nHumanitarian aid https://bank.gov.ua/en/about/humanitarian-aid-to-ukraine\n\nAny help is welcomed.\n\n##\n\n[![Build Status](https://travis-ci.org/AlexKhymenko/ngx-permissions.svg?branch=master)](https://travis-ci.org/AlexKhymenko/ngx-permissions)\n[![codecov](https://codecov.io/gh/AlexKhymenko/ngx-permissions/branch/master/graph/badge.svg)](https://codecov.io/gh/AlexKhymenko/ngx-permissions)\n[![npm version](https://badge.fury.io/js/ngx-permissions.svg)](https://badge.fury.io/js/ngx-permissions)\n![npm](https://img.shields.io/npm/dm/ngx-permissions)\n\n## Documentation and examples\nDocumentation here is outdated please visit [wiki-page](https://github.com/AlexKhymenko/ngx-permissions/wiki).\nTo see better structured documentation go to [wiki-page](https://github.com/AlexKhymenko/ngx-permissions/wiki).  \nIn `one month` the detailed functionality description will be available only on wiki page.\n\n## Demo\nYou can test library in [Plunker](https://plnkr.co/edit/n6Wa6hXg0JzI6e050wBt?p=preview)\n\n## YouTube\nI'm working on tutorial for the library will add more video with time. This is my first videos [YouTube](https://www.youtube.com/playlist?list=PLHw3vRAUIqUOLqBpoR-eYvZxiPGPh18y5)\n\n## Support\nIf You have chance please support on patreon for more open source ideas  [![Support me on Patreon](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3DalexKhymenko%26type%3Dpatrons\u0026style=flat)](https://patreon.com/alexKhymenko)\n\nOr on buy me a coffee [![BuyMeACoffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-ffdd00?style=for-the-badge\u0026logo=buy-me-a-coffee\u0026logoColor=black)](https://www.buymeacoffee.com/alexKhymenko)\n\n## Table of contents\n\nSome functionality is missing visit [wiki-page](https://github.com/AlexKhymenko/ngx-permissions/wiki)\n\n- [Installation](#installation)\n- [Consuming library](#consuming-library)\n- [Managing Permissions](#managing-permissions)\n- [Managing Roles](#managing-roles)\n- [Controlling access in views](#controlling-access-in-views)\n- [Usage with Routes](#usage-with-routes)\n- [Development](#development)\n- [License](#license)\n\n## Compatibility matrix\n\n| Library Version | Angular Version | RxJS Version   |\n|-----------------|-----------------|----------------|\n| 19              | \u003e19.0.0         | -              |\n| 13              | \u003e13.0.0         | -              |\n| 7               | \u003e8.0.0 \u003c 13.0.0 | -              |\n| 5               | \u003e4.0.0 \u003c 8.0.0  | \u003e6.0.0         |\n| 4               | \u003e4.0.0 \u003c 8.0.0  | \u003e5.5.0         |\n| 2               | \u003e4.0.0 \u003c 8.0.0  | -              |\n| 1               | \u003e2.0.0 \u003c 4.0.0  | -              |\n\n\n## Installation\n\nTo install this library, run:\n\n```bash\n$ npm install ngx-permissions --save\n```\n\n## Consuming library\n\nYou can import library in any Angular application by running:\n\n```bash\n$ npm install ngx-permissions  --save\n```\n\nand then from your Angular `AppModule`:\n\n```typescript\nimport { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\n\nimport { AppComponent } from './app.component';\n\n// Import your library\nimport { NgxPermissionsModule } from 'ngx-permissions';\n\n@NgModule({\n  declarations: [\n    AppComponent\n  ],\n  imports: [\n    BrowserModule,\n\n    // Specify your library as an import\n     NgxPermissionsModule.forRoot()\n  ],\n  providers: [],\n  bootstrap: [AppComponent]\n})\nexport class AppModule { }\n```\n\nSharedModule\n\nIf you use a SharedModule that you import in multiple other feature modules, you can export the NgxPermissionsModule to make sure you don't have to import it in every module.\n```typescript\n@NgModule({\n    exports: [\n        CommonModule,\n        NgxPermissionsModule\n    ]\n})\nexport class SharedModule { }\n```\n\u003e Note: Never call a forRoot static method in the SharedModule. You might end up with different instances of the service in your injector tree. But you can use forChild if necessary.\n\n##### Lazy loaded modules\n\nWhen you lazy load a module, you should use the `forChild` static method to import the `NgxPermissionsModule`.\n\nSince lazy loaded modules use a different injector from the rest of your application, you can configure them separately.\nYou can also isolate the service by using `permissionsIsolate: true` or `rolesIsolate: true`. In which case the service is a completely isolated instance.\nOtherwise, by default, it will share its data with other instances of the service.\n\n```typescript\n@NgModule({\n    imports: [\n        NgxPermissionsModule.forChild()\n    ]\n})\nexport class LazyLoadedModule { }\n```\n\n```typescript\n@NgModule({\n    imports: [\n        NgxPermissionsModule.forChild({\n        permissionsIsolate: true, \n        rolesIsolate: true})\n    ]\n})\nexport class LazyIsolatedLoadedModule { }\n```\n\n\nOnce your library is imported, you can use its components, directives and pipes in your Angular application:\n\nImport service to the main application and load permissions\n\n```typescript\nimport { Component, OnInit } from '@angular/core';\nimport { NgxPermissionsService } from 'ngx-permissions';\nimport { HttpClient } from '@angular/common/http';\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html',\n  styleUrls: ['./app.component.scss']\n})\nexport class AppComponent implements OnInit {\n\n  title = 'app';\n\n   constructor(private permissionsService: NgxPermissionsService,\n               private http: HttpClient) {}\n\n  ngOnInit(): void {\n    const perm = [\"ADMIN\", \"EDITOR\"];\n\n    this.permissionsService.loadPermissions(perm);\n    \n     this.http.get('url').subscribe((permissions) =\u003e {\n       //const perm = [\"ADMIN\", \"EDITOR\"]; example of permissions\n       this.permissionsService.loadPermissions(permissions);\n    })\n  }\n}\n```\n\nUsage in templates \n\n```html\n\u003cdiv *ngxPermissionsOnly=\"['ADMIN', 'GUEST']\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n\u003c/div\u003e\n\n\u003cng-template ngxPermissionsOnly=\"ADMIN\"\u003e\n  \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n \u003c/ng-template\u003e\n \n \u003cng-template [ngxPermissionsExcept]=\"['JOHNY']\"\u003e\n   \u003cdiv\u003e All will see it except JOHNY\u003c/div\u003e\n \u003c/ng-template\u003e\n```\n### Managing permissions\n\n\nOverview\n----------------------------\n\n1. [Introduction](#introduction)\n2. [Defining permissions](#defining-permissions)\n  1. [Individual permissions](#individual-permissions)\n  2. [To load permissions before application start up](#to-load-permissions-before-application-start-up)\n  3. [Multiple permissions](#multiple-permissions)\n3. [Removing permissions](#removing-permissions)\n4. [Retrieving permissions](#retrieving-permissions)\n\nIntroduction\n----------------------------\n\nLet's start with little explanation **what** permission is. Permission is the most atomic **ability** that a user can have \nin your application. So you can think about permission as a smallest action that user can do inside your site. \n\nBut can `user` or `anonymous` be a permission? Technically yes, but from business point of view you should treat them \nas Roles that are more complex objects that can store more complex logic. \n\n\u003e :bulb: **Note**   \n\u003e It's a good convention to start permission with a verb and combine them with resource or object, so permissions like `readDocuments` or `listSongs` \nare meaningful and easy to understand for other programmes. Notice that they are named lowerCamelCase for easy differentiation form roles.\n\n\u003e :skull: **Warning**   \n\u003e This library is intended for simplify the client side development workflow in a role based web application. **DO NOT RELY ONLY ON THIS CHECKS FOR YOU APPLICATION SECURITY!** Client side checks can be easily bypassed, so always implement the checks on the backend!\n \nDefining permissions\n----------------------------\nSo, how do you tell Permission what does 'readDocuments' or 'listSongs' mean and how to know if the current user belongs\nto those definitions?\n\nWell, Permission allows you to set different 'permissions' definitions along with the logic that determines if the current \nsession belongs to them. To do that library exposes special container `NgxPermissionsService` that allows you to manipulate them freely.\n\n### Individual permissions\n\nTo add permissions individually `NgxPermissionsService` exposes method `addPermission` that generic usage is shown below or add as array: \n\n```typescript\n[...]\n ngOnInit() {\n    this.permissionsService.addPermission('changeSomething')\n    this.permissionsService.addPermission(['changeSomething', 'anotherAlso'])\n    this.permissionsService.addPermission('changeSomething', () =\u003e {\n        return true;\n    })\n     \n    this.permissionsService.addPermission('anotherPermissions', (permissionName, permissionsObject) =\u003e {\n        return !!permissionsObject[permissionName];\n    });\n    this.permissionsService.addPermission(['anotherPermissions', 'AnotherOne'], (permissionName, permissionsObject) =\u003e {\n        return !!permissionsObject[permissionName];\n    });\n     \n    //Will add validation function to every permission\n     this.permissionsService.addPermission(['anotherPermissions', 'AnotherOne'], (permissionName, permissionsObject) =\u003e {\n         return !!permissionsObject[permissionName];\n     });\n     \n     this.permissionsService.addPermission('permissions', (permissionName, permissionsObject) =\u003e {\n       return this.checkSession().toPromise();\n     });\n }\n\n```\n\n### To load permissions before application start up\n\nAPP_INITIALIZER is defined in angular/core. You include it in your app.module.ts like this.\n\n\nAPP_INITIALIZER is an OpaqueToken that references the ApplicationInitStatus service. ApplicationInitStatus is a multi provider. It supports multiple dependencies and you can use it in your providers list multiple times. It is used like this.\n```typescript\nimport { APP_INITIALIZER } from '@angular/core';\n\n@NgModule({\n  providers: [\n    DictionaryService,\n    {\n      provide: APP_INITIALIZER,\n      useFactory: (ds: DictionaryService, ps: NgxPermissionsService ) =\u003e function() {return ds.load().then((data) =\u003e {return ps.loadPermissions(data)})},\n      deps: [LoadService, NgxPermissionsService],\n      multi: true\n    }]\n})\nexport class AppModule { }\n```\n\nValidation function are injected with any angular services. There are 2 local injectables available that can be used to implement more complex validation logic.\n\n| Injectable Local       | Description                                                               | \n| :--------------------- | :------------------------------------------------------------------------ |\n| `permissionName`       | String representing name of checked permission                            |\n| `permissionsObject`    | Object of store permissions storing permissions properties                            |\n\n\nIt also have to return one of values to properly represent results:\n \n| Validation result      | Returned value             | \n| :--------------------- | :------------------------- |\n| Valid                  | [`true`\\|`Promise.resolve() but it should not resolve false`]   |\n| Invalid                | [`false`\\|`Promise.reject() or Promise.resolve(false)`]   |\n### Multiple permissions\n\nTo define multiple permissions  method `loadPermissions` can be used. The only \ndifference from `definePermission` is that it accepts `Array` of permission names instead of single one. \n\n\nOften meet example of usage is set of permissions (e.g. received from server after user login) that you will iterate over to \ncheck if permission is valid.\n\n```typescript\nconst permissions = ['listMeeting', 'seeMeeting', 'editMeeting', 'deleteMeeting']\nNgxPermissionsService.loadPermissions(permissions) \nNgxPermissionsService.loadPermissions(permissions, (permissionName, permissionStore) =\u003e {\n    return !!permissionStore[permissionName];\n}) \n```\nNOTE: This method will remove older permissions and pass only new;\n\nRemoving permissions\n----------------------------\n\nYou can easily remove **all** permissions form the `NgxPermissionsService` (e.g. after user logged out or switched profile) by calling:  \n\n```typescript\nNgxPermissionsService.flushPermissions();\n```\n\nAlternatively you can use `removePermission` to delete defined permissions manually:\n\n```typescript\nNgxPermissionsService.removePermission('user');\n```\n\nRetrieving permissions\n----------------------------\n\nAnd to get all user permissions use method `getPermissions` or use Observable `permissions$`:\n\n```typescript\nvar permissions = NgxPermissionsService.getPermissions();\n\nNgxPermissionsService.permissions$.subscribe((permissions) =\u003e {\n    console.log(permissions)\n})\n```\n\n## Managing roles\n\nBefore start\n----------------------------\n\nMake sure you are familiar with:\n- [Managing permissions](#managing-permissions)   \n\nOverview\n----------------------------\n\n1. [Introduction](#before-start)\n2. [Defining roles](#defining-roles)\n  1. [Individual roles](#individual-roles)\n  2. [Multiple roles](#multiple-roles)\n3. [Removing roles](#removing-roles)\n4. [Getting all roles](#getting-all-roles)\n\nIntroduction\n----------------------------\nBy definition a role is a named set of abilities (permissions) by which a specific group of users is identified. \nSo for example `USER` or `ANONYMOUS` would be roles and not permissions. We can represent our `USER` role as a group of permissions that the role should be able to perform. For example: `listArticles`, `editArticles` and other custom server/browser validated privileges.    \n\n\u003e :bulb: **Note**   \n\u003e It's a good convention to name roles with UPPER_CASE, so roles like `ACCOUNTANT` or `ADMIN` are easier to distinguish from permissions.\n\nDefining roles\n----------------------------\n\n### Individual roles\n\nSimilarly to permissions we are gonna use here `RolesService` that exposes `addRole` allowing to define custom roles used by users in your application. \n\n```typescript\n[...]\n\nNgxRolesService\n  .addRole('ROLE_NAME', ['permissionNameA', 'permissionNameB', 'permissionNameC', ...])\n  \nNgxRolesService.addRole('Guest', () =\u003e {\n      return this.sessionService.checkSession().toPromise();\n  }); \n\nNgxRolesService.addRole('Guest', () =\u003e {\n      return true;\n  }); \n```\n\nValidation function are injected with any angular services. There are 2 local injectables available that can be used to implement more complex validation logic.\n\n| Parameter              | Description                                                               | \n| :--------------------- | :------------------------------------------------------------------------ |\n| `roleName`             | String representing name of checked role                                  |\n| `transitionProperties` | Array or validation function |\n\n\nIt also have to return one of values to properly represent results:\n \n| Validation result      | Returned value             | \n| :--------------------- | :------------------------- |\n| Valid                  | [`true`\\|`Promise.resolve() but it should not resolve false`]   |\n| Invalid                | [`false`\\|`Promise.reject() or Promise.resolve(false)`]   |\n\n \u003e Note: Right now to make request to the backend it only supports promises\n \u003e Note: If at least one of request fulfils it will show the component\n\n\nUsage of `addRole` is very similar to `addPermissions`:\n\n```typescript\nNgxRolesService\n  NgxPermission\n  // Library will internally validate if 'listEvents' and 'editEvents' permissions are valid when checking if role is valid   \n  .addRole('ADMIN', ['listEvents', 'editEvents']);  \n  \nNgxRolesService.addRole('Guest', () =\u003e {\n      return this.sessionService.checkSession().toPromise();\n  });  \n  \n```\n\n### Multiple roles\n\nService `NgxRolesService` allows you define multiple roles with `addRoles` method. This method accepts `Object` containing keys as a role names and corresponding validators as values. \n\n```typescript\nNgxRolesService    \n  // Or use your own function/service to validate role\n  .addRoles({\n    'USER': ['canReadInvoices'],\n    'ADMIN': ['canReadInvoices','canEditInvoices','canUploadImages'],\n    'GUEST': () =\u003e {\n        return this.sessionService.checkSessions().toPromise();\n    }\n  });\n```\n\n\u003e :bulb: **Note**   \n\nRemoving roles\n----------------------------\n\nTo remove **all** roles use `flushRoles` method:  \n\n```typescript\nNgxRolesService.flushRoles();\n```\n\nAlternatively you can use `removeRole` to delete defined role manually:\n\n```typescript\nNgxRolesService.removeRole('USER');\n```\n\nGetting all roles\n----------------------------\n\nTo get specific role use method `getRole`:\n\n```javascript\nlet role = NgxRolesService.getRole('roleName');\n```\n\nAnd to get all roles form `NgxRolesService` use method `getRoles` or use `Observable roles$`:\n\n```typescript\nlet roles = NgxRolesService.getRoles();\n\nNgxRolesService.roles$.subscribe((data) =\u003e {\n    console.log(data);\n})\n```\n\n\n## Controlling access in views\n\nOverview\n----------------------------\n\n1. [Permission directive](#permission-directive)\n  1. [Basic usage](#basic-usage)\n\nPermission directive\n----------------------------\n  \nPermission module exposes directive `ngxPermissionsOnly` and `ngxPermissionsExcept` that can show/hide elements of your application based on set of permissions.\n \u003e :fire: **Important**   \n \u003e  Else, then syntax is supported.   \n Note if you use `then` block don't put anything in main block it will be not visible, only `then` block will be used.\n \n\nPermission directive accepts several attributes:\n\n| Attribute             | Value                    | Description      |\n| :----------------------|:------------------------:| :----------------|\n| `ngxPermissionsOnly`     | \u003ccode\u003e[String \u0026#124; String[]]\u003c/code\u003e   | Single or multiple permissions allowed to access content | \n| `ngxPermissionsExcept`   | \u003ccode\u003e[String \u0026#124; String[]]\u003c/code\u003e   | Single or multiple permissions denied to access content|\n| `(permissionsAuthorized)`   | EventEmitter       | EventEmitter emitted when authorized                         |\n| `(permissionsUnauthorized)` | EventEmitter       | EventEmitter emitted when unAuthorized                       |\n### Basic usage\n\nDirectives accepts either single permission that has to be met in order to display it's content,\nYou can use both `ngxPermissionsOnly` and `ngxPermissionsExcept` at the same time:\n \n```html\n\u003cng-template [ngxPermissionsOnly]=\"['ADMIN']\" (permissionsAuthorized)=\"yourCustomAuthorizedFunction()\" (permissionsUnauthorized)=\"yourCustomAuthorizedFunction()\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n \u003c/ng-template\u003e\n \u003cng-template [ngxPermissionsOnly]=\"'ADMIN'\"  [ngxPermissionsExcept]=\"'Manager'\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n \u003c/ng-template\u003e\n  \u003cng-template ngxPermissionsOnly=\"ADMIN\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n \u003c/ng-template\u003e\n \n \u003cng-template [ngxPermissionsExcept]=\"['JOHNY']\"\u003e\n   \u003cdiv\u003e All will see it except JOHNY\u003c/div\u003e\n \u003c/ng-template\u003e\n```\n\nOr set of permissions separated by 'coma':\n\n```html\n\u003cng-template [ngxPermissionsOnly]=\"['ADMIN', 'GUEST']\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n\u003c/ng-template\u003e\n\n \u003cng-template [ngxPermissionsExcept]=\"['ADMIN', 'JOHNY']\"\u003e\n   \u003cdiv\u003eAll will see it except admin and Johny\u003c/div\u003e\n \u003c/ng-template\u003e\n  \u003cng-template [ngxPermissionsExcept]=\"['ADMIN', 'JOHNY']\" [ngxPermissionsOnly]=\"['MANAGER']\"\u003e\n    \u003cdiv\u003eAll will see it except admin and Johny\u003c/div\u003e\n  \u003c/ng-template\u003e\n  \n  \u003cng-template [ngxPermissionsExcept]=\"['MANAGER']\" \n  [ngxPermissionExceptThen]=\"thenBlock\" \n  [ngxPermissionExceptElse]=\"elseBlock\"\u003e\n    \u003c/ng-template\u003e\n   \u003cng-template #elseBlock\u003e\n       \u003cdiv\u003eelseBlock\u003c/div\u003e\n   \u003c/ng-template\u003e\n   \u003cng-template #thenBlock\u003e\n       \u003cdiv\u003ethenBlock\u003c/div\u003e\n   \u003c/ng-template\u003e\n   \n   \u003cng-template\n     [ngxPermissionsOnly]=\"['MANAGER']\" \n     [ngxPermissionsOnlyThen]=\"thenBlock\" \n     [ngxPermissionsOnlyElse]=\"elseBlock\"\u003e\n       \u003c/ng-template\u003e\n      \u003cng-template #elseBlock\u003e\n          \u003cdiv\u003eelseBlock\u003c/div\u003e\n      \u003c/ng-template\u003e\n      \u003cng-template #thenBlock\u003e\n          \u003cdiv\u003ethenBlock\u003c/div\u003e\n      \u003c/ng-template\u003e\n    \n    \n \n```\n\nOr just simply by *\n```html\n\u003cdiv *ngxPermissionsOnly=\"['ADMIN', 'GUEST']\"\u003e\n    \u003cdiv\u003eYou can see this text congrats\u003c/div\u003e\n\u003c/div\u003e\n\n \u003cdiv *ngxPermissionsOnly=\"['THEN_BLOCK']; else elseBlock; then thenBlock\"\u003emain\u003c/div\u003e\n     \u003cng-template #elseBlock\u003e\n         \u003cdiv\u003eelseBlock\u003c/div\u003e\n     \u003c/ng-template\u003e\n     \u003cng-template #thenBlock\u003e\n         \u003cdiv\u003ethenBlock\u003c/div\u003e\n     \u003c/ng-template\u003e\n     \n \u003cdiv *ngxPermissionsExcept=\"['THEN_BLOCK']; else elseBlock; then thenBlock\"\u003e\u003c/div\u003e\n       \u003cng-template #elseBlock\u003e\n           \u003cdiv\u003eelseBlock\u003c/div\u003e\n       \u003c/ng-template\u003e\n       \u003cng-template #thenBlock\u003e\n           \u003cdiv\u003ethenBlock\u003c/div\u003e\n       \u003c/ng-template\u003e\n\n```\n \u003e Note: You cant use `*` style with other * style directives like `*ngIf`. You should wrap them. And YES i don't like it either.\n  ```html\n   \u003cdiv *ngxPermissionsOnly=\"['ADMIN', 'GUEST']\"\u003e\n    \u003cdiv *ngIf=\"true\"\u003e\n      You can see this text congrats\n    \u003c/div\u003e\n   \u003c/div\u003e\n\n   ```\n   \u003e  :fire: **Important**   \n   \u003e  Using with except and only `together` should use `ngxPermissionsElse` or `ngxPermissionsThen`\n   ```html\n       \u003cng-template [ngxPermissionsExcept]=\"'FAIL_BLOCK'\" \n       [ngxPermissionsOnly]=\"'ONLY_BLOCK'\"\n       [ngxPermissionsElse]=\"elseBlock\"\n       [ngxPermissionsThen]=\"thenBlock\"\u003e\n                 \n       \u003c/ng-template\u003e\n       \u003cng-template #elseBlock\u003e\n           \u003cdiv\u003eelseBlock\u003c/div\u003e\n       \u003c/ng-template\u003e\n       \u003cng-template #thenBlock\u003e\n           \u003cdiv\u003ethenBlock\u003c/div\u003e\n       \u003c/ng-template\u003e\n   ```\n\n\nUsage with Routes\n----------------------------\n\n1. [Introduction](#introduction)\n2. [Property only and except](#property-only-and-except)\n  1. [Single permission/role](#single-permissionrole)\n  2. [Multiple permissions/roles](#multiple-permissionsroles) \n  3. [Dynamic access](#dynamic-access)\n3. [Property redirectTo](#property-redirectto)\n  1. [Single rule redirection](#single-redirection-rule)\n  2. [Multiple rule redirection](#multiple-redirection-rules)  \n  3. [Dynamic redirection rules](#dynamic-redirection-rules)\n4. [Implemented Guards](#implemented-guards)   \n  1. [Can Activate Guard](#can-activate-guard) \n  2. [Can Load Guard](#can-load-guard)\n  3. [Can Activate Child Guard]($can-activate-child-guard)\n5. [Common use cases](#common-use-cases)\n  1. [Two guards when first make request for authorisation and gets permissions second checks for permissions](#two-guards-when-first-make-request-for-authorisation-and-gets-permissions-second-checks-for-permissions)\n\nIntroduction\n----------------------------\n\nNow you are ready to start working with controlling access to the states of your application. In order to restrict any state ngx-permission rely on angular-route's `data` property, reserving key `permissions` allowing to define authorization configuration.\n\nPermissions object accepts following properties:\n\n| Property        | Accepted value                   |\n| :-------------- | :------------------------------- |\n| `only`          | [`String`\\|`Array`\\|`Function`]              |\n| `except`        | [`String`\\|`Array`\\|`Function`]              |\n| `redirectTo`    | [`String`]                       |\n\nProperty only and except\n----------------------------\n\nProperty `only`:\n  - is used to explicitly define permission or role that are allowed to access the state   \n  - when used as `String` contains single permission or role\n  - when used as `Array` contains set of permissions and/or roles\n\nProperty `except`: \n  - is used to explicitly define permission or role that are denied to access the state\n  - when used as `String` contains single permission or role\n  - when used as `Array` contains set of permissions and/or roles\n\n\u003e :fire: **Important**   \n\u003e If you combine both `only` and `except` properties you have to make sure they are not excluding each other, because denied roles/permissions would not allow access the state for users even if allowed ones would pass them.   \n\n \n#### Single permission/role \n\nIn simplest cases you allow users having single role permission to access the state. To achieve that you can pass as `String` desired role/permission to only/except property:\nYou can use `except` and `only` at the same time;\n```typescript\nimport { RouterModule, Routes } from '@angular/router';\nimport { NgModule } from '@angular/core';\nimport { HomeComponent } from './home/home.component';\nimport { NgxPermissionsGuard } from 'ngx-permissions';\n\nconst appRoutes: Routes = [\n  { path: 'home',\n    component: HomeComponent,\n    canActivate: [NgxPermissionsGuard],\n    data: {\n      permissions: {\n        only: 'ADMIN'\n      }\n    }\n  },\n];\n@NgModule({\n  imports: [\n    RouterModule.forRoot(appRoutes)\n  ],\n  exports: [\n    RouterModule\n  ]\n})\nexport class AppRoutingModule {}\n\n```\n\nIn given case when user is trying to access `home` state `NgxPermissionsGuard` service is called checking if `isAuthorized` permission is valid: \n  - if permission definition is not found it stops transition\n \n\n#### Multiple permissions/roles \n\nOften several permissions/roles are sufficient to allow/deny user to access the state. Then array value comes in handy:  \n\n```typescript\nimport { RouterModule, Routes } from '@angular/router';\nimport { NgModule } from '@angular/core';\nimport { HomeComponent } from './home/home.component';\nimport { NgxPermissionsGuard } from 'ngx-permissions';\n\nconst appRoutes: Routes = [\n  { path: 'home',\n    component: HomeComponent,\n    canActivate: [NgxPermissionsGuard],\n    data: {\n      permissions: {\n        only: ['ADMIN', 'MODERATOR'],\n        except: ['GUEST']\n      }\n    }\n  },\n];\n@NgModule({\n  imports: [\n    RouterModule.forRoot(appRoutes)\n  ],\n  exports: [\n    RouterModule\n  ]\n})\nexport class AppRoutingModule {}\n```\n\nWhen `NgxPermissionsGuard` service will be called it would expect user to have either `ADMIN` or `MODERATOR` permissions to pass him to `home` route.\n\n[//]: \u003c\u003e (\u003e :bulb: **Note**   \n          \u003e Between values in array operator **OR** is used to create alternative. If you need **AND** operator between permissions define additional `PermRole` containing set of those. \n)\n\n#### Dynamic access\n\nYou can find states that would require to verify access dynamically - often depending on parameters.     \n\nLet's imagine situation where user want to modify the invoice. We need to check every time if he is allowed to do that on state level. We are gonna use `ActivatedRouteSnapshot` and `RouterStateSnapshot`   object to check weather he is able to do that.\n\n\u003e To make AOT compatible you should export function. \n\u003e Below is presented code AOT Compatible\n\nAOT compatible \n```typescript\nexport function testPermissions(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {\n  if (route.params['id'] === 42) {\n    return ['MANAGER', \"UTILS\"]\n  } else {\n    return 'ADMIN'\n  }\n}\nconst appRoutes: Routes = [\n  { path: 'dynamic/:id',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n        permissions: {\n          only: testPermissions\n        }\n      }\n    }\n];\n```\n\n\u003e :skull: **Warning**   \n\u003e The code below is not AOT compatible\n\n```typescript\nconst appRoutes: Routes = [\n  { path: 'dynamic/:id',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n        permissions: {\n          only: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) =\u003e {\n              if (route.params['id'] === 42) {\n                  return ['MANAGER', \"UTILS\"]\n                } else {\n                  return 'ADMIN'\n                }\n          }\n        }\n      }\n    }\n];\n```\n\nSo whenever we try access state with param `id = 42` set to true additional check for permission `manager and utils` will be made. Otherwise only `ADMIN` will be required.\n\n\u003e :fire: **Important**   \n\u003e Notice that function must always return array or string of roles/permissions in order to work properly. \n\nProperty redirectTo\n----------------------------\n\nProperty redirectTo:\n  - when used as `String` defines single redirection rule\n  - when used as `Objects` defines single/multiple redirection rules\n  - when used as `Function` defines dynamic redirection rule(s)\n\n### Single redirection rule\n\nIn case you want to redirect to a specific state when the user is not authorized, set `redirectTo` path to that route.\n\n\n```typescript\nimport { RouterModule, Routes } from '@angular/router';\nimport { NgModule } from '@angular/core';\nimport { HomeComponent } from './home/home.component';\nimport { NgxPermissionsGuard } from 'ngx-permissions';\n\nconst appRoutes: Routes = [\n  { path: 'home',\n    component: HomeComponent,\n    canActivate: [NgxPermissionsGuard],\n    data: {\n      permissions: {\n        only: ['ADMIN', 'MODERATOR'],\n        redirectTo: '/another-route'\n      }\n    }\n  },\n];\n@NgModule({\n  imports: [\n    RouterModule.forRoot(appRoutes)\n  ],\n  exports: [\n    RouterModule\n  ]\n})\nexport class AppRoutingModule {}\n```\n\nIn order to pass additional properties like params, set `redirectTo` to an object. \n`navigationCommands` and `navigationExtras` are reserved words it corresponds to parameters passed to router.navigate function\n`navigate(commands: any[], extras: NavigationExtras): Promise\u003cboolean\u003e`\n\n```typescript\n\nconst appRoutes: Routes = [\n  { path: 'home',\n    component: HomeComponent,\n    canActivate: [NgxPermissionsGuard],\n    data: {\n      permissions: {\n        only: ['ADMIN', 'MODERATOR'],\n        redirectTo: {\n            navigationCommands: ['123'],\n            navigationExtras: {\n                skipLocationChange: true\n            }\n        }               \n    }\n  },\n];\n@NgModule({\n  imports: [\n    RouterModule.forRoot(appRoutes)\n  ],\n  exports: [\n    RouterModule\n  ]\n})\n````\n## Multiple redirection rules\n\nIn case you want to redirect the user based on `denied` permission/role to create redirection strategies. In order to do that you have to create redirection `Object` that contain keys representing rejected permissions or roles and values implementing redirection rules.\n \nRedirection rules are represented by following values:\n\n| Value type    | Return                     | Usage                                         | \n| :------------ | :------------------------- | :-------------------------------------------- |\n| `String`      | [`String`]                 | Simple state transitions                      |\n| `Object`      | [`Object`]                 | Redirection with custom parameters or options | \n| `Function`    | [`String`\\|`Object`]       | Dynamic properties-based redirection          | \n\n\n\u003e :bulb: **Note**   \n\u003e Use _default_ property that will handle fallback redirect for not defined permissions. \n\nThe simplest example of multiple redirection rules are redirection based on pairs role/permission and state. When user is not granted to access the state will be redirected to `agendaList` if missing `canReadAgenda` permission or to `dashboard` when missing `canEditAgenda`. Property `default` is reserved for cases when you want handle specific cases leaving default redirection. \n\n\n\n```typescript\n  const appRoutes: Routes = [\n    { path: 'home',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n       permissions: {\n               only: ['canReadAgenda','canEditAgenda'],\n               redirectTo: {\n                 canReadAgenda: 'agendaList',\n                 canEditAgenda: 'dashboard',\n                 default: 'login'\n               }\n        }\n      }\n    },\n  ];\n  @NgModule({\n    imports: [\n      RouterModule.forRoot(appRoutes)\n    ],\n    exports: [\n      RouterModule\n    ]\n  })\n```\n\nIf you need more control over redirection parameters `Object` as a value can be used to customise target url `navigationCommands` and transition `navigationExtras`.\n\u003e :bulb: **Note**  `navigationCommands` and `navigationExtras` are reserved words it corresponds to parameters passed to router.navigate function\n`navigate(commands: any[], extras: NavigationExtras): Promise\u003cboolean\u003e`\n\n```typescript \n\n  const appRoutes: Routes = [\n    { path: 'home',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n         permissions: {\n               only: ['canEditAgenda'],\n               redirectTo: \n                 canEditAgenda: {\n                   navigationCommands: 'dashboard',\n                   navigationExtras: {\n                       skipLocationChange: true\n                   }\n                 \n                 },\n                 default: 'login'\n             }\n          }\n      }\n    },\n  ];\n  @NgModule({\n    imports: [\n      RouterModule.forRoot(appRoutes)\n    ],\n    exports: [\n      RouterModule\n    ]\n  })  \n```\n\nTo present usage `redirectTo` as `Object` with values as `Function` in a state definition `agenda` presented below redirection rules are interpreted as:\n- when user does not have `canReadAgenda` invoked function returns string representing the state name to which unauthorized user will be redirected\n- when user does not have `canEditAgenda` invoked function returns object with custom options and params that will be passed along to transited `dashboard` url\n\n\n```typescript\n\n const appRoutes: Routes = [\n    { path: 'home',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n       permissions: {\n              only: ['canReadAgenda','canEditAgenda'],\n              redirectTo: {\n                canReadAgenda: (rejectedPermissionName: string, activateRouteSnapshot: ActivatedRouteSnapshot, routeStateSnapshot: RouterStateSnapshot) =\u003e {\n                  return 'dashboard';\n                },\n                canEditAgenda: (rejectedPermissionName: string, activateRouteSnapshot: ActivatedRouteSnapshot, routeStateSnapshot: RouterStateSnapshot) =\u003e {\n                  return {\n                      navigationCommands: ['/dashboard'],\n                      navigationExtras: {\n                          skipLocationChange: true\n                      }\n                  }\n                },\n                default: 'login'\n            }\n        }\n      }\n    },\n  ];\n  @NgModule({\n    imports: [\n      RouterModule.forRoot(appRoutes)\n    ],\n    exports: [\n      RouterModule\n    ]\n  })\n```\n\u003e :fire: **Important**   \n\u003e Above code is not AOT compatible to make it AOT compatible extract it to function\n\u003e `navigationCommands` and `navigationExtras` reserved words. Matching parameter to router.navigate function\n\n```typescript\nexport function canReadAgenda(rejectedPermissionName: string, activateRouteSnapshot: ActivatedRouteSnapshot, routeStateSnapshot: RouterStateSnapshot) =\u003e {                                                 \n    return 'dashboard';\n},\n\nredirectTo: {\n    canReadAgenda: canReadAgenda\n \n}\n```\n\n### Dynamic redirection rules\n\nSimilarly to examples showing defining dynamic access to state redirection can also be defined based on any parameters of `ActivatedRouteSnapshot` and `RouterStateSnapshot`;\n\n\u003e :bulb: **Note**   \n\u003e Remember to always return state name or object.\n\n```typescript \nconst appRoutes: Routes = [\n    { path: 'home/:isEditable',\n      component: HomeComponent,\n      canActivate: [NgxPermissionsGuard],\n      data: {\n      permissions: {\n             only: ['canReadAgenda','canEditAgenda'],\n             redirectTo: (rejectedPermissionName: string, activateRouteSnapshot: ActivatedRouteSnapshot, routerStateSnapshot: RouterStateSnapshot) =\u003e {\n               if(activateRouteSnapshot.params['id'] === 42){\n                 return 'login';\n               } else {\n                 return 'dashboard'\n               }\n             }\n      }\n    },\n  ];\n  @NgModule({\n    imports: [\n      RouterModule.forRoot(appRoutes)\n    ],\n    exports: [\n      RouterModule\n    ]\n  })\n```\n\n\u003e :fire: **Important**   \n\u003e The code above is not AOT compatible. To make it AOT compatible extract it to a function\n\n```typescript\nexport function redirectToFunc(rejectedPermissionName: string, activateRouteSnapshot: ActivatedRouteSnapshot, routerStateSnapshot: RouterStateSnapshot) =\u003e {\n     if(activateRouteSnapshot.params['id'] === 42){\n       return 'login';\n     } else {\n       return 'dashboard'\n     }\n   }\n\nredirectTo: redirectToFunc\n```\n----------------------------\n\n## Implemented Guards\n\n### Can Activate Guard\nNgxPermissionsGuard implements CanActivate interface, see examples above.\n\n### Can Load Guard\n\nNgxPermissionsGuard implements CanLoad Interface. Functionality is the same as canActivate \n\n```typescript\nconst appRoutes: Routes = [\n\n  {\n    path: 'lazy',\n    data: {\n      permissions: {\n        except: 'ADDDMIN',\n      }\n    },\n    canLoad: [NgxPermissionsGuard],\n    loadChildren: 'app/lazy-module/lazy-module.module#LazyModule'\n  },\n \n\n];\n@NgModule({\n  imports: [\n    RouterModule.forRoot(appRoutes)\n  ],\n  exports: [\n    RouterModule\n  ],\n  providers: [\n    // CanDeactivateGuard\n  ]\n})\nexport class AppRoutingModule {}\n\n\n \n```\n\n\u003e :fire: **Warning**   \n\u003e * The only difference if you use as a function the parameter is **only 1** and its type of  **Route**\n\n```typescript\n\n{\n    path: 'lazy',\n    data: {\n      permissions: {\n         only: (route: Route) =\u003e {\n                  //logic here\n                   return ['MANAGER', \"UTILS\"]\n                  }\n      }\n    },\n    canLoad: [NgxPermissionsGuard],\n    loadChildren: 'app/lazy-module/lazy-module.module#LazyModule'\n  },\n```\n\n### Can Activate Child Guard\n\n`NgxPermissionsGuard` implements CanLoad Interface. Functionality is the same as canActivate \n\n\u003e :fire: **Warning**   \n\u003e * Rules and data must be specified on **Child Components** not on parent component\n\n```typescript\nconst appRoutes: Routes = [\n  { path: '',\n    component: IsolateComponent,\n    canActivateChild: [NgxPermissionsGuard],\n    children: [\n      {\n        path: 'except-should',\n        component: AnotherComponent,\n        data: {\n          permissions: {\n            except: 'ADMIN'\n          }\n        }\n      },\n      {\n        path: 'only-should',\n        component: ComeComponent,\n        data: {\n          permissions: {\n            only: 'GUEST'\n          }\n        }\n      },\n    ]\n  },\n];\n```\n----------------------------\n\n\n## Common use cases\n\n### Two guards when first make request for authorization and gets permissions second checks for permissions\n\nThis method only works with `angular 4.3.2` or higher see https://github.com/angular/angular/issues/15670\n\nThere are a lot of times you have 2 guard one for authorisation when it makes request for permissions and second is permissions guard\nand you want them to work in chain. To make them work in chain You should use them in a following way:\n\n```typescript\n\nlet routes = [\n  { path: '', \n    canActivate: [AuthGuard],\n    children: [\n      {path: 'component', \n      component: ComponentName, \n      canActivate: [NgxPermissionsGuard],\n      data: {\n         permissions: {\n           only: ['ADMIN', 'MODERATOR'],\n           redirectTo: 'another-route'\n         }\n       }}\n    ]\n  }\n]\n```\n\u003e Note: Make sure the permission request in chained in auth guard\n ```js \n    canActivate() {\n        return authLogin().then((obj) =\u003e {\n            // or load here if you dont need second request\n            // this.permissions.service.loadPermissions(obj.permissions)\n           \n            return this.authPermissions.getPermissions('url');\n        }).then((permissions) =\u003e {\n            this.permissions.service.loadPermissions(permissions)\n        )\n    }\n```\n\n\n| --- |\n## Development\n\nTo generate all `*.js`, `*.d.ts` and `*.metadata.json` files:\n\n```bash\n$ npm run build\n```\n\nTo lint all `*.ts` files:\n\n```bash\n$ npm run lint\n```\n## Thank You\n\n`Thank You for using the library and support. HAVE A GREAT DAY!`\n\n## For google\nangular 2 permissions, angular 4 permissions, angular permissions, angular 5 permissions ng2 permissions ng permissions\nng-permissions ng2-permissions angular2 permissions  angular4 permissions angular 5 permissions\n\n## License\n\nMIT © [Oleksandr Khymenko](mailto:alexanderKhymenko@gmail.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlexKhymenko%2Fngx-permissions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAlexKhymenko%2Fngx-permissions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAlexKhymenko%2Fngx-permissions/lists"}