import { Response, Request } from "express"; import { Controller, Post } from "@ControllerPattern/index"; import ApiController from "@Common/system/controller-pattern/ApiController"; import { Service } from "typedi"; import CustomersService, { InvalidPasswordError, InvalidTotpCodeError, NotRegisteredCustomerError, PasswordAlreadySetError, SmsNotExpiredError, TotpCodeExpiredError, } from "@Services/customer/CustomersService/CustomersService"; import AuthService from "@Services/common/AuthService/AuthService"; import { Customer } from "le-coffre-resources/dist/SuperAdmin"; @Controller() @Service() export default class AuthController extends ApiController { constructor(private customerService: CustomersService, private authService: AuthService) { super(); } @Post("/api/v1/customer/auth/mail/verify-sms") protected async mailVerifySms(req: Request, response: Response) { const email = req.body["email"]; if (!email) { this.httpBadRequest(response, "Email is required"); return; } try { const customer = await this.customerService.verifyEmail2FASms(email); if (!customer) { this.httpNotFoundRequest(response, "Customer not found"); return; } this.httpSuccess(response, { partialPhoneNumber: customer.contact?.cell_phone_number.replace(/\s/g, "").slice(-4) }); } catch (error) { if (error instanceof SmsNotExpiredError) { this.httpTooEarlyRequest(response, error.message); return; } console.log(error); this.httpInternalError(response); } } @Post("/api/v1/customer/auth/login") protected async login(req: Request, response: Response) { const email = req.body["email"]; const totpCode = req.body["totpCode"]; const password = req.body["password"]; if (!email) { this.httpBadRequest(response, "email is required"); return; } if (!totpCode) { this.httpBadRequest(response, "totpCode is required"); return; } if (!password) { this.httpBadRequest(response, "password is required"); return; } try { const customer = await this.customerService.login(email, totpCode, password); if (!customer) { this.httpBadRequest(response, "Customer not found"); return; } const customerHydrated = Customer.hydrate(customer); const payload = await this.authService.getCustomerJwtPayload([customerHydrated]); const accessToken = this.authService.generateAccessToken(payload); const refreshToken = this.authService.generateRefreshToken(payload); this.httpSuccess(response, { accessToken, refreshToken }); } catch (error) { if (error instanceof TotpCodeExpiredError || error instanceof NotRegisteredCustomerError) { this.httpBadRequest(response, error.message); return; } if (error instanceof InvalidTotpCodeError || error instanceof InvalidPasswordError) { this.httpUnauthorized(response, error.message); return; } console.log(error); this.httpInternalError(response); return; } } @Post("/api/v1/customer/auth/set-password") protected async setPassword(req: Request, response: Response) { const email = req.body["email"]; const totpCode = req.body["totpCode"]; const password = req.body["password"]; if (!email) { this.httpBadRequest(response, "Email is required"); return; } if (!totpCode) { this.httpBadRequest(response, "Sms code is required"); return; } if (!password) { this.httpBadRequest(response, "Password is required"); return; } try { const customer = await this.customerService.setFirstPassword(email, totpCode, password); if (!customer) { this.httpBadRequest(response, "Customer not found"); return; } const customerHydrated = Customer.hydrate(customer); const payload = await this.authService.getCustomerJwtPayload([customerHydrated]); const accessToken = this.authService.generateAccessToken(payload); const refreshToken = this.authService.generateRefreshToken(payload); this.httpSuccess(response, { accessToken, refreshToken }); } catch (error) { if (error instanceof TotpCodeExpiredError || error instanceof PasswordAlreadySetError) { this.httpBadRequest(response, error.message); return; } if (error instanceof InvalidTotpCodeError) { this.httpUnauthorized(response, error.message); return; } console.log(error); this.httpInternalError(response); return; } } @Post("/api/v1/customer/auth/verify-totp-code") protected async verifyTotpCode(req: Request, response: Response) { const totpCode = req.body["totpCode"]; const email = req.body["email"]; if (!totpCode) { this.httpBadRequest(response, "totpCode is required"); return; } if (!email) { this.httpBadRequest(response, "email is required"); return; } try { const code = await this.customerService.verifyTotpCode(totpCode, email); if (!code) { this.httpNotFoundRequest(response, "Customer not found"); return; } this.httpSuccess(response, { validCode: true, reason: code.reason, }); } catch (error) { if (error instanceof InvalidTotpCodeError || error instanceof TotpCodeExpiredError) { this.httpUnauthorized(response, error.message); return; } console.log(error); this.httpInternalError(response); } } }