Authorization
Authorization filters restrict records before generated read, update, delete, and export operations reach the query service. Create authorization also runs, allowing the authorizer to reject a request.
Authorization filters complement Nest guards. Use a guard for authentication and coarse endpoint access; use an authorizer for record-level visibility.
Inline authorizer
Decorate the response DTO with @Authorize. The first argument is the HTTP request and the second describes the generated operation.
import { Request } from 'express'
import { Authorize, FilterableField, IDField } from '@ptc-org/nestjs-query-rest'
type AuthenticatedRequest = Request & {
user: { id: string }
}
@Authorize<TodoItemDTO>({
authorize: (request: AuthenticatedRequest) => ({
ownerId: { eq: request.user.id }
})
})
export class TodoItemDTO {
@IDField()
id!: number
@FilterableField({ filterOnly: true })
ownerId!: string
}
For collection requests, the authorization filter is merged with the client filter. For single-record, update, and delete requests it is passed as an additional service filter, preventing access to records owned by another user.
Authorizer class
Use an injectable class for more involved rules:
import { ForbiddenException, Injectable } from '@nestjs/common'
import { Filter } from '@ptc-org/nestjs-query-core'
import { AuthorizationContext, CustomAuthorizer, OperationGroup } from '@ptc-org/nestjs-query-rest'
@Injectable()
export class TodoItemAuthorizer implements CustomAuthorizer<TodoItemDTO> {
async authorize(request: AuthenticatedRequest, context: AuthorizationContext): Promise<Filter<TodoItemDTO>> {
if (context.operationGroup === OperationGroup.CREATE && !request.user) {
throw new ForbiddenException()
}
return { ownerId: { eq: request.user.id } }
}
}
@Authorize(TodoItemAuthorizer)
export class TodoItemDTO {}
AuthorizationContext contains:
operationName: generated controller method name, such asqueryManyorupdateOne.operationGroup:read,create,update,delete, orexport.readonly: whether the operation does not modify data.many: whether the operation can affect multiple records.
The module registers authorizer providers for DTOs listed in either endpoints or dtos.
Add a guard
Ensure the request has a user before the authorizer runs:
{
DTOClass: TodoItemDTO,
EntityClass: TodoItemEntity,
guards: [JwtAuthGuard]
}
Guards and authorizers can also be scoped through the read, create, update, delete, and export operation options.