import { getSessionUser, canMutate } from "@/lib/session"; import { redirect } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { getTenantRequestById } from "@/lib/db"; import { OnboardingFlow } from "@/components/onboarding/onboarding-flow"; import { BackLink } from "@/components/ui/back-link"; /** * /dashboard/edit/[id] — re-opens the onboarding wizard with the * fields of a still-pending request pre-filled (Bug 6). On submit, * the wizard PATCHes /api/onboarding/[id] instead of POSTing to * /api/onboarding. * * Hard guards * ----------- * - Logged-in customer owner (or platform user) only — same as the * /dashboard/new page. * - Request must exist, belong to the caller's org, and be in 'pending' * status. Editing approved/provisioning rows would race against the * operator; we redirect such cases back to the dashboard rather than * render an invalid wizard. * * Pre-fill * -------- * The wizard takes a single `editingRequest` prop — when present, it * (a) pre-populates state from those values and (b) targets the PATCH * endpoint on submit. When absent, it behaves exactly as today (POST * to /api/onboarding). * * Note on encrypted secrets * ------------------------- * Per-package secrets are NEVER decrypted server-side and exposed to * the client (would be a clear security regression). When editing, * the wizard opens with empty secret fields and the user re-enters * any they want to change. If they don't touch the package-secrets * UI, the existing encrypted blob in the DB is preserved by the * PATCH endpoint (it only re-encrypts when the wizard sends a * non-empty secrets payload). */ export default async function EditRequestPage({ params, }: { params: Promise<{ id: string; locale: string }>; }) { const { id } = await params; const user = await getSessionUser(); if (!user) redirect("/login"); if (user.isPlatform) redirect("/dashboard"); if (!canMutate(user)) redirect("/dashboard"); const tr = await getTenantRequestById(id); if (!tr) redirect("/dashboard"); if (tr.zitadelOrgId !== user.orgId) redirect("/dashboard"); if (tr.status !== "pending") redirect("/dashboard"); const t = await getTranslations("dashboard"); const tOnboarding = await getTranslations("onboarding"); return (
{tOnboarding("editRequestDescription")}