Datenbank bereinigt / Gitea-Integration gefixt

Dieser Commit ist enthalten in:
hendrik_gebhardt@gmx.de
2026-01-04 00:24:11 +00:00
committet von Server Deploy
Ursprung 395598c2b0
Commit c21be47428
37 geänderte Dateien mit 30993 neuen und 809 gelöschten Zeilen

Datei anzeigen

@ -10,45 +10,14 @@ const router = express.Router();
const { getDb } = require('../database');
const { authenticateToken, requireAdmin } = require('../middleware/auth');
const logger = require('../utils/logger');
const backup = require('../utils/backup');
/**
* Standard-Upload-Einstellungen
* Standard-Upload-Einstellungen (neues Format mit Dateiendungen)
*/
const DEFAULT_UPLOAD_SETTINGS = {
maxFileSizeMB: 15,
allowedTypes: {
images: {
enabled: true,
types: ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'image/svg+xml']
},
documents: {
enabled: true,
types: ['application/pdf']
},
office: {
enabled: true,
types: [
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation'
]
},
text: {
enabled: true,
types: ['text/plain', 'text/csv', 'text/markdown']
},
archives: {
enabled: true,
types: ['application/zip', 'application/x-rar-compressed', 'application/x-7z-compressed']
},
data: {
enabled: true,
types: ['application/json']
}
}
allowedExtensions: ['pdf', 'docx', 'txt']
};
// Alle Admin-Routes erfordern Authentifizierung und Admin-Rolle
@ -351,6 +320,17 @@ router.get('/upload-settings', (req, res) => {
if (setting) {
const settings = JSON.parse(setting.value);
// Migration: Altes Format (allowedTypes) auf neues Format (allowedExtensions) umstellen
if (settings.allowedTypes && !settings.allowedExtensions) {
// Altes Format erkannt - auf Standard-Einstellungen zurücksetzen
logger.info('Migriere Upload-Einstellungen auf neues Format (allowedExtensions)');
db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)')
.run('upload_settings', JSON.stringify(DEFAULT_UPLOAD_SETTINGS));
res.json(DEFAULT_UPLOAD_SETTINGS);
return;
}
res.json(settings);
} else {
// Standard-Einstellungen zurückgeben und speichern
@ -369,24 +349,36 @@ router.get('/upload-settings', (req, res) => {
*/
router.put('/upload-settings', (req, res) => {
try {
const { maxFileSizeMB, allowedTypes } = req.body;
const { maxFileSizeMB, allowedExtensions } = req.body;
// Validierung
if (typeof maxFileSizeMB !== 'number' || maxFileSizeMB < 1 || maxFileSizeMB > 100) {
return res.status(400).json({ error: 'Maximale Dateigröße muss zwischen 1 und 100 MB liegen' });
}
if (!allowedTypes || typeof allowedTypes !== 'object') {
return res.status(400).json({ error: 'Ungültige Dateityp-Konfiguration' });
if (!Array.isArray(allowedExtensions) || allowedExtensions.length === 0) {
return res.status(400).json({ error: 'Mindestens eine Dateiendung muss erlaubt sein' });
}
const settings = { maxFileSizeMB, allowedTypes };
// Endungen validieren (nur alphanumerisch, 1-10 Zeichen)
const validExtensions = allowedExtensions
.map(ext => ext.toLowerCase().replace(/^\./, '')) // Punkt am Anfang entfernen
.filter(ext => /^[a-z0-9]{1,10}$/.test(ext));
if (validExtensions.length === 0) {
return res.status(400).json({ error: 'Keine gültigen Dateiendungen angegeben' });
}
// Duplikate entfernen
const uniqueExtensions = [...new Set(validExtensions)];
const settings = { maxFileSizeMB, allowedExtensions: uniqueExtensions };
const db = getDb();
db.prepare('INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)')
.run('upload_settings', JSON.stringify(settings));
logger.info(`Admin ${req.user.username} hat Upload-Einstellungen geändert`);
logger.info(`Admin ${req.user.username} hat Upload-Einstellungen geändert: ${uniqueExtensions.join(', ')}`);
res.json(settings);
} catch (error) {
@ -404,7 +396,12 @@ function getUploadSettings() {
const setting = db.prepare('SELECT value FROM settings WHERE key = ?').get('upload_settings');
if (setting) {
return JSON.parse(setting.value);
const settings = JSON.parse(setting.value);
// Bei altem Format oder fehlendem allowedExtensions: Standard verwenden
if (!settings.allowedExtensions || !Array.isArray(settings.allowedExtensions)) {
return DEFAULT_UPLOAD_SETTINGS;
}
return settings;
}
return DEFAULT_UPLOAD_SETTINGS;
} catch (error) {
@ -413,6 +410,42 @@ function getUploadSettings() {
}
}
/**
* POST /api/admin/backup/create - Sofortiges verschlüsseltes Backup erstellen
*/
router.post('/backup/create', (req, res) => {
try {
const backupPath = backup.createBackup();
if (backupPath) {
logger.info(`Admin ${req.user.username} hat manuelles Backup erstellt`);
res.json({
success: true,
message: 'Verschlüsseltes Backup erfolgreich erstellt',
backupPath: backupPath.split('/').pop() // Nur Dateiname zurückgeben
});
} else {
res.status(500).json({ error: 'Backup-Erstellung fehlgeschlagen' });
}
} catch (error) {
logger.error('Backup-Erstellung durch Admin fehlgeschlagen:', error);
res.status(500).json({ error: 'Interner Fehler beim Erstellen des Backups' });
}
});
/**
* GET /api/admin/backup/list - Liste aller verschlüsselten Backups
*/
router.get('/backup/list', (req, res) => {
try {
const backups = backup.listBackups();
res.json(backups);
} catch (error) {
logger.error('Fehler beim Auflisten der Backups:', error);
res.status(500).json({ error: 'Fehler beim Auflisten der Backups' });
}
});
module.exports = router;
module.exports.getUploadSettings = getUploadSettings;
module.exports.DEFAULT_UPLOAD_SETTINGS = DEFAULT_UPLOAD_SETTINGS;