From cc9ab04112e39cfe07bb241ba7713b15e4d6f48a Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 14 May 2024 12:49:19 +0300 Subject: [PATCH] apps/api: create AuthToken decorator --- apps/api/src/account/account.controller.ts | 10 ++++++---- apps/api/src/app.controller.ts | 10 ++++++---- apps/api/src/decorators/token.decorator.ts | 14 ++++++++++++++ apps/api/src/ldap/ldap.controller.ts | 14 +++++++------- apps/api/src/types/auth-controller.ts | 4 ++-- 5 files changed, 35 insertions(+), 17 deletions(-) create mode 100644 apps/api/src/decorators/token.decorator.ts diff --git a/apps/api/src/account/account.controller.ts b/apps/api/src/account/account.controller.ts index 97b42fa..5d295c9 100644 --- a/apps/api/src/account/account.controller.ts +++ b/apps/api/src/account/account.controller.ts @@ -23,6 +23,7 @@ import { ApiResponse, ApiTags } from '@nestjs/swagger'; import { FastifyReply, FastifyRequest } from 'fastify'; import { cookieOptions } from 'src/config/cookie'; import { env } from 'src/config/env'; +import { AuthToken } from 'src/decorators/token.decorator'; import { Credentials } from 'src/dto/credentials'; import { Account } from 'src/schemas/account.schema'; import type { BaseAuthController } from 'src/types/auth-controller'; @@ -128,10 +129,11 @@ export class AccountController implements BaseAuthController { } @Get('/get-user') - async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { - const token = req.cookies[env.COOKIE_TOKEN_NAME]; - if (!token) throw new UnauthorizedException(); - + async getUser( + @Req() req: FastifyRequest, + @Res() reply: FastifyReply, + @AuthToken() token: string + ) { const account = await this.accountService.getUser(token); if (!account) throw new UnauthorizedException('Account not found'); diff --git a/apps/api/src/app.controller.ts b/apps/api/src/app.controller.ts index 7488159..e4bf59c 100644 --- a/apps/api/src/app.controller.ts +++ b/apps/api/src/app.controller.ts @@ -1,6 +1,7 @@ import { AccountService } from './account/account.service'; import { AppService } from './app.service'; import { env } from './config/env'; +import { AuthToken } from './decorators/token.decorator'; import { LdapService } from './ldap/ldap.service'; import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common'; import { ApiExcludeController } from '@nestjs/swagger'; @@ -17,10 +18,11 @@ export class AppController { ) {} @Get('auth') - public async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { - const token = req.cookies[env.COOKIE_TOKEN_NAME] || req.headers?.authorization?.split(' ')[1]; - if (!token) return reply.status(HttpStatus.UNAUTHORIZED).send(); - + public async auth( + @Req() req: FastifyRequest, + @Res() reply: FastifyReply, + @AuthToken() token: string + ) { try { return this.handleDefaultCheck(req, reply, token); } catch (error) { diff --git a/apps/api/src/decorators/token.decorator.ts b/apps/api/src/decorators/token.decorator.ts new file mode 100644 index 0000000..7713126 --- /dev/null +++ b/apps/api/src/decorators/token.decorator.ts @@ -0,0 +1,14 @@ +import { env } from '../config/env'; +import type { ExecutionContext } from '@nestjs/common'; +import { createParamDecorator, UnauthorizedException } from '@nestjs/common'; + +export const AuthToken = createParamDecorator((_data: unknown, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + + const token = + request.cookies[env.COOKIE_TOKEN_NAME] || request.headers?.authorization?.split(' ')[1]; + + if (!token) throw new UnauthorizedException('Token is missing'); + + return token; +}); diff --git a/apps/api/src/ldap/ldap.controller.ts b/apps/api/src/ldap/ldap.controller.ts index a1f9dfc..6e5dab5 100644 --- a/apps/api/src/ldap/ldap.controller.ts +++ b/apps/api/src/ldap/ldap.controller.ts @@ -19,6 +19,7 @@ import { ApiResponse, ApiTags } from '@nestjs/swagger'; import { FastifyReply, FastifyRequest } from 'fastify'; import { cookieOptions } from 'src/config/cookie'; import { env } from 'src/config/env'; +import { AuthToken } from 'src/decorators/token.decorator'; import type { BaseAuthController } from 'src/types/auth-controller'; import { User } from 'src/utils/ldap'; @@ -57,8 +58,7 @@ export class LdapController implements BaseAuthController { } @Get('/logout') - async logout(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { - const token = req.cookies[env.COOKIE_TOKEN_NAME]; + async logout(@Req() req: FastifyRequest, @Res() reply: FastifyReply, @AuthToken() token: string) { if (token) await this.ldapService.logout(token); this.clearCookies(req, reply); @@ -71,11 +71,11 @@ export class LdapController implements BaseAuthController { status: HttpStatus.OK, type: User, }) - async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { - const token = req.cookies[env.COOKIE_TOKEN_NAME]; - - if (!token) throw new UnauthorizedException(); - + async getUser( + @Req() req: FastifyRequest, + @Res() reply: FastifyReply, + @AuthToken() token: string + ) { const user = await this.ldapService.getUser(token); if (!user) throw new UnauthorizedException('User not found'); diff --git a/apps/api/src/types/auth-controller.ts b/apps/api/src/types/auth-controller.ts index ee4d7a6..63d5082 100644 --- a/apps/api/src/types/auth-controller.ts +++ b/apps/api/src/types/auth-controller.ts @@ -2,7 +2,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify'; import type { Credentials } from 'src/dto/credentials'; export type BaseAuthController = { - getUser: (req: FastifyRequest, reply: FastifyReply) => Promise; + getUser: (req: FastifyRequest, reply: FastifyReply, token: string) => Promise; login: (credentials: Credentials, req: FastifyRequest, reply: FastifyReply) => Promise; - logout: (req: FastifyRequest, reply: FastifyReply) => Promise; + logout: (req: FastifyRequest, reply: FastifyReply, token: string) => Promise; };