diff --git a/src/helpers/error/instances/forwarder.ts b/src/helpers/error/instances/forwarder.ts index b9a5821..6fd301b 100644 --- a/src/helpers/error/instances/forwarder.ts +++ b/src/helpers/error/instances/forwarder.ts @@ -1,9 +1,9 @@ import { AppError } from "./app"; export function ErrorForwarder( - statusCode: number, - message: string, - cause: unknown + cause: unknown, + statusCode: number = 500, + message: string = "Unexpected error" ): never { if (cause instanceof AppError) { throw cause; diff --git a/src/modules/auth/controller/authVerification.controller.ts b/src/modules/auth/controller/authVerification.controller.ts index 463ff01..631e835 100644 --- a/src/modules/auth/controller/authVerification.controller.ts +++ b/src/modules/auth/controller/authVerification.controller.ts @@ -11,13 +11,16 @@ import { COOKIE_KEYS } from "../../../constants/cookie.keys"; export const authVerification = async (ctx: Context) => { try { + // Get the auth token from cookies const cookie = getCookie(ctx); if (!cookie.auth_token) return returnErrorResponse(ctx.set, 401, "Auth token not found"); + // Verify the auth token and get the user session const authService = await authVerificationService(cookie.auth_token); return returnWriteResponse(ctx.set, 200, "User authenticated", authService); } catch (error) { + // If token is invalid or expired, clear the auth cookie and return an error response clearCookies(ctx.set, [COOKIE_KEYS.AUTH]); return mainErrorHandler(ctx.set, error); } diff --git a/src/modules/auth/services/authVerification.service.ts b/src/modules/auth/services/authVerification.service.ts index ed0636a..fedcdf7 100644 --- a/src/modules/auth/services/authVerification.service.ts +++ b/src/modules/auth/services/authVerification.service.ts @@ -1,7 +1,8 @@ import { AppError } from "../../../helpers/error/instances/app"; +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; import { jwtDecode } from "../../../helpers/http/jwt/decode"; import { checkUserSessionInCacheService } from "../../userSession/services/checkUserSessionInCache.service"; -import { getUserSessionService } from "../../userSession/services/getUserSession.service"; +import { getUserSessionFromDBService } from "../../userSession/services/getUserSessionFromDB.service"; import { storeUserSessionToCacheService } from "../../userSession/services/storeUserSessionToCache.service"; import { JWTSessionPayload } from "../auth.types"; @@ -18,14 +19,10 @@ export const authVerificationService = async (cookie: string) => { if (!sessionCheckOnRedis) { // If not found in Redis, check the database - const sessionCheckOnDB = await getUserSessionService(jwtSession.id); + const sessionCheckOnDB = await getUserSessionFromDBService(jwtSession.id); // If the session found in the database, store it in Redis. if not, throw an error - if ( - !sessionCheckOnDB || - !sessionCheckOnDB.isAuthenticated || - new Date(sessionCheckOnDB.validUntil) < new Date() - ) { + if (!sessionCheckOnDB) { throw new AppError(401, "Session invalid or expired"); } else { // Store the session in Redis with the remaining time until expiration @@ -38,9 +35,10 @@ export const authVerificationService = async (cookie: string) => { return sessionCheckOnDB; } } else { + // If the session is found in Redis, return it return jwtSession; } } catch (error) { - throw new AppError(401, "Token is invalid", error); + ErrorForwarder(error, 401, "Token is invalid"); } }; diff --git a/src/modules/debug/debug.service.ts b/src/modules/debug/debug.service.ts index 58e4b13..2f659bf 100644 --- a/src/modules/debug/debug.service.ts +++ b/src/modules/debug/debug.service.ts @@ -6,6 +6,6 @@ export const debugService = async () => { const dataFromService = await debug2Service(); return dataFromService; } catch (error) { - ErrorForwarder(402, "Error from 1", error); + ErrorForwarder(error); } }; diff --git a/src/modules/debug/debug2.service.ts b/src/modules/debug/debug2.service.ts index 216821a..c5e4fe3 100644 --- a/src/modules/debug/debug2.service.ts +++ b/src/modules/debug/debug2.service.ts @@ -6,6 +6,6 @@ export const debug2Service = async () => { const dataFromService = await debug3Service(); return dataFromService; } catch (error) { - ErrorForwarder(402, "Error from 2", error); + ErrorForwarder(error, 502); } }; diff --git a/src/modules/debug/debug3.service.ts b/src/modules/debug/debug3.service.ts index 21052e5..5e7a94e 100644 --- a/src/modules/debug/debug3.service.ts +++ b/src/modules/debug/debug3.service.ts @@ -1,5 +1,9 @@ import { AppError } from "../../helpers/error/instances/app"; +import { ErrorForwarder } from "../../helpers/error/instances/forwarder"; export const debug3Service = async () => { - throw new AppError(402, "Error from 3"); + // throw new AppError(402, "Error from 3"); + const data = "RAWR"; + // return data; + ErrorForwarder(data); }; diff --git a/src/modules/userSession/repositories/findUniqueUserSessionInDB.repository.ts b/src/modules/userSession/repositories/findUniqueUserSessionInDB.repository.ts index e52e113..a6cb1f3 100644 --- a/src/modules/userSession/repositories/findUniqueUserSessionInDB.repository.ts +++ b/src/modules/userSession/repositories/findUniqueUserSessionInDB.repository.ts @@ -1,26 +1,33 @@ +import { AppError } from "../../../helpers/error/instances/app"; import { prisma } from "../../../utils/databases/prisma/connection"; export const findUniqueUserSessionInDBRepo = async (identifier: string) => { - const userSession = await prisma.userSession.findUnique({ - where: { - id: identifier, - }, - include: { - user: { - omit: { - password: true, - updatedAt: true, - }, - include: { - roles: true, + try { + const userSession = await prisma.userSession.findUnique({ + where: { + id: identifier, + }, + include: { + user: { + omit: { + password: true, + updatedAt: true, + }, + include: { + roles: true, + }, }, }, - }, - omit: { - deletedAt: true, - updatedAt: true, - }, - }); + omit: { + deletedAt: true, + updatedAt: true, + }, + }); - return userSession; + if (!userSession) return false; + + return userSession; + } catch (error) { + throw new AppError(500, "Database Error", error); + } }; diff --git a/src/modules/userSession/services/checkUserSessionInCache.service.ts b/src/modules/userSession/services/checkUserSessionInCache.service.ts index 17ca5c0..c8abee9 100644 --- a/src/modules/userSession/services/checkUserSessionInCache.service.ts +++ b/src/modules/userSession/services/checkUserSessionInCache.service.ts @@ -1,12 +1,19 @@ -import { AppError } from "../../../helpers/error/instances/app"; +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; import { checkUserSessionInCacheRepo } from "../repositories/checkUserSessionInCache.repository"; export const checkUserSessionInCacheService = async ( userId: string, sessionId: string ) => { - const redisKeyName = `${process.env.app_name}:users:${userId}:sessions:${sessionId}`; + try { + // Construct the Redis key name using the userId and sessionId + const redisKeyName = `${process.env.app_name}:users:${userId}:sessions:${sessionId}`; - const userSessionInRedis = await checkUserSessionInCacheRepo(redisKeyName); - return userSessionInRedis; + // Check if the user session exists in Redis + const userSessionInRedis = await checkUserSessionInCacheRepo(redisKeyName); + return userSessionInRedis; + } catch (error) { + // Forward the error with a 400 status code and a message + ErrorForwarder(error, 400, "Bad Request"); + } }; diff --git a/src/modules/userSession/services/getUserSession.service.ts b/src/modules/userSession/services/getUserSession.service.ts deleted file mode 100644 index 06fade5..0000000 --- a/src/modules/userSession/services/getUserSession.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { AppError } from "../../../helpers/error/instances/app"; -import { findUniqueUserSessionInDBRepo } from "../repositories/findUniqueUserSessionInDB.repository"; - -export const getUserSessionService = async (identifier: string) => { - try { - const userSession = await findUniqueUserSessionInDBRepo(identifier); - return userSession; - } catch (error) { - throw new AppError(401, "Unable to get user session", error); - } -}; diff --git a/src/modules/userSession/services/getUserSessionFromDB.service.ts b/src/modules/userSession/services/getUserSessionFromDB.service.ts new file mode 100644 index 0000000..57696b4 --- /dev/null +++ b/src/modules/userSession/services/getUserSessionFromDB.service.ts @@ -0,0 +1,23 @@ +import { AppError } from "../../../helpers/error/instances/app"; +import { findUniqueUserSessionInDBRepo } from "../repositories/findUniqueUserSessionInDB.repository"; + +export const getUserSessionFromDBService = async (identifier: string) => { + try { + // Check is session exists in DB + const userSession = await findUniqueUserSessionInDBRepo(identifier); + + // If session not found, return false + if ( + !userSession || + !userSession.isAuthenticated || + new Date(userSession.validUntil) < new Date() + ) + return false; + + // If session found, return it + return userSession; + } catch (error) { + // If any DB error occurs, throw an AppError + throw new AppError(401, "Unable to get user session", error); + } +}; diff --git a/src/modules/userSession/services/storeUserSessionToCache.service.ts b/src/modules/userSession/services/storeUserSessionToCache.service.ts index cfd50ad..d27d51f 100644 --- a/src/modules/userSession/services/storeUserSessionToCache.service.ts +++ b/src/modules/userSession/services/storeUserSessionToCache.service.ts @@ -7,9 +7,11 @@ export const storeUserSessionToCacheService = async ( timeExpires: number ) => { try { + // Store user session in cache with expiration time await storeUserSessionToCacheRepo(userSession, timeExpires); return; } catch (error) { + // If any error occurs while storing session in cache, throw an AppError throw new AppError(401, "Failed to store user session to cache"); } };