Evo.Auth/apps/api/src/app.controller.ts
2024-06-05 12:34:28 +03:00

97 lines
2.7 KiB
TypeScript

import { AccountService } from './account/account.service';
import { AppService } from './app.service';
import { env } from './config/env';
import { AuthParams, Params } from './decorators/auth-mode.decorator';
import { AuthToken } from './decorators/token.decorator';
import { LdapService } from './ldap/ldap.service';
import { isTokenExpired } from './utils/error';
import { Controller, Get, HttpStatus, Req, Res } from '@nestjs/common';
import { ApiExcludeController } from '@nestjs/swagger';
import { FastifyReply, FastifyRequest } from 'fastify';
import { cookieOptions } from 'src/config/cookie';
@Controller()
@ApiExcludeController()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly accountService: AccountService,
private readonly ldapService: LdapService
) {}
@Get('auth')
public async auth(
@Req() req: FastifyRequest,
@Res() reply: FastifyReply,
@AuthToken() token: string,
@AuthParams() authParams: Params
) {
try {
return this.handleDefaultCheck(authParams, req, reply, token);
} catch (error) {
if (isTokenExpired(error)) {
return this.handleExpiredToken(authParams, token, req, reply);
}
return this.handleError(req, reply);
}
}
private async handleExpiredToken(
{ authMode, refreshToken }: Params,
token: string,
req: FastifyRequest,
reply: FastifyReply
) {
if (!refreshToken) return this.handleError(req, reply);
try {
let newToken = '';
if (authMode === 'ldap-tfa') {
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();
} catch {
return this.handleError(req, reply);
}
}
private handleDefaultCheck(
{ authMode }: Params,
req: FastifyRequest,
reply: FastifyReply,
token: string
) {
const { aud } = this.appService.checkToken(token);
const originalUri = req.headers['x-original-uri'];
if (
authMode === 'ldap-tfa' &&
aud === 'auth' &&
!['/auth', '/login', '/socket.io'].some((x) => originalUri.includes(x))
) {
return this.handleError(req, reply);
}
reply.header('Authorization', `Bearer ${token}`);
return reply.send();
}
private handleError(_req: FastifyRequest, reply: FastifyReply) {
return reply.status(HttpStatus.UNAUTHORIZED).send();
}
}