Add image attachments to feedback form (JPEG/PNG)

- File input in feedback modal (max 3 images, 5 MB each)
- Frontend validation for file count and size
- Backend: multipart/form-data with UploadFile, MIME attachments
- Images attached to feedback email as base64-encoded attachments
- Only JPEG and PNG allowed (validated server-side)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-03-10 13:35:47 +01:00
Ursprung 8a84b7c306
Commit c3680c3673
4 geänderte Dateien mit 69 neuen und 7 gelöschten Zeilen

Datei anzeigen

@@ -197,6 +197,23 @@ const API = {
return this._request('POST', '/feedback', data);
},
async sendFeedbackForm(formData) {
const token = localStorage.getItem('osint_token');
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 60000);
const resp = await fetch(this.baseUrl + '/feedback', {
method: 'POST',
headers: { 'Authorization': token ? 'Bearer ' + token : '' },
body: formData,
signal: controller.signal,
});
clearTimeout(timeout);
if (!resp.ok) {
const err = await resp.json().catch(() => ({}));
throw new Error(err.detail || 'Fehler ' + resp.status);
}
},
// Export
exportIncident(id, format, scope) {
const token = localStorage.getItem('osint_token');

Datei anzeigen

@@ -2168,10 +2168,30 @@ const App = {
return;
}
// Dateien pruefen
const fileInput = document.getElementById('fb-files');
const files = fileInput ? Array.from(fileInput.files) : [];
if (files.length > 3) {
UI.showToast('Maximal 3 Bilder erlaubt.', 'error');
return;
}
for (const f of files) {
if (f.size > 5 * 1024 * 1024) {
UI.showToast('Datei "' + f.name + '" ist groesser als 5 MB.', 'error');
return;
}
}
btn.disabled = true;
btn.textContent = 'Wird gesendet...';
try {
await API.sendFeedback({ category, message });
const formData = new FormData();
formData.append('category', category);
formData.append('message', message);
for (const f of files) {
formData.append('files', f);
}
await API.sendFeedbackForm(formData);
closeModal('modal-feedback');
UI.showToast('Feedback gesendet. Vielen Dank!', 'success');
} catch (err) {