diff --git a/backend/database.js b/backend/database.js index f711ff4..c77a442 100644 --- a/backend/database.js +++ b/backend/database.js @@ -337,6 +337,7 @@ const ShareDB = { FROM shares s JOIN users u ON s.user_id = u.id WHERE s.share_code = ? + AND (s.expires_at IS NULL OR s.expires_at > datetime('now')) `).get(shareCode); }, diff --git a/backend/server.js b/backend/server.js index b3c5b72..7cac112 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1735,7 +1735,7 @@ app.post('/api/share/:code/verify', shareRateLimitMiddleware, async (req, res) = }); // 获取分享的文件列表(支持本地存储和SFTP) -app.post('/api/share/:code/list', async (req, res) => { +app.post('/api/share/:code/list', shareRateLimitMiddleware, async (req, res) => { const { code } = req.params; const { password, path: subPath } = req.body; @@ -1753,12 +1753,21 @@ app.post('/api/share/:code/list', async (req, res) => { // 验证密码 if (share.share_password && !ShareDB.verifyPassword(password, share.share_password)) { + // 记录密码错误 + if (req.shareRateLimitKey) { + shareLimiter.recordFailure(req.shareRateLimitKey); + } return res.status(401).json({ success: false, message: '密码错误' }); } + // 清除失败记录(密码验证成功或无密码) + if (req.shareRateLimitKey && share.share_password) { + shareLimiter.recordSuccess(req.shareRateLimitKey); + } + // 获取分享者的用户信息 const shareOwner = UserDB.findById(share.user_id); if (!shareOwner) { @@ -1912,7 +1921,7 @@ app.post('/api/share/:code/download', (req, res) => { }); // 分享文件下载(支持本地存储和SFTP,公开API,需要分享码和密码验证) -app.get('/api/share/:code/download-file', async (req, res) => { +app.get('/api/share/:code/download-file', shareRateLimitMiddleware, async (req, res) => { const { code } = req.params; const { path: filePath, password } = req.query; let storage; @@ -1936,11 +1945,20 @@ app.get('/api/share/:code/download-file', async (req, res) => { // 验证密码(如果需要) if (share.share_password) { + // 记录密码错误 + if (req.shareRateLimitKey) { + shareLimiter.recordFailure(req.shareRateLimitKey); + } if (!password || !ShareDB.verifyPassword(password, share.share_password)) { return res.status(401).json({ success: false, message: '密码错误或未提供密码' }); + // 清除失败记录(密码验证成功) + if (req.shareRateLimitKey && share.share_password) { + shareLimiter.recordSuccess(req.shareRateLimitKey); + } + } }