74 lines
2.1 KiB
TypeScript
74 lines
2.1 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { getSessionUser, canMutate } from "@/lib/session";
|
|
import { getTenant } from "@/lib/k8s";
|
|
import { writePackageSecrets } from "@/lib/openbao";
|
|
import { getPackageDef } from "@/lib/packages";
|
|
|
|
export async function POST(
|
|
req: NextRequest,
|
|
{ params }: { params: Promise<{ name: string }> }
|
|
) {
|
|
const user = await getSessionUser();
|
|
if (!user)
|
|
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
|
|
|
if (!canMutate(user)) {
|
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
|
}
|
|
|
|
const { name } = await params;
|
|
const body = await req.json();
|
|
const { packageId, secrets } = body as {
|
|
packageId: string;
|
|
secrets: Record<string, string>;
|
|
};
|
|
|
|
if (!packageId || !secrets || typeof secrets !== "object") {
|
|
return NextResponse.json(
|
|
{ error: "Missing packageId or secrets" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const pkgDef = getPackageDef(packageId);
|
|
if (!pkgDef)
|
|
return NextResponse.json({ error: "Unknown package" }, { status: 400 });
|
|
if (!pkgDef.requiresSecrets)
|
|
return NextResponse.json(
|
|
{ error: "Package does not require secrets" },
|
|
{ status: 400 }
|
|
);
|
|
|
|
const requiredKeys = (pkgDef.secrets || []).map((s) => s.key);
|
|
const missing = requiredKeys.filter((k) => !secrets[k]?.trim());
|
|
if (missing.length > 0) {
|
|
return NextResponse.json(
|
|
{ error: `Missing: ${missing.join(", ")}` },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
try {
|
|
const tenant = await getTenant(name);
|
|
if (!tenant)
|
|
return NextResponse.json({ error: "Not found" }, { status: 404 });
|
|
|
|
if (
|
|
!user.isPlatform &&
|
|
tenant.metadata.labels?.["pieced.ch/zitadel-org-id"] !== user.orgId
|
|
) {
|
|
return NextResponse.json({ error: "Forbidden" }, { status: 403 });
|
|
}
|
|
|
|
// Use tenant-{name} to match the operator's vault path convention
|
|
await writePackageSecrets(`tenant-${name}`, packageId, secrets);
|
|
return NextResponse.json({ ok: true });
|
|
} catch (e: any) {
|
|
console.error("Secret write error:", e.message);
|
|
return NextResponse.json(
|
|
{ error: "Failed to store secrets" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|