Some checks failed
Deploy to Cloudflare Workers / deploy (push) Has been cancelled
127 lines
3.4 KiB
TypeScript
127 lines
3.4 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import { createAdminClient, hasAdminClient } from "@/lib/supabase/admin";
|
|
import { formatSignupError } from "@/lib/supabase/auth-errors";
|
|
import type { PortalRole } from "@/lib/auth/roles";
|
|
|
|
type Body = {
|
|
email?: string;
|
|
password?: string;
|
|
displayName?: string;
|
|
portalRole?: PortalRole;
|
|
};
|
|
|
|
function parsePortalRole(value: unknown): PortalRole {
|
|
return value === "league_master" ? "league_master" : "manager";
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
if (!hasAdminClient()) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error:
|
|
"Server signup is not configured. Add SUPABASE_SERVICE_ROLE_KEY to .env.local or use client signup.",
|
|
useClient: true,
|
|
},
|
|
{ status: 503 }
|
|
);
|
|
}
|
|
|
|
let body: Body;
|
|
try {
|
|
body = await request.json();
|
|
} catch {
|
|
return NextResponse.json(
|
|
{ success: false, error: "Invalid JSON body" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const email = body.email?.trim().toLowerCase();
|
|
const password = body.password;
|
|
const displayName = body.displayName?.trim() || email?.split("@")[0] || "User";
|
|
const portalRole = parsePortalRole(body.portalRole);
|
|
|
|
if (!email || !password) {
|
|
return NextResponse.json(
|
|
{ success: false, error: "Email and password are required" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
if (password.length < 6) {
|
|
return NextResponse.json(
|
|
{ success: false, error: "Password must be at least 6 characters" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const autoConfirm =
|
|
process.env.SUPABASE_AUTO_CONFIRM_EMAIL === "true" ||
|
|
process.env.NODE_ENV === "development";
|
|
|
|
try {
|
|
const admin = createAdminClient();
|
|
|
|
const { data: created, error: createError } =
|
|
await admin.auth.admin.createUser({
|
|
email,
|
|
password,
|
|
email_confirm: autoConfirm,
|
|
user_metadata: {
|
|
display_name: displayName,
|
|
portal_role: portalRole,
|
|
},
|
|
});
|
|
|
|
if (createError) {
|
|
const message = formatSignupError(createError.message);
|
|
const status = createError.status === 422 ? 422 : 500;
|
|
return NextResponse.json({ success: false, error: message }, { status });
|
|
}
|
|
|
|
const userId = created.user?.id;
|
|
if (!userId) {
|
|
return NextResponse.json(
|
|
{ success: false, error: "User was not created" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
const { error: profileError } = await admin.from("profiles").upsert(
|
|
{
|
|
id: userId,
|
|
display_name: displayName,
|
|
portal_role: portalRole,
|
|
},
|
|
{ onConflict: "id" }
|
|
);
|
|
|
|
if (profileError) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: formatSignupError(
|
|
profileError.message.includes("portal_role")
|
|
? "Database error saving new user"
|
|
: profileError.message
|
|
),
|
|
},
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
userId,
|
|
needsEmailConfirmation: !autoConfirm,
|
|
portalRole,
|
|
});
|
|
} catch (e) {
|
|
const message = e instanceof Error ? e.message : "Signup failed";
|
|
return NextResponse.json(
|
|
{ success: false, error: formatSignupError(message) },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|