76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { fail, handleOptions, json } from "../_shared/http.ts";
|
|
import { createServiceClient, requireUser, slugify } from "../_shared/supabase.ts";
|
|
|
|
Deno.serve(async (req) => {
|
|
const preflight = handleOptions(req);
|
|
if (preflight) return preflight;
|
|
|
|
if (req.method !== "POST") return fail("Method not allowed", 405);
|
|
|
|
const { user, error: userError } = await requireUser(req);
|
|
if (!user) return fail(userError ?? "Unauthorized", 401);
|
|
|
|
let body: {
|
|
organization_id?: string;
|
|
name?: string;
|
|
slug?: string;
|
|
icon_url?: string | null;
|
|
};
|
|
try {
|
|
body = await req.json();
|
|
} catch {
|
|
return fail("Invalid JSON body");
|
|
}
|
|
|
|
const organizationId = (body.organization_id ?? "").trim();
|
|
if (!organizationId) return fail("organization_id is required");
|
|
const name = body.name?.trim();
|
|
const iconUrl = body.icon_url === null ? null : body.icon_url?.trim();
|
|
if ((name == null || name.length === 0) && body.icon_url === undefined) {
|
|
return fail("name or icon_url is required");
|
|
}
|
|
|
|
const serviceClient = createServiceClient();
|
|
const { data: member, error: memberError } = await serviceClient
|
|
.from("organization_members")
|
|
.select("role")
|
|
.eq("organization_id", organizationId)
|
|
.eq("user_id", user.id)
|
|
.maybeSingle();
|
|
|
|
if (memberError) return fail(memberError.message, 400);
|
|
if (!member || !["owner", "admin"].includes(member.role)) {
|
|
return fail("forbidden", 403);
|
|
}
|
|
|
|
const patch: {
|
|
name?: string;
|
|
slug?: string;
|
|
icon_url?: string | null;
|
|
} = {};
|
|
|
|
if (name != null && name.length > 0) {
|
|
const slug = slugify((body.slug ?? "").trim() || name);
|
|
if (!slug) return fail("slug is invalid");
|
|
patch.name = name;
|
|
patch.slug = slug;
|
|
}
|
|
|
|
if (body.icon_url !== undefined) {
|
|
patch.icon_url = iconUrl && iconUrl.length > 0 ? iconUrl : null;
|
|
}
|
|
|
|
const { data: organization, error: updateError } = await serviceClient
|
|
.from("organizations")
|
|
.update(patch)
|
|
.eq("id", organizationId)
|
|
.select("id, name, slug, icon_url, owner_user_id, created_at")
|
|
.single();
|
|
|
|
if (updateError) {
|
|
if (updateError.code === "23505") return fail("slug is already taken", 409);
|
|
return fail(updateError.message, 400);
|
|
}
|
|
|
|
return json({ organization });
|
|
});
|