Pull Request branch dev-clone to main #1
|
|
@ -3,19 +3,19 @@ import { HTTPException } from "hono/http-exception";
|
||||||
import db from "../../drizzle";
|
import db from "../../drizzle";
|
||||||
import { respondents } from "../../drizzle/schema/respondents";
|
import { respondents } from "../../drizzle/schema/respondents";
|
||||||
import { users } from "../../drizzle/schema/users";
|
import { users } from "../../drizzle/schema/users";
|
||||||
|
import { rolesSchema } from "../../drizzle/schema/roles";
|
||||||
import { rolesToUsers } from "../../drizzle/schema/rolesToUsers";
|
import { rolesToUsers } from "../../drizzle/schema/rolesToUsers";
|
||||||
import { hashPassword } from "../../utils/passwordUtils";
|
import { hashPassword } from "../../utils/passwordUtils";
|
||||||
import requestValidator from "../../utils/requestValidator";
|
import requestValidator from "../../utils/requestValidator";
|
||||||
import authInfo from "../../middlewares/authInfo";
|
import authInfo from "../../middlewares/authInfo";
|
||||||
import checkPermission from "../../middlewares/checkPermission";
|
import { or, eq } from "drizzle-orm";
|
||||||
import { and, eq, or } from "drizzle-orm";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import HonoEnv from "../../types/HonoEnv";
|
import HonoEnv from "../../types/HonoEnv";
|
||||||
|
|
||||||
const registerFormSchema = z.object({
|
const registerFormSchema = z.object({
|
||||||
name: z.string().min(1).max(255),
|
name: z.string().min(1).max(255),
|
||||||
username: z.string().min(1).max(255),
|
username: z.string().min(1).max(255),
|
||||||
email: z.string().email().optional(),
|
email: z.string().email(),
|
||||||
password: z.string().min(6),
|
password: z.string().min(6),
|
||||||
companyName: z.string().min(1).max(255),
|
companyName: z.string().min(1).max(255),
|
||||||
position: z.string().min(1).max(255),
|
position: z.string().min(1).max(255),
|
||||||
|
|
@ -23,135 +23,110 @@ const registerFormSchema = z.object({
|
||||||
address: z.string().min(1),
|
address: z.string().min(1),
|
||||||
phoneNumber: z.string().min(1).max(13),
|
phoneNumber: z.string().min(1).max(13),
|
||||||
isEnabled: z.string().default("false"),
|
isEnabled: z.string().default("false"),
|
||||||
roles: z
|
|
||||||
.string()
|
|
||||||
.refine(
|
|
||||||
(data) => {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(data);
|
|
||||||
return Array.isArray(parsed);
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
message: "Roles must be an array",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const respondentsRoute = new Hono<HonoEnv>()
|
const respondentsRoute = new Hono<HonoEnv>()
|
||||||
.use(authInfo)
|
.use(authInfo)
|
||||||
.post(
|
//post user
|
||||||
"/",
|
.post("/", requestValidator("json", registerFormSchema), async (c) => {
|
||||||
checkPermission("register.create"),
|
const formData = c.req.valid("json");
|
||||||
requestValidator("json", registerFormSchema),
|
|
||||||
async (c) => {
|
|
||||||
const formData = c.req.valid("json");
|
|
||||||
|
|
||||||
console.log("Form Data:", formData);
|
// Check if the provided email or username is already exists in database
|
||||||
|
const conditions = [];
|
||||||
// Build conditions based on available formData
|
if (formData.email) {
|
||||||
const conditions = [];
|
conditions.push(eq(users.email, formData.email));
|
||||||
if (formData.email) {
|
|
||||||
conditions.push(eq(users.email, formData.email));
|
|
||||||
}
|
|
||||||
conditions.push(eq(users.username, formData.username));
|
|
||||||
|
|
||||||
const existingUser = await db
|
|
||||||
.select()
|
|
||||||
.from(users)
|
|
||||||
.where(or(...conditions));
|
|
||||||
|
|
||||||
console.log("Existing Users:", existingUser);
|
|
||||||
|
|
||||||
const existingRespondent = await db
|
|
||||||
.select()
|
|
||||||
.from(respondents)
|
|
||||||
.where(eq(respondents.phoneNumber, formData.phoneNumber));
|
|
||||||
|
|
||||||
console.log("Existing Respondents:", existingRespondent);
|
|
||||||
|
|
||||||
if (existingUser.length > 0) {
|
|
||||||
throw new HTTPException(400, {
|
|
||||||
message: "Email atau username sudah terdaftar",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingRespondent.length > 0) {
|
|
||||||
throw new HTTPException(400, {
|
|
||||||
message: "Nomor HP sudah terdaftar",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the password
|
|
||||||
const hashedPassword = await hashPassword(formData.password);
|
|
||||||
|
|
||||||
console.log("Hashed Password:", hashedPassword);
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
isEnabled: formData.isEnabled?.toLowerCase() === "true" || true,
|
|
||||||
})
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
console.log("New User:", newUser);
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Respondent Created for User ID:", newUser.id);
|
|
||||||
|
|
||||||
// If roles are included in the request, add to rolesToUsers
|
|
||||||
if (formData.roles) {
|
|
||||||
try {
|
|
||||||
const roles = JSON.parse(formData.roles) as string[];
|
|
||||||
if (roles.length) {
|
|
||||||
await trx.insert(rolesToUsers).values(
|
|
||||||
roles.map((role) => ({
|
|
||||||
userId: newUser.id,
|
|
||||||
roleId: role,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error parsing roles:", error);
|
|
||||||
throw new HTTPException(400, {
|
|
||||||
message: "Invalid roles format",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
conditions.push(eq(users.username, formData.username));
|
||||||
|
|
||||||
|
const existingUser = await db
|
||||||
|
.select()
|
||||||
|
.from(users)
|
||||||
|
.where(
|
||||||
|
or(
|
||||||
|
eq(users.email, formData.email),
|
||||||
|
eq(users.username, formData.username)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingRespondent = await db
|
||||||
|
.select()
|
||||||
|
.from(respondents)
|
||||||
|
.where(eq(respondents.phoneNumber, formData.phoneNumber));
|
||||||
|
|
||||||
|
if (existingUser.length > 0) {
|
||||||
|
throw new HTTPException(400, {
|
||||||
|
message: "Email or username has been registered",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingRespondent.length > 0) {
|
||||||
|
throw new HTTPException(400, {
|
||||||
|
message: "Phone number has been registered",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash the password
|
||||||
|
const hashedPassword = await hashPassword(formData.password);
|
||||||
|
|
||||||
|
// Start a transaction
|
||||||
|
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,
|
||||||
|
isEnabled: formData.isEnabled?.toLowerCase() === "true" || true,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
.catch(() => {
|
||||||
|
throw new HTTPException(500, { message: "Error creating user" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
throw new HTTPException(500, {
|
||||||
|
message: "Error creating respondent",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Automatically assign "user" role to the new user
|
||||||
|
const [role] = await trx
|
||||||
|
.select()
|
||||||
|
.from(rolesSchema)
|
||||||
|
.where(eq(rolesSchema.code, "user"))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (!role) {
|
||||||
|
throw new HTTPException(500, { message: "Role 'user' not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
await trx.insert(rolesToUsers).values({
|
||||||
|
userId: newUser.id,
|
||||||
|
roleId: role.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return newUser;
|
||||||
|
});
|
||||||
|
|
||||||
|
return c.json(
|
||||||
|
{
|
||||||
|
message: "User created successfully",
|
||||||
|
},
|
||||||
|
201
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
export default respondentsRoute;
|
export default respondentsRoute;
|
||||||
Loading…
Reference in New Issue
Block a user