diff --git a/backend/src/tools/dateien/routes.js b/backend/src/tools/dateien/routes.js index cf263a4..c6f0ef4 100644 --- a/backend/src/tools/dateien/routes.js +++ b/backend/src/tools/dateien/routes.js @@ -10,6 +10,42 @@ const UPLOAD_DIR = process.env.UPLOAD_DIR || '/data/uploads'; if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true }); const webdav = require('./webdav'); +// ── WebDAV Hilfsfunktionen ──────────────────────────────────────────────── +function getFolderPathById(folderId) { + if (!folderId) return ''; + const parts = []; + let cur = folderId; + const seen = new Set(); + while (cur) { + if (seen.has(cur)) break; seen.add(cur); + const fo = db.prepare('SELECT name, parent_id FROM folders WHERE id=?').get(cur); + if (!fo) break; + parts.unshift(fo.name.replace(/[\/]/g, '_')); + cur = fo.parent_id; + } + return parts.join('/'); +} + +function davFileUrl(username, folderId, filename) { + const cfg = webdav.getConfig(); + if (!cfg.enabled) return null; + const base = webdav.userPath(cfg, username); + const folder = getFolderPathById(folderId); + return folder ? `${base}/${folder}/${filename}` : `${base}/${filename}`; +} + +function davFolderUrl(username, folderId) { + const cfg = webdav.getConfig(); + if (!cfg.enabled) return null; + const base = webdav.userPath(cfg, username); + const folder = getFolderPathById(folderId); + return folder ? `${base}/${folder}` : base; +} + +function getUserName(userId) { + return db.prepare('SELECT username FROM users WHERE id=?').get(userId)?.username || String(userId); +} + const getSetting = key => db.prepare('SELECT value FROM admin_settings WHERE key=?').get(key)?.value; const diskStorage = multer.diskStorage({ @@ -102,7 +138,11 @@ router.post('/folders', authenticate, (req, res) => { if (!parent) return res.status(404).json({ error: 'Überordner nicht gefunden' }); } const r = db.prepare('INSERT INTO folders (user_id,name,parent_id) VALUES (?,?,?)').run(req.user.id, name.trim(), parentId); - res.json(enrichFolder(db.prepare('SELECT * FROM folders WHERE id=?').get(r.lastInsertRowid))); + const newFolder = db.prepare('SELECT * FROM folders WHERE id=?').get(r.lastInsertRowid); + // WebDAV: Ordner anlegen + const _davFolderCreate = davFolderUrl(getUserName(req.user.id), newFolder.id); + if (_davFolderCreate) webdav.mkdirp(_davFolderCreate).catch(e => console.warn('[webdav] mkdir:', e.message)); + res.json(enrichFolder(newFolder)); }); router.delete('/folders/:id', authenticate, (req, res) => { @@ -111,6 +151,9 @@ router.delete('/folders/:id', authenticate, (req, res) => { // Delete all files inside const files = db.prepare('SELECT * FROM files WHERE folder_id=? AND user_id=?').all(folder.id, req.user.id); for (const f of files) { try { fs.unlinkSync(path.join(UPLOAD_DIR, f.filename)); } catch {} } + // WebDAV: Ordner löschen (vor DB-Löschung damit Pfad noch auflösbar) + const _davFolderDel = davFolderUrl(getUserName(req.user.id), folder.id); + if (_davFolderDel) webdav.deleteFile(_davFolderDel).catch(e => console.warn('[webdav] rmdir:', e.message)); db.prepare('DELETE FROM files WHERE folder_id=? AND user_id=?').run(folder.id, req.user.id); db.prepare('DELETE FROM folders WHERE id=?').run(folder.id); res.json({ success: true }); @@ -200,32 +243,11 @@ router.post('/', authenticate, (req, res) => { .run(uid, req.file.filename, req.file.originalname, req.file.mimetype||'application/octet-stream', req.file.size, folderId); const newFile = db.prepare('SELECT f.*,u.username as owner FROM files f JOIN users u ON u.id=f.user_id WHERE f.id=?').get(r.lastInsertRowid); - // WebDAV: Datei asynchron spiegeln mit Ordnerstruktur - const cfg = webdav.getConfig(); - if (cfg.enabled) { - const user = db.prepare('SELECT username FROM users WHERE id=?').get(uid); - // Ordnerpfad auflösen - function getFolderPath(fid) { - if (!fid) return ''; - const parts = []; - let cur = fid; - const seen = new Set(); - while (cur) { - if (seen.has(cur)) break; seen.add(cur); - const fo = db.prepare('SELECT name, parent_id FROM folders WHERE id=?').get(cur); - if (!fo) break; - parts.unshift(fo.name.replace(/[/\\]/g, '_')); - cur = fo.parent_id; - } - return parts.join('/'); - } - const folderPath = getFolderPath(folderId); - const userBase = webdav.userPath(cfg, user.username); - const davPath = folderPath - ? `${userBase}/${folderPath}/${req.file.originalname}` - : `${userBase}/${req.file.originalname}`; + // WebDAV: Datei asynchron spiegeln + const _davPath = davFileUrl(getUserName(uid), folderId, req.file.originalname); + if (_davPath) { fs.readFile(path.join(UPLOAD_DIR, req.file.filename), (err, buf) => { - if (!err) webdav.uploadFile(buf, davPath, req.file.mimetype).catch(e => console.error('[webdav upload]', e.message)); + if (!err) webdav.uploadFile(buf, _davPath, req.file.mimetype).catch(e => console.error('[webdav upload]', e.message)); }); } @@ -333,6 +355,9 @@ router.get('/:id/download', authenticate, async (req, res) => { router.delete('/:id', authenticate, (req, res) => { const file = db.prepare('SELECT * FROM files WHERE id=? AND user_id=?').get(req.params.id, req.user.id); if (!file) return res.status(404).json({ error: 'Nicht gefunden' }); + // WebDAV: Datei löschen + const _davFileDel = davFileUrl(getUserName(file.user_id), file.folder_id, file.originalname); + if (_davFileDel) webdav.deleteFile(_davFileDel).catch(e => console.warn('[webdav] delete:', e.message)); try { fs.unlinkSync(path.join(UPLOAD_DIR, file.filename)); } catch {} db.prepare('DELETE FROM files WHERE id=?').run(file.id); res.json({ success: true });