add:module:user:repository:checkUserEmailAndUsernameAvailabillity | add repository for check username and email availabillity

This commit is contained in:
rafiarrafif
2025-06-16 21:37:53 +07:00
parent ac10ae14f6
commit f0e1614709
13 changed files with 143 additions and 24 deletions

View File

@ -1,14 +1,16 @@
import jwt from "jsonwebtoken";
import { JWTSessionPayload } from "../../../../modules/auth/auth.types";
import { AppError } from "../../../error/instances/app";
export const jwtDecode = (payload: string) => {
// return payload;
if (!payload) throw "JWT decode payload not found";
if (!payload) throw new AppError(401, "Unauthorized");
const JWTKey = process.env.JWT_SECRET!;
try {
const decodedPayload = jwt.verify(payload, JWTKey);
return decodedPayload;
return decodedPayload as JWTSessionPayload;
} catch (error) {
throw "JWT expired or not valid";
throw new AppError(401, "Invalid or expired token");
}
};

View File

@ -2,11 +2,20 @@ import { Context } from "elysia";
import { mainErrorHandler } from "../../helpers/error/handler";
import { debugService } from "./debug.service";
import { returnWriteResponse } from "../../helpers/callback/httpResponse";
import { getCookie } from "../../helpers/http/userHeader/cookies/getCookies";
import { checkUserEmailAndUsernameAvailabillity } from "../user/repositories/checkUserEmailAndUsernameAvailability.repository";
import { jwtDecode } from "../../helpers/http/jwt/decode";
export const debugController = async (ctx: Context) => {
try {
const dataFromService = await debugService();
return returnWriteResponse(ctx.set, 200, "Message Sent", dataFromService);
const userCookie = getCookie(ctx);
const jwtSession = jwtDecode(userCookie.auth_token!);
jwtSession.user.email = ctx.params.email;
jwtSession.user.username = ctx.params.username;
const checkAvailabillity = await checkUserEmailAndUsernameAvailabillity(
jwtSession.user
);
return checkAvailabillity;
} catch (error) {
return mainErrorHandler(ctx.set, error);
}

View File

@ -1,7 +1,7 @@
import Elysia from "elysia";
import { debugController } from "./debug.controller";
export const debugModule = new Elysia({ prefix: "/debug" }).get(
"/",
export const debugModule = new Elysia({ prefix: "/debug" }).post(
"/:username/:email",
debugController
);

View File

@ -27,7 +27,7 @@ import { createUserSchema } from "../schemas/createUser.schema";
* "password": "password123"
* }
*/
export const createUser = async (
export const createUserController = async (
ctx: Context & { body: Prisma.UserCreateInput }
) => {
// Validate the user input using a validation schema

View File

@ -0,0 +1,31 @@
import { Context } from "elysia";
import {
returnErrorResponse,
returnWriteResponse,
} from "../../../helpers/callback/httpResponse";
import { mainErrorHandler } from "../../../helpers/error/handler";
import { Prisma } from "@prisma/client";
import { editUserService } from "../services/editUser.service";
import { getCookie } from "../../../helpers/http/userHeader/cookies/getCookies";
export const editUserController = async (
ctx: Context & {
params: { username: string };
body: Prisma.UserUncheckedCreateInput;
}
) => {
try {
const userCookie = getCookie(ctx);
if (!userCookie.auth_token)
return returnErrorResponse(ctx.set, 401, "User Unauthenticated");
const editUser = await editUserService(
ctx.params.username,
userCookie.auth_token,
ctx.body
);
return editUser;
} catch (error) {
return mainErrorHandler(ctx.set, error);
}
};

View File

@ -6,7 +6,7 @@ import { Context } from "elysia";
import { getAllUsersService } from "../services/getAllUser.service";
import { mainErrorHandler } from "../../../helpers/error/handler";
export const getAllUser = async (ctx: Context) => {
export const getAllUserController = async (ctx: Context) => {
try {
const allUser = await getAllUsersService();
return returnReadResponse(

View File

@ -1,7 +1,9 @@
import Elysia from "elysia";
import { getAllUser } from "./controller/getAllUser.controller";
import { createUser } from "./controller/createUser.controller";
import { getAllUserController } from "./controller/getAllUser.controller";
import { createUserController } from "./controller/createUser.controller";
import { editUserController } from "./controller/editUser.controller";
export const userModule = new Elysia({ prefix: "/users" })
.get("/", getAllUser)
.post("/", createUser);
.get("/", getAllUserController)
.post("/", createUserController)
.put("/:username", editUserController);

View File

@ -0,0 +1,23 @@
import { Prisma } from "@prisma/client";
import { userModel } from "../user.model";
export const checkUserEmailAndUsernameAvailabillity = async (
payload: Partial<Prisma.UserGetPayload<Record<string, never>>>
) => {
try {
const checkUsernameAndEmailAvailabillity = await userModel.findFirst({
where: {
OR: [
{ username: payload.username ?? undefined },
{ email: payload.email ?? undefined },
],
NOT: {
id: payload.id,
},
},
});
return checkUsernameAndEmailAvailabillity;
} catch (error) {
throw error;
}
};

View File

@ -0,0 +1,23 @@
import { Prisma } from "@prisma/client";
import { userModel } from "../user.model";
export const updateUserRepo = async (
identifier: string,
payload: Prisma.UserUncheckedCreateInput
) => {
try {
const userData = await userModel.update({
where: {
username: identifier,
},
data: {
username: payload.username,
name: payload.name,
birthDate: payload.name,
},
});
return userData;
} catch (error) {
throw error;
}
};

View File

@ -1,18 +1,19 @@
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) => {
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
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) {
throw error;
ErrorForwarder(error, 500, "Internal server error");
}
};

View File

@ -0,0 +1,24 @@
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 { updateUserRepo } from "../repositories/updateUser.repository";
export const editUserService = async (
identifier: string,
cookie: string,
payload: Prisma.UserUncheckedCreateInput
) => {
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);
if (jwtSession.user.username !== identifier) {
throw new AppError(401, "Unauthorized");
}
const updateUser = updateUserRepo(identifier, payload);
return updateUser;
} catch (error) {
ErrorForwarder(error, 500, "Internal server error");
}
};

View File

@ -1,14 +1,14 @@
import Elysia from "elysia";
import {authModule} from './modules/auth';
import {userSessionModule} from './modules/userSession';
import {userRoleModule} from './modules/userRole';
import {debugModule} from './modules/debug';
import {userModule} from './modules/user';
import {userRoleModule} from './modules/userRole';
import {userSessionModule} from './modules/userSession';
import {authModule} from './modules/auth';
const routes = new Elysia()
.use(authModule)
.use(userSessionModule)
.use(userRoleModule)
.use(debugModule)
.use(userModule)
.use(userRoleModule)
.use(userSessionModule);
.use(authModule);
export { routes };