feat: Synology WebDAV Integration - Admin-Einstellungen + Datei-Spiegelung

This commit is contained in:
2026-06-14 00:19:00 +02:00
parent d29c3b5530
commit d564323c00
4 changed files with 340 additions and 2 deletions

View File

@@ -170,4 +170,60 @@ router.put('/users/:id/hidden', authenticate, requireAdmin, (req, res) => {
res.json({ hidden: newHidden });
});
// ── WebDAV / Synology NAS Einstellungen ───────────────────────────────────
router.get('/webdav', authenticate, requireAdmin, (req, res) => {
const get = k => db.prepare('SELECT value FROM admin_settings WHERE key=?').get(k)?.value || '';
res.json({
url: get('webdav_url'),
user: get('webdav_user'),
password: get('webdav_password'),
basePath: get('webdav_base_path') || '/dickendock',
enabled: get('webdav_enabled') === '1',
});
});
router.put('/webdav', authenticate, requireAdmin, (req, res) => {
const { url, user, password, basePath, enabled } = req.body;
const set = (k, v) => db.prepare('INSERT OR REPLACE INTO admin_settings (key,value) VALUES (?,?)').run(k, v || '');
set('webdav_url', url);
set('webdav_user', user);
set('webdav_password', password);
set('webdav_base_path', basePath || '/dickendock');
set('webdav_enabled', enabled ? '1' : '0');
res.json({ ok: true });
});
router.post('/webdav/test', authenticate, requireAdmin, async (req, res) => {
// Temporär die gesendeten Werte zum Testen nutzen (noch nicht gespeichert)
const { url, user, password, basePath } = req.body;
try {
const https = require('https');
const http = require('http');
const base = new URL(url);
const testPath = (base.pathname.replace(/\/$/, '') + (basePath || '/dickendock')).replace(/\/+/g, '/');
const mod = base.protocol === 'https:' ? https : http;
const auth = 'Basic ' + Buffer.from(`${user}:${password}`).toString('base64');
await new Promise((resolve, reject) => {
const req2 = mod.request({
hostname: base.hostname,
port: base.port || (base.protocol === 'https:' ? 443 : 80),
path: testPath,
method: 'PROPFIND',
headers: { 'Authorization': auth, 'Depth': '0', 'Content-Type': 'application/xml' },
rejectUnauthorized: false,
timeout: 8000,
}, r => { r.resume(); r.statusCode < 400 || r.statusCode === 404 ? resolve(r.statusCode) : reject(new Error(`HTTP ${r.statusCode}`)); });
req2.on('error', reject);
req2.on('timeout', () => { req2.destroy(); reject(new Error('Timeout')); });
req2.write('<?xml version="1.0"?><propfind xmlns="DAV:"><prop><displayname/></prop></propfind>');
req2.end();
});
res.json({ ok: true });
} catch(e) {
res.status(502).json({ error: e.message });
}
});
module.exports = router;