diff --git a/apps/api/src/app.controller.ts b/apps/api/src/app.controller.ts new file mode 100644 index 0000000..f380f7b --- /dev/null +++ b/apps/api/src/app.controller.ts @@ -0,0 +1,27 @@ +import { AppService } from './app.service'; +import { env } from './config/env'; +import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common'; +import { FastifyReply, FastifyRequest } from 'fastify'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + @Get('auth') + public async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { + const token = req.cookies[env.COOKIE_TOKEN_NAME]; + + try { + this.appService.checkToken(token); + + return reply.send(); + } catch { + // if (error.name === 'TokenExpiredError') { + // const newToken = this.appService.refreshToken(token); + + // return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, cookieOptions).send(); + // } + + return reply.status(HttpStatus.UNAUTHORIZED).send(); + } + } +} diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 45552bc..8356048 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -1,3 +1,5 @@ +import { AppController } from './app.controller'; +import { AppService } from './app.service'; import { env } from './config/env'; import { LdapModule } from './ldap/ldap.module'; import { UsersModule } from './users/users.module'; @@ -8,7 +10,7 @@ import { MongooseModule } from '@nestjs/mongoose'; @Global() @Module({ - controllers: [], + controllers: [AppController], exports: [JwtModule], imports: [ ConfigModule.forRoot({ @@ -24,6 +26,7 @@ import { MongooseModule } from '@nestjs/mongoose'; UsersModule, MongooseModule.forRoot(`mongodb://${env.MONGO_HOST}`), ], + providers: [AppService], }) // eslint-disable-next-line @typescript-eslint/no-extraneous-class export class AppModule {} diff --git a/apps/api/src/app.service.ts b/apps/api/src/app.service.ts new file mode 100644 index 0000000..47a278e --- /dev/null +++ b/apps/api/src/app.service.ts @@ -0,0 +1,19 @@ +import type { DecodedToken } from './ldap/types/jwt'; +import { Injectable } from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; + +@Injectable() +export class AppService { + constructor(private readonly jwtService: JwtService) {} + + public checkToken(token: string) { + this.jwtService.verify(token); + } + + public refreshToken(token: string) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { exp, iat, ...payload } = this.jwtService.decode(token) as DecodedToken; + + return this.jwtService.sign(payload); + } +} diff --git a/apps/api/src/config/cookie.ts b/apps/api/src/config/cookie.ts new file mode 100644 index 0000000..d9799cb --- /dev/null +++ b/apps/api/src/config/cookie.ts @@ -0,0 +1,9 @@ +import type { CookieSerializeOptions } from '@fastify/cookie'; +import { env } from 'src/config/env'; + +export const cookieOptions: CookieSerializeOptions = { + httpOnly: true, + maxAge: env.API_TOKEN_TTL, + path: '/', + secure: true, +}; diff --git a/apps/api/src/ldap/ldap.controller.ts b/apps/api/src/ldap/ldap.controller.ts index c1fa6b8..77e6d02 100644 --- a/apps/api/src/ldap/ldap.controller.ts +++ b/apps/api/src/ldap/ldap.controller.ts @@ -6,19 +6,13 @@ import { LdapService } from './ldap.service'; import type { CookieSerializeOptions } from '@fastify/cookie'; import { Body, Controller, Get, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common'; import { FastifyReply, FastifyRequest } from 'fastify'; +import { cookieOptions } from 'src/config/cookie'; import { env } from 'src/config/env'; @Controller('ldap') export class LdapController { cookieOptions: CookieSerializeOptions; - constructor(private readonly ldapService: LdapService) { - this.cookieOptions = { - httpOnly: true, - maxAge: env.API_TOKEN_TTL, - path: '/', - secure: true, - }; - } + constructor(private readonly ldapService: LdapService) {} private clearCookies(req, reply) { if (req.cookies) { @@ -37,7 +31,7 @@ export class LdapController { try { const token = await this.ldapService.login(login, password); - return reply.setCookie(env.COOKIE_TOKEN_NAME, token, this.cookieOptions).status(200).send(); + return reply.setCookie(env.COOKIE_TOKEN_NAME, token, cookieOptions).status(200).send(); } catch { throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED); } @@ -53,25 +47,6 @@ export class LdapController { return reply.status(302).redirect('/login'); } - @Get('auth') - async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { - const token = req.cookies[env.COOKIE_TOKEN_NAME]; - - try { - this.ldapService.checkToken(token); - - return reply.send(); - } catch (error) { - if (error.name === 'TokenExpiredError') { - const newToken = this.ldapService.refreshToken(token); - - return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, this.cookieOptions).send(); - } - - return reply.status(HttpStatus.UNAUTHORIZED).send(); - } - } - @Get('/get-user') async getUser(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { const token = req.cookies[env.COOKIE_TOKEN_NAME]; diff --git a/apps/api/src/ldap/ldap.service.ts b/apps/api/src/ldap/ldap.service.ts index dc28f36..1f78444 100644 --- a/apps/api/src/ldap/ldap.service.ts +++ b/apps/api/src/ldap/ldap.service.ts @@ -35,17 +35,6 @@ export class LdapService { } } - public checkToken(token: string) { - this.jwtService.verify(token); - } - - public refreshToken(token: string) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { exp, iat, ...payload } = this.jwtService.decode(token) as DecodedToken; - - return this.jwtService.sign(payload); - } - public async getUser(token: string) { const { username } = this.jwtService.decode(token) as DecodedToken;