62 lines
2.0 KiB
TypeScript
62 lines
2.0 KiB
TypeScript
import { Router } from "express";
|
|
import type { Request, Response } from "express";
|
|
import z from "zod";
|
|
import { auth } from "../../../pkg/auth/auth.js";
|
|
import { db } from "../../../pkg/db/db.js";
|
|
import { count } from "drizzle-orm";
|
|
import { user } from "../../../pkg/db/schema/auth-schema.js";
|
|
import { APIError, betterAuth } from "better-auth";
|
|
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);
|
|
console.log(totalUsers[0].count);
|
|
try {
|
|
// Parse + validate incoming JSON against Zod schema
|
|
const validated = registerSchema.parse(req.body);
|
|
|
|
// Call Better Auth signUp
|
|
const user = await auth.api.signUpEmail({
|
|
body: validated,
|
|
});
|
|
|
|
if (totalUsers[0].count === 0) {
|
|
systemAdminRole(user.user.id);
|
|
}
|
|
return res.status(201).json(user);
|
|
} catch (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(400).json({
|
|
success: false,
|
|
message: err.message,
|
|
error: err.status,
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
export default router;
|