const express = require('express'); const crypto = require('crypto'); const db = require('../db'); const router = express.Router(); // Create share link router.post('/', (req, res) => { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) return res.status(401).json({ error: 'No token' }); try { const jwt = require('jsonwebtoken'); const decoded = jwt.verify(token, process.env.JWT_SECRET || 'clouddisk-secret-key'); const { fileId, password, expiresIn } = req.body; // Verify file ownership const file = db.query( 'SELECT * FROM files WHERE id = ? AND user_id = ?', [fileId, decoded.userId] ); if (file.length === 0) { return res.status(404).json({ error: 'File not found' }); } // Generate share token const shareToken = crypto.randomBytes(16).toString('hex'); // Calculate expiration const expiresAt = expiresIn ? new Date(Date.now() + expiresIn * 1000).toISOString() : null; const result = db.run( 'INSERT INTO shares (file_id, share_token, password, expires_at) VALUES (?, ?, ?, ?)', [fileId, shareToken, password || null, expiresAt] ); res.json({ success: true, shareToken, shareUrl: `/share/${shareToken}` }); } catch (error) { res.status(500).json({ error: error.message }); } }); // Get share info router.get('/:token', (req, res) => { try { const share = db.query( 'SELECT * FROM shares WHERE share_token = ?', [req.params.token] ); if (share.length === 0) { return res.status(404).json({ error: 'Share not found' }); } // Check expiration if (share[0].expires_at && new Date(share[0].expires_at) < new Date()) { return res.status(410).json({ error: 'Share expired' }); } // Get file info const file = db.query( 'SELECT id, name, type, size FROM files WHERE id = ?', [share[0].file_id] ); // Increment view count db.run( 'UPDATE shares SET view_count = view_count + 1 WHERE id = ?', [share[0].id] ); res.json({ file: file[0], requiresPassword: !!share[0].password, expiresAt: share[0].expires_at, viewCount: share[0].view_count }); } catch (error) { res.status(500).json({ error: error.message }); } }); // Verify share password router.post('/:token/verify', (req, res) => { const { password } = req.body; const share = db.query( 'SELECT * FROM shares WHERE share_token = ?', [req.params.token] ); if (share.length === 0) { return res.status(404).json({ error: 'Share not found' }); } if (share[0].password && share[0].password !== password) { return res.status(401).json({ error: 'Invalid password' }); } res.json({ success: true }); }); // Download shared file router.get('/:token/download', (req, res) => { const share = db.query( 'SELECT * FROM shares WHERE share_token = ?', [req.params.token] ); if (share.length === 0) { return res.status(404).json({ error: 'Share not found' }); } // Check if password protected if (share[0].password) { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'Password required' }); } } const file = db.query( 'SELECT * FROM files WHERE id = ?', [share[0].file_id] ); if (file.length === 0) { return res.status(404).json({ error: 'File not found' }); } res.download(file[0].path, file[0].name); }); module.exports = router;