apps/api: add create token with audience in ldap-tfa controller

support token with audience in app controller
This commit is contained in:
vchikalkin 2024-05-14 15:38:32 +03:00
parent 092d2c98a1
commit 83975b0520
6 changed files with 37 additions and 13 deletions

View File

@ -94,6 +94,7 @@ export class AccountService {
public async refreshToken(token: string) {
try {
this.jwtService.verify(token);
const { username } = this.jwtService.decode(token) as DecodedToken;
const account = await this.accountModel.findOne({ username });

View File

@ -26,12 +26,10 @@ export class AppController {
@AuthToken() token: string,
@AuthParams() authParams: Params
) {
const { refreshToken } = authParams;
try {
return this.handleDefaultCheck(req, reply, token);
} catch (error) {
if (isTokenExpired(error) && refreshToken) {
if (isTokenExpired(error)) {
try {
return this.handleExpiredToken(authParams, token, req, reply);
} catch {
@ -44,16 +42,31 @@ export class AppController {
}
private async handleExpiredToken(
{ authMode }: Params,
{ authMode, refreshToken }: Params,
token: string,
req: FastifyRequest,
reply: FastifyReply
) {
if (!refreshToken) return this.handleError(req, reply);
try {
const newToken =
authMode === 'account'
? await this.accountService.refreshToken(token)
: await this.ldapService.refreshToken(token);
let newToken = '';
if (authMode === 'ldap-tfa') {
const { aud } = this.appService.checkToken(token);
if (aud === 'auth') return this.handleError(req, reply);
newToken = await this.ldapService.refreshToken(token);
}
if (authMode === 'ldap') {
newToken = await this.ldapService.refreshToken(token);
}
if (authMode === 'account') {
newToken = await this.accountService.refreshToken(token);
}
reply.header('Authorization', `Bearer ${newToken}`);
return reply.setCookie(env.COOKIE_TOKEN_NAME, newToken, cookieOptions).send();
@ -62,8 +75,12 @@ export class AppController {
}
}
private handleDefaultCheck(_req: FastifyRequest, reply: FastifyReply, token: string) {
private handleDefaultCheck(req: FastifyRequest, reply: FastifyReply, token: string) {
this.appService.checkToken(token);
const { aud } = this.appService.checkToken(token);
if (aud === 'auth') return this.handleError(req, reply);
reply.header('Authorization', `Bearer ${token}`);
return reply.send();

View File

@ -8,11 +8,11 @@ export class AppService {
constructor(private readonly jwtService: JwtService) {}
public checkToken(token: string) {
this.jwtService.verify(token);
return this.jwtService.decode<DecodedToken>(token);
}
public refreshToken(token: string) {
const payload = this.jwtService.decode(token) as DecodedToken;
const payload = this.jwtService.decode<DecodedToken>(token);
return this.jwtService.sign(omit(payload, ['iat', 'exp']));
}

View File

@ -2,6 +2,8 @@
import { Body, Controller, HttpException, HttpStatus, Post, Req, Res } from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';
import { FastifyReply, FastifyRequest } from 'fastify';
import { cookieOptions } from 'src/config/cookie';
import { env } from 'src/config/env';
import { Credentials } from 'src/dto/credentials';
import { LdapController } from 'src/ldap/ldap.controller';
@ -18,9 +20,11 @@ export class LdapTfaController extends LdapController {
@Res() reply: FastifyReply
) {
try {
const user = await this.ldapService.getUser(credentials.login);
const token = await this.ldapService.login(credentials, {
audience: 'auth',
});
return reply.status(200).send(user);
return reply.setCookie(env.COOKIE_TOKEN_NAME, token, cookieOptions).status(200).send();
} catch {
throw new HttpException('Unauthorized', HttpStatus.UNAUTHORIZED);
}

View File

@ -43,6 +43,7 @@ export class LdapService {
public async refreshToken(token: string) {
try {
this.jwtService.verify(token);
const { username } = this.jwtService.decode(token) as DecodedToken;
const user = await ldap.authenticate(username);

View File

@ -4,6 +4,7 @@ export type TokenPayload = {
};
export type DecodedToken = {
aud?: string;
exp: number;
iat: number;
} & TokenPayload;