add first operation in user role

This commit is contained in:
rafiarrafif
2025-05-06 18:48:33 +07:00
parent 9e90d7c4f4
commit 40a7ffc005
9 changed files with 241 additions and 3 deletions

View File

@ -0,0 +1,80 @@
/**
* Returns a standardized response for write operations (POST, PUT, DELETE).
* Only includes data in the response during development.
*
* @param set - Function to set HTTP headers.
* @param status - HTTP status code of the response.
* @param message - A message describing the result.
* @param data - Optional data for success responses or error description (only returned in development).
*
* @returns An object with `status`, `message`, and optionally `data` (in development only).
*/
export function returnWriteResponse(
set: any,
status: number,
message?: string,
data?: any
) {
set.status = status;
const response: Record<string, any> = {
status,
message,
};
if (process.env.APP_ENV === "development") response.data = data;
return response;
}
/**
* Returns a standardized response for read operations (GET).
* Always includes data in the response regardless of the environment.
*
* @param set - Function to set HTTP headers.
* @param status - HTTP status code of the response.
* @param message - A message describing the result.
* @param data - Data to include in the response.
*
* @returns An object with `status`, `message`, and `data`.
*/
export function returnReadResponse(
set: any,
status: number,
message: string,
data: any
) {
set.status = status;
return {
status,
message,
data,
};
}
/**
* Returns a standardized error response for handling errors in catch blocks.
*
* @param set - Function to set HTTP headers.
* @param status - HTTP status code of the error response.
* @param message - A message describing the error.
* @param errorDetails - Optional, detailed information about the error (e.g., stack trace).
*
* @returns An object with `status`, `message`, and optionally `error_details` (in development only).
*/
export function returnErrorResponse(
set: any,
status: number,
message: string,
errorDetails?: any
) {
set.status = status;
const response: Record<string, any> = {
status: "error",
message,
};
if (process.env.APP_ENV === "development" && errorDetails)
response.error_details = errorDetails;
return response;
}

View File

@ -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"
);
}
};

View File

@ -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;
}