From ab84abf366e3231864903eeff98a72c1fce96dcc Mon Sep 17 00:00:00 2001 From: rafiarrafif Date: Tue, 27 May 2025 23:06:37 +0700 Subject: [PATCH] complete: complete login process --- .../loginWithPassword.controller.ts | 18 +++++-- .../loginWithPassword.ts} | 0 .../services/loginWithPassword.service.ts | 7 ++- .../findUserByEmailOrUsername.repository.ts | 54 ++++++++++--------- .../findUserByEmailOrUsername.service.ts | 3 +- 5 files changed, 50 insertions(+), 32 deletions(-) rename src/modules/auth/{auth.schema.ts => schemas/loginWithPassword.ts} (100%) diff --git a/src/modules/auth/controller/loginWithPassword.controller.ts b/src/modules/auth/controller/loginWithPassword.controller.ts index dfaea9b..a4a0eba 100644 --- a/src/modules/auth/controller/loginWithPassword.controller.ts +++ b/src/modules/auth/controller/loginWithPassword.controller.ts @@ -1,31 +1,41 @@ -import { Context } from "elysia"; -import { loginWithPasswordService } from "../services/loginWithPassword.service"; -import { loginWithPasswordSchema } from "../auth.schema"; import { returnErrorResponse, returnWriteResponse, } from "../../../helpers/callback/httpResponse"; +import { Context } from "elysia"; +import { loginWithPasswordService } from "../services/loginWithPassword.service"; import { LoginWithPasswordRequest } from "../auth.types"; import { mainErrorHandler } from "../../../helpers/error/handler"; import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation"; import { setCookie } from "../../../helpers/http/userHeader/cookies/setCookies"; import { COOKIE_KEYS } from "../../../constants/cookie.keys"; +import { loginWithPasswordSchema } from "../schemas/loginWithPassword"; export const loginWithPassword = async ( ctx: Context & { body: LoginWithPasswordRequest } ) => { + // Validate the request body against the schema const { error } = loginWithPasswordSchema.validate(ctx.body); if (error || !ctx.body) return returnErrorResponse(ctx.set, 400, "Invalid user input", error); + // Extract user header information const userHeaderInfo = getUserHeaderInformation(ctx); try { + // Call the service to handle login with password const jwtToken = await loginWithPasswordService(ctx.body, userHeaderInfo); + // Set the authentication cookie with the JWT token const cookie = setCookie(ctx.set, COOKIE_KEYS.AUTH, jwtToken); - return returnWriteResponse(ctx.set, 200, "Authentication Success", cookie); + return returnWriteResponse( + ctx.set, + 200, + "Authentication Success", + jwtToken + ); } catch (error) { + // Handle any errors that occur during the login process return mainErrorHandler(ctx.set, error); } }; diff --git a/src/modules/auth/auth.schema.ts b/src/modules/auth/schemas/loginWithPassword.ts similarity index 100% rename from src/modules/auth/auth.schema.ts rename to src/modules/auth/schemas/loginWithPassword.ts diff --git a/src/modules/auth/services/loginWithPassword.service.ts b/src/modules/auth/services/loginWithPassword.service.ts index 5022250..12624c1 100644 --- a/src/modules/auth/services/loginWithPassword.service.ts +++ b/src/modules/auth/services/loginWithPassword.service.ts @@ -5,6 +5,7 @@ import { AppError } from "../../../helpers/error/instances/app"; import { UserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation/types"; import { createUserSessionService } from "../../userSession/services/createUserSession.service"; import { jwtEncode } from "../../../helpers/http/jwt/encode"; +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; export const loginWithPasswordService = async ( request: LoginWithPasswordRequest, @@ -14,6 +15,9 @@ export const loginWithPasswordService = async ( // search for user data using an identifier (username or email) const userData = await findUserByEmailOrUsernameService(request.identifier); + // if user data is not found, throw an error + if (!userData) throw new AppError(404, "User not found"); + // validate the password in the request with the existing one if (!(await bcrypt.compare(request.password, userData.password))) throw new AppError(401, "Password incorrect"); @@ -26,9 +30,8 @@ export const loginWithPasswordService = async ( // create JWT token that contain user session const jwtToken = jwtEncode(userSession); - return jwtToken; } catch (error) { - throw error; + ErrorForwarder(error); } }; diff --git a/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts b/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts index 9ed0060..b894ce0 100644 --- a/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts +++ b/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts @@ -2,34 +2,38 @@ import { AppError } from "../../../helpers/error/instances/app"; import { userModel } from "../user.model"; export const findUserByEmailOrUsernameRepo = async (identifier: string) => { - const userData = - (await userModel.findUnique({ - where: { email: identifier }, - include: { - roles: { - omit: { - createdBy: true, - createdAt: true, - updatedAt: true, - deletedAt: true, + try { + const userData = + (await userModel.findUnique({ + where: { email: identifier }, + include: { + roles: { + omit: { + createdBy: true, + createdAt: true, + updatedAt: true, + deletedAt: true, + }, }, }, - }, - })) || - (await userModel.findUnique({ - where: { username: identifier }, - include: { - roles: { - omit: { - createdBy: true, - createdAt: true, - updatedAt: true, - deletedAt: true, + })) || + (await userModel.findUnique({ + where: { username: identifier }, + include: { + roles: { + omit: { + createdBy: true, + createdAt: true, + updatedAt: true, + deletedAt: true, + }, }, }, - }, - })); + })); - if (!userData) throw new AppError(404, "User not exist"); - return userData; + if (!userData) return false; + return userData; + } catch (error) { + throw new AppError(500, "Database error", error); + } }; diff --git a/src/modules/user/services/findUserByEmailOrUsername.service.ts b/src/modules/user/services/findUserByEmailOrUsername.service.ts index 06d977d..86ed437 100644 --- a/src/modules/user/services/findUserByEmailOrUsername.service.ts +++ b/src/modules/user/services/findUserByEmailOrUsername.service.ts @@ -1,3 +1,4 @@ +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; import { findUserByEmailOrUsernameRepo } from "../repositories/findUserByEmailOrUsername.repository"; export const findUserByEmailOrUsernameService = async (identifier: string) => { @@ -5,6 +6,6 @@ export const findUserByEmailOrUsernameService = async (identifier: string) => { const userData = await findUserByEmailOrUsernameRepo(identifier); return userData; } catch (error) { - throw error; + ErrorForwarder(error); } };