All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m55s
93 lines
2.3 KiB
TypeScript
93 lines
2.3 KiB
TypeScript
import type { APIRoute } from "astro";
|
|
import { db } from "../../../db";
|
|
import {
|
|
users,
|
|
organizations,
|
|
members,
|
|
siteSettings,
|
|
} from "../../../db/schema";
|
|
import { hashPassword, setAuthCookie } from "../../../lib/auth";
|
|
import { isValidEmail, MAX_LENGTHS } from "../../../lib/validation";
|
|
import { eq, count, sql } from "drizzle-orm";
|
|
import { nanoid } from "nanoid";
|
|
|
|
export const POST: APIRoute = async ({ request, cookies, redirect }) => {
|
|
const userCountResult = await db.select({ count: count() }).from(users).get();
|
|
const isFirstUser = userCountResult ? userCountResult.count === 0 : true;
|
|
|
|
if (!isFirstUser) {
|
|
const registrationSetting = await db
|
|
.select()
|
|
.from(siteSettings)
|
|
.where(eq(siteSettings.key, "registration_enabled"))
|
|
.get();
|
|
|
|
const registrationEnabled = registrationSetting?.value === "true";
|
|
|
|
if (!registrationEnabled) {
|
|
return redirect("/signup?error=registration_disabled");
|
|
}
|
|
}
|
|
|
|
const formData = await request.formData();
|
|
const name = formData.get("name")?.toString();
|
|
const email = formData.get("email")?.toString();
|
|
const password = formData.get("password")?.toString();
|
|
|
|
if (!name || !email || !password) {
|
|
return redirect("/signup?error=missing_fields");
|
|
}
|
|
|
|
if (!isValidEmail(email)) {
|
|
return redirect("/signup?error=invalid_email");
|
|
}
|
|
|
|
if (name.length > MAX_LENGTHS.name) {
|
|
return redirect("/signup?error=name_too_long");
|
|
}
|
|
|
|
if (password.length > MAX_LENGTHS.password) {
|
|
return redirect("/signup?error=password_too_long");
|
|
}
|
|
|
|
if (password.length < 8) {
|
|
return redirect("/signup?error=password_too_short");
|
|
}
|
|
|
|
const existingUser = await db
|
|
.select()
|
|
.from(users)
|
|
.where(eq(users.email, email))
|
|
.get();
|
|
if (existingUser) {
|
|
return redirect("/login?registered=true");
|
|
}
|
|
|
|
const passwordHash = await hashPassword(password);
|
|
const userId = nanoid();
|
|
|
|
await db.insert(users).values({
|
|
id: userId,
|
|
name,
|
|
email,
|
|
passwordHash,
|
|
isSiteAdmin: isFirstUser,
|
|
});
|
|
|
|
const orgId = nanoid();
|
|
await db.insert(organizations).values({
|
|
id: orgId,
|
|
name: `${name}'s Organization`,
|
|
});
|
|
|
|
await db.insert(members).values({
|
|
userId,
|
|
organizationId: orgId,
|
|
role: "owner",
|
|
});
|
|
|
|
setAuthCookie(cookies, userId);
|
|
|
|
return redirect("/dashboard");
|
|
};
|