From 76f76f3c908199ba5b0cbad72f2dd9ce2c67fb3b Mon Sep 17 00:00:00 2001 From: VPS 4 Deploy Agent Date: Sat, 30 May 2026 17:32:09 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20add=20public=20thumbnail=20endpoint=20wi?= =?UTF-8?q?thout=20auth=20=E2=80=94=20allow=20images=20to=20load=20without?= =?UTF-8?q?=20login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dental-server/routes/images.js | 35 --------------------------------- dental-server/server.js | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/dental-server/routes/images.js b/dental-server/routes/images.js index e26d57e..e15492f 100644 --- a/dental-server/routes/images.js +++ b/dental-server/routes/images.js @@ -467,41 +467,6 @@ router.delete('/:id', async (req, res) => { } }); -// ================================================================ -// GET /api/images/:id/thumbnail — Retorna URL da thumbnail -// (lazy-loaded para não bloquear listagens) -// ================================================================ -router.get('/:id/thumbnail', async (req, res) => { - try { - const image = await db.get('SELECT thumb_filename, filename, client_name, patient_name FROM images WHERE id = $1', [req.params.id]); - if (!image) return res.status(404).json({ error: 'Imagem não encontrada' }); - - const fileToCheck = image.thumb_filename || image.filename; - let url; - - // Tenta URL local primeiro (mais rápido) - const fsSync = require('fs'); - const path = require('path'); - const localPath = path.join(process.env.UPLOAD_DIR || '/app/uploads', fileToCheck); - - if (fsSync.existsSync(localPath)) { - url = `/uploads/${fileToCheck}`; - } else { - // Se não existe localmente, tenta Wasabi - try { - const wasabiUrl = await storage.getImageUrl(fileToCheck, image.client_name, image.patient_name, false); - url = wasabiUrl || `/uploads/${fileToCheck}`; - } catch (e) { - console.error('Erro ao gerar URL Wasabi para thumbnail:', e); - url = `/uploads/${fileToCheck}`; - } - } - res.json({ url }); - } catch (e) { - res.status(500).json({ error: e.message }); - } -}); - // ================================================================ // GET /api/images/:id/file-url — Retorna a URL de visualização // full-res de uma imagem (para o painel Original do modal) diff --git a/dental-server/server.js b/dental-server/server.js index e563cd1..2d8a95f 100644 --- a/dental-server/server.js +++ b/dental-server/server.js @@ -584,6 +584,42 @@ async function checkInstallationMiddleware(req, res, next) { // Aplicar middleware apenas para verificar APIs app.use(checkInstallationMiddleware); +// ================================================================ +// ROTAS PÚBLICAS (SEM AUTENTICAÇÃO) +// ================================================================ + +// Endpoint público para servir thumbnails (sem autenticação) +// Usado pelo frontend para carregar imagens sem bloquear o socket.io +app.get('/api/images/:id/thumbnail', async (req, res) => { + try { + const image = await db.get('SELECT thumb_filename, filename, client_name, patient_name FROM images WHERE id = $1', [req.params.id]); + if (!image) return res.status(404).json({ error: 'Imagem não encontrada' }); + + const fileToCheck = image.thumb_filename || image.filename; + let url; + + const fsSync = require('fs'); + const path = require('path'); + const localPath = path.join(process.env.UPLOAD_DIR || '/app/uploads', fileToCheck); + + if (fsSync.existsSync(localPath)) { + url = `/uploads/${fileToCheck}`; + } else { + // Se não existe localmente, tenta Wasabi + try { + const wasabiUrl = await storage.getImageUrl(fileToCheck, image.client_name, image.patient_name, false); + url = wasabiUrl || `/uploads/${fileToCheck}`; + } catch (e) { + console.error('Erro ao gerar URL Wasabi para thumbnail:', e); + url = `/uploads/${fileToCheck}`; + } + } + res.json({ url }); + } catch (e) { + res.status(500).json({ error: e.message }); + } +}); + // ================================================================ // ROTAS PROTEGIDAS (REQUEREM AUTENTICAÇÃO) // ================================================================