Provides an Angular module and directives to manage authorization and permissions in your application. It allows you to control the visibility and enabled state of UI elements based on user permissions. The package includes an `AuthorizationService` to check permissions and directives to easily integrate permission checks into your templates and components.
Add the package to your workspace:
Example :yarn add @rxap/authorizationInstall peer dependencies:
Example :yarn add @angular/core @angular/forms @angular/material @rxap/utilities rxjs Execute the init generator:
Example :yarn nx g @rxap/authorization:initThe @rxap/authorization package provides a robust and flexible way to manage user permissions in Angular applications. It supports permission-based view rendering, component enabling/disabling, and hierarchical scoping.
Directives: Import the HasPermissionModule in your application or feature module to use the directives in your templates:
import { HasPermissionModule } from '@rxap/authorization';
@NgModule({
imports: [
HasPermissionModule,
// ...
],
})
export class AppModule {}Alternatively, you can import individual standalone directives as needed (e.g., IfHasPermissionDirective, MatButtonHasEnablePermissionDirective).
Providers: Use the provideAuthorization() utility to configure the service and its dependencies (like disabling authorization via config).
import { provideAuthorization } from '@rxap/authorization';
import { ApplicationConfig } from '@angular/core';
export const appConfig: ApplicationConfig = {
providers: [
provideAuthorization(),
// ... other providers, ensure ConfigService is also provided/available if needed
]
};The core of the package is the AuthorizationService. It holds the current user's permissions and provides methods to check access.
Permissions are stored as a list of strings. You typically set these after user authentication.
Example :import { AuthorizationService } from '@rxap/authorization';
@Injectable({ providedIn: 'root' })
export class AuthService {
constructor(private authorizationService: AuthorizationService) {}
login() {
// ... authenticate user ...
const permissions = ['user.read', 'user.write', 'admin.*'];
this.authorizationService.setPermissions(permissions);
}
}You can check permissions programmatically using hasPermission (sync) or hasPermission$ (observable).
// Synchronous check
if (this.authorizationService.hasPermission('user.create')) {
// ...
}
// Observable check
this.authorizationService.hasPermission$('user.create').subscribe(canCreate => {
// ...
});The service supports dot notation and wildcards:
'user.read' matches 'user.read'.*): The * character matches any sequence of characters.'admin.*' matches 'admin.settings', 'admin.users', etc.'*.read' matches 'user.read', 'product.read', etc.'*' matches everything (superuser).The package provides several directives to деклараtively control the UI based on permissions.
*rxapIfHasPermissionConditionally renders an element if the user has the specified permission.
Example :<div *rxapIfHasPermission="'feature.view'">
You can see this feature.
</div>
<div *rxapIfHasPermission="'feature.admin'; else accessDenied">
Admin Panel
</div>
<ng-template #accessDenied>
<p>Access Denied</p>
</ng-template>rxapHasEnablePermissionDisables the host component if the user lacks the permission. This is often better than hiding controls entirely, as it shows what is available.
Supported Components:
<button>)mat-button, mat-raised-button, mat-icon-button, mat-fab, etc.)matInput)mat-select)mat-checkbox)mat-slide-toggle)[formControl], [formControlName])Usage:
Example :<!-- Button is disabled without 'user.delete' permission -->
<button mat-button [rxapHasEnablePermission]="'user.delete'" (click)="deleteUser()">
Delete User
</button>
<!-- Form control is disabled without 'user.edit' permission -->
<input matInput [formControl]="emailCtrl" [rxapHasEnablePermission]="'user.edit'">rxapHasWritePermissionSets the readonly attribute of an element based on permission. Useful for inputs where you want to show the value but prevent editing.
<input [rxapHasWritePermission]="'user.edit'" value="Read-only unless you have permission">The package uses a specific concept for scoping permissions, allowing you to reuse components with generic permission checks in different contexts.
Scopes use slash notation (scope/permission) in the permission list.
'edit').'admin') or scoped (e.g., 'products/edit').'products').When checking for 'edit' inside the 'products' scope:
'products/'.'products/edit' becomes 'edit'.'edit'.Global permissions (without slashes) are always included in the check.
setAuthorizationScopeYou can define a scope for a component subtree using the setAuthorizationScope helper function.
import { setAuthorizationScope } from '@rxap/authorization';
@Component({
selector: 'app-product-list',
template: `
<!-- This checks for 'products/create' (mapped to 'create') -->
<button *rxapIfHasPermission="'create'">Create Product</button>
`,
providers: [
setAuthorizationScope('products'),
]
})
export class ProductListComponent {}If the user has the permission 'products/create', they will see the button. If they have 'users/create', they will not (unless they are also in the 'users' scope).
You can technically nest scopes by providing dot-separated scopes (e.g., 'admin.users'), which would look for 'admin.users/permission'.
The provideAuthorization() function automatically configures the service to check the configuration for authorization.disabled.
If you are using @rxap/config, you can disable authorization by setting the authorization.disabled property to true in your configuration file/environment.
{
"authorization": {
"disabled": true
}
}This is useful for local development or testing environments where you want to bypass permission checks.
Example :Initialize the package in the workspace
nx g @rxap/authorization:init