import { APIError } from "better-auth"; import { count, eq, sql } from "drizzle-orm"; import { Router } from "express"; import z from "zod"; import { db } from "../db/db.controller.js"; import { user } from "../db/schema/auth.schema.js"; import { auth } from "../utils/auth.utils.js"; import { apiReturn } from "../utils/returnHelper.utils.js"; const r = 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, _, and ."), displayUsername: z .string() .min(2) .max(100) .optional() .describe("if you leave blank it will be the same as your username"), role: z .enum(["user"]) .optional() .describe("What roles are available to use."), data: z .record(z.string(), z.unknown()) .optional() .describe( "This allows us to add extra fields to the data to parse against", ), }); r.post("/", async (req, res) => { // 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); const userCount = totalUsers[0]?.count ?? 0; try { // validate the body is correct before accepting it let validated = registerSchema.parse(req.body); validated = { ...validated, data: { lastLogin: new Date(Date.now()) }, username: validated.username, }; // Call Better Auth signUp const newUser = await auth.api.signUpEmail({ body: validated, }); // if we have no users yet lets make this new one the admin if (userCount === 0) { // make this user an admin await db .update(user) .set({ role: "admin", updatedAt: sql`NOW()` }) .where(eq(user.id, newUser.user.id)); } apiReturn(res, { success: true, level: "info", //connect.success ? "info" : "error", module: "routes", subModule: "auth", message: `${validated.username} was just created`, data: [newUser], status: 200, //connect.success ? 200 : 400, }); } catch (err) { if (err instanceof z.ZodError) { const flattened = z.flattenError(err); // return res.status(400).json({ // error: "Validation failed", // details: flattened, // }); apiReturn(res, { success: false, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "auth", message: "Validation failed", data: [flattened.fieldErrors], status: 400, //connect.success ? 200 : 400, }); } if (err instanceof APIError) { apiReturn(res, { success: false, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "auth", message: err.message, data: [err.status], status: 400, //connect.success ? 200 : 400, }); } apiReturn(res, { success: false, level: "error", //connect.success ? "info" : "error", module: "routes", subModule: "auth", message: "Internal Server Error creating user", data: [err], status: 400, //connect.success ? 200 : 400, }); } // apiReturn(res, { // success: true, // level: "info", //connect.success ? "info" : "error", // module: "routes", // subModule: "auth", // message: "Testing route", // data: [], // status: 200, //connect.success ? 200 : 400, // }); }); export default r;