Dateien nach "backend/src/tools/dateien" hochladen
This commit is contained in:
@@ -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 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user