|
|
61c99ce5c0
|
✨ 添加登录验证码功能 - 增强系统安全性
## 新增功能
- 密码输错2次后自动显示验证码
- 4位数字验证码,点击可刷新
- 验证码有效期5分钟
- 基于IP和用户名双重防护
- 前台和后台登录均支持
## 后端改动
- 新增验证码生成API: GET /api/captcha
- 修改登录API支持验证码验证
- 添加session管理验证码
- 增强RateLimiter防爆破机制
## 前端改动
- 登录表单添加验证码输入框(条件显示)
- 验证码图片展示和刷新功能
- 自动触发验证码显示逻辑
## 依赖更新
- 新增: svg-captcha (验证码生成)
- 新增: express-session (session管理)
## 文档
- CAPTCHA_FEATURE.md - 详细功能文档
- CAPTCHA_README.md - 快速开始指南
- test_captcha.sh - 自动化测试脚本
- 更新说明_验证码功能.txt - 中文说明
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-21 16:32:32 +00:00 |
|
|
|
7d1cb7b506
|
🐛 修复文件夹分享bug - 只显示第一个文件的问题
问题:
- 分享文件夹时,分享链接只显示文件夹内第一个文件
- 原因:前端无论文件还是文件夹都使用share_type='file'
- 后端对非file类型的分享路径处理不正确
修复方案:
1. 前端修改(frontend/app.js):
- shareFileForm添加isDirectory字段标记是否为文件夹
- openShareFileModal设置isDirectory值
- createShareFile根据isDirectory设置正确的share_type
* 文件: share_type='file'
* 文件夹: share_type='directory'
2. 后端修改(backend/database.js):
- 修复ShareDB.create中的sharePath逻辑
- file类型:使用file_path(单文件路径)
- directory类型:使用file_path(文件夹路径)
- all类型:使用'/'(根目录)
测试:
- 分享单个文件:正常显示单个文件
- 分享文件夹:正常显示文件夹内所有文件
- 分享所有文件:正常显示根目录所有文件
|
2025-11-18 17:58:31 +08:00 |
|
|
|
746539a067
|
🔒 修复CORS逻辑 - 正确处理同源请求
问题:
- 第一次修复过于严格,拒绝了所有无Origin头的请求
- 导致浏览器的同源请求被拒绝,网站完全无法使用
修复方案:
- 允许无Origin头的请求(同源请求不触发CORS)
- 严格验证带Origin头的跨域请求(必须在白名单中)
- 拒绝所有未授权的跨域请求
文件修改:
- backend/server.js: 修正CORS中间件逻辑(第48-63行)
测试:
- 同源请求正常工作
- 恶意跨域请求被拒绝
- API返回正确的状态码(不再是500错误)
|
2025-11-18 17:08:22 +08:00 |
|
|
|
e026c13fd3
|
🔒 修复CORS严重安全漏洞 & 增强Nginx安全配置
## 关键修复
### 1. 修复backend/server.js的CORS漏洞 ⚠️ CRITICAL
**问题**: 原代码 `if (!origin || allowedOrigins.includes(origin))`
会允许所有没有Origin头的请求通过,导致恶意请求绕过CORS保护
**修复**: 严格白名单模式
```javascript
// 只允许白名单中的域名
if (origin && allowedOrigins.includes(origin)) {
callback(null, true);
} else {
// 拒绝所有其他请求
callback(new Error('CORS策略不允许来自该来源的访问'));
}
```
**影响**:
- ✅ 阻止所有恶意域名的跨域访问
- ✅ 保护JWT token不被窃取
- ✅ 从63.6%预计提升到90%+安全评分
### 2. 增强install.sh中的Nginx安全配置
在所有三个nginx配置函数中添加了完整的安全规则:
- `configure_nginx_http_first()` - 初始HTTP配置
- `configure_nginx_http()` - 纯HTTP模式
- `configure_nginx_https()` - HTTPS模式
**新增安全配置**:
```nginx
# 安全响应头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # HTTPS专用
# 隐藏Nginx版本
server_tokens off;
# 禁止访问隐藏文件 (.git, .env等)
location ~ /\. {
deny all;
return 404;
}
# 禁止访问敏感文件
location ~ \.(env|git|config|key|pem|crt|sql|bak|backup|old|log)$ {
deny all;
return 404;
}
```
**防护效果**:
- ✅ 阻止访问 /.env, /.git/config
- ✅ 阻止访问备份文件 .bak, .sql
- ✅ 防止点击劫持、XSS、MIME嗅探攻击
- ✅ 强制HTTPS(HTTPS环境下)
- ✅ 隐藏服务器信息
## 部署方法
在服务器上执行:
```bash
cd /var/www/wanwanyun
git pull origin master
bash install.sh --repair # 重新生成Nginx配置
# 或者手动
pm2 restart wanwanyun-backend
nginx -t && systemctl reload nginx
```
然后运行安全测试验证:
```bash
node security-test.js
```
预期改进:
- CORS测试: 只有cs.workyai.cn被允许 ✅
- 敏感文件: 全部返回404 ✅
- 安全响应头: 全部检测到 ✅
- 安全评分: 63.6% → 90%+ 🎯
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-18 16:58:19 +08:00 |
|
|
|
32429334ab
|
🔒 重大安全更新:修复CORS、XSS、敏感文件暴露等漏洞
本次更新修复了安全测试中发现的所有严重问题,大幅提升系统安全性。
## 修复的安全问题
### 1. CORS跨域配置漏洞 ⚠️ 严重
**问题**: 默认允许所有域名访问(ALLOWED_ORIGINS=*)
**修复**:
- 默认值改为空数组,生产环境必须明确配置域名白名单
- 未配置时拒绝所有跨域请求(生产环境)
- 开发环境仅允许localhost访问
### 2. XSS跨站脚本攻击 ⚠️ 严重
**问题**: 用户输入未过滤,可注入恶意脚本
**修复**:
- 添加XSS过滤中间件,自动转义所有POST/PUT请求的用户输入
- 过滤 <, >, ', " 等危险字符
- 递归处理嵌套对象和数组
### 3. 缺少安全响应头 ⚠️ 重要
**问题**: 缺少X-Frame-Options等安全响应头
**修复**:
- X-Frame-Options: SAMEORIGIN (防止点击劫持)
- X-Content-Type-Options: nosniff (防止MIME嗅探)
- X-XSS-Protection: 1; mode=block
- Strict-Transport-Security (HTTPS环境)
- Content-Security-Policy (内容安全策略)
- 隐藏X-Powered-By和Server版本信息
### 4. 敏感文件暴露风险 ⚠️ 严重
**问题**: .env、.git等敏感文件可能被访问
**修复**:
- Nginx配置禁止访问以.开头的隐藏文件
- 禁止访问.env、.git、.config、.key、.pem等敏感文件
- 更新.gitignore,防止敏感文件提交到代码仓库
- 添加证书、密钥等文件类型到忽略列表
## 代码改动
### backend/server.js
- 修改CORS默认配置,移除危险的 * 通配符
- 添加安全响应头中间件
- 添加XSS过滤中间件(sanitizeInput函数)
- 生产环境强制检查ALLOWED_ORIGINS配置
### nginx/nginx.conf
- 添加安全响应头配置
- 禁止访问隐藏文件和敏感文件的location规则
- 隐藏Nginx版本号(server_tokens off)
### .gitignore
- 添加敏感配置文件保护(.env.local, config.json等)
- 添加证书和密钥文件类型(.key, .pem, .crt等)
### deploy.sh
- 修改默认配置,移除ALLOWED_ORIGINS=*
- 添加安全警告提示
## 部署说明
⚠️ **重要**: 更新后必须配置ALLOWED_ORIGINS环境变量!
### 手动部署
编辑 `backend/.env` 文件:
```bash
ALLOWED_ORIGINS=https://cs.workyai.cn
NODE_ENV=production
```
### 使用install.sh部署
脚本会自动根据域名配置ALLOWED_ORIGINS
## 测试结果
修复前安全评分: 57.6% (14个安全问题)
修复后预期评分: 90%+ (预计解决12+个问题)
## 兼容性
- ✅ 向后兼容,不影响现有功能
- ✅ 开发环境自动允许localhost访问
- ⚠️ 生产环境必须配置ALLOWED_ORIGINS(否则无法访问)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-18 16:29:44 +08:00 |
|
WanWanYun
|
0bb7bd5219
|
fix: 修复文件夹详情功能 + 添加文件夹分享
修复内容:
1. 【文件夹详情无反应】
- 问题: folder-info API中变量名冲突
- 原因: API参数名'path'与Node.js的'path'模块冲突
- 具体: 第1193行 `const itemPath = path.join(dirPath, item.name)`
这里的path被当作API参数(字符串)而不是模块
- 修复:
* API参数改为 `const { path: dirPath, folderName }`
* 使用dirPath替代path
* countFiles函数参数改为countDirPath避免混淆
- 效果: 查看详情功能现在正常工作
新功能:
2. 【文件夹分享】
- 移除分享功能的文件限制
- 右键菜单"分享"选项对文件和文件夹都显示
- 文件夹分享后可访问该文件夹下所有文件
- 与现有分享API完全兼容(share_type支持file和all)
技术细节:
- backend/server.js:
* 第1138行: path参数改为dirPath
* 第1186行: countFiles函数参数改为countDirPath
* 第1193行: 使用path.join正确引用模块
- frontend/app.html:
* 移除 `v-if="!contextMenuFile.isDirectory"` 限制
* 文件夹也显示"分享"菜单项
使用方式:
1. 右键文件夹 → "查看详情" → 显示大小、文件数、子文件夹数
2. 右键文件夹 → "分享" → 分享整个文件夹
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-16 00:15:43 +08:00 |
|
WanWanYun
|
f64f86cd78
|
fix: 修复文件夹右键菜单问题 + 新增文件夹详情功能
修复内容:
1. 【文件夹右键菜单无法显示】
- 问题: showFileContextMenu() 中仍有 `if (file.isDirectory) return` 阻止代码
- 原因: 之前的修复脚本替换失败,代码仍在
- 修复: 手动移除这行限制代码
- 效果: 文件夹现在可以正常右键操作(重命名、删除、查看详情)
新功能:
2. 【文件夹详情查看】
后端API (POST /api/files/folder-info):
- 接收参数: path(当前路径), folderName(文件夹名称)
- 计算文件夹总大小(递归统计所有文件)
- 统计文件数量和子文件夹数量
- 返回数据: name, path, size, fileCount, folderCount
- 仅支持本地存储
前端功能:
- 右键菜单新增"查看详情"选项(仅文件夹显示)
- 详情弹窗显示:
* 文件夹名称
* 文件夹路径
* 总大小(格式化显示)
* 文件数量
* 子文件夹数量
- 加载中状态提示
- 错误处理和提示
使用方式:
1. 右键点击任意文件夹
2. 选择"查看详情"
3. 弹窗显示文件夹统计信息
技术改动:
- backend/server.js: +100行 (新增folder-info API)
- frontend/app.html: +40行 (详情弹窗UI + 菜单项)
- frontend/app.js: +30行 (状态 + showFolderInfo方法)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-16 00:07:21 +08:00 |
|
WanWanYun
|
e5c932a351
|
feat: 新增本地存储文件夹管理功能
新功能概述:
- 支持在本地存储模式下创建文件夹
- 支持删除文件夹(递归删除)
- 支持重命名文件夹(已有功能,天然支持)
- 文件夹配额计算正确
后端改动:
1. 新增创建文件夹API (backend/server.js)
- POST /api/files/mkdir
- 参数: path(当前路径), folderName(文件夹名称)
- 安全检查: 禁止特殊字符(/ \ .. :),防止路径遍历攻击
- 仅限本地存储使用
- 创建前检查文件夹是否已存在
2. 改进删除功能 (backend/storage.js)
- LocalStorageClient.delete() 现在支持删除文件夹
- 使用 fs.rmSync(path, { recursive: true }) 递归删除
- 新增 calculateFolderSize() 方法计算文件夹总大小
- 删除文件夹时正确更新配额使用情况
前端改动:
1. 新建文件夹按钮 (frontend/app.html)
- 在"上传文件"按钮旁新增"新建文件夹"按钮
- 仅本地存储模式显示
2. 新建文件夹弹窗 (frontend/app.html)
- 简洁的创建表单
- 支持回车键快速创建
- 使用优化的弹窗关闭逻辑(防止拖动选择文本时误关闭)
3. 前端API调用 (frontend/app.js)
- 新增 createFolderForm 状态
- 新增 createFolder() 方法
- 前端参数验证
- 创建成功后自动刷新文件列表
4. 右键菜单优化 (frontend/app.html)
- 文件夹不显示"下载"按钮(文件夹暂不支持打包下载)
- 文件夹不显示"分享"按钮(分享单个文件夹暂不支持)
- 文件夹支持"重命名"和"删除"操作
安全性:
- 文件夹名称严格验证,禁止包含 / \ .. : 等特殊字符
- 路径安全检查,防止目录遍历攻击
- 仅限本地存储模式使用(SFTP存储使用上传工具管理)
配额管理:
- 空文件夹不占用配额
- 删除文件夹时正确释放配额(计算所有子文件大小)
- 删除非空文件夹会递归删除所有内容
使用方式:
1. 登录后切换到本地存储模式
2. 点击"新建文件夹"按钮
3. 输入文件夹名称,点击创建
4. 双击文件夹进入,支持多级目录
5. 右键文件夹可重命名或删除
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-15 23:46:20 +08:00 |
|
|
|
a41a29d581
|
fix: 分享详情页显示到期时间
问题:
- 分享列表中显示的到期时间正确
- 但点进分享详情页时,到期时间只显示"永久有效"
原因:
- /api/share/:code/verify 接口返回的 share 对象中缺少 expires_at 字段
- 前端 shareInfo.expires_at 为 undefined,导致始终显示"永久有效"
修复:
- 在 server.js:1650 添加 expires_at 到响应数据中
- 现在分享详情页能正确显示到期时间
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 20:59:48 +08:00 |
|
|
|
d99568e418
|
fix: 修复前端所有页面的文字溢出问题
修复内容:
1. 文件列表 - 列表视图文件名溢出控制
2. 用户列表 - 用户名和邮箱溢出控制
3. 分享列表 - 文件路径和分享链接溢出控制
所有长文本现在都会正确显示省略号,不会导致UI布局异常
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 19:47:36 +08:00 |
|
|
|
8cda4c1a0b
|
fix: 修复时区问题 - 使用本地时区存储和比较时间
## 问题
- 之前使用UTC时间存储expires_at
- 前端解析时当成本地时间,导致显示时间差8小时
- 例如: 数据库存 08:37 (UTC),前端显示 08:37 (本地),实际应该显示 16:37
## 修复
1. database.js create方法: 使用本地时区格式化时间
- 使用 getFullYear/getMonth/getDate 等获取本地时间
- 格式化为 YYYY-MM-DD HH:MM:SS (本地时间)
2. database.js findByCode方法: 使用本地时区比较
- 改为 datetime('now', 'localtime')
- 确保与存储的本地时间格式匹配
3. 调试日志也使用本地时区
## 效果
- 创建分享时,expires_at存储的是服务器本地时间
- 前端显示时间与服务器时间一致
- 过期判断使用本地时区,结果正确
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 16:46:26 +08:00 |
|
|
|
d56388dd29
|
fix: 修复分享过期时间格式导致的过滤失败问题
## 问题分析
通过调试日志发现,过期分享仍能访问的根本原因是:
- expires_at 存储格式: `2025-11-14T07:31:31.922Z` (ISO 8601)
- datetime('now') 返回格式: `2025-11-14 08:19:52` (SQLite格式)
- SQLite进行字符串比较时: 'T' (ASCII 84) > ' ' (ASCII 32)
- 导致条件 `expires_at > datetime('now')` 对已过期分享仍返回true
## 修复内容
1. database.js: 修改create方法,将expires_at转换为SQLite datetime格式
- 旧格式: 2025-11-14T07:31:31.922Z
- 新格式: 2025-11-14 07:31:31
2. fix_expires_at_format.js: 数据库修复脚本
- 将已存在的ISO格式时间转换为SQLite格式
- 确保历史数据也能正确过滤
## 部署步骤
```bash
cd /var/www/wanwanyun
git pull
cd backend
node fix_expires_at_format.js # 修复历史数据
pm2 restart wanwanyun-backend # 重启服务
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 16:25:31 +08:00 |
|
|
|
eaf9ad7bb1
|
debug: 添加详细的分享验证调试日志
## 调试内容
为了排查过期分享仍能访问的问题,添加了详细的调试日志:
### 1. database.js - ShareDB.findByCode()
- 记录调用时的参数和SQLite当前时间
- 记录SQL查询结果(是否找到、过期时间、分享类型)
- 便于对比JavaScript时间和SQLite时间
### 2. server.js - /api/share/:code/verify
- 记录请求时间戳、分享码、是否有密码、请求IP
- 记录findByCode的返回结果和过期状态
### 3. server.js - /api/share/:code/list
- 记录请求时间戳、分享码、子路径、密码状态
- 记录findByCode的返回结果和过期状态
## 使用方法
1. 管理员在管理后台开启调试模式
2. 访问分享链接 https://cs.workyai.cn/s/oSrhV9D3
3. 查看后端console日志输出
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 16:09:01 +08:00 |
|
|
|
84e9a19f3e
|
fix: 修复分享到期时间显示的两个问题
问题1: 分享成功提示中到期时间显示为"永久有效"
- 修复: backend/database.js 的create方法添加返回expires_at字段
- 修复: backend/server.js 的API响应中添加expires_at字段
- 现在创建分享后会正确显示设置的到期时间
问题2: share.html分享页面不显示到期时间
- 新增: 在分享信息中添加到期时间显示(frontend/share.html:527-528)
- 新增: 添加formatExpireTime/isExpiringSoon/isExpired方法
- 效果: 访问分享页面时可以看到"到期时间"或"永久有效"
改进:
- 使用颜色区分状态(绿色=永久/正常, 黄色=即将过期, 红色=已过期)
- 友好的时间显示格式(X天后过期/明天过期等)
注意: 关于0.01天显示问题的优化方案已文档化,需要手动修改app.js
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-14 13:54:38 +08:00 |
|
|
|
4879d4891f
|
fix: 修复分享过期时间和防爆破保护覆盖不全的安全问题
问题1 - 分享过期时间未强制校验:
- 在ShareDB.findByCode()中添加过期时间检查
- SQL条件: AND (s.expires_at IS NULL OR s.expires_at > datetime('now'))
- 现在过期的分享链接将返回404,无法访问
问题2 - 分享密码防爆破保护覆盖不全:
- 给/api/share/:code/list添加shareRateLimitMiddleware
- 给/api/share/:code/download-file添加shareRateLimitMiddleware
- 在两个接口的密码验证失败时调用recordFailure
- 在两个接口的密码验证成功时调用recordSuccess
- 防止攻击者绕过/verify接口直接暴力破解
影响:
- 分享过期后将无法访问(安全性提升)
- 所有分享密码验证接口都受到限流保护(10次/10分钟)
- 修复了可绕过防爆破保护的安全漏洞
|
2025-11-14 00:15:15 +08:00 |
|
|
|
f6e88d85e7
|
fix: 修复防爆破保护不生效的问题
问题原因:
- 登录接口缺少recordFailure调用
- 分享密码接口缺少recordFailure和recordSuccess调用
修复内容:
- 在用户不存在时记录失败尝试
- 在密码错误时记录失败尝试
- 在分享密码错误时记录失败尝试
- 在分享密码验证成功时清除失败记录
测试方法:
- 连续5次错误登录后应被封锁30分钟
- 连续10次错误分享密码后应被封锁20分钟
|
2025-11-13 23:20:25 +08:00 |
|
|
|
c439966bc5
|
feat: 添加登录和分享密码防爆破保护
- 新增RateLimiter类实现基于IP和用户名的限流
- 登录接口: 5次失败/15分钟后封锁30分钟
- 分享密码: 10次失败/10分钟后封锁20分钟
- 支持X-Forwarded-For反向代理
- 自动清理过期记录
- 详细的安全日志记录
|
2025-11-13 22:45:22 +08:00 |
|
|
|
c8f3ab5881
|
feat: 修复CORS安全漏洞 + 升级主页设计
🔒 安全修复:
- 修复分享链接HTTP/HTTPS协议识别问题
- 自动配置CORS安全策略(根据部署模式)
- 自动配置Cookie安全设置(HTTPS环境)
- 移除不安全的默认CORS配置
✨ 功能改进:
- install.sh: 升级create_env_file()函数,智能配置CORS
* 域名+HTTPS模式: ALLOWED_ORIGINS=https://domain
* 域名+HTTP模式: ALLOWED_ORIGINS=http://domain
* IP模式: 留空并显示安全警告
- backend/server.js: 添加getProtocol()函数,正确识别HTTPS
- backend/.env.example: 完全重写,添加详细的CORS配置说明
🎨 主页升级:
- frontend/index.html: 全新现代化设计
* 渐变背景+动画效果
* 9大功能特性展示
* 8项技术栈展示
* 完美响应式支持
📝 修改文件:
- backend/server.js (第63-83行, 1255行, 1282行)
- install.sh (第2108-2195行)
- backend/.env.example (完全重写)
- frontend/index.html (完全重写)
🔗 相关问题:
- 修复CORS允许任意域名访问的安全漏洞
- 修复分享链接使用HTTP的问题
- 解决Cookie在HTTP环境下的安全隐患
💡 向后兼容:
- 已部署项目可选择性升级
- 手动添加ALLOWED_ORIGINS配置即可生效
🎉 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-13 21:36:49 +08:00 |
|
|
|
bfa07c53bb
|
fix: 修复shareOwner变量作用域错误
问题:在/api/share/:code/verify接口中,shareOwner在定义前被使用
修复:将shareOwner定义移至使用之前
|
2025-11-13 19:32:43 +08:00 |
|
|
|
7c18e6fea4
|
fix: 修复storage.js中的正则表达式语法错误
问题:
- getFullPath方法中的正则表达式 [\/\] 语法错误
- 导致"Invalid regular expression: missing /"错误
- 影响文件上传和列表功能
修复:
- 将错误的 [\/\] 修正为 [\/\]
- 添加空值处理 relativePath || ''
- 完善路径处理逻辑,支持Linux和Windows环境
🔐 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-13 19:25:46 +08:00 |
|
|
|
2f2f712dae
|
Merge branch 'master' of https://gitee.com/yu-yon/vue-driven-cloud-storage
|
2025-11-13 18:00:34 +08:00 |
|
|
|
04e9ff5b7e
|
fix: 修复两个安全漏洞
1. 修复分享下载接口越权访问漏洞(高危)
- 添加isPathWithinShare函数验证请求路径是否在分享范围内
- 单文件分享只允许下载该文件
- 目录分享只允许下载该目录及子目录的文件
- 防止攻击者通过构造path参数访问分享者的任意文件
- 相关文件:backend/server.js
2. 修复本地存储路径处理问题(中高危)
- 优化getFullPath方法处理绝对路径的逻辑
- 修复Linux环境下path.join处理'/'导致的路径错误
- 将绝对路径转换为相对路径,确保正确拼接用户目录
- 相关文件:backend/storage.js
🔐 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-13 18:00:09 +08:00 |
|
WanWanYun
|
e5ba17329c
|
功能: 添加管理员上传工具检测和上传功能
- 后端: 添加 GET /api/admin/check-upload-tool 检测工具是否存在
- 后端: 添加 POST /api/admin/upload-tool 允许管理员手动上传exe
- 前端: 管理员界面新增上传工具管理卡片
- 前端: 支持检测工具状态、显示文件信息、手动上传
- 验证: 文件必须是.exe格式且大小>20MB
|
2025-11-12 20:45:17 +08:00 |
|
WanWanYun
|
c272724c5c
|
修复: 防止管理员封禁自己的账号
- 在封禁用户API中添加自我封禁检查
- 当管理员尝试封禁自己时返回400错误
- 错误消息: "不能封禁自己的账号"
- 解封自己不受限制(虽然被封禁后无法登录后台操作)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-12 11:38:02 +08:00 |
|
WanWanYun
|
0c55b599ef
|
修复: 非标准端口部署时分享链接未携带端口号的问题
- 添加 generateShareUrl 辅助函数,智能处理端口号
- 支持通过 PUBLIC_PORT 环境变量配置nginx监听端口
- 更新 POST /api/share/create 使用新的URL生成方法
- 更新 GET /api/share/my 使用新的URL生成方法
- 修复IP模式部署时分享链接无法正常访问的问题
|
2025-11-11 23:25:05 +08:00 |
|
|
|
88f2b152f6
|
修复: 分享下载使用分享者当前存储类型而非创建时存储类型
- 问题: 用户切换到本地存储后,旧分享仍使用创建时的SFTP存储类型,导致404错误
- 修复: 在4个位置将share.storage_type改为shareOwner.current_storage_type
- /api/share/:code/verify (缓存未命中逻辑)
- /api/share/:code/verify (错误回退逻辑)
- /api/share/:code/list (文件列表)
- /api/share/:code/download-file (文件下载)
- 重构: 调整代码顺序,先获取shareOwner再定义storageType
- 日志: 添加"(分享者当前)"标识,便于调试
|
2025-11-11 18:29:20 +08:00 |
|
|
|
230937eba8
|
修复: 添加原密码验证UI并修复中文文件名乱码
## 问题1: 修改密码缺少原密码验证UI
后端已有current_password验证,但前端没有输入框:
- 用户无法输入当前密码
- 导致密码修改功能无法正常使用
修复内容(前端):
1. app.html: 添加当前密码输入框
2. app.js:
- 添加current_password字段到data
- 添加current_password必填验证
- 请求体中包含current_password
- 成功后清空current_password
## 问题2: 中文文件名上传后乱码
原因:
- multer默认将文件名从UTF-8转换为Latin1编码
- req.file.originalname获取到的是乱码
修复内容(后端):
1. 配置multer.diskStorage自定义文件名处理
2. 在filename回调中将Latin1转回UTF-8:
Buffer.from(file.originalname, 'latin1').toString('utf8')
3. 在上传路由中同样转换originalname
4. 临时文件名使用时间戳+随机数+原始文件名避免冲突
影响范围:
- 所有文件上传操作
- 中文、日文、韩文等非ASCII文件名
测试建议:
- 上传中文文件名文件(如测试文档.pdf)
- 上传emoji文件名
- 修改密码功能完整流程测试
|
2025-11-11 16:09:49 +08:00 |
|
|
|
9eade3e3e6
|
性能: 优化磁盘信息获取方式,改为异步执行
问题:
- /api/admin/storage-stats 使用 execSync 同步执行 df/wmic 命令
- 同步执行会阻塞事件循环,影响并发请求处理
- 磁盘信息获取可能需要几百毫秒,影响响应速度
优化内容:
1. 导入 util.promisify 将 exec 转换为异步函数
2. 将路由处理函数改为 async
3. 使用 execAsync 替代 execSync 执行 df 命令
4. 使用 execAsync 替代 execSync 执行 wmic 命令
优势:
- 不阻塞事件循环,提升并发性能
- 管理员查看存储统计时不影响其他用户操作
- 更符合 Node.js 最佳实践
|
2025-11-11 15:24:39 +08:00 |
|
|
|
60bc89ffea
|
修复: 修复文件下载时storage连接资源泄漏问题
问题:
- /api/files/download 路由在文件流下载时没有关闭storage连接
- 当下载大文件或多个并发下载时,会导致SFTP连接积累
- 可能导致连接池耗尽和内存泄漏
修复内容:
1. 添加stream.on('error')事件处理:流错误时关闭storage连接
2. 添加stream.on('close')事件处理:流传输完成时关闭storage连接
3. 增强catch块:在stream创建之前发生错误时关闭storage连接
影响范围:
- /api/files/download(用户文件下载)
- /api/share/:code/download-file(分享文件下载,已有处理逻辑)
测试建议:
- 测试正常文件下载
- 测试下载过程中断(用户取消下载)
- 测试下载不存在的文件(错误处理)
- 测试大文件下载和并发下载
|
2025-11-11 15:06:20 +08:00 |
|
|
|
2a58380b32
|
修复: 优化存储配额检查时机,支持文件覆盖场景
问题描述:
- 上传文件覆盖已有文件时配额检查不准确
- 只检查新文件大小,不考虑旧文件会被删除释放的空间
- 导致误报配额不足,阻止合理的文件覆盖操作
- 空间统计不准确,累积误差
修复内容:
1. 智能配额检查
- 上传前检测目标文件是否存在
- 计算净增量(新文件大小 - 旧文件大小)
- 只在净增量为正时才检查配额
- 覆盖更小文件时不检查配额
2. 准确的空间更新
- 使用净增量更新已使用空间
- 支持负增量(文件变小时减少用量)
- 避免重复计算导致的累积误差
3. 容错处理
- try-catch捕获旧文件不存在的情况
- 确保即使旧文件检查失败也能继续
修复场景示例:
- 配额10GB,已使用9.5GB
- 有一个1GB的旧文件
- 上传0.8GB新文件覆盖
- 修复前: 9.5+0.8=10.3GB > 10GB ❌ 拒绝
- 修复后: 9.5-1+0.8=9.3GB < 10GB ✓ 允许
影响范围: 本地存储文件上传功能
测试建议:
- 测试文件覆盖场景配额检查正确
- 验证空间使用统计准确
- 确认新文件上传场景仍正常工作
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 14:28:46 +08:00 |
|
|
|
c9553ff497
|
修复: 添加分享缓存过期机制(TTL)
问题描述:
- 分享文件缓存使用Map没有过期机制
- 缓存会无限增长,占用内存
- 文件更新或删除后缓存不会自动清除
- 长期运行可能导致内存泄漏
修复内容:
1. 实现TTLCache类
- 支持自定义过期时间(默认1小时)
- 自动检查缓存是否过期
- API完全兼容Map(set/get/has/delete)
2. 添加自动清理机制
- 每10分钟自动清理过期缓存
- 记录清理日志便于监控
- 提供destroy方法停止清理定时器
3. 替换shareFileCache为TTLCache实例
- 设置1小时TTL
- 无需修改现有代码
- 向后兼容所有现有使用
缓存特性:
- get()时自动检查过期
- has()时自动检查过期
- 定期清理避免内存积累
- size()方法获取当前缓存数量
影响范围: 分享文件缓存管理
测试建议:
- 验证分享链接访问后缓存生效
- 验证1小时后缓存自动失效
- 监控日志确认定期清理执行
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 14:19:35 +08:00 |
|
|
|
4a9d31806b
|
修复: 优化文件上传临时文件清理机制
问题描述:
- 文件删除操作可能抛出异常导致程序中断
- 服务器崩溃或重启后残留临时文件无法清理
- 没有自动清理机制
修复内容:
1. 添加safeDeleteFile()安全删除函数
- 使用try-catch捕获删除异常
- 记录删除日志和错误信息
- 不会因删除失败而中断主流程
2. 添加cleanupOldTempFiles()定期清理函数
- 启动时自动清理超过24小时的临时文件
- 防止临时文件堆积占用磁盘空间
- 容错处理避免清理失败影响启动
3. 替换所有fs.unlinkSync为safeDeleteFile
- 文件大小超限时的临时文件清理
- 上传成功后的临时文件清理
- 上传失败时的临时文件清理
影响范围: 文件上传功能
测试建议:
- 上传文件后检查uploads目录临时文件已删除
- 重启服务器验证旧临时文件自动清理
- 模拟删除失败场景验证不影响主流程
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:46:33 +08:00 |
|
|
|
3359cb8c01
|
安全: 为Cookie添加secure和sameSite安全标志
问题描述:
- Cookie仅设置了httpOnly,缺少其他安全标志
- 未启用secure标志,HTTPS环境下cookie可能被劫持
- 缺少sameSite保护,存在CSRF风险
修复内容:
1. 添加secure标志,从环境变量COOKIE_SECURE控制
- HTTPS环境设置为true
- HTTP环境设置为false
2. 添加sameSite: 'lax'防止CSRF攻击
- lax模式在导航时允许cookie
- 阻止第三方站点的POST请求携带cookie
3. 保留httpOnly: true防止XSS攻击
4. 保留maxAge: 7天的过期时间
配置说明:
- .env中设置 COOKIE_SECURE=true (HTTPS环境)
- .env中设置 COOKIE_SECURE=false (HTTP环境)
影响范围: 用户登录认证cookie安全性
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:36:12 +08:00 |
|
|
|
ee555af1a5
|
安全: 优化CORS配置,支持环境变量控制允许的来源
问题描述:
- CORS配置使用origin: true允许所有来源
- 无法限制跨域访问,存在CSRF风险
- 生产环境应该只允许特定域名访问
修复内容:
1. 从环境变量ALLOWED_ORIGINS读取允许的来源列表
2. 支持多个域名配置(逗号分隔)
3. 实现origin验证回调函数
4. 默认允许所有(*),但在生产环境会发出警告
5. 记录并拒绝未授权来源的请求
配置示例:
- 开发环境: ALLOWED_ORIGINS=*
- 生产环境: ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
影响范围: 跨域请求控制
测试建议:
- 配置ALLOWED_ORIGINS后验证只有指定域名可以访问
- 生产环境使用*时应该看到警告日志
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:33:38 +08:00 |
|
|
|
9d510afa60
|
安全: 修复密码修改无需验证旧密码的安全漏洞
问题描述:
- 用户修改密码时不需要验证当前密码
- 攻击者获取session后可直接修改密码
- 违反基本的安全最佳实践
修复内容:
1. 添加current_password必填验证
2. 在更新密码前验证当前密码正确性
3. 验证失败返回401错误
4. 更新API文档注释
API变更:
POST /api/user/change-password
请求参数:
- current_password (新增,必填)
- new_password (已有,必填)
影响范围: 用户密码修改功能
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:23:18 +08:00 |
|
|
|
a953bda39a
|
安全: 修复JWT密钥使用默认值的安全隐患
问题描述:
- JWT_SECRET使用硬编码默认值,存在严重安全风险
- 生产环境token可被轻易伪造
修复内容:
1. 在auth.js中添加JWT密钥安全检查
- 检测默认密钥并发出警告
- 生产环境强制要求设置JWT_SECRET
2. 更新.env.example添加JWT_SECRET配置说明
- 提供密钥生成方法
- 添加其他安全配置项
3. 优化deploy.sh部署脚本
- 自动生成随机JWT密钥
- 检测并替换默认密钥
影响范围: 安全认证模块
测试建议:
- 启动服务验证JWT_SECRET警告正常显示
- 使用deploy.sh部署验证自动生成密钥
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 13:17:57 +08:00 |
|
WanWanYun
|
f097dfd179
|
修复: 将默认上传限制从100MB提升到10GB
- database.js: 修改数据库初始化默认值为10GB (10737418240字节)
- server.js: 修改两处fallback默认值为10GB
- 确保新部署的系统默认支持10GB单文件上传
- 解决用户报告的100MB上传限制问题
版本: v1.2.5
|
2025-11-11 01:57:06 +08:00 |
|
WanWanYun
|
77bb2f7bdc
|
修复: 管理员账号密码无法正确设置的问题
- 在 server.js 开头添加 require('dotenv').config()
- 确保环境变量从 .env 文件正确加载
- 修复了安装时设置的管理员账号密码不生效的问题
版本: v1.2.4
|
2025-11-11 01:50:18 +08:00 |
|
WanWanYun
|
4e9a3a5d26
|
修复: 管理员账号密码从环境变量读取
问题描述:
- 安装时设置的管理员账号密码无效
- 始终使用硬编码的 admin/admin123
修复内容:
- createDefaultAdmin() 函数现在从环境变量读取
- 使用 process.env.ADMIN_USERNAME 和 ADMIN_PASSWORD
- 保留默认值作为后备方案
影响范围:
- backend/database.js: createDefaultAdmin() 函数 (lines 130-159)
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
|
2025-11-11 00:27:54 +08:00 |
|
WanWanYun
|
8c7664a400
|
v1.1.2: 修复依赖安装问题
主要修复:
1. 降级 better-sqlite3: 12.4.1 → 11.8.1
- 兼容 Node.js 18.x
- 解决版本不匹配导致的安装失败
2. 添加编译工具依赖
- APT: build-essential, python3
- YUM/DNF: gcc-c++, make, python3
- Zypper: gcc-c++, make, python3
- 解决原生模块编译失败问题
问题分析:
- better-sqlite3@12+ 要求 Node.js 20+
- 编译原生模块需要 C++ 编译器和 Python
- 旧版本服务器可能缺少编译工具链
解决方案:
- 使用兼容 Node.js 18+ 的 better-sqlite3 版本
- 自动安装所有必需的编译工具
- 确保在所有支持的系统上都能正常编译
|
2025-11-10 23:35:33 +08:00 |
|
WanWanYun
|
0f133962dc
|
Initial commit - 玩玩云文件管理系统 v1.0.0
- 完整的前后端代码
- 支持本地存储和SFTP存储
- 文件分享功能
- 上传工具源代码
- 完整的部署文档
- Nginx配置模板
技术栈:
- 后端: Node.js + Express + SQLite
- 前端: Vue.js 3 + Axios
- 存储: 本地存储 / SFTP远程存储
|
2025-11-10 21:50:16 +08:00 |
|