From d2ecdfab11b9cefa8bf2d6e7e5915e1947ca3597 Mon Sep 17 00:00:00 2001 From: abiyasa05 Date: Thu, 8 Aug 2024 14:28:24 +0700 Subject: [PATCH] create: API for register --- apps/backend/src/data/permissions.ts | 3 + apps/backend/src/data/roles.ts | 10 ++- apps/backend/src/index.ts | 2 + apps/backend/src/routes/register/route.ts | 83 +++++++++++++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 apps/backend/src/routes/register/route.ts diff --git a/apps/backend/src/data/permissions.ts b/apps/backend/src/data/permissions.ts index 1e91356..8fc61fe 100644 --- a/apps/backend/src/data/permissions.ts +++ b/apps/backend/src/data/permissions.ts @@ -32,6 +32,9 @@ const permissionsData = [ { code: "roles.delete", }, + { + code: "register.create", + }, ] as const; export type SpecificPermissionCode = (typeof permissionsData)[number]["code"]; diff --git a/apps/backend/src/data/roles.ts b/apps/backend/src/data/roles.ts index 2c42327..bc087b5 100644 --- a/apps/backend/src/data/roles.ts +++ b/apps/backend/src/data/roles.ts @@ -17,10 +17,18 @@ const roleData: RoleData[] = [ name: "Super Admin", permissions: permissionsData.map((permission) => permission.code), }, + { + code: "user", + description: + "Has full access to the system and can manage all features and settings", + isActive: true, + name: "User", + permissions: ["register.create"], + }, ]; // Manually specify the union of role codes -export type RoleCode = "super-admin" | "*"; +export type RoleCode = "super-admin" | "user" | "*"; const exportedRoleData = roleData; diff --git a/apps/backend/src/index.ts b/apps/backend/src/index.ts index c0fbe56..a8204c1 100644 --- a/apps/backend/src/index.ts +++ b/apps/backend/src/index.ts @@ -3,6 +3,7 @@ import { configDotenv } from "dotenv"; import { Hono } from "hono"; import authRoutes from "./routes/auth/route"; import usersRoute from "./routes/users/route"; +import respondentsRoute from "./routes/register/route"; import { verifyAccessToken } from "./utils/authUtils"; import permissionRoutes from "./routes/permissions/route"; import { cors } from "hono/cors"; @@ -78,6 +79,7 @@ const routes = app .route("/dashboard", dashboardRoutes) .route("/roles", rolesRoute) .route("/dev", devRoutes) + .route("/register", respondentsRoute) .onError((err, c) => { if (err instanceof DashboardError) { return c.json( diff --git a/apps/backend/src/routes/register/route.ts b/apps/backend/src/routes/register/route.ts new file mode 100644 index 0000000..9ac5706 --- /dev/null +++ b/apps/backend/src/routes/register/route.ts @@ -0,0 +1,83 @@ +import { Hono } from "hono"; +import { HTTPException } from "hono/http-exception"; +import db from "../../drizzle"; +import { respondents } from "../../drizzle/schema/respondents"; +import { users } from "../../drizzle/schema/users"; +import { hashPassword } from "../../utils/passwordUtils"; +import requestValidator from "../../utils/requestValidator"; +import authInfo from "../../middlewares/authInfo"; +import checkPermission from "../../middlewares/checkPermission"; +import { and, eq, isNull, ilike, or, sql } from "drizzle-orm"; +import { z } from "zod"; +import HonoEnv from "../../types/HonoEnv"; + +const registerFormSchema = z.object({ + name: z.string().min(1).max(255), + username: z.string().min(1).max(255), + email: z.string().email().optional(), + password: z.string().min(6), + companyName: z.string().min(1).max(255), + position: z.string().min(1).max(255), + workExperience: z.string().min(1).max(255), + address: z.string().min(1), + phoneNumber: z.string().min(1).max(13), +}); + +const respondentsRoute = new Hono() + .use(authInfo) + //create user and respondent + .post( + "/", + checkPermission("register.create"), + requestValidator("json", registerFormSchema), + async (c) => { + const formData = c.req.valid("json"); + + // Hash the password + const hashedPassword = await hashPassword(formData.password); + + // Start a transaction + try { + const result = await db.transaction(async (trx) => { + // Create user + const [newUser] = await trx + .insert(users) + .values({ + name: formData.name, + username: formData.username, + email: formData.email, + password: hashedPassword, + }) + .returning(); + + // Create respondent + await trx + .insert(respondents) + .values({ + companyName: formData.companyName, + position: formData.position, + workExperience: formData.workExperience, + address: formData.address, + phoneNumber: formData.phoneNumber, + userId: newUser.id, + }); + + return newUser; + }); + + return c.json( + { + message: "User and respondent created successfully", + }, + 201 + ); + } catch (error) { + console.error("Error creating user and respondent:", error); + throw new HTTPException(500, { + message: "Error creating user and respondent", + }); + } + } + ); + +export default respondentsRoute; \ No newline at end of file