storeFile (Allowlist, Magic Bytes, Größenlimits, Dateinamen-Normalisierung, SHA-256, Versionierung über lineageId), FileScanner mit optionalem ClamAV-Hook, Sichtbarkeits-/Scope-Autorisierung, Upload-Route und Umbau der Download-Route von files/[...key] auf files/[documentId]. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
"use server";
|
|
|
|
import { revalidatePath } from "next/cache";
|
|
import { moduleGuard } from "@/server/action-guard";
|
|
import { ctxFromGuard } from "@/server/services/context";
|
|
import { formObject, toActionError, type ActionState } from "@/server/api/action-state";
|
|
import { deleteDocument, updateDocumentMeta } from "@/server/services/documents/access";
|
|
import type { DocumentCategory, DocumentVisibility } from "@prisma/client";
|
|
|
|
const guard = moduleGuard("documents");
|
|
|
|
/** Only revalidate same-app paths passed by our own pages. */
|
|
function safePath(path: string): string {
|
|
return path.startsWith("/") && !path.startsWith("//") ? path.split("?")[0] : "/documents";
|
|
}
|
|
|
|
export async function updateDocumentAction(documentId: string, returnPath: string, _prev: ActionState, fd: FormData): Promise<ActionState> {
|
|
try {
|
|
const ctx = ctxFromGuard(await guard("document:write"));
|
|
const v = formObject(fd, ["title", "category", "visibility"]);
|
|
await updateDocumentMeta(ctx, documentId, {
|
|
title: v.title ?? null,
|
|
category: v.category as DocumentCategory | undefined,
|
|
visibility: v.visibility as DocumentVisibility | undefined,
|
|
});
|
|
} catch (err) {
|
|
return toActionError(err);
|
|
}
|
|
revalidatePath(safePath(returnPath));
|
|
revalidatePath("/documents");
|
|
return { status: "ok" };
|
|
}
|
|
|
|
export async function deleteDocumentAction(documentId: string, returnPath: string): Promise<ActionState> {
|
|
try {
|
|
const ctx = ctxFromGuard(await guard("document:write"));
|
|
await deleteDocument(ctx, documentId);
|
|
} catch (err) {
|
|
return toActionError(err);
|
|
}
|
|
revalidatePath(safePath(returnPath));
|
|
revalidatePath("/documents");
|
|
return { status: "ok" };
|
|
}
|