panels-origin/api/document_serve.ts
Cursor Agent 17d9393b9e
fix(padron): vista previa inline, eliminar y reemplazar documentos
- Sirve documentos con Content-Type real e inline por defecto (query disposition)
- DocumentPreviewDialog reconstruye blob con MIME correcto para PDF/imagen
- RPC y DELETE para eliminar documentos del expediente; botón en UI
- Permiso IAM documents.delete; store archiva todas las versiones previas del tipo
- Limpia FileUpload tras subir; is_current robusto en listas vigente/histórico

Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
2026-09-16 21:11:11 +00:00

24 lines
1 KiB
TypeScript

/** Cabeceras HTTP para bytes de documento cifrado ya descifrados. */
export function documentServeHeaders(
doc: { original_name: string; mime?: string },
opts: { inline?: boolean } = {},
): Record<string, string> {
const inline = opts.inline !== false;
const mime = (doc.mime || "").trim() || "application/octet-stream";
const name = doc.original_name || "documento";
const disposition = inline ? "inline" : "attachment";
return {
"Content-Type": mime,
"X-Content-Type-Options": "nosniff",
"Content-Disposition": `${disposition}; filename="${encodeURIComponent(name)}"`,
"Cache-Control": "private, max-age=60",
};
}
export function wantsInlineDocumentDisposition(url: URL | string): boolean {
const u = typeof url === "string" ? new URL(url, "http://local") : url;
const d = (u.searchParams.get("disposition") || u.searchParams.get("inline") || "").toLowerCase();
if (d === "attachment" || d === "download" || d === "0" || d === "false") return false;
if (d === "inline" || d === "1" || d === "true") return true;
return true;
}