From 40a7ffc005ea6c5acfeb4592ac1b12d710f99130 Mon Sep 17 00:00:00 2001 From: rafiarrafif Date: Tue, 6 May 2025 18:48:33 +0700 Subject: [PATCH] add first operation in user role --- bun.lockb | Bin 22482 -> 30694 bytes package.json | 6 +- .../callback/httpResponse.ts | 0 src/helpers/jwt/decodeToken/index.ts | 46 ++++++++++ src/helpers/jwt/decodeToken/types.ts | 62 ++++++++++++++ .../controller/createUserRole.controller.ts | 79 +++++++++++++++++- .../services/createUserRole.service.ts | 20 +++++ src/modules/userRole/userRole.model.ts | 3 + src/modules/userRole/userRole.schema.ts | 28 +++++++ 9 files changed, 241 insertions(+), 3 deletions(-) rename src/{utils => helpers}/callback/httpResponse.ts (100%) create mode 100644 src/helpers/jwt/decodeToken/index.ts create mode 100644 src/helpers/jwt/decodeToken/types.ts diff --git a/bun.lockb b/bun.lockb index d0482c763bc69c9cc8188a6bb5a44dc4c0fe1d2b..e4fd7e65f77e8666732ac404558ac978aef11d15 100644 GIT binary patch delta 9044 zcmeG>cT`i!*Lg7^gdzkLLKhUJm_TTu1`tJxA|et|L4yPh(gPy4uww5ruI*>T-W9v( zuHx=m*4}m3t}BYVx}vh8tKYpZ?-6#-?m6H2zWwtz=iIq-%iOthXWqOimv>T6UQzR< z9Uy~Edd{8@Gig>Kvy%kiow$Wn*v{}&Ks>R=5TV#w7}tTlH2I{Ib|xE zz74b;=$!`KP6vfNy&fm0Ktn6Y_#6&8;sO{O7BTn_9*1KBv;b(t>fCaz25i1J($g;i z3xU5{ps)WmV01{MR;%R!{+wWAy*+J7aY?}_KTadiI&)B{1Vt;r+1a_O5;cdDrOqrJ z0j}HtgD5`%7#-RU*cNa#V2sf4f`U;R(02#jc0kXD*08~gkfFR1FggUi<+KG{Sgg_J zfy3Ea^=Nf|iT1V`M@NV9B(!1!3X=e1$W?%`;e3WZ57y8?6~rAQqSj`XYI3tU7T`5H z{t3K82c81P`qu#?|2RW$18fcSQoyJ;8E^-{#UhA5DrPW>v5cZWLpuUS#{>-jEwqjX z?gPe#&I88!wG6!uFgCORFzSs5j17%sPxkSm)hpf-D*B-(zFLk?~(kEs{)^uZuMBY%fmZ}3LR_vB*IVVFlb-nuGb3> zTfZrgG|qTl_wG`MxL;Dut2#fj-&kG0s!877868nIR`DT; z7nyJ49roeiyTEmOzrVKc#=KZ{(2%ALS5w#2J@(@-+xH~9q}}sU-{%9{c3(H~Ymd|jj>a)*&)T=$N*17mk=**eZ`f%l*}UG{|s3k$+dH1u0` zxMy*S^M-+;llDC2x>KYhFILzK`Wgv+7Lpocxp^Z{NkGBm=5UD2)Qb$`8JkB_98Ro( z%hz*fFZdg{+QLm4g)YRQG`fl|;lij3u!uYvLh3cdmk z0yyc8P6#`L4JioP5Sfu&m<|+H;*%P_-10w+4BF

