/* eslint-disable class-methods-use-this */ /* eslint-disable import/no-extraneous-dependencies */ import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common'; import { FastifyReply, FastifyRequest } from 'fastify'; import { AuthService } from './auth.service'; import { COOKIE_TOKEN_NAME } from './lib/constants'; import { Credentials } from './types/request'; @Controller() export class AuthController { cookieOptions: { maxAge: number; path: string }; constructor(private readonly authService: AuthService) { this.cookieOptions = { maxAge: Number.parseInt(process.env.TOKEN_TTL, 10), path: '/', }; } private clearCookies(req, reply) { if (req.cookies) { Object.keys(req.cookies).forEach((cookieName) => { reply.clearCookie(cookieName, { path: '/', }); }); } } @Post('/signin') async login(@Body() credentials: Credentials, @Res() reply: FastifyReply) { const { login, password } = credentials; try { const token = await this.authService.login(login, password); return await reply.setCookie(COOKIE_TOKEN_NAME, token, this.cookieOptions).status(200).send(); } catch { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED); } } @Get('/logout') async logout(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { this.clearCookies(req, reply); const token = req.cookies[COOKIE_TOKEN_NAME]; await this.authService.logout(token); return reply.status(302).redirect('/login'); } @Get('/auth') async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { const token = req.cookies[COOKIE_TOKEN_NAME]; try { this.authService.checkToken(token); return await reply.send(); } catch (error) { if (error.name === 'TokenExpiredError') { const newToken = this.authService.refreshToken(token); return await reply.setCookie(COOKIE_TOKEN_NAME, newToken, this.cookieOptions).send(); } throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED); } } }