feat: WebDAV Echtzeit-Sync bei Datei/Ordner erstellen und löschen
This commit is contained in:
@@ -10,6 +10,42 @@ const UPLOAD_DIR = process.env.UPLOAD_DIR || '/data/uploads';
|
|||||||
if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true });
|
if (!fs.existsSync(UPLOAD_DIR)) fs.mkdirSync(UPLOAD_DIR, { recursive: true });
|
||||||
const webdav = require('./webdav');
|
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 getSetting = key => db.prepare('SELECT value FROM admin_settings WHERE key=?').get(key)?.value;
|
||||||
|
|
||||||
const diskStorage = multer.diskStorage({
|
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' });
|
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);
|
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) => {
|
router.delete('/folders/:id', authenticate, (req, res) => {
|
||||||
@@ -111,6 +151,9 @@ router.delete('/folders/:id', authenticate, (req, res) => {
|
|||||||
// Delete all files inside
|
// Delete all files inside
|
||||||
const files = db.prepare('SELECT * FROM files WHERE folder_id=? AND user_id=?').all(folder.id, req.user.id);
|
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 {} }
|
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 files WHERE folder_id=? AND user_id=?').run(folder.id, req.user.id);
|
||||||
db.prepare('DELETE FROM folders WHERE id=?').run(folder.id);
|
db.prepare('DELETE FROM folders WHERE id=?').run(folder.id);
|
||||||
res.json({ success: true });
|
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);
|
.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);
|
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
|
// WebDAV: Datei asynchron spiegeln
|
||||||
const cfg = webdav.getConfig();
|
const _davPath = davFileUrl(getUserName(uid), folderId, req.file.originalname);
|
||||||
if (cfg.enabled) {
|
if (_davPath) {
|
||||||
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}`;
|
|
||||||
fs.readFile(path.join(UPLOAD_DIR, req.file.filename), (err, buf) => {
|
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) => {
|
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);
|
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' });
|
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 {}
|
try { fs.unlinkSync(path.join(UPLOAD_DIR, file.filename)); } catch {}
|
||||||
db.prepare('DELETE FROM files WHERE id=?').run(file.id);
|
db.prepare('DELETE FROM files WHERE id=?').run(file.id);
|
||||||
res.json({ success: true });
|
res.json({ success: true });
|
||||||
|
|||||||
Reference in New Issue
Block a user