vW~nLLm?MLx{vURFn*CSX?Sl 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 KG$Sg{CI15~MCw5R delta 4162 zcmd^CeNa@_6~Fhvvh2djf*Kb@5fNAv7IuYQK35QA3>XEiJp3YRSi>qt0;n;g0!=y- zotgwsYpk_qFm|ew42nc!bhP=Z8pqa$_4LuMZ>C*IyS8lC=?8z5Joc?^)}-LciooUF zO(z=mH`=L(&u3FW)qB9^wb71BA`_b3h4t=bh09zLfdcbhU zEx<(JQeZ6bzIE%?1mTzjc@*Tf_F%`_6+*1)2y6&E(Aja=Bt#tad!mFG2V4jo1I!2V z1S&#uAMDsa5Uo!%(6MrTu(erS!P|B53@?Eh4Lk+p4h{iX|J{(>1-uJ#E0FC};8@@+ zAltct>^C0BcIJ@$SA>lx_AZe1=YZ@#2xR*{iwI~P>0+Y46Ql zyd&dSS&?O3>DiC!_ne|`(`<_qedWVfQoY%yoD)0{ z7M~>&>+RJYqJ5TPNM(=&yIVFw@DX-Y1as$q$)) zN}7pk?0(Z)tbab;V=qz8nCJo&H=*#e!ucMy$iwgk2s6ki15iwZzWTcT`07i65jtXW zm>OU)o83(Nz!huUuMC|sDVhgU)<@I!1ix}Vnl2>xO*gO;s_3T)C8k2GOSQ&r1vgvc z&VtihtynExHy_*_t#uzb-QxprHJZ+aeXV=6gVQ}ug3~>su*-GbTyS$WkGGXWUV6zC ztyCq@_Bg+?ErBk?dFe@0WEWORFmcEc1FbN!4)f3oBlZiQ3|jejWIaA4tuSJn@CT+9 zM(j`i@U-$Dkp7gI*u{PD$--k!)GT#md2&c*v8+Co%6Yc zqb(ELC_ST=3R7&fC8JhG(CZm0U4@jBSu0JnDO080lWg=GNM_1%sx&**MmwCf(n9Y* z`a7hutXdgE+p<(TIN3&jhGe6GG?g0DY&2_Xt&F4IsVYTJvC*fH;;CYqN+%%wa9XV# zP4zh{wWQnVSWc}ROVXv1Bf~}kSFIdJ1CY)`8k<`y6KO@RN)Kh)=qHfIQ+%FEPN$95 z=heyy^m3jmCsLwYl_~Tf>PhrE>QqYgsB$uGLY+oKsHafYbXBHP59$nh2X!X7^Hu4j zZK$*8ebiH_s6ds|s26oM4WrJX3a=_%^gYzMbPaVL-R)DQoBB|D=pU%3Q+=T-^XU-k z0+L0l^wJ{KJ{l;RXOUtgZUo^kq`R|KSwwx=^XL(ibMRtGi=?))Smj<5Z7n-$I*p4v zhI-1L8SE~9Ne;G^e`K{fiuIMvE~Y*6%9BQJ>xGs4kJcD!E-j&^`pM*|v(Mr^z(?44 zP%?-=N?dKixXmyK{}%9Hoc1B}v6Ttp<1Pg>36x4bb)&oZ0GkHN2IYWUpj=QM$PL2H zEO_JbS6cwWeb4v0CZZH|yel*^W;J-pOpsK5WmI06XK0FgtKfxe5dm%Rd~UfRX{+i{G;k>W3SCs^D0PyO8a)aoHn-7{ zZ2a#>>^#$xn|E_~jN}M%!SHXu!1%F0`smMk`tSM7tVplR$DNDACW>6-Q9^b`LXf|t zq9-FK^WLysMHICzawrR<=r4;Lbw(ml)L&U?SHAs(B7@jWh}4~w;`2Rxao>8U-Y@Rd z$V2RDWtAJv*I!WNQtV|8cp#ce7gzZW(fG~3eEG*ec-C{eC=!e7DZl~=BM~@nu6wHb z>e^SrE$J3Iv)JJ^G6%=4TkiQ6yn(QRkz4E=pLg=-!}l!?w=`QQc8Md|NJebqs)qOV zZ#Wk=*kPgaB@Qpr7cKh;zF2xNKWgoVVFM$<`Sl~Ks@=QZeL386&O(pF)yRmRtqv}0 zpOLvYY+&R}Lw)uMuQ`Y3gI67mxSteE#9EfswTt>6mh7pKnQ^y^Rj5 zc6eh~msgQ@*-YB7%#(BqB7g6X78YET4~-gWtAYZhSfy8%%_X^f{9s%2<_J2lGJEjj r`@bRSQmc7z$?EH|G3A|`+5#Q953Fkr(6u$mR340?zF;#A74QBR6v^~_ diff --git a/package.json b/package.json index f94ba05..cfd7221 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,11 @@ }, "dependencies": { "@prisma/client": "^6.7.0", - "elysia": "latest" + "@types/jsonwebtoken": "^9.0.9", + "cookie": "^1.0.2", + "elysia": "latest", + "joi": "^17.13.3", + "jsonwebtoken": "^9.0.2" }, "devDependencies": { "bun-types": "latest", diff --git a/src/utils/callback/httpResponse.ts b/src/helpers/callback/httpResponse.ts similarity index 100% rename from src/utils/callback/httpResponse.ts rename to src/helpers/callback/httpResponse.ts diff --git a/src/helpers/jwt/decodeToken/index.ts b/src/helpers/jwt/decodeToken/index.ts new file mode 100644 index 0000000..cbafd46 --- /dev/null +++ b/src/helpers/jwt/decodeToken/index.ts @@ -0,0 +1,46 @@ +import jwt from "jsonwebtoken"; +import { Context } from "elysia"; +import { JWTAuthToken } from "./types"; +import { returnErrorResponse } from "../../callback/httpResponse"; +import { parse } from "cookie"; + +/** + * Verifies the authentication cookie from the request header. + * + * This helper function is used in an ElysiaJS context to check the validity of + * a user's authentication token stored in cookies. If the cookie is not found, + * it returns a `400 Bad Request`. If the token is invalid or expired, it returns + * a `401 Unauthorized`. If the token is valid, it returns the decoded user data. + * + * @param ctx - The request context from Elysia, used to read headers and set the response. + * + * @returns The decoded JWT payload if the token is valid, + * or a standardized error response if the cookie is missing or invalid. + * + * @example + * const decodedToken = decodeAuthToken(ctx); + * ctx => Elysia context + */ +export const JWTDecodeToken = (ctx: Context): JWTAuthToken => { + const cookiePayload = ctx.request.headers.get("Cookie"); + if (!cookiePayload) + throw returnErrorResponse(ctx.set, 400, "Bad Request", "No cookies found"); + + const cookies = parse(cookiePayload); + const cookiesToken = cookies.auth_token!; + + try { + const decodedToken = jwt.verify( + cookiesToken, + process.env.JWT_SECRET! + ) as JWTAuthToken; + return decodedToken; + } catch (error) { + throw returnErrorResponse( + ctx.set, + 401, + "Unauthorized", + "Invalid or expired token" + ); + } +}; diff --git a/src/helpers/jwt/decodeToken/types.ts b/src/helpers/jwt/decodeToken/types.ts new file mode 100644 index 0000000..3d094f0 --- /dev/null +++ b/src/helpers/jwt/decodeToken/types.ts @@ -0,0 +1,62 @@ +export interface JWTAuthToken { + id: string; + isAuthenticated: boolean; + userId: string; + deviceType: string; + deviceOs: string; + deviceIp: string; + isOnline: boolean; + lastOnline: Date; + validUntil: Date; + deletedAt: null; + createdAt: Date; + updatedAt: Date; + user: User; + iat: number; + exp: number; +} + +interface User { + id: string; + name: string; + username: string; + email: string; + birthDate: null; + gender: null; + phoneCC: null; + phoneNumber: null; + bioProfile: null; + profilePicture: null; + commentPicture: null; + preferenceId: null; + verifiedAt: null; + disabledAt: null; + deletedAt: null; + createdAt: Date; + updatedAt: Date; + roles: Role[]; +} + +interface Role { + id: string; + name: string; + primaryColor: string; + secondaryColor: string; + pictureImage: string; + badgeImage: null; + isSuperadmin: boolean; + canEditMedia: boolean; + canManageMedia: boolean; + canEditEpisodes: boolean; + canManageEpisodes: boolean; + canEditComment: boolean; + canManageComment: boolean; + canEditUser: boolean; + canManageUser: boolean; + canEditSystem: boolean; + canManageSystem: boolean; + createdBy: string; + deletedAt: null; + createdAt: Date; + updatedAt: Date; +} diff --git a/src/modules/userRole/controller/createUserRole.controller.ts b/src/modules/userRole/controller/createUserRole.controller.ts index dfdc25b..0e398aa 100644 --- a/src/modules/userRole/controller/createUserRole.controller.ts +++ b/src/modules/userRole/controller/createUserRole.controller.ts @@ -1,5 +1,80 @@ +import { Prisma } from "@prisma/client"; import { Context } from "elysia"; +import { + returnErrorResponse, + returnWriteResponse, +} from "../../../helpers/callback/httpResponse"; +import { handlePrismaError } from "../../../utils/databases/prisma/error/handler"; +import { createUserRoleSchema } from "../userRole.schema"; +import { JWTDecodeToken } from "../../../helpers/jwt/decodeToken"; +import { prisma } from "../../../utils/databases/prisma/connection"; +import { createUserRoleService } from "../services/createUserRole.service"; -export const createUserRole = (ctx: Context) => { - return "Hello User Role Module"; +/** + * @function createUserRole + * @description Creates a new user role in the database. + * + * @param {Context & { body: UserRole }} ctx - The context object containing the request body. + * @param {UserRole} ctx.body - The user role 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 role creation. + * + * @example + * Request route: POST /roles + * Request body: + * { + * "userID": "e31668e6-c261-4a7e-9469-ffad734cf2dd", + * "name": "Admin", + * "primaryColor": "#D9D9D9", + * "secondaryColor": "#FFFFFF", + * "pictureImage": "https://example.com/picture.jpg", + * "badgeImage": "https://example.com/badge.jpg", + * "isSuperadmin": false, + * "canEditMedia": false, + * "canManageMedia": false, + * "canEditEpisodes": false, + * "canManageEpisodes": false, + * "canEditComment": false, + * "canManageComment": false, + * "canEditUser": false, + * "canManageUser": false, + * "canEditSystem": false, + * "canManageSystem": false + * } + */ +export const createUserRole = async ( + ctx: Context & { body: Prisma.UserRoleUncheckedCreateInput } +) => { + const { error } = createUserRoleSchema.validate(ctx.body); + if (error) + return returnErrorResponse(ctx.set, 400, "Invalid user input", error); + + const formData: Prisma.UserRoleUncheckedCreateInput = { ...ctx.body }; + const userCreator = JWTDecodeToken(ctx); + + const dataPayload = { + ...formData, + isSuperadmin: Boolean(formData.isSuperadmin), + canEditMedia: Boolean(formData.canEditMedia), + canManageMedia: Boolean(formData.canManageMedia), + canEditEpisodes: Boolean(formData.canEditEpisodes), + canManageEpisodes: Boolean(formData.canManageEpisodes), + canEditComment: Boolean(formData.canEditComment), + canManageComment: Boolean(formData.canManageComment), + canEditUser: Boolean(formData.canEditUser), + canManageUser: Boolean(formData.canManageUser), + canEditSystem: Boolean(formData.canEditSystem), + canManageSystem: Boolean(formData.canManageSystem), + createdBy: userCreator.user.id, + deletedAt: null, + }; + + createUserRoleService(dataPayload) + .then((result) => + returnWriteResponse(ctx.set, 201, "User role created", result) + ) + .catch((error) => + returnErrorResponse(ctx.set, 500, "Internal Server Error", error) + ); }; diff --git a/src/modules/userRole/services/createUserRole.service.ts b/src/modules/userRole/services/createUserRole.service.ts index e69de29..134738a 100644 --- a/src/modules/userRole/services/createUserRole.service.ts +++ b/src/modules/userRole/services/createUserRole.service.ts @@ -0,0 +1,20 @@ +import { Prisma } from "@prisma/client"; +import { userRoleModel } from "../userRole.model"; +import { handlePrismaError } from "../../../utils/databases/prisma/error/handler"; +import { returnErrorResponse } from "../../../helpers/callback/httpResponse"; +import { Context } from "elysia"; + +export const createUserRoleService = async ( + ctx: Context, + userRoleData: Prisma.UserRoleUncheckedCreateInput +) => { + try { + const newUserRole = await userRoleModel.create({ + data: userRoleData, + }); + return newUserRole; + } catch (error) { + const { status, message, details } = handlePrismaError(error); + throw returnErrorResponse(ctx.set, status, message, details); + } +}; diff --git a/src/modules/userRole/userRole.model.ts b/src/modules/userRole/userRole.model.ts index e69de29..8b2d986 100644 --- a/src/modules/userRole/userRole.model.ts +++ b/src/modules/userRole/userRole.model.ts @@ -0,0 +1,3 @@ +import { prisma } from "../../utils/databases/prisma/connection"; + +export const userRoleModel = prisma.userRole; diff --git a/src/modules/userRole/userRole.schema.ts b/src/modules/userRole/userRole.schema.ts index e69de29..1a9308d 100644 --- a/src/modules/userRole/userRole.schema.ts +++ b/src/modules/userRole/userRole.schema.ts @@ -0,0 +1,28 @@ +import Joi from "joi"; + +export const createUserRoleSchema = Joi.object({ + name: Joi.string().min(4).max(255).required(), + primaryColor: Joi.string() + .pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) + .optional(), + secondaryColor: Joi.string() + .pattern(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/) + .optional(), + pictureImage: Joi.string() + .uri({ scheme: ["http", "https"] }) + .optional(), + badgeImage: Joi.string() + .uri({ scheme: ["http", "https"] }) + .optional(), + isSuperadmin: Joi.boolean().required(), + canEditMedia: Joi.boolean().required(), + canManageMedia: Joi.boolean().required(), + canEditEpisodes: Joi.boolean().required(), + canManageEpisodes: Joi.boolean().required(), + canEditComment: Joi.boolean().required(), + canManageComment: Joi.boolean().required(), + canEditUser: Joi.boolean().required(), + canManageUser: Joi.boolean().required(), + canEditSystem: Joi.boolean().required(), + canManageSystem: Joi.boolean().required(), +});