import { RouteHandlerMethod } from 'fastify' import { Uuid } from '@theoryofnekomata/uuid-buffer' import { Controller } from 'src/packages/fastify-utils-theoryofnekomata' import { UserService, UserServiceImpl } from 'src/modules/user' import { LoginUserFormData } from 'src/modules/auth/models' import { SessionService, SessionServiceImpl } from 'src/modules/auth/Session.service' import { LoggedOutData, LoggedInData, UnableToLogInError, UnableToLogOutError, } from 'src/modules/auth/responses' export interface AuthController extends Controller<'logIn' | 'logOut'> {} export class AuthControllerImpl implements AuthController { private readonly sessionService: SessionService private readonly userService: UserService constructor() { this.sessionService = new SessionServiceImpl() this.userService = new UserServiceImpl() } readonly logIn: RouteHandlerMethod = async (request, reply) => { const { username, password } = request.body as LoginUserFormData try { const existingUser = await this.userService.getFromCredentials({ username, password, }) const newSession = await this.sessionService.create({ userId: existingUser.id, }) reply.sendData(new LoggedInData(newSession)) } catch (causeRaw) { const cause = causeRaw as Error throw new UnableToLogInError( 'Authorization could not be performed on the credentials provided. Either try again later or ensure registration using the previous credentials.', { cause }, ) } } readonly logOut: RouteHandlerMethod = async (request, reply) => { const sessionId = request.session?.id; if (sessionId) { try { await this.sessionService.expire(Uuid.from(sessionId)) reply.sendData(new LoggedOutData()) return } catch { // noop } } throw new UnableToLogOutError( 'De-authorization could not be performed. Ensure session data is present and/or clear local data to carry out the operation.') } }