Security News
Create React App Officially Deprecated Amid React 19 Compatibility Issues
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
loopback4-authorization
Advanced tools
A loopback-next extension for authorization in loopback applications. Its a very simplistic yet powerful and effective implementation using simple string based permissions.
It provides three ways of integration
Refer to the usage section below for details on integration
npm install loopback4-authorization
For a quick starter guide, you can refer to our loopback 4 starter application which utilizes method #3 from the above in a simple multi-tenant application.
In order to use this component into your LoopBack application, please follow below steps.
this.component(AuthorizationComponent);
@model({
name: 'users',
})
export class User extends Entity implements Permissions<string> {
// .....
// other attributes here
// .....
@property({
type: 'array',
itemType: 'string',
})
permissions: string[];
constructor(data?: Partial<User>) {
super(data);
}
}
@model({
name: 'roles',
})
export class Role extends Entity implements Permissions<string> {
// .....
// other attributes here
// .....
@property({
type: 'array',
itemType: 'string',
})
permissions: string[];
constructor(data?: Partial<Role>) {
super(data);
}
}
@model({
name: 'users',
})
export class User extends Entity implements UserPermissionsOverride<string> {
// .....
// other attributes here
// .....
@property({
type: 'array',
itemType: 'object',
})
permissions: UserPermission<string>[];
constructor(data?: Partial<User>) {
super(data);
}
}
@inject(AuthorizatonBindings.USER_PERMISSIONS)
private readonly getUserPermissions: UserPermissionsFn<string>,
and invoke it
const permissions = this.getUserPermissions(user.permissions, role.permissions);
import {inject} from '@loopback/context';
import {
FindRoute,
HttpErrors,
InvokeMethod,
ParseParams,
Reject,
RequestContext,
RestBindings,
Send,
SequenceHandler,
} from '@loopback/rest';
import {AuthenticateFn, AuthenticationBindings} from 'loopback4-authentication';
import {
AuthorizatonBindings,
AuthorizeErrorKeys,
AuthorizeFn,
UserPermissionsFn,
} from 'loopback4-authorization';
import {AuthClient} from './models/auth-client.model';
import {User} from './models/user.model';
const SequenceActions = RestBindings.SequenceActions;
export class MySequence implements SequenceHandler {
constructor(
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
@inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
@inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
@inject(SequenceActions.SEND) public send: Send,
@inject(SequenceActions.REJECT) public reject: Reject,
@inject(AuthenticationBindings.USER_AUTH_ACTION)
protected authenticateRequest: AuthenticateFn<AuthUser>,
@inject(AuthenticationBindings.CLIENT_AUTH_ACTION)
protected authenticateRequestClient: AuthenticateFn<AuthClient>,
@inject(AuthorizatonBindings.AUTHORIZE_ACTION)
protected checkAuthorisation: AuthorizeFn,
@inject(AuthorizatonBindings.USER_PERMISSIONS)
private readonly getUserPermissions: UserPermissionsFn<string>,
) {}
async handle(context: RequestContext) {
const requestTime = Date.now();
try {
const {request, response} = context;
const route = this.findRoute(request);
const args = await this.parseParams(request, route);
request.body = args[args.length - 1];
await this.authenticateRequestClient(request);
const authUser: User = await this.authenticateRequest(request);
// Do ths if you are using method #3
const permissions = this.getUserPermissions(
authUser.permissions,
authUser.role.permissions,
);
// This is the important line added for authorization. Needed for all 3 methods
const isAccessAllowed: boolean = await this.checkAuthorisation(
permissions, // do authUser.permissions if using method #1
);
// Checking access to route here
if (!isAccessAllowed) {
throw new HttpErrors.Forbidden(AuthorizeErrorKeys.NotAllowedAccess);
}
const result = await this.invoke(route, args);
this.send(response, result);
} catch (err) {
this.reject(context, err);
}
}
}
The above sequence also contains user authentication using loopback4-authentication package. You can refer to the documentation for the same for more details.
@authorize(['CreateRole'])
@post(rolesPath, {
responses: {
[STATUS_CODE.OK]: {
description: 'Role model instance',
content: {
[CONTENT_TYPE.JSON]: {schema: {'x-ts-type': Role}},
},
},
},
})
async create(@requestBody() role: Role): Promise<Role> {
return await this.roleRepository.create(role);
}
This endpoint will only be accessible if logged in user has permission 'CreateRole'.
A good practice is to keep all permission strings in a separate enum file like this.
export const enum PermissionKey {
ViewOwnUser = 'ViewOwnUser',
ViewAnyUser = 'ViewAnyUser',
ViewTenantUser = 'ViewTenantUser',
CreateAnyUser = 'CreateAnyUser',
CreateTenantUser = 'CreateTenantUser',
UpdateOwnUser = 'UpdateOwnUser',
UpdateTenantUser = 'UpdateTenantUser',
UpdateAnyUser = 'UpdateAnyUser',
DeleteTenantUser = 'DeleteTenantUser',
DeleteAnyUser = 'DeleteAnyUser',
ViewTenant = 'ViewTenant',
CreateTenant = 'CreateTenant',
UpdateTenant = 'UpdateTenant',
DeleteTenant = 'DeleteTenant',
ViewRole = 'ViewRole',
CreateRole = 'CreateRole',
UpdateRole = 'UpdateRole',
DeleteRole = 'DeleteRole',
ViewAudit = 'ViewAudit',
CreateAudit = 'CreateAudit',
UpdateAudit = 'UpdateAudit',
DeleteAudit = 'DeleteAudit',
}
If you've noticed a bug or have a question or have a feature request, search the issue tracker to see if someone else in the community has already created a ticket. If not, go ahead and make one! All feature requests are welcome. Implementation time may vary. Feel free to contribute the same, if you can. If you think this extension is useful, please star it. Appreciation really helps in keeping this project alive.
Please read CONTRIBUTING.md for details on the process for submitting pull requests to us.
Code of conduct guidelines here.
FAQs
ARC authorization extension for loopback-next applications.
The npm package loopback4-authorization receives a total of 1,515 weekly downloads. As such, loopback4-authorization popularity was classified as popular.
We found that loopback4-authorization demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.
Security News
The Linux Foundation is warning open source developers that compliance with global sanctions is mandatory, highlighting legal risks and restrictions on contributions.