import { APIError, betterAuth } from "better-auth"; import { count, eq, sql } from "drizzle-orm"; import type { Request, Response } from "express"; import { Router } from "express"; import z from "zod"; import { auth } from "../../../pkg/auth/auth.js"; import { db } from "../../../pkg/db/db.js"; import { user } from "../../../pkg/db/schema/auth-schema.js"; import { systemAdminRole } from "../../admin/controller/systemAdminRole.js"; const router = Router(); const registerSchema = z.object({ email: z.email(), name: z.string().min(2).max(100), password: z.string().min(8, "Password must be at least 8 characters"), username: z .string() .min(3) .max(32) .regex(/^[a-zA-Z0-9_]+$/, "Only alphanumeric + underscores"), displayUsername: z.string().min(2).max(100).optional(), // optional in your API, but supported }); router.post("/", async (req: Request, res: Response) => { // check if we are the first user so we can add as system admin to all modules const totalUsers = await db.select({ count: count() }).from(user); try { // Parse + validate incoming JSON against Zod schema const validated = registerSchema.parse(req.body); // Call Better Auth signUp const newUser = await auth.api.signUpEmail({ body: validated, }); if (totalUsers[0].count === 0) { systemAdminRole(newUser.user.id); } await db .update(user) .set({ lastLogin: sql`NOW()` }) .where(eq(user.id, newUser.user.id)); return res .status(201) .json({ success: true, message: "User created", data: newUser }); } catch (err) { console.log(err); if (err instanceof z.ZodError) { const flattened = z.flattenError(err); return res.status(400).json({ error: "Validation failed", details: flattened, }); } if (err instanceof APIError) { return res.status(200).json({ success: false, message: err.message, error: err.status, }); } return res.status(200).json({ success: false, message: "There was an error creating your user.", error: err, }); } }); export default router;