apps/api: refresh account mode token

This commit is contained in:
vchikalkin 2024-01-16 14:07:51 +03:00
parent 85f1976386
commit fd8837c835
3 changed files with 33 additions and 5 deletions

View File

@ -6,7 +6,7 @@ import { Account, AccountSchema } from 'src/schemas/account.schema';
@Module({ @Module({
controllers: [AccountController], controllers: [AccountController],
exports: [], exports: [AccountService],
imports: [MongooseModule.forFeature([{ name: Account.name, schema: AccountSchema }])], imports: [MongooseModule.forFeature([{ name: Account.name, schema: AccountSchema }])],
providers: [AccountService], providers: [AccountService],
}) })

View File

@ -6,7 +6,7 @@ import * as bcrypt from 'bcrypt';
import { Model } from 'mongoose'; import { Model } from 'mongoose';
import { omit } from 'radash'; import { omit } from 'radash';
import type { Credentials } from 'src/dto/credentials'; 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 { Account } from 'src/schemas/account.schema';
import { generatePassword } from 'src/utils/password'; 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) { public async getUser(token: string) {
try { try {
const { username } = this.jwtService.verify(token) as TokenPayload; const { username } = this.jwtService.verify(token) as TokenPayload;

View File

@ -1,3 +1,4 @@
import { AccountService } from './account/account.service';
import { AppService } from './app.service'; import { AppService } from './app.service';
import { env } from './config/env'; import { env } from './config/env';
import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common'; import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common';
@ -8,7 +9,10 @@ import { cookieOptions } from 'src/config/cookie';
@Controller() @Controller()
@ApiExcludeController() @ApiExcludeController()
export class AppController { export class AppController {
constructor(private readonly appService: AppService) {} constructor(
private readonly appService: AppService,
private readonly accountService: AccountService
) {}
@Get('auth') @Get('auth')
public async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) { public async auth(@Req() req: FastifyRequest, @Res() reply: FastifyReply) {
@ -35,8 +39,12 @@ export class AppController {
return reply.send(); return reply.send();
} }
private handleExpiredToken(req: FastifyRequest, reply: FastifyReply, token: string) { private async handleExpiredToken(req: FastifyRequest, reply: FastifyReply, token: string) {
const newToken = this.appService.refreshToken(token); const authMode = req.headers['auth-mode'];
const newToken =
authMode === 'account'
? await this.accountService.refreshToken(token)
: this.appService.refreshToken(token);
reply.header('Authorization', `Bearer ${newToken}`); reply.header('Authorization', `Bearer ${newToken}`);
return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, cookieOptions).send(); return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, cookieOptions).send();