diff --git a/supabase/functions/create-account/index.ts b/supabase/functions/create-account/index.ts new file mode 100644 index 0000000..6df5ab3 --- /dev/null +++ b/supabase/functions/create-account/index.ts @@ -0,0 +1,91 @@ +import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.0"; +import { z } from "npm:zod@3.23.8"; + +const corsHeaders = { + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": + "authorization, x-client-info, x-supabase-client-platform, x-supabase-api-version, apikey, content-type", + "Access-Control-Allow-Methods": "POST, OPTIONS", +}; + +const BodySchema = z.object({ + email: z.string().trim().email().max(255), + password: z.string().min(8).max(100), + company: z.string().trim().max(200).optional().default(""), + phone: z.string().trim().max(30).optional().default(""), +}); + +const admin = createClient( + Deno.env.get("SUPABASE_URL")!, + Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!, +); + +Deno.serve(async (req) => { + if (req.method === "OPTIONS") return new Response("ok", { headers: corsHeaders }); + if (req.method !== "POST") { + return new Response(JSON.stringify({ error: "Method not allowed" }), { + status: 405, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + try { + const parsed = BodySchema.safeParse(await req.json()); + if (!parsed.success) { + return new Response( + JSON.stringify({ error: "Ogiltiga fält", details: parsed.error.flatten().fieldErrors }), + { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }, + ); + } + const { email, password, company, phone } = parsed.data; + + // Try to create user with email_confirm=true so they can sign in immediately + const { data: created, error: createErr } = await admin.auth.admin.createUser({ + email, + password, + email_confirm: true, + user_metadata: { company, phone }, + }); + + if (createErr) { + const msg = createErr.message || ""; + const alreadyExists = + msg.toLowerCase().includes("already") || + msg.toLowerCase().includes("registered") || + msg.toLowerCase().includes("exists"); + if (alreadyExists) { + return new Response(JSON.stringify({ ok: true, existed: true }), { + status: 200, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + console.error("createUser error:", createErr); + return new Response(JSON.stringify({ error: msg }), { + status: 400, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } + + // Best-effort update profile + if (created?.user?.id) { + await admin + .from("profiles") + .update({ + company_name: company || null, + phone: phone || null, + }) + .eq("user_id", created.user.id); + } + + return new Response(JSON.stringify({ ok: true, existed: false }), { + status: 200, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } catch (err: any) { + console.error("create-account error:", err); + return new Response(JSON.stringify({ error: err?.message ?? "Något gick fel" }), { + status: 500, + headers: { ...corsHeaders, "Content-Type": "application/json" }, + }); + } +});