diff --git a/src/modules/auth/services/loginWithPassword.service.ts b/src/modules/auth/services/loginWithPassword.service.ts index cc32f1c..5e2df2d 100644 --- a/src/modules/auth/services/loginWithPassword.service.ts +++ b/src/modules/auth/services/loginWithPassword.service.ts @@ -1,5 +1,5 @@ import bcrypt from "bcrypt"; -import { findUserByEmailOrUsernameService } from "../../user/services/findUserByEmailOrUsername.service"; +import { findUserByEmailOrUsernameService } from "../../user/services/getUserData.service"; import { LoginWithPasswordRequest } from "../auth.types"; import { AppError } from "../../../helpers/error/instances/app"; import { UserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation/types"; diff --git a/src/modules/user/controller/checkUserPassword.controller.ts b/src/modules/user/controller/checkUserPassword.controller.ts deleted file mode 100644 index 5813d79..0000000 --- a/src/modules/user/controller/checkUserPassword.controller.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Context } from "elysia"; -import { checkUserPasswordService } from "../services/checkUserPassword.service"; -import { jwtDecode } from "../../../helpers/http/jwt/decode"; -import { getCookie } from "../../../helpers/http/userHeader/cookies/getCookies"; -import { mainErrorHandler } from "../../../helpers/error/handler"; -import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; - -export const checkUserPasswordController = async ( - ctx: Context & { body: { password: string } } -) => { - try { - // Get the credentials information from cookies - const cookie = getCookie(ctx); - const jwtPayload = jwtDecode(cookie.auth_token!); - - // Execute the check user password service - const checkUserPassword = await checkUserPasswordService( - jwtPayload.user.username, - ctx.body.password - ); - - // If the password is valid, return a success response - return returnWriteResponse( - ctx.set, - 204, - "Password is valid", - checkUserPassword - ); - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/user/controller/createUser.controller.ts b/src/modules/user/controller/createUser.controller.ts deleted file mode 100644 index 3c4dead..0000000 --- a/src/modules/user/controller/createUser.controller.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - returnErrorResponse, - returnWriteResponse, -} from "../../../helpers/callback/httpResponse"; -import { Prisma } from "@prisma/client"; -import { Context } from "elysia"; -import { createUserService } from "../services/createUser.service"; -import { mainErrorHandler } from "../../../helpers/error/handler"; -import { createUserSchema } from "../schemas/createUser.schema"; - -/** - * @function createUser - * @description Creates a new user in the database. - * - * @param {Context & { body: Prisma.UserCreateInput }} ctx - The context object containing the request body. - * @param {Prisma.UserCreateInput} ctx.body - The user data to be created. - * - * @returns {Promise} A response object indicating success or failure. - * @throws {Object} An error response object if validation fails or an error occurs during user creation. - * - * @example - * Request route: POST /users - * Request body: - * { - * "username": "john_doe", - * "email": "john@example.com", - * "password": "password123" - * } - */ -export const createUserController = async ( - ctx: Context & { body: Prisma.UserCreateInput } -) => { - // Validate the user input using a validation schema - const { error } = createUserSchema.validate(ctx.body); - if (error) - return returnErrorResponse(ctx.set, 400, "Invalid user input", error); - - // Create the user in the database using the service - try { - const newUser = await createUserService(ctx.body); - return returnWriteResponse( - ctx.set, - 201, - "User created successfully", - newUser - ); - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/user/controller/createUserViaRegister.controller.ts b/src/modules/user/controller/createUserViaRegister.controller.ts new file mode 100644 index 0000000..aaa8235 --- /dev/null +++ b/src/modules/user/controller/createUserViaRegister.controller.ts @@ -0,0 +1,21 @@ +import { Context } from "elysia"; +import { createUserSchema } from "../schemas/createUser.schema"; +import { mainErrorHandler } from "../../../helpers/error/handler"; +import { createUserViaRegisterService } from "../services/createUserViaRegister.service"; +import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; + +export const createUserViaRegisterController = async (ctx: Context) => { + try { + const validate = createUserSchema.parse(ctx.body); + + const createUser = await createUserViaRegisterService(validate); + return returnWriteResponse( + ctx.set, + 201, + "User Successfully Created", + createUser + ); + } catch (error) { + return mainErrorHandler(ctx.set, error); + } +}; diff --git a/src/modules/user/controller/editUser.controller.ts b/src/modules/user/controller/editUser.controller.ts deleted file mode 100644 index 3be7f2c..0000000 --- a/src/modules/user/controller/editUser.controller.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { Context } from "elysia"; -import { - returnErrorResponse, - returnWriteResponse, -} from "../../../helpers/callback/httpResponse"; -import { mainErrorHandler } from "../../../helpers/error/handler"; -import { Prisma } from "@prisma/client"; -import { updateUserService } from "../services/updateUser.service"; -import { getCookie } from "../../../helpers/http/userHeader/cookies/getCookies"; -import { getUserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation"; -import { setCookie } from "../../../helpers/http/userHeader/cookies/setCookies"; -import { COOKIE_KEYS } from "../../../constants/cookie.keys"; -import { jwtEncode } from "../../../helpers/http/jwt/encode"; -import { editUserSchema } from "../schemas/editUser.schema"; - -/** - * @function editUserController - * @description Updates user profile information. Requires valid JWT authentication token in cookies. - * On success, returns updated user data and sets a new JWT token in cookies. - * In development environment, the new JWT token is also returned in the response. - * - * @param {Context & { body: Prisma.UserUncheckedCreateInput }} ctx - The context object containing request information. - * @param {Object} ctx.body - The updated user data. - * - * @returns {Promise} A response object indicating success or failure. - * @throws {Object} An error response if authentication fails or validation errors occur. - * - * @example - * Request route: PUT /users - * Request headers: - * { - * "Cookie": "auth_token=" - * } - * Request body: - * { - * "username": "new_username", - * "name": "Updated Name", - * "birthDate": "1990-01-01T00:00:00.000Z", - * "gender": "male", - * "phoneCC": 62, - * "phoneNumber": 81234567890, - * "bioProfile": "Updated bio", - * "profilePicture": JPG/PNG/JPEG File, - * "commentPicture": JPG/PNG/JPEG File, - * "deletedAt": null - * } - * - * Success Response: - * Status: 201 Created - * { - * "message": "User data updated", - * "token": "" // Only in development environment - * } - * - * Failure Responses: - * - 401 Unauthorized: Missing or invalid authentication token - * - 400 Bad Request: Invalid user data - * - 500 Internal Server Error: Database operation failed - */ -export const editUserController = async ( - ctx: Context & { - body: Prisma.UserUncheckedCreateInput; - } -) => { - // Validate the request body against the edit user schema - const { error } = editUserSchema.validate(ctx.body); - if (error) - return returnErrorResponse(ctx.set, 422, "Invalid form input", error); - - try { - // Get the user JWT token from cookies, if the token is not found, return an error response - const userCookie = getCookie(ctx); - const auth_token = userCookie.auth_token!; - - // Get user browser header information from the context - const userHeaderInfo = getUserHeaderInformation(ctx); - - // Excecute the edit user data service - const newUserData = await updateUserService( - auth_token, - userHeaderInfo, - ctx.body - ); - - // create a new JWT token with the updated user data, and set it in the cookies - const newJwtToken = await jwtEncode(newUserData); - setCookie(ctx.set, COOKIE_KEYS.AUTH, newJwtToken); - - return returnWriteResponse(ctx.set, 201, "User data updated", newJwtToken); - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/user/controller/findUserByEmail.controller.ts b/src/modules/user/controller/findUserByEmail.controller.ts deleted file mode 100644 index 6159ec3..0000000 --- a/src/modules/user/controller/findUserByEmail.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Context } from "elysia"; -import { findUserByEmailService } from "../services/findUserByEmail.service"; -import { mainErrorHandler } from "../../../helpers/error/handler"; - -export const findUserByEmailController = async (ctx: Context) => { - try { - const findUserByEmail = await findUserByEmailService(ctx.params.email); - return findUserByEmail; - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/user/controller/getAllUser.controller.ts b/src/modules/user/controller/getAllUser.controller.ts deleted file mode 100644 index cc6c185..0000000 --- a/src/modules/user/controller/getAllUser.controller.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { returnReadResponse } from "../../../helpers/callback/httpResponse"; -import { Context } from "elysia"; -import { getAllUsersService } from "../services/getAllUser.service"; -import { mainErrorHandler } from "../../../helpers/error/handler"; - -export const getAllUserController = async (ctx: Context) => { - try { - const allUser = await getAllUsersService(); - return returnReadResponse( - ctx.set, - 200, - "All user ranks successfully", - allUser - ); - } catch (error) { - return mainErrorHandler(ctx.set, error); - } -}; diff --git a/src/modules/user/controller/softDeleteUser.controller.ts b/src/modules/user/controller/softDeleteUser.controller.ts deleted file mode 100644 index 039187d..0000000 --- a/src/modules/user/controller/softDeleteUser.controller.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Context } from "elysia"; -import { returnWriteResponse } from "../../../helpers/callback/httpResponse"; - -export const softDeleteUserController = async (ctx: Context) => { - const data = ctx.params.username; - return returnWriteResponse(ctx.set, 201, "Okay", data); -}; diff --git a/src/modules/user/index.ts b/src/modules/user/index.ts index 4c8beef..c834ec5 100644 --- a/src/modules/user/index.ts +++ b/src/modules/user/index.ts @@ -1,30 +1,7 @@ import Elysia from "elysia"; -import { getAllUserController } from "./controller/getAllUser.controller"; -import { createUserController } from "./controller/createUser.controller"; -import { editUserController } from "./controller/editUser.controller"; -import { unautenticatedMiddleware } from "../../middleware/auth/unauthenticated.middleware"; -import { authenticatedMiddleware } from "../../middleware/auth/authenticated.middleware"; -import { checkUserPasswordController } from "./controller/checkUserPassword.controller"; -import { isOwnerOrAdminMiddleware } from "../../middleware/userRoles/isOwnerOrAdmin.middleware"; -import { softDeleteUserController } from "./controller/softDeleteUser.controller"; -import { findUserByEmailController } from "./controller/findUserByEmail.controller"; +import { createUserViaRegisterController } from "./controller/createUserViaRegister.controller"; -export const userModule = new Elysia({ prefix: "/users" }) - .get("/", getAllUserController) - .get("/e/:email", findUserByEmailController) - .group("", (app) => - app - .onBeforeHandle(unautenticatedMiddleware) // middleware to ensure the user is not authenticated - .post("/", createUserController) - ) - .group("", (app) => - app - .onBeforeHandle(authenticatedMiddleware) // middleware to ensure the user is authenticated - .put("/", editUserController) - .post("/check-password", checkUserPasswordController) - ) - .group("", (app) => - app - .onBeforeHandle(isOwnerOrAdminMiddleware) - .delete(":username", softDeleteUserController) - ); +export const userModule = new Elysia({ prefix: "/users" }).post( + "/", + createUserViaRegisterController +); diff --git a/src/modules/user/repositories/checkUserEmailAndUsernameAvailabillity.repository.ts b/src/modules/user/repositories/checkUserEmailAndUsernameAvailabillity.repository.ts deleted file mode 100644 index a30f4c5..0000000 --- a/src/modules/user/repositories/checkUserEmailAndUsernameAvailabillity.repository.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { userModel } from "../user.model"; - -export const checkUserEmailAndUsernameAvailabillityRepo = async ( - id: string, - username: string, - email: string -) => { - const checkUsernameAndEmailAvailabillity = await userModel.findFirst({ - where: { - OR: [{ username: username ?? undefined }, { email: email ?? undefined }], - NOT: { - id: id, - }, - }, - }); - return checkUsernameAndEmailAvailabillity; -}; diff --git a/src/modules/user/repositories/create/createUserViaRegister.repository.ts b/src/modules/user/repositories/create/createUserViaRegister.repository.ts new file mode 100644 index 0000000..4578aa2 --- /dev/null +++ b/src/modules/user/repositories/create/createUserViaRegister.repository.ts @@ -0,0 +1,10 @@ +import { userModel } from "../../user.model"; +import { createUserViaRegisterInput } from "../../user.types"; + +export const createUserViaRegisterRepository = async ( + payload: createUserViaRegisterInput +) => { + return await userModel.create({ + data: payload, + }); +}; diff --git a/src/modules/user/repositories/createUser.repository.ts b/src/modules/user/repositories/createUser.repository.ts deleted file mode 100644 index 747a468..0000000 --- a/src/modules/user/repositories/createUser.repository.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Prisma } from "@prisma/client"; -import { userModel } from "../user.model"; - -export const createUserRepo = async (data: Prisma.UserCreateInput) => { - const userData = await userModel.create({ - data, - omit: { - password: true, - }, - }); - - return userData; -}; diff --git a/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts b/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts deleted file mode 100644 index ba7cb31..0000000 --- a/src/modules/user/repositories/findUserByEmailOrUsername.repository.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { userModel } from "../user.model"; -import { FindUserByEmailOrUsernameOptions } from "../user.types"; - -export const findUserByEmailOrUsernameRepository = async ( - identifier: string, - options: FindUserByEmailOrUsernameOptions -) => { - const userData = await userModel.findUnique({ - where: { email: identifier }, - include: { - assignedRoles: { - select: { - role: { - omit: { - createdBy: true, - updatedAt: true, - createdAt: true, - deletedAt: true, - }, - }, - }, - }, - }, - }); - - if (!userData) return false; - return userData; -}; diff --git a/src/modules/user/repositories/getAllUser.repository.ts b/src/modules/user/repositories/getAllUser.repository.ts deleted file mode 100644 index ddc839e..0000000 --- a/src/modules/user/repositories/getAllUser.repository.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { userModel } from "../user.model"; - -export const getAllUserRepo = async () => { - const data = await userModel.findMany({ - where: { - deletedAt: null, - }, - }); - - return data; -}; diff --git a/src/modules/user/repositories/updateUser.repository.ts b/src/modules/user/repositories/updateUser.repository.ts deleted file mode 100644 index 6044948..0000000 --- a/src/modules/user/repositories/updateUser.repository.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Prisma } from "@prisma/client"; -import { userModel } from "../user.model"; - -export const updateUserRepository = async ( - username: string, - payload: Prisma.UserUpdateInput -) => { - const userData = await userModel.update({ - where: { - username, - }, - data: payload, - }); - - return userData; -}; diff --git a/src/modules/user/schemas/createUser.schema.ts b/src/modules/user/schemas/createUser.schema.ts index ed89fba..0728643 100644 --- a/src/modules/user/schemas/createUser.schema.ts +++ b/src/modules/user/schemas/createUser.schema.ts @@ -1,19 +1,17 @@ -import Joi from "joi"; +import z from "zod"; -export const createUserSchema = Joi.object({ - name: Joi.string() - .min(4) - .max(255) - .required(), - username: Joi.string() - .min(4) - .max(255) - .required(), - email: Joi.string() - .email() - .required(), - password: Joi.string() - .min(8) - .max(255) - .required(), +export const createUserSchema = z.object({ + name: z.string(), + username: z + .string() + .min(4) //Total all username character must over 4 character + .regex(/^[a-zA-Z0-9_-]+$/), //Prohibiting the use of spaces and symbols other than - and _ + email: z.email(), + password: z + .string() + .min(8) //Total all password chaacter must over 8 character + .regex(/[A-Z]/) //Min has 1 uppercase letter + .regex(/[a-z]/) //Min has 1 lowercase letter + .regex(/[0-9]/) //Min has 1 number + .regex(/[^A-Za-z0-9"]/), //Min has 1 symbol character }); diff --git a/src/modules/user/services/checkUserEmailAndUsernameAvailabillity.service.ts b/src/modules/user/services/checkUserEmailAndUsernameAvailabillity.service.ts deleted file mode 100644 index 4d8f456..0000000 --- a/src/modules/user/services/checkUserEmailAndUsernameAvailabillity.service.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Prisma } from "@prisma/client"; -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { checkUserEmailAndUsernameAvailabillityRepo } from "../repositories/checkUserEmailAndUsernameAvailabillity.repository"; - -export const checkUserEmailAndUsernameAvailabillityService = async ( - payload: Prisma.UserUpdateInput, - idException: string -) => { - try { - const usernameAndEmailAvailabillity = - checkUserEmailAndUsernameAvailabillityRepo( - idException!, - payload.username as string, - payload.email as string - ); - return usernameAndEmailAvailabillity; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/user/services/checkUserPassword.service.ts b/src/modules/user/services/checkUserPassword.service.ts deleted file mode 100644 index 60f20b4..0000000 --- a/src/modules/user/services/checkUserPassword.service.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { AppError } from "../../../helpers/error/instances/app"; -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { comparePassword } from "../../../helpers/security/password/compare"; -import { findUserByEmailOrUsernameService } from "./findUserByEmailOrUsername.service"; -import { User } from "@prisma/client"; - -export const checkUserPasswordService = async ( - username: string, - password: string -) => { - try { - // find user by username and get the password - const userData = (await findUserByEmailOrUsernameService(username, { - verbose: true, - })) as User; - const StoredPassword = userData.password; - - // compare the provided password with the stored password - const matchingPassword = await comparePassword(password, StoredPassword); - if (!matchingPassword) { - throw new AppError(401, "Invalid Credential"); - } - - return true; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/user/services/createUser.service.ts b/src/modules/user/services/createUser.service.ts deleted file mode 100644 index d60ce18..0000000 --- a/src/modules/user/services/createUser.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Prisma } from "@prisma/client"; -import { hashPassword } from "../../../helpers/security/password/hash"; -import { createUserRepo } from "../repositories/createUser.repository"; -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; - -export const createUserService = async (userData: Prisma.UserCreateInput) => { - try { - const { password, ...rest } = userData; // Destructure the password and the rest of the user data - const hashedPassword = await hashPassword(password); // Hash the password before saving to the database - - const newUser = await createUserRepo({ - ...rest, - password: hashedPassword, - }); - return newUser; - } catch (error) { - ErrorForwarder(error, 500, "Internal server error"); - } -}; diff --git a/src/modules/user/services/createUserViaRegister.service.ts b/src/modules/user/services/createUserViaRegister.service.ts new file mode 100644 index 0000000..46da8f2 --- /dev/null +++ b/src/modules/user/services/createUserViaRegister.service.ts @@ -0,0 +1,19 @@ +import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; +import { hashPassword } from "../../../helpers/security/password/hash"; +import { createUserViaRegisterRepository } from "../repositories/create/createUserViaRegister.repository"; +import { createUserViaRegisterInput } from "../user.types"; + +export const createUserViaRegisterService = async ( + payload: createUserViaRegisterInput +) => { + try { + const hashedPassword = await hashPassword(payload.password); + + return createUserViaRegisterRepository({ + ...payload, + password: hashedPassword, + }); + } catch (error) { + ErrorForwarder(error); + } +}; diff --git a/src/modules/user/services/findUserByEmail.service.ts b/src/modules/user/services/findUserByEmail.service.ts deleted file mode 100644 index de5f456..0000000 --- a/src/modules/user/services/findUserByEmail.service.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { findUserByEmailOrUsernameRepository } from "../repositories/findUserByEmailOrUsername.repository"; - -export const findUserByEmailService = async (email: string) => { - try { - const findUserByEmail = findUserByEmailOrUsernameRepository(email, { - queryTarget: "email", - }); - return findUserByEmail; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/user/services/findUserByEmailOrUsername.service.ts b/src/modules/user/services/findUserByEmailOrUsername.service.ts deleted file mode 100644 index c22da58..0000000 --- a/src/modules/user/services/findUserByEmailOrUsername.service.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AppError } from "../../../helpers/error/instances/app"; -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { findUserByEmailOrUsernameRepository } from "../repositories/findUserByEmailOrUsername.repository"; -import { FindUserByEmailOrUsernameOptions } from "../user.types"; - -export const findUserByEmailOrUsernameService = async ( - identifier: string, - options: FindUserByEmailOrUsernameOptions -) => { - try { - const userData = await findUserByEmailOrUsernameRepository( - identifier, - options - ); - if (!userData) throw new AppError(404, "User not found"); - - return userData; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/user/services/getAllUser.service.ts b/src/modules/user/services/getAllUser.service.ts deleted file mode 100644 index 0b899e5..0000000 --- a/src/modules/user/services/getAllUser.service.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { getAllUserRepo } from "../repositories/getAllUser.repository"; - -export const getAllUsersService = async () => { - try { - const allUser = await getAllUserRepo(); - return allUser; - } catch (error) { - ErrorForwarder(error); - } -}; diff --git a/src/modules/user/services/updateUser.service.ts b/src/modules/user/services/updateUser.service.ts deleted file mode 100644 index 2e4ee86..0000000 --- a/src/modules/user/services/updateUser.service.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { Prisma } from "@prisma/client"; -import { jwtDecode } from "../../../helpers/http/jwt/decode"; -import { AppError } from "../../../helpers/error/instances/app"; -import { ErrorForwarder } from "../../../helpers/error/instances/forwarder"; -import { updateUserRepository } from "../repositories/updateUser.repository"; -import { checkUserEmailAndUsernameAvailabillityService } from "./checkUserEmailAndUsernameAvailabillity.service"; -import { logoutService } from "../../auth/services/logout.service"; -import { loginFromSystemService } from "../../auth/services/loginFromSystem.service"; -import { UserHeaderInformation } from "../../../helpers/http/userHeader/getUserHeaderInformation/types"; -import { saveAvatar } from "../../../helpers/files/saveFile/modules/saveAvatar"; -import { saveCommentBackground } from "../../../helpers/files/saveFile/modules/saveCommentBackgorund"; - -export const updateUserService = async ( - cookie: string, - userHeaderInfo: UserHeaderInformation, - payload: Prisma.UserUpdateInput -) => { - try { - // Decode the JWT token and verify the user, if the user is not the same as the identifier, throw an error - const jwtSession = jwtDecode(cookie); - - // Check if the username or email is being taken by another user, if so, throw an error - const isUsernameOrEmailIsBeingTaken = await checkUserEmailAndUsernameAvailabillityService( - payload, - jwtSession.userId - ); - if (isUsernameOrEmailIsBeingTaken) - throw new AppError( - 409, - "The username or email has already taken by another user." - ); - - // Store the avatar to the file system if provided in the payload - let storeAvatar: string | undefined = undefined; - if (payload.avatar) storeAvatar = await saveAvatar(payload.avatar as File); - - // Store the comment background to the file system if provided in the payload - let storeCommentBackground: string | undefined = undefined; - if (payload.commentBackground) - storeCommentBackground = await saveCommentBackground( - payload.commentBackground as File - ); - - // Prepare the fields to update, only include fields that are provided in the payload - const fieldsToUpdate: Partial = { - ...(payload.username && payload.username !== jwtSession.user.username - ? { username: payload.username } - : {}), - - ...(payload.name !== undefined ? { name: payload.name } : {}), - ...(payload.birthDate !== undefined - ? { birthDate: payload.birthDate } - : {}), - ...(payload.gender !== undefined ? { gender: payload.gender } : {}), - ...(payload.phoneCC !== undefined ? { phoneCC: payload.phoneCC } : {}), - ...(payload.phoneNumber !== undefined - ? { phoneNumber: payload.phoneNumber } - : {}), - ...(payload.bioProfile !== undefined - ? { bioProfile: payload.bioProfile } - : {}), - ...(storeAvatar !== undefined ? { avatar: storeAvatar } : {}), - ...(storeCommentBackground !== undefined - ? { commentBackground: storeCommentBackground } - : {}), - ...(payload.deletedAt !== undefined - ? { deletedAt: payload.deletedAt } - : {}), - }; - - // Update the user in the database, use username from the JWT session to find the user - await updateUserRepository(jwtSession.user.username, fieldsToUpdate); - - // Clear the session and re-login the user to get a new JWT token - await logoutService(cookie); - const newUserSession = await loginFromSystemService( - jwtSession.userId, - userHeaderInfo - ); - - return newUserSession; - } catch (error) { - ErrorForwarder(error, 500, "Internal server error"); - } -}; diff --git a/src/modules/user/user.types.ts b/src/modules/user/user.types.ts index c4d1e26..996de8f 100644 --- a/src/modules/user/user.types.ts +++ b/src/modules/user/user.types.ts @@ -1,10 +1,16 @@ -export interface FindUserByEmailOrUsernameOptions { - queryTarget: "email" | "username" | "both"; - verbosity?: FindUserByEmailOrUsernameVerbosity; // If true, returns the user with all details including sensitive information +export interface getUserDataService { + identifier: string; + queryTarget: "id" | "email" | "username" | "email_username"; + options?: getUserDataOptions; } -enum FindUserByEmailOrUsernameVerbosity { - "exists", - "basic", - "extended", - "full", +export interface getUserDataOptions { + verbosity?: "exists" | "basic" | "full"; + include?: ("preference" | "role")[]; +} + +export interface createUserViaRegisterInput { + name: string; + username: string; + email: string; + password: string; }