This is simple guard which can protect your routes by Role (RBAC) and also has the ability to check the ownership chain of the requested entity.
MIT License
This is simple guard which can protect your routes by Role (RBAC) and also has the ability to check the ownership chain of the requested entity.
As an example consider that you are a user belonging to an organization which has some books associated. Now, if you request a book by id this guard will check if the book that you are trying to fetch belongs to the organization that you are associated and so on. You only need to pass the models chain as well as the property chain.
npm i @nextnm/nestjs-next-guard
export interface ICheckOwnerShip {
requestParam: string; // name of param that has the id mentioned in caveat 3
modelChain: string[]; // the chain of ownership between models
propertyChain: string[]; // array of the properties that link the models
godRole?: string; // the role that will overcome the verification
}
import * as mongoose from 'mongoose';
import { NextGuardModule } from '@nextnm/nestjs-next-guard';
...
@Module({
imports: [
DbModule,
NextGuardModule.forRoot(),
],
controllers: [],
providers: [],
exports: [NestjsNextGuardModule],
})
export class YOURModule {}
We support Redis cache to improve performance when we have multiple chain nodes to verify ownership
import * as mongoose from 'mongoose';
import { NextGuardModule } from '@nextnm/nestjs-next-guard';
...
@Module({
imports: [
DbModule,
NextGuardModule.forRoot(
{
redisConfiguration: {
url: 'redis://localhost:6379'
retry_strategy: () => 1000,
mongooseInstance: mongoose,
},
}
),
],
controllers: [],
providers: [],
exports: [NestjsNextGuardModule],
})
export class YOURModule {}
Be aware that both decorators (Roles and CheckOwnerShip) are optional so use them as you want.
User:
{
_id:ObjectId
}
Site:
{
_id:ObjectId,
user:ObjectId
}
Page:
{
_id:ObjectId,
site:ObjectId
}
import { CheckOwnerShip, Roles } from '@nextnm/nestjs-next-guard';
...
@CheckOwnerShip({
requestParam: 'modelId',
propertyChain: ['site', 'user'], // The last property will be compared with the Id of the user making the request
modelChain: ['Page','Site'],
godRole: ExistingRoles.SYS_ADMIN, // If the user has this role not check will be done by the guard
})
@Roles(ExistingRoles.USER, ExistingRoles.ADMIN) // Provide the roles that you allow to execute this method,example: 'USER', 'ADMIN'
@UseGuards(NextGuard)
@Get(':modelId')
async findPageById(@Param('id') id: string) {
//...
}
User:
{
_id:ObjectId,
organization:ObjectId
}
Organization:
{
_id:ObjectId
}
import { CheckOwnerShip, Roles } from '@nextnm/nestjs-next-guard';
...
@CheckOwnerShip({
requestParam: 'id',
propertyChain: ['_id','organization','_id'], // The last property will be compared with the Id of the user making the request
modelChain: ['Organization','User'],
godRole: ExistingRoles.SYS_ADMIN, // If the user has this role not check will be done by the guard
})
@Roles(ExistingRoles.USER, ExistingRoles.ADMIN) // Provide the roles that you allow to execute this method,example: 'USER', 'ADMIN'
@UseGuards(AuthGuard('jwt'),NextGuard)
@Get('/:id')
findOrganizationById(@Param() params): Promise<ReadOrganizationDto> {
//...
}
Contributions are welcome! See Contributing.
Nuno Carvalho (nextnm/nextNC) Site
Licensed under the MIT License - see the LICENSE file for details.