admin / Synapse-Sonar
publicAttack Surface Simulation
Synapse-Sonar / synapse-sonar / app / api / tenant / settings / route.ts
2123 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import { requireTenantContext, HttpError } from "@/lib/auth"; import { assertCan } from "@/lib/rbac"; import { prisma } from "@/lib/prisma"; export const runtime = "nodejs"; /** GET — tenant settings (any member may read). */ export async function GET() { try { const ctx = await requireTenantContext(); assertCan(ctx.role, "user:read"); const tenant = await prisma.tenant.findUnique({ where: { id: ctx.tenantId }, select: { name: true, mfaRequired: true }, }); return NextResponse.json({ name: tenant?.name ?? "", mfaRequired: tenant?.mfaRequired ?? false, }); } catch (err) { return errorResponse(err); } } const SettingsSchema = z .object({ name: z.string().min(1).max(80).optional(), mfaRequired: z.boolean().optional(), }) .refine((v) => v.name !== undefined || v.mfaRequired !== undefined, { message: "Nothing to update", }); /** PATCH — update org name and/or MFA policy (Tenant Admin only). */ export async function PATCH(req: NextRequest) { try { const ctx = await requireTenantContext(); assertCan(ctx.role, "user:manage"); const body = SettingsSchema.parse(await req.json()); const tenant = await prisma.tenant.update({ where: { id: ctx.tenantId }, data: { ...(body.name !== undefined ? { name: body.name } : {}), ...(body.mfaRequired !== undefined ? { mfaRequired: body.mfaRequired } : {}), }, select: { name: true, mfaRequired: true }, }); return NextResponse.json({ ok: true, ...tenant }); } catch (err) { return errorResponse(err); } } function errorResponse(err: unknown) { if (err instanceof HttpError) { return NextResponse.json({ error: err.message }, { status: err.status }); } if (err instanceof z.ZodError) { return NextResponse.json({ error: "Invalid input", details: err.issues }, { status: 422 }); } const status = (err as { status?: number }).status ?? 500; return NextResponse.json({ error: (err as Error).message }, { status }); } |