Dateien nach "backend/src/tools/dateien" hochladen

This commit is contained in:
2026-05-28 07:54:26 +02:00
parent eef8ef2042
commit 53b66eaf96

View File

@@ -149,7 +149,8 @@ router.get('/', authenticate, (req, res) => {
const sharedByMe = folderId ? [] : db.prepare(` const sharedByMe = folderId ? [] : db.prepare(`
SELECT DISTINCT f.*, u.username as owner, SELECT DISTINCT f.*, u.username as owner,
GROUP_CONCAT(su.username) as shared_with_names, GROUP_CONCAT(su.username) as shared_with_names,
MIN(s.created_at) as shared_at MIN(s.created_at) as shared_at,
MAX(s.accessed_at) as accessed_at
FROM files f JOIN users u ON u.id=f.user_id FROM files f JOIN users u ON u.id=f.user_id
JOIN file_shares s ON s.file_id=f.id JOIN file_shares s ON s.file_id=f.id
JOIN users su ON su.id=s.shared_with JOIN users su ON su.id=s.shared_with
@@ -193,16 +194,34 @@ router.post('/', authenticate, (req, res) => {
}); });
}); });
router.get('/:id/download', authenticate, (req, res) => { router.get('/:id/download', authenticate, async (req, res) => {
const uid = req.user.id; const uid = req.user.id;
const file = db.prepare('SELECT * FROM files WHERE id=?').get(req.params.id); const file = db.prepare('SELECT * FROM files WHERE id=?').get(req.params.id);
if (!file) return res.status(404).json({ error: 'Nicht gefunden' }); if (!file) return res.status(404).json({ error: 'Nicht gefunden' });
const ok = file.user_id===uid
|| db.prepare('SELECT id FROM file_shares WHERE file_id=? AND shared_with=?').get(file.id, uid) const isOwner = file.user_id === uid;
|| (file.folder_id && isInSharedFolder(file.folder_id, uid)); const share = db.prepare('SELECT * FROM file_shares WHERE file_id=? AND shared_with=?').get(file.id, uid);
if (!ok) return res.status(403).json({ error: 'Kein Zugriff' }); const inSharedDir = file.folder_id && isInSharedFolder(file.folder_id, uid);
if (!isOwner && !share && !inSharedDir) return res.status(403).json({ error: 'Kein Zugriff' });
// Passwortprüfung für Shares (Owner braucht kein Passwort)
if (!isOwner && share?.password_hash) {
const bcrypt = require('bcryptjs');
const pw = req.query.password || req.headers['x-share-password'] || '';
const ok = pw && await bcrypt.compare(pw, share.password_hash);
if (!ok) return res.status(403).json({ error: 'Falsches Passwort', passwordRequired: true });
}
const fp = path.join(UPLOAD_DIR, file.filename); const fp = path.join(UPLOAD_DIR, file.filename);
if (!fs.existsSync(fp)) return res.status(404).json({ error: 'Datei fehlt' }); if (!fs.existsSync(fp)) return res.status(404).json({ error: 'Datei fehlt' });
// Zugriff tracken
if (share && !share.accessed_at) {
db.prepare("UPDATE file_shares SET accessed_at = datetime('now','localtime') WHERE file_id=? AND shared_with=?")
.run(file.id, uid);
}
res.download(fp, file.originalname); res.download(fp, file.originalname);
}); });
@@ -217,16 +236,34 @@ router.delete('/:id', authenticate, (req, res) => {
router.get('/:id/shares', authenticate, (req, res) => { router.get('/:id/shares', 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' });
res.json(db.prepare('SELECT u.id,u.username,s.created_at as shared_at FROM file_shares s JOIN users u ON u.id=s.shared_with WHERE s.file_id=?').all(file.id)); res.json(db.prepare(`
SELECT u.id, u.username, s.created_at as shared_at,
s.accessed_at,
CASE WHEN s.password_hash IS NOT NULL THEN 1 ELSE 0 END as has_password
FROM file_shares s JOIN users u ON u.id=s.shared_with
WHERE s.file_id=?
`).all(file.id));
}); });
router.post('/:id/share', authenticate, (req, res) => { router.post('/:id/share', authenticate, async (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' });
const target = db.prepare('SELECT * FROM users WHERE username=?').get(req.body.username); const target = db.prepare('SELECT * FROM users WHERE username=?').get(req.body.username);
if (!target) return res.status(404).json({ error: 'Benutzer nicht gefunden' }); if (!target) return res.status(404).json({ error: 'Benutzer nicht gefunden' });
if (target.id === req.user.id) return res.status(400).json({ error: 'Kann nicht mit dir selbst teilen' }); if (target.id === req.user.id) return res.status(400).json({ error: 'Kann nicht mit dir selbst teilen' });
db.prepare('INSERT OR IGNORE INTO file_shares (file_id,shared_by,shared_with) VALUES (?,?,?)').run(file.id, req.user.id, target.id); let passwordHash = null;
if (req.body.password) {
const bcrypt = require('bcryptjs');
passwordHash = await bcrypt.hash(req.body.password, 10);
}
const existing = db.prepare('SELECT id FROM file_shares WHERE file_id=? AND shared_with=?').get(file.id, target.id);
if (existing) {
db.prepare('UPDATE file_shares SET password_hash=?, accessed_at=NULL WHERE file_id=? AND shared_with=?')
.run(passwordHash, file.id, target.id);
} else {
db.prepare('INSERT INTO file_shares (file_id,shared_by,shared_with,password_hash) VALUES (?,?,?,?)')
.run(file.id, req.user.id, target.id, passwordHash);
}
res.json({ success: true }); res.json({ success: true });
}); });