diff --git a/src/api/auth/auth.controller.ts b/src/api/auth/auth.controller.ts index 4cebe85..6aef10f 100644 --- a/src/api/auth/auth.controller.ts +++ b/src/api/auth/auth.controller.ts @@ -65,41 +65,52 @@ export const updateUser = async (id: string, body: { export const generateToken = async (context: any) => { try { const userId = context?.params?.userId; - // generating accessToken and refreshToken - const user = await checkUserInDB(userId); - if (user?.found === true) { + const access_cookie = context?.cookie?.access_token?.value; + const refresh_cookie = context?.cookie?.refresh_token?.value; - // generate access token - const accessToken = jwt.sign({ userId }, ENV.JWT_ACCESS_TOKEN_SECRET, { expiresIn: '3h' }); + if (access_cookie !== undefined || refresh_cookie !== undefined) { + const verify = await verifyAuth(context?.cookie); + return verify; + } + else if (access_cookie === undefined && refresh_cookie === undefined && userId !== undefined) { + const user = await checkUserInDB(userId); + if (user?.found === true) { - // generate refresh token - const refreshToken = jwt.sign({ userId }, ENV.JWT_REFRESH_TOKEN_SECRET, { expiresIn: '7d' }); + // generate access token + const accessToken = jwt.sign({ userId }, ENV.JWT_ACCESS_TOKEN_SECRET, { expiresIn: '3h' }); - // store refresh token in db - const storeRToken = await storeRefreshToken(userId, refreshToken); + // generate refresh token + const refreshToken = jwt.sign({ userId }, ENV.JWT_REFRESH_TOKEN_SECRET, { expiresIn: '7d' }); - if (storeRToken.status === 200) { - context.cookie.access_token.set({ - value: accessToken, - httpOnly: true, - secure: true, // Set to true in production - sameSite: 'none', // Adjust based on your needs - path: "/", - maxAge: 3 * 60 * 60, // 3 hours in seconds - }); + // store refresh token in db + const storeRToken = await storeRefreshToken(userId, refreshToken); - context.cookie.refresh_token.set({ - value: refreshToken, - httpOnly: true, - secure: true, // Set to true in production - sameSite: 'none', // Adjust based on your needs - path: "/", - maxAge: 7 * 24 * 60 * 60, // 7 days in seconds - }); + if (storeRToken.status === 200) { + context.cookie.access_token.set({ + value: accessToken, + httpOnly: true, + secure: true, // Set to true in production + sameSite: 'none', // Adjust based on your needs + path: "/", + maxAge: 3 * 60 * 60, // 3 hours in seconds + }); - return { status: 200, message: "Token generated successfully", token: accessToken, userId: user?.id }; + context.cookie.refresh_token.set({ + value: refreshToken, + httpOnly: true, + secure: true, // Set to true in production + sameSite: 'none', // Adjust based on your needs + path: "/", + maxAge: 7 * 24 * 60 * 60, // 7 days in seconds + }); + + return { status: 201, message: "Token generated successfully", token: accessToken, userId: user?.id }; + } + return { status: 500, message: "An error occurred while storing the refresh token" }; + } + else { + return { status: 404, message: "User not found" }; } - return { status: 500, message: "An error occurred while storing the refresh token" }; } else { return { status: 404, message: "Unauthorized!!!" }; @@ -110,19 +121,5 @@ export const generateToken = async (context: any) => { } } -export const verifyToken = async (context: any) => { - try { - // if token is in cookie, verify it - // const token_cookie = context.cookie.access_token.value; - const verify = await verifyAuth(context.cookie); - - return verify; - - } catch (error: any) { - console.log("Error in verifyToken:", error.message || error.toString()); - return { status: 500, message: `An error occurred while verifying the token` }; - } -} - diff --git a/src/api/auth/auth.route.ts b/src/api/auth/auth.route.ts index 1f18e87..1abb812 100644 --- a/src/api/auth/auth.route.ts +++ b/src/api/auth/auth.route.ts @@ -1,5 +1,5 @@ import Elysia, { t } from "elysia"; -import { generateToken, getUserData, updateUser, verifyToken } from "./auth.controller"; +import { generateToken, getUserData, updateUser } from "./auth.controller"; export const authRoute = new Elysia({ prefix: "/auth", @@ -27,5 +27,3 @@ authRoute.post("/user/update/:userId", async ({ params: { userId }, body }) => a authRoute.get("/generate-token/:userId", async (context) => await generateToken(context)); -authRoute.get("/verify-token", async (context) => await verifyToken(context)); - diff --git a/src/api/project/project.controller.ts b/src/api/project/project.controller.ts index 8bab7da..a13bab6 100644 --- a/src/api/project/project.controller.ts +++ b/src/api/project/project.controller.ts @@ -5,26 +5,26 @@ import { createEmptyProject } from "../../helper/projects/createProject"; import { createBucket } from "../../helper/upload/createBucket"; import { removeBucket } from "../../helper/upload/removeBucket"; -export const getEachProjects = async (id: string) => { +export const getEachProjects = async (id: string, token: string) => { try { const project = await db.select().from(projects).where(eq(projects.id, id)).limit(1); if (project.length === 0) { - return { status: 404, message: "Project not found" }; + return { status: 404, message: "Project not found", token }; } - return { status: 200, message: "Project fetched successfully", data: project[0] }; + return { status: 200, message: "Project fetched successfully", data: project[0], token }; } catch (error: any) { console.log(error.message); - return { status: 500, message: "An error occurred while fetching projects" }; + return { status: 500, message: "An error occurred while fetching projects", token }; } }; -export const getAllProjects = async (userId: string) => { +export const getAllProjects = async (userId: string, token: string) => { try { // Fetch all projects for the given user const allProjects = await db.select().from(projects).where(eq(projects.userId, userId)); if (allProjects.length === 0) { - return { status: 404, message: "No projects found" }; + return { status: 404, message: "No projects found", token }; } // Filter out projects where `object` is empty (null or an empty object) @@ -42,33 +42,33 @@ export const getAllProjects = async (userId: string) => { } if (validProjects.length === 0) { - return { status: 404, message: "No projects found" }; + return { status: 404, message: "No projects found", token }; } - return { status: 200, message: "Projects fetched successfully", data: validProjects }; + return { status: 200, message: "Projects fetched successfully", data: validProjects, token }; } catch (error: any) { console.log(error.message); - return { status: 500, message: "An error occurred while fetching projects" }; + return { status: 500, message: "An error occurred while fetching projects", token }; } }; -export const createProject = async (userId: string) => { +export const createProject = async (userId: string, token: string) => { try { const { id } = await createEmptyProject(userId); const bucket = await createBucket(id); - return { status: 200, message: "New project created successfully", data: { id, bucketName: bucket } }; + return { status: 200, message: "New project created successfully", data: { id, bucketName: bucket }, token }; } catch (error: any) { console.log(error.message); - return { status: 500, message: "An error occurred while creating projects" } + return { status: 500, message: "An error occurred while creating projects", token } } }; -export const updateProject = async (id: string, body: any) => { +export const updateProject = async (id: string, body: any, token: string) => { try { // 1. Validate if project exists const existingProject = await db.select().from(projects).where(eq(projects.id, id)).limit(1); if (existingProject.length === 0) { - return { status: 404, message: "Project not found" }; + return { status: 404, message: "Project not found", token }; } const { object, name, description, preview_url } = body; @@ -82,33 +82,33 @@ export const updateProject = async (id: string, body: any) => { }).where(eq(projects.id, id)).returning(); if (updatedProject.length === 0) { - return { status: 500, message: "Failed to update the project" }; + return { status: 500, message: "Failed to update the project", token }; } - return { status: 200, message: "Project updated successfully", data: updatedProject[0] }; + return { status: 200, message: "Project updated successfully", data: updatedProject[0], token }; } catch (error: any) { console.log("Error updating project:", error.message || error.toString()); - return { status: 500, message: "An error occurred while updating the project" }; + return { status: 500, message: "An error occurred while updating the project", token }; } }; -export const deleteProject = async (id: string) => { +export const deleteProject = async (id: string, token: string) => { try { const deleteProject = await db.delete(projects).where(eq(projects.id, id)).returning({ id: projects.id }); if (deleteProject.length === 0) { - return { status: 404, message: "Project not found" }; + return { status: 404, message: "Project not found", token }; } const projectId = deleteProject[0].id; const bucketDeletionResult = await removeBucket(projectId); if (bucketDeletionResult.status !== 200) { - return { status: bucketDeletionResult.status, message: `Error deleting bucket: ${bucketDeletionResult.message}` }; + return { status: bucketDeletionResult.status, message: `Error deleting bucket: ${bucketDeletionResult.message}`, token }; } - return { status: 200, message: "Project and associated bucket deleted successfully" }; + return { status: 200, message: "Project and associated bucket deleted successfully", token }; } catch (error: any) { console.log("Error in deleteProject:", error.message || error.toString()); - return { status: 500, message: "An error occurred while deleting the project" }; + return { status: 500, message: "An error occurred while deleting the project", token }; } }; diff --git a/src/api/project/project.route.ts b/src/api/project/project.route.ts index 21454ce..69f7f72 100644 --- a/src/api/project/project.route.ts +++ b/src/api/project/project.route.ts @@ -13,7 +13,15 @@ export const projectRoutes = new Elysia({ return { authData }; // Inject into context }); -projectRoutes.get("/each/:project_id", ({ params: { project_id } }) => getEachProjects(project_id), { +projectRoutes.get("/each/:project_id", async ({ params: { project_id }, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData.token; + const response = await getEachProjects(project_id, token); + return response; + } +}, { params: t.Object({ project_id: t.String() }) @@ -24,16 +32,31 @@ projectRoutes.get("/", async ({ authData }: any) => { return authData; else { const userId = authData.userId; - const response = await getAllProjects(userId); + const token = authData.token; + const response = await getAllProjects(userId, token); return response; } }); -projectRoutes.post("/create", ({ userId }: any) => createProject(userId)); +projectRoutes.post("/create", async ({ authData }: any) => { + if (authData.status !== 200) + return authData; + else { + const userId = authData.userId; + const token = authData.token; + const response = await createProject(userId, token); + return response; + } +}); -projectRoutes.put("/update/:project_id", async ({ body, params: { project_id } }) => { - const response = await updateProject(project_id, body); - return response; +projectRoutes.put("/update/:project_id", async ({ body, params: { project_id }, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData.token; + const response = await updateProject(project_id, body, token); + return response; + } }, { params: t.Object({ project_id: t.String() @@ -46,7 +69,15 @@ projectRoutes.put("/update/:project_id", async ({ body, params: { project_id } } }) }); -projectRoutes.delete("/delete/:project_id", ({ params: { project_id } }) => deleteProject(project_id), { +projectRoutes.delete("/delete/:project_id", async ({ params: { project_id }, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData.token; + const response = await deleteProject(project_id, token); + return response; + } +}, { params: t.Object({ project_id: t.String() }) diff --git a/src/api/upload/upload.controller.ts b/src/api/upload/upload.controller.ts index 550c7c6..7083a9d 100644 --- a/src/api/upload/upload.controller.ts +++ b/src/api/upload/upload.controller.ts @@ -4,21 +4,21 @@ import { uploads } from "../../db/schema"; import { uploadToMinio } from "../../helper/upload/uploadToMinio"; import { removeFromMinio } from "../../helper/upload/removeFromMinio"; -export const uploadPhoto = async (file: File, project_id: string, userId: string) => { +export const uploadPhoto = async (file: File, project_id: string, userId: string, token: string) => { try { // Validate userId if (!userId || typeof userId !== "string") { - return { status: 400, message: "Invalid user ID" }; + return { status: 400, message: "Invalid user ID", token }; } // Validate projectId if (!project_id || typeof project_id !== "string") { - return { status: 400, message: "Invalid project ID" }; + return { status: 400, message: "Invalid project ID", token }; } // Validate file input if (!file || !(file instanceof File) || !file.name) { - return { status: 400, message: "Invalid or missing file" }; + return { status: 400, message: "Invalid or missing file", token }; } // Extract file extension (e.g., ".jpg", ".png") @@ -31,7 +31,7 @@ export const uploadPhoto = async (file: File, project_id: string, userId: string // Upload file to MinIO with the unique filename const urlLink = await uploadToMinio(file, project_id, uniqueFileName); if (!urlLink || !urlLink.url) { - return { status: 500, message: "File upload failed" }; + return { status: 500, message: "File upload failed", token }; } // Save file info in DB with modified filename @@ -41,18 +41,18 @@ export const uploadPhoto = async (file: File, project_id: string, userId: string projectId: project_id, }).returning(); - return { status: 200, message: "File uploaded successfully", data: saveFile }; + return { status: 200, message: "File uploaded successfully", data: saveFile, token }; } catch (error: any) { console.error("Error processing file:", error); - return { status: 500, message: "An error occurred while uploading the photo" }; + return { status: 500, message: "An error occurred while uploading the photo", token }; } }; -export const deletePhoto = async (url: string) => { +export const deletePhoto = async (url: string, token: string) => { try { if (!url) { - return { status: 404, message: "File ID is missing" } + return { status: 404, message: "File ID is missing", token } } const deleteFile = await db @@ -62,40 +62,40 @@ export const deletePhoto = async (url: string) => { // Ensure there's a file to delete if (!deleteFile || deleteFile.length === 0) { - return { status: 404, message: "File not found" }; + return { status: 404, message: "File not found", token }; } const { projectId, filename } = deleteFile[0]; // Ensure projectId and filename are valid if (!projectId || !filename) { - return { status: 400, message: "Invalid project ID or filename" }; + return { status: 400, message: "Invalid project ID or filename", token }; } const minioRemove = await removeFromMinio(projectId, filename); - return { status: 200, message: minioRemove.msg }; + return { status: 200, message: minioRemove.msg, token }; } catch (error: any) { console.error("Error processing file:", error); - return { status: 500, message: `An error occurred while deleting the photo: ${error.message}` }; + return { status: 500, message: `An error occurred while deleting the photo: ${error.message}`, token }; } }; -export const getAllPhoto = async (id: string) => { +export const getAllPhoto = async (id: string, token: string) => { try { // project id if (!id) { - return { status: 404, message: "Project ID is missing" } + return { status: 404, message: "Project ID is missing", token } } const getAllPhoto = await db.select().from(uploads).where(eq(uploads.projectId, id)); if (getAllPhoto.length === 0) { - return { status: 200, message: "No photos found for the given project ID", data: [] } + return { status: 200, message: "No photos found for the given project ID", data: [], token } } - return { status: 200, message: "All photos retrieved successfully", data: getAllPhoto }; + return { status: 200, message: "All photos retrieved successfully", data: getAllPhoto, token }; } catch (error: any) { console.log(`Error getting photos: ${error.message}`); - return { status: 500, message: "An error occurred while getting the photos" } + return { status: 500, message: "An error occurred while getting the photos", token } } } diff --git a/src/api/upload/upload.route.ts b/src/api/upload/upload.route.ts index 4cd3d70..cca3954 100644 --- a/src/api/upload/upload.route.ts +++ b/src/api/upload/upload.route.ts @@ -10,16 +10,19 @@ export const uploadRoutes = new Elysia({ } }).derive(async ({ cookie }) => { const authData = await verifyAuth(cookie); - if (authData.status !== 200) { - return { authData }; - } - return { userId: authData.userId }; // Inject into context + return { authData }; // Inject into context }); -uploadRoutes.post("/add", async ({ body, userId }) => { - const user_id: String | any = userId; - const { id: project_id, file } = body; - return uploadPhoto(file, project_id, user_id); +uploadRoutes.post("/add", async ({ body, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData?.token; + const user_id: String | any = authData?.userId; + const { id: project_id, file } = body; + const response = await uploadPhoto(file, project_id, user_id, token); + return response; + } }, { body: t.Object({ file: t.File(), @@ -27,16 +30,30 @@ uploadRoutes.post("/add", async ({ body, userId }) => { }) }); -uploadRoutes.delete("/delete", async ({ query }) => { - const { url } = query; - return deletePhoto(url); +uploadRoutes.delete("/delete", async ({ query, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData?.token; + const { url } = query; + const response = await deletePhoto(url, token); + return response; + } }, { query: t.Object({ url: t.String(), }) }); -uploadRoutes.get("/getAll/:id", async ({ params: { id } }) => getAllPhoto(id), { +uploadRoutes.get("/getAll/:id", async ({ params: { id }, authData }) => { + if (authData.status !== 200) + return authData; + else { + const token = authData?.token; + const response = await getAllPhoto(id, token); + return response; + } +}, { params: t.Object({ id: t.String() }) diff --git a/src/middlewares/auth.middlewares.ts b/src/middlewares/auth.middlewares.ts index 41cf6ef..17fa35b 100644 --- a/src/middlewares/auth.middlewares.ts +++ b/src/middlewares/auth.middlewares.ts @@ -16,7 +16,7 @@ export const verifyAuth = async (cookie: any) => { // Query the user from the database const findUser = await db.select().from(users).where(eq(users.id, verify_cookie.userId)); if (findUser.length > 0) { - return { status: 200, message: "Token verified successfully", userId: findUser[0].id }; + return { status: 200, message: "Token verified successfully", token: access_cookie, userId: findUser[0].id }; } else { return { status: 401, message: "Unauthorized" };