fix: fix.env.example

This commit is contained in:
rafiarrafif
2025-06-14 15:05:20 +07:00
parent b52f1202eb
commit ac10ae14f6
75 changed files with 2532 additions and 2532 deletions

View File

@ -1,80 +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;
}
/**
* 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

@ -1,54 +1,54 @@
import { Prisma } from "@prisma/client";
import { returnErrorResponse } from "../../callback/httpResponse";
import { AppError } from "../instances/app";
import { PrismaErrorCodeList } from "../../../utils/databases/prisma/error/codeList";
export const mainErrorHandler = (set: any, error: unknown) => {
if (error instanceof AppError) {
return returnErrorResponse(
set,
error.statusCode,
error.message,
error.details
);
}
if (error instanceof Prisma.PrismaClientKnownRequestError) {
const errorInfo = PrismaErrorCodeList[error.code];
if (errorInfo)
return returnErrorResponse(
set,
errorInfo.status,
errorInfo.message,
error.meta ?? {}
);
}
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
return returnErrorResponse(set, 500, "Unknown database error");
}
if (error instanceof Prisma.PrismaClientRustPanicError) {
return returnErrorResponse(
set,
500,
"Database engine crashed unexpectedly"
);
}
if (error instanceof Prisma.PrismaClientInitializationError) {
return returnErrorResponse(set, 503, `Can't reach database server.`, error);
}
if (error instanceof Prisma.PrismaClientValidationError) {
return returnErrorResponse(
set,
400,
"Invalid input to query",
error.message
);
}
return returnErrorResponse(set, 500, "Internal server error");
};
import { Prisma } from "@prisma/client";
import { returnErrorResponse } from "../../callback/httpResponse";
import { AppError } from "../instances/app";
import { PrismaErrorCodeList } from "../../../utils/databases/prisma/error/codeList";
export const mainErrorHandler = (set: any, error: unknown) => {
if (error instanceof AppError) {
return returnErrorResponse(
set,
error.statusCode,
error.message,
error.details
);
}
if (error instanceof Prisma.PrismaClientKnownRequestError) {
const errorInfo = PrismaErrorCodeList[error.code];
if (errorInfo)
return returnErrorResponse(
set,
errorInfo.status,
errorInfo.message,
error.meta ?? {}
);
}
if (error instanceof Prisma.PrismaClientUnknownRequestError) {
return returnErrorResponse(set, 500, "Unknown database error");
}
if (error instanceof Prisma.PrismaClientRustPanicError) {
return returnErrorResponse(
set,
500,
"Database engine crashed unexpectedly"
);
}
if (error instanceof Prisma.PrismaClientInitializationError) {
return returnErrorResponse(set, 503, `Can't reach database server.`, error);
}
if (error instanceof Prisma.PrismaClientValidationError) {
return returnErrorResponse(
set,
400,
"Invalid input to query",
error.message
);
}
return returnErrorResponse(set, 500, "Internal server error");
};

View File

@ -1,13 +1,13 @@
export class AppError extends Error {
public readonly statusCode: number;
public readonly details?: any;
constructor(statusCode = 400, message: string, details?: any) {
super(message);
this.name = "AppError";
this.statusCode = statusCode;
this.details = details;
Object.setPrototypeOf(this, AppError.prototype);
}
}
export class AppError extends Error {
public readonly statusCode: number;
public readonly details?: any;
constructor(statusCode = 400, message: string, details?: any) {
super(message);
this.name = "AppError";
this.statusCode = statusCode;
this.details = details;
Object.setPrototypeOf(this, AppError.prototype);
}
}

View File

@ -1,21 +1,21 @@
import { Prisma } from "@prisma/client";
import { AppError } from "./app";
export function ErrorForwarder(
cause: unknown,
statusCode: number = 500,
message: string = "Unexpected error"
): never {
if (
cause instanceof AppError ||
cause instanceof Prisma.PrismaClientKnownRequestError ||
cause instanceof Prisma.PrismaClientUnknownRequestError ||
cause instanceof Prisma.PrismaClientRustPanicError ||
cause instanceof Prisma.PrismaClientInitializationError ||
cause instanceof Prisma.PrismaClientValidationError
) {
throw cause;
}
throw new AppError(statusCode, message, cause);
}
import { Prisma } from "@prisma/client";
import { AppError } from "./app";
export function ErrorForwarder(
cause: unknown,
statusCode: number = 500,
message: string = "Unexpected error"
): never {
if (
cause instanceof AppError ||
cause instanceof Prisma.PrismaClientKnownRequestError ||
cause instanceof Prisma.PrismaClientUnknownRequestError ||
cause instanceof Prisma.PrismaClientRustPanicError ||
cause instanceof Prisma.PrismaClientInitializationError ||
cause instanceof Prisma.PrismaClientValidationError
) {
throw cause;
}
throw new AppError(statusCode, message, cause);
}

View File

@ -1,14 +1,14 @@
import jwt from "jsonwebtoken";
export const jwtDecode = (payload: string) => {
// return payload;
if (!payload) throw "JWT decode payload not found";
const JWTKey = process.env.JWT_SECRET!;
try {
const decodedPayload = jwt.verify(payload, JWTKey);
return decodedPayload;
} catch (error) {
throw "JWT expired or not valid";
}
};
import jwt from "jsonwebtoken";
export const jwtDecode = (payload: string) => {
// return payload;
if (!payload) throw "JWT decode payload not found";
const JWTKey = process.env.JWT_SECRET!;
try {
const decodedPayload = jwt.verify(payload, JWTKey);
return decodedPayload;
} catch (error) {
throw "JWT expired or not valid";
}
};

View File

@ -1,62 +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;
}
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;
}

View File

@ -1,11 +1,11 @@
import jwt from "jsonwebtoken";
export const jwtEncode = (payload: any) => {
const tokenLifetime = Number(process.env.SESSION_EXPIRE!);
const jwtSecret = process.env.JWT_SECRET!;
const jwtToken = jwt.sign(payload, jwtSecret, {
expiresIn: tokenLifetime,
});
return jwtToken;
};
import jwt from "jsonwebtoken";
export const jwtEncode = (payload: any) => {
const tokenLifetime = Number(process.env.SESSION_EXPIRE!);
const jwtSecret = process.env.JWT_SECRET!;
const jwtToken = jwt.sign(payload, jwtSecret, {
expiresIn: tokenLifetime,
});
return jwtToken;
};

View File

@ -1,33 +1,33 @@
import { serialize } from "cookie";
export const clearCookies = (
set: any,
cookieKeys: string[],
options?: Partial<{
httpOnly: boolean;
secure: boolean;
sameSite: "strict" | "lax" | "none";
path: string;
}>
) => {
// Define the default configurations for clearing cookies
const defaultOptions = {
httpOnly: true,
secure: true,
sameSite: "strict" as const,
path: "/",
...options,
};
// Create an array of cleared cookies with the specified names
const clearedCookies = cookieKeys.map((name) => {
return serialize(name, "", {
...defaultOptions,
expires: new Date(0),
});
});
// Set the cleared cookies in the response headers
set.headers["set-cookie"] = clearedCookies;
return clearedCookies;
};
import { serialize } from "cookie";
export const clearCookies = (
set: any,
cookieKeys: string[],
options?: Partial<{
httpOnly: boolean;
secure: boolean;
sameSite: "strict" | "lax" | "none";
path: string;
}>
) => {
// Define the default configurations for clearing cookies
const defaultOptions = {
httpOnly: true,
secure: true,
sameSite: "strict" as const,
path: "/",
...options,
};
// Create an array of cleared cookies with the specified names
const clearedCookies = cookieKeys.map((name) => {
return serialize(name, "", {
...defaultOptions,
expires: new Date(0),
});
});
// Set the cleared cookies in the response headers
set.headers["set-cookie"] = clearedCookies;
return clearedCookies;
};

View File

@ -1,13 +1,13 @@
import { parse } from "cookie";
import { Context } from "elysia";
import { AppError } from "../../../error/instances/app";
export const getCookie = (ctx: Context) => {
try {
const cookiePayload = ctx.request.headers.get("Cookie");
const cookies = parse(cookiePayload!);
return cookies;
} catch (error) {
throw new AppError(401, "Cookie not found");
}
};
import { parse } from "cookie";
import { Context } from "elysia";
import { AppError } from "../../../error/instances/app";
export const getCookie = (ctx: Context) => {
try {
const cookiePayload = ctx.request.headers.get("Cookie");
const cookies = parse(cookiePayload!);
return cookies;
} catch (error) {
throw new AppError(401, "Cookie not found");
}
};

View File

@ -1,34 +1,34 @@
import { serialize } from "cookie";
export const setCookie = async (
set: any,
name: string,
payload: string,
options?: Partial<{
httpOnly: boolean;
secure: boolean;
sameSite: "strict" | "lax" | "none";
maxAge: number;
path: string;
}>
) => {
// Define the default configurations for the cookie
const cookieLifetime = Number(process.env.SESSION_EXPIRE!);
const defaultOptions = {
httpOnly: true,
secure: true,
sameSite: "strict" as const,
maxAge: cookieLifetime,
path: "/",
};
// Merge the default options with the provided options
const finalOptions = { ...defaultOptions, ...options };
// Create the serialized cookie string
const serializedCookie = serialize(name, payload, finalOptions);
// Set the cookie in the response headers
set.headers["set-cookie"] = serializedCookie;
return serializedCookie;
};
import { serialize } from "cookie";
export const setCookie = async (
set: any,
name: string,
payload: string,
options?: Partial<{
httpOnly: boolean;
secure: boolean;
sameSite: "strict" | "lax" | "none";
maxAge: number;
path: string;
}>
) => {
// Define the default configurations for the cookie
const cookieLifetime = Number(process.env.SESSION_EXPIRE!);
const defaultOptions = {
httpOnly: true,
secure: true,
sameSite: "strict" as const,
maxAge: cookieLifetime,
path: "/",
};
// Merge the default options with the provided options
const finalOptions = { ...defaultOptions, ...options };
// Create the serialized cookie string
const serializedCookie = serialize(name, payload, finalOptions);
// Set the cookie in the response headers
set.headers["set-cookie"] = serializedCookie;
return serializedCookie;
};

View File

@ -1,26 +1,26 @@
import { Context } from "elysia";
import { UAParser } from "ua-parser-js";
import { UserHeaderInformation } from "./types";
export const getUserHeaderInformation = (
ctx: Context
): UserHeaderInformation => {
const headers = ctx.request.headers;
const userAgentHeader = headers.get("user-agent") || "desktop";
const userAgent = new UAParser(userAgentHeader);
const userIP =
headers.get("cf-connecting-ip") ||
headers.get("x-real-ip") ||
headers.get("x-forwarded-for")?.split(",")[0] ||
"Unknown IP";
const userHeaderInformation = {
ip: userIP,
deviceType: userAgent.getDevice().type || "desktop",
deviceOS: userAgent.getOS().name + " " + userAgent.getOS().version,
browser: userAgent.getBrowser().name + " " + userAgent.getBrowser().version,
};
return userHeaderInformation;
};
import { Context } from "elysia";
import { UAParser } from "ua-parser-js";
import { UserHeaderInformation } from "./types";
export const getUserHeaderInformation = (
ctx: Context
): UserHeaderInformation => {
const headers = ctx.request.headers;
const userAgentHeader = headers.get("user-agent") || "desktop";
const userAgent = new UAParser(userAgentHeader);
const userIP =
headers.get("cf-connecting-ip") ||
headers.get("x-real-ip") ||
headers.get("x-forwarded-for")?.split(",")[0] ||
"Unknown IP";
const userHeaderInformation = {
ip: userIP,
deviceType: userAgent.getDevice().type || "desktop",
deviceOS: userAgent.getOS().name + " " + userAgent.getOS().version,
browser: userAgent.getBrowser().name + " " + userAgent.getBrowser().version,
};
return userHeaderInformation;
};

View File

@ -1,6 +1,6 @@
export interface UserHeaderInformation {
ip: string;
deviceType: string;
deviceOS: string;
browser: string;
}
export interface UserHeaderInformation {
ip: string;
deviceType: string;
deviceOS: string;
browser: string;
}

View File

@ -1,6 +1,6 @@
import bcrypt from "bcrypt";
export const hashPassword = async (password: string): Promise<string> => {
const saltRounds = Number(process.env.SALT_ROUNDS);
return await bcrypt.hash(password, saltRounds);
};
import bcrypt from "bcrypt";
export const hashPassword = async (password: string): Promise<string> => {
const saltRounds = Number(process.env.SALT_ROUNDS);
return await bcrypt.hash(password, saltRounds);
};