Authorization

Authorization with Decorators

The authGuard decorator below does two things:

  • Checks if a user is authorised and returns an Unauthorised status if not.
  • Adds currentUser to the request object.

To extend req object you can define your custom interface that extends VovkRequest. Let's imagine that Prisma ORM is used at the project.

/src/types.ts
import type { VovkRequest } from 'vovk'
import type { User } from '@prisma/client';
 
export interface GuardedRequest<BODY = undefined, QUERY extends Record<string, string> | undefined = undefined>
  extends VovkRequest<BODY, QUERY> {
  currentUser: User;
}
 

Then define the authGuard decorator itself.

/src/decorators/authGuard.ts
import { HttpException, HttpStatus, createDecorator } from 'vovk';
import type { GuardedRequest } from '../types';
 
const authGuard = createDecorator(async (req: GuardedRequest, next) => {
  // ... define userId and isAuthorised
  // parse access token for example
 
  if (!isAuthorised) {
    throw new HttpException(HttpStatus.UNAUTHORIZED, 'Unauthorized');
  }
 
  const currentUser = await prisma.user.findUnique({ where: { id: userId } });
 
  req.currentUser = currentUser;
 
  return next();
});
 
export default authGuard;

And finally use the decorator and define the request object with your newly created GuardedRequest type.

// ...
export default class UserController {
  // ...
  @get('current-user')
  @authGuard()
  static async getCurrentUser(req: GuardedRequest</* ... */>) {
    return req.currentUser;
  }
 
  // ...
}