From fd8837c8354e2c702cb1235721ddfac669863849 Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Tue, 16 Jan 2024 14:07:51 +0300 Subject: [PATCH] apps/api: refresh account mode token --- apps/api/src/account/account.module.ts | 2 +- apps/api/src/account/account.service.ts | 22 +++++++++++++++++++++- apps/api/src/app.controller.ts | 14 +++++++++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/apps/api/src/account/account.module.ts b/apps/api/src/account/account.module.ts index f87c10f..aade86a 100644 --- a/apps/api/src/account/account.module.ts +++ b/apps/api/src/account/account.module.ts @@ -6,7 +6,7 @@ import { Account, AccountSchema } from 'src/schemas/account.schema'; @Module({ controllers: [AccountController], - exports: [], + exports: [AccountService], imports: [MongooseModule.forFeature([{ name: Account.name, schema: AccountSchema }])], providers: [AccountService], }) diff --git a/apps/api/src/account/account.service.ts b/apps/api/src/account/account.service.ts index efdb9d4..4918d2a 100644 --- a/apps/api/src/account/account.service.ts +++ b/apps/api/src/account/account.service.ts @@ -6,7 +6,7 @@ import * as bcrypt from 'bcrypt'; import { Model } from 'mongoose'; import { omit } from 'radash'; import type { Credentials } from 'src/dto/credentials'; -import type { TokenPayload } from 'src/ldap/types/jwt'; +import type { DecodedToken, TokenPayload } from 'src/ldap/types/jwt'; import { Account } from 'src/schemas/account.schema'; import { generatePassword } from 'src/utils/password'; @@ -80,6 +80,26 @@ export class AccountService { } } + public async refreshToken(token: string) { + try { + const { username } = this.jwtService.decode(token) as DecodedToken; + + const account = await this.accountModel.findOne({ username }); + if (!account) { + throw new UnauthorizedException('Account not found'); + } + + const payload: TokenPayload = { + username, + ...omit(account.toJSON(), ['password', '_id', '__v']), + }; + + return this.jwtService.sign(payload); + } catch (error) { + throw new UnauthorizedException(error); + } + } + public async getUser(token: string) { try { const { username } = this.jwtService.verify(token) as TokenPayload; diff --git a/apps/api/src/app.controller.ts b/apps/api/src/app.controller.ts index dd4263e..74bf452 100644 --- a/apps/api/src/app.controller.ts +++ b/apps/api/src/app.controller.ts @@ -1,3 +1,4 @@ +import { AccountService } from './account/account.service'; import { AppService } from './app.service'; import { env } from './config/env'; import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common'; @@ -8,7 +9,10 @@ import { cookieOptions } from 'src/config/cookie'; @Controller() @ApiExcludeController() export class AppController { - constructor(private readonly appService: AppService) {} + constructor( + private readonly appService: AppService, + private readonly accountService: AccountService + ) {} @Get('auth') public async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { @@ -35,8 +39,12 @@ export class AppController { return reply.send(); } - private handleExpiredToken(req: FastifyRequest, reply: FastifyReply, token: string) { - const newToken = this.appService.refreshToken(token); + private async handleExpiredToken(req: FastifyRequest, reply: FastifyReply, token: string) { + const authMode = req.headers['auth-mode']; + const newToken = + authMode === 'account' + ? await this.accountService.refreshToken(token) + : this.appService.refreshToken(token); reply.header('Authorization', `Bearer ${newToken}`); return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, cookieOptions).send();