From 25b658acce5051a825cbe224cab6a55bb5859e1d Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 27 Mar 2026 11:08:52 +0100 Subject: [PATCH] feat(admin): enhance adult verification file handling and localization - Added a new method in AdminService to resolve adult verification file paths, improving file retrieval logic. - Updated the AdminVerificationView to display a message when the verification document is missing. - Localized the missing document message in German, English, and Spanish for better user experience. --- backend/services/adminService.js | 29 +++++++++++++++++-- frontend/src/i18n/locales/de/admin.json | 1 + frontend/src/i18n/locales/en/admin.json | 1 + frontend/src/i18n/locales/es/admin.json | 1 + .../src/views/admin/AdultVerificationView.vue | 19 +++++++++++- 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/backend/services/adminService.js b/backend/services/adminService.js index 0eea9d1..6c2a5f1 100644 --- a/backend/services/adminService.js +++ b/backend/services/adminService.js @@ -39,6 +39,27 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); class AdminService { + resolveAdultVerificationFile(requestData) { + if (!requestData || typeof requestData !== 'object') { + return null; + } + + const candidates = []; + if (requestData.fileName) { + candidates.push(path.join(__dirname, '..', 'images', 'adult-verification', requestData.fileName)); + } + if (requestData.storedFileName && requestData.storedFileName !== requestData.fileName) { + candidates.push(path.join(__dirname, '..', 'images', 'adult-verification', requestData.storedFileName)); + } + if (requestData.filePath) { + candidates.push(path.isAbsolute(requestData.filePath) + ? requestData.filePath + : path.join(__dirname, '..', requestData.filePath)); + } + + return candidates.find((candidate) => candidate && fs.existsSync(candidate)) || null; + } + removeEroticStorageFile(type, hash) { if (!hash) { return; @@ -302,13 +323,15 @@ class AdminService { } catch { verificationRequest = null; } + const resolvedDocumentPath = this.resolveAdultVerificationFile(verificationRequest); return { id: user.hashedId, username: user.username, active: !!user.active, age, adultVerificationStatus: verificationStatus, - adultVerificationRequest: verificationRequest + adultVerificationRequest: verificationRequest, + adultVerificationDocumentAvailable: !!resolvedDocumentPath }; }).filter((row) => row.age !== null && row.age >= 18); @@ -404,8 +427,8 @@ class AdminService { throw new Error('norequest'); } - const filePath = path.join(__dirname, '..', 'images', 'adult-verification', requestData.fileName); - if (!fs.existsSync(filePath)) { + const filePath = this.resolveAdultVerificationFile(requestData); + if (!filePath) { throw new Error('nofile'); } diff --git a/frontend/src/i18n/locales/de/admin.json b/frontend/src/i18n/locales/de/admin.json index 0b79649..c46dd31 100644 --- a/frontend/src/i18n/locales/de/admin.json +++ b/frontend/src/i18n/locales/de/admin.json @@ -45,6 +45,7 @@ "previewTitle": "Nachweis-Vorschau", "closePreview": "Vorschau schließen", "previewUnavailable": "Für diesen Dateityp ist hier keine Vorschau verfügbar.", + "documentMissing": "Die Nachweisdatei wurde auf dem Server nicht gefunden.", "empty": "Keine passenden Anfragen gefunden.", "loadError": "Die Freigaben konnten nicht geladen werden.", "updateError": "Der Status konnte nicht geändert werden.", diff --git a/frontend/src/i18n/locales/en/admin.json b/frontend/src/i18n/locales/en/admin.json index 16d3a64..423f528 100644 --- a/frontend/src/i18n/locales/en/admin.json +++ b/frontend/src/i18n/locales/en/admin.json @@ -45,6 +45,7 @@ "previewTitle": "Proof preview", "closePreview": "Close preview", "previewUnavailable": "No inline preview is available for this file type.", + "documentMissing": "The verification file was not found on the server.", "empty": "No matching requests found.", "loadError": "Could not load approvals.", "updateError": "Could not update the status.", diff --git a/frontend/src/i18n/locales/es/admin.json b/frontend/src/i18n/locales/es/admin.json index 799a077..79313d6 100644 --- a/frontend/src/i18n/locales/es/admin.json +++ b/frontend/src/i18n/locales/es/admin.json @@ -45,6 +45,7 @@ "previewTitle": "Vista previa de la prueba", "closePreview": "Cerrar vista previa", "previewUnavailable": "No hay vista previa integrada para este tipo de archivo.", + "documentMissing": "El archivo de verificación no se encontró en el servidor.", "empty": "No se han encontrado solicitudes.", "loadError": "No se pudieron cargar las aprobaciones.", "updateError": "No se pudo actualizar el estado.", diff --git a/frontend/src/views/admin/AdultVerificationView.vue b/frontend/src/views/admin/AdultVerificationView.vue index 2ad7424..c33e4c0 100644 --- a/frontend/src/views/admin/AdultVerificationView.vue +++ b/frontend/src/views/admin/AdultVerificationView.vue @@ -44,7 +44,15 @@ @@ -149,6 +157,10 @@ export default { } }, async openDocument(row) { + if (!row.adultVerificationDocumentAvailable) { + showApiError(this, null, this.$t('admin.adultVerification.documentMissing')); + return; + } try { const response = await apiClient.get(`/api/admin/users/${row.id}/adult-verification/document`, { responseType: 'blob' @@ -269,6 +281,11 @@ export default { gap: 4px; } +.adult-verification__missing-file { + color: #a94442; + font-size: 0.9rem; +} + .adult-verification__actions .secondary { background: transparent; }