From 8907f8fa95858c19f7b00b09d75453ba7bb36611 Mon Sep 17 00:00:00 2001
From: Lizandro Guarnizo <77708265+lizandrogd@users.noreply.github.com>
Date: Mon, 16 Mar 2026 20:14:22 -0500
Subject: [PATCH] up
---
api/lab/descargar_orden.php | 68 +++++++++++++++++++++++++++++++++++++
lab_domicilios.php | 2 +-
lab_formulario_builder.php | 5 ++-
3 files changed, 71 insertions(+), 4 deletions(-)
create mode 100644 api/lab/descargar_orden.php
diff --git a/api/lab/descargar_orden.php b/api/lab/descargar_orden.php
new file mode 100644
index 0000000..851cb4e
--- /dev/null
+++ b/api/lab/descargar_orden.php
@@ -0,0 +1,68 @@
+ 'Archivo inválido']);
+ exit;
+}
+
+// Solo archivos con prefijo de orden (seguridad adicional)
+if (!preg_match('/^orden_[a-zA-Z0-9_]+\.[a-zA-Z0-9]+$/', $filename)) {
+ http_response_code(403);
+ echo json_encode(['error' => 'Acceso denegado']);
+ exit;
+}
+
+$path = realpath(__DIR__ . '/../../uploads/media/' . $filename);
+$base = realpath(__DIR__ . '/../../uploads/media');
+
+// Verificar que el archivo esté dentro del directorio permitido
+if (!$path || !$base || strpos($path, $base) !== 0 || !is_file($path)) {
+ http_response_code(404);
+ echo json_encode(['error' => 'Archivo no encontrado']);
+ exit;
+}
+
+// Detectar MIME real
+$finfo = finfo_open(FILEINFO_MIME_TYPE);
+$mime = finfo_file($finfo, $path);
+finfo_close($finfo);
+
+// Mapa de extensiones como fallback
+$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
+$mimeMap = [
+ 'pdf' => 'application/pdf',
+ 'doc' => 'application/msword',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'jpg' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'gif' => 'image/gif',
+ 'webp' => 'image/webp',
+];
+
+if (!$mime || $mime === 'application/octet-stream') {
+ $mime = $mimeMap[$ext] ?? 'application/octet-stream';
+}
+
+// Tipos que el navegador puede mostrar inline
+$inlineTypes = ['application/pdf', 'image/jpeg', 'image/png', 'image/gif', 'image/webp'];
+$disposition = in_array($mime, $inlineTypes) ? 'inline' : 'attachment';
+
+header('Content-Type: ' . $mime);
+header('Content-Disposition: ' . $disposition . '; filename="' . rawurlencode($filename) . '"');
+header('Content-Length: ' . filesize($path));
+header('Cache-Control: private, max-age=3600');
+header('X-Content-Type-Options: nosniff');
+
+readfile($path);
+exit;
diff --git a/lab_domicilios.php b/lab_domicilios.php
index 26ae622..ce8cfa5 100644
--- a/lab_domicilios.php
+++ b/lab_domicilios.php
@@ -580,7 +580,7 @@ async function verDomicilio(id) {
Ver ficha orden #${dom.orden_id}
`;
if (lf) return `
-
Abrir / Descargar archivo
diff --git a/lab_formulario_builder.php b/lab_formulario_builder.php
index a872608..43624f4 100644
--- a/lab_formulario_builder.php
+++ b/lab_formulario_builder.php
@@ -936,13 +936,12 @@ async function cargarFormulario(id) {
$('tb-categoria').value = f.categoria;
$('tb-firma').checked = !!f.permite_firma;
$('tb-firma-req').checked = !!f.requiere_firma;
- const _firmaCampo = (_campos || []).find(c => c.tipo === 'firma');
+ _campos = f.esquema_decoded || [];
+ const _firmaCampo = _campos.find(c => c.tipo === 'firma');
const _fModos = _firmaCampo?.modos || ['canvas','foto'];
$('tb-firma-canvas').checked = _fModos.includes('canvas');
$('tb-firma-foto').checked = _fModos.includes('foto');
- _campos = f.esquema_decoded || [];
-
// Campos doc
const tieneOverride = !!(f.doc_encabezado || f.doc_logo_base64 || f.doc_color);
$('tb-usar-global').checked = !tieneOverride;