4324d886d8
重构开发者工具检测机制 - 使用多重检测方法
...
修复了控制台在其他页面打开后仍能在本站显示的问题。
核心改进:
1. 新增Console对象toString检测(最有效)
2. 优化debugger暂停时间检测
3. 保留窗口尺寸检测作为补充
4. 综合多种方法,提高检测准确率
5. 页面加载时立即执行检测
6. 持续监控确保实时防护
检测原理:
- console.log会触发对象的toString方法
- 当控制台打开时,这个方法会被调用
- 通过标志位检测到调用,即可判断控制台已打开
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-17 20:33:01 +08:00
69e864bcfb
增强开发者工具检测防护功能
...
修复了用户可以在其他页面先打开F12控制台,然后访问网站时绕过禁用的问题。
主要改进:
- 页面加载时立即检测开发者工具是否已打开
- 新增 debugger 断点检测机制,检测更灵敏
- 检测到开发者工具时显示美观的全屏警告页面
- 防止重复警告显示
- 调试模式下所有保护机制自动禁用
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-17 19:57:02 +08:00
WanWanYun
cb4bf0e8d5
fix: 修复文件夹详情功能点击无反应的问题
...
问题描述:
- 右键文件夹 → 点击"查看详情"
- 菜单关闭但没有任何反应
- 详情弹窗不显示
根本原因:
在 contextMenuAction(action) 的 switch 语句中
**缺少 case 'info': 分支**
代码分析:
```javascript
contextMenuAction(action) {
switch (action) {
case 'preview': ...
case 'download': ...
case 'rename': ...
case 'share': ... // ❌ 直接跳到share,跳过了info
case 'delete': ...
}
}
```
修复方案:
在 rename 和 share 之间添加:
```javascript
case 'info':
this.showFolderInfo(this.contextMenuFile);
break;
```
修复后流程:
1. 右键文件夹 → "查看详情"
2. 触发 contextMenuAction('info')
3. 执行 showFolderInfo(file)
4. 调用后端 API: POST /api/files/folder-info
5. 显示详情弹窗(大小、文件数、子文件夹数)
之前为什么漏掉:
添加showFolderInfo方法时,忘记在contextMenuAction中注册该action
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-16 00:22:40 +08:00
WanWanYun
a9b269af12
fix: 修复更新时无法选择是否保留上传工具的问题
...
问题描述:
- 显示了选择菜单,但read命令直接跳过
- 无法输入选择,直接使用默认值1
- 用户想选择2也无法输入
原因分析:
- update流程中标准输入可能被重定向或被其他命令消耗
- read命令从stdin读取时可能读到空输入
- 导致直接使用默认值
解决方案:
使用 `< /dev/tty` 强制从终端读取:
```bash
read -p "▶ 请选择 [1/2, 默认:1]: " KEEP_UPLOAD_TOOL < /dev/tty
```
工作原理:
- /dev/tty: 当前终端设备
- < /dev/tty: 强制从终端读取输入
- 即使stdin被重定向,仍能从终端获取用户输入
测试建议:
运行 bash install.sh update 时:
1. 显示选择菜单
2. 等待用户输入
3. 输入1: 保留工具
4. 输入2: 重新下载
5. 直接回车: 使用默认值1
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-16 00:21:22 +08:00
WanWanYun
2e0376e7e5
fix: 修复更新脚本选择"不保留上传工具"无法触发重新下载的问题
...
问题描述:
- 更新时选择"2) 删除并重新下载"
- 但实际上只是删除并复制了新的upload-tool目录
- 没有触发后续的build_upload_tool()重新下载
- 导致用户无法获取最新的上传工具
原因分析:
- else分支(选择2)只做了 rm + cp 操作
- 复制的新目录中没有dist/玩玩云上传工具.exe
- 但后续检查逻辑看的是文件是否存在和大小
- 如果目录结构存在,即使文件不存在也不会重新下载
修复方案:
在else分支最后添加:
```bash
# 删除dist目录以触发后续重新下载
rm -rf "${PROJECT_DIR}/upload-tool/dist"
```
修复后逻辑:
1. 选择"1"保留:
- 备份dist目录
- 更新upload-tool脚本文件
- 恢复dist目录
- 跳过后续下载
2. 选择"2"重新下载:
- 删除整个upload-tool
- 复制新的upload-tool
- **删除dist目录** ✅ NEW
- 触发后续build_upload_tool()重新下载
验证:
后续update_install_dependencies后面的检查:
```bash
if [[ ! -f "${PROJECT_DIR}/upload-tool/dist/玩玩云上传工具.exe" ]]; then
build_upload_tool # ✅ 会被触发
fi
```
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-16 00:19:13 +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
e10ff04166
feat: 优化更新流程 - 添加保留上传工具选项
...
问题背景:
- 之前每次更新都会删除并重新下载上传工具(43MB)
- 重新下载耗时长(1-2分钟),且可能因网络问题失败
- 但如果不删除,万一上传工具有更新也无法获取
优化方案:
在更新流程中添加用户选择:
更新上传工具逻辑:
1. 检测是否已存在上传工具可执行文件
2. 验证文件大小(>30MB为有效)
3. 如果存在有效工具,显示选择菜单:
╔════════════════════════════════════════════════════════════╗
║ 上传工具更新选项 ║
╠════════════════════════════════════════════════════════════╣
║ 1) 保留现有上传工具(推荐,节省下载时间) ║
║ 2) 删除并重新下载(如果工具有更新) ║
╚════════════════════════════════════════════════════════════╝
选项1 - 保留现有工具:
- 创建临时目录备份dist/玩玩云上传工具.exe
- 更新upload-tool目录的脚本文件
- 恢复备份的可执行文件
- 优点: 节省1-2分钟下载时间,避免网络问题
选项2 - 重新下载:
- 删除整个upload-tool目录
- 在后续步骤重新下载最新工具
- 适用: 官方发布了新版本上传工具
默认行为:
- 默认选项1(保留),直接回车即可
- 如果现有文件大小异常(<30MB),自动重新下载
- 如果不存在上传工具,直接复制新目录
技术改动:
- install.sh update_pull_latest_code() 函数
- 添加用户交互选择逻辑
- 添加文件大小验证
- 添加备份和恢复逻辑
使用建议:
- 日常更新: 选择"1"保留,节省时间
- 重大版本更新: 选择"2"重新下载,确保最新
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-16 00:11:17 +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
560b90f7f7
fix: 修复文件夹功能的多个严重bug
...
问题修复:
1. 【文件夹无法重命名和删除】
- 原因: showFileContextMenu 函数中 `if (file.isDirectory) return` 阻止了文件夹显示右键菜单
- 修复: 移除这个限制,允许文件夹显示右键菜单
- 效果: 文件夹现在可以右键重命名和删除
2. 【进入文件夹后无法返回上一页】
- 原因: 页面没有路径导航条(面包屑导航)
- 修复: 在文件列表上方添加完整的路径导航组件
- 功能:
* 显示当前路径层级
* 点击路径中的任意层级可快速跳转
* "返回上一级"按钮
* "返回根目录"按钮
- 新增 navigateUp() 方法处理返回上一级
3. 【上传文件到子文件夹路径错误(undefined文件夹)】
- 原因: loadFiles() 调用时未传递 path 参数,导致 currentPath 变为 undefined
- 修复:
* loadFiles 开头添加安全检查: `this.currentPath = path || '/'`
* createFolder 成功后调用 loadFiles 时传递 currentPath
- 效果: 路径不会变成undefined,文件正确上传到当前目录
4. 【优化删除确认提示】
- 旧提示: "只能删除空文件夹"(错误信息)
- 新提示: "⚠️ 警告:文件夹内所有文件将被永久删除!"(准确描述行为)
技术改动:
- frontend/app.html: +15行 (路径导航条UI)
- frontend/app.js: +10行 (navigateUp方法 + 安全检查)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-15 23:59:08 +08:00
WanWanYun
de3b75c536
fix: 修复createFolder方法未正确添加到Vue methods中的问题
...
问题: 点击"新建文件夹"按钮时控制台报错 "createFolder is not a function"
原因: 之前使用正则表达式添加方法时没有成功匹配,导致方法未被添加
修复: 手动在renameFile方法后面正确添加createFolder方法
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-15 23:50:27 +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
WanWanYun
3977e72c9e
fix: 修复弹窗交互问题和拖放上传UI重复显示
...
问题描述:
1. 弹窗点击外部关闭时,选择文本拖动鼠标到窗口外会误触关闭
2. 拖放文件上传的提示UI重复显示了两次
修复内容:
【弹窗交互优化】
- 将所有模态框的 @click 事件改为 @mousedown.self + @mouseup.self 组合
- 新增 handleModalMouseDown 和 handleModalMouseUp 方法
- 只有在同一个overlay元素上按下和释放鼠标时才关闭弹窗
- 解决了选择文本时拖动鼠标导致弹窗意外关闭的问题
- 受影响的弹窗:
* 重命名文件弹窗
* 分享所有文件弹窗
* 分享单个文件弹窗
* 忘记密码弹窗
* 文件审查弹窗
* 编辑存储权限弹窗
【拖放UI修复】
- 删除了重复的拖放上传提示层(原第670-677行)
- 保留文件列表区域内的拖放提示层(第711-718行)
- 现在拖放上传提示只显示一次
技术改进:
- mousedown.self: 只在overlay本身被按下时触发
- mouseup.self: 只在overlay本身被释放时触发
- 记录mousedown的目标,只有目标一致才执行关闭
- 提升了用户体验,避免误操作
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-15 22:32:50 +08:00
WanWanYun
eed2533f29
fix: 修复宝塔面板环境下install.sh安装脚本Nginx重载失败导致脚本闪退的问题
...
问题描述:
- 在宝塔面板环境下运行install.sh时,Nginx重载步骤会因为命令失败导致整个脚本闪退
- 由于脚本使用了 set -e,任何命令返回非0退出码都会导致脚本终止
修复内容:
1. configure_nginx_http_first 函数 (2408-2446行):
- 移除可能失败的 /etc/init.d/bt restart 命令
- 在所有Nginx命令前添加配置测试
- 使用 || true 防止命令失败导致脚本退出
- 优化错误提示,失败时不退出脚本
2. configure_nginx_final 函数 (2504-2538行):
- 同样的修复逻辑应用到Nginx重载环节
- 确保即使Nginx操作失败,脚本也能继续执行后续步骤
技术改进:
- 先测试Nginx配置再reload,避免配置错误导致服务中断
- reload失败时自动尝试重启Nginx
- 所有可能失败的命令都添加了错误处理
- 保留systemctl作为备用方案
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-15 19:31:52 +08:00
14ee0b4301
删除文件 test_rate_limit.sh
2025-11-14 17:28:12 +00:00
1fcf623059
删除文件 test_share_security.sh
2025-11-14 17:28:05 +00: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
f02bcee646
fix: 彻底修复所有表格和列表的文字溢出问题
...
关键修复:
1. 所有表格添加 table-layout: fixed
2. 表格列头添加明确的宽度百分比控制
3. 文件列表 - 修复 display: flex 导致的溢出
- 将 flex 从 td 移到内部 div
- 文件名使用 flex: 1 + min-width: 0
- 所有图标添加 flex-shrink: 0
4. 分享列表 - 移除 max-width,使用列头宽度控制
5. 用户列表 - 移除 max-width,使用列头宽度控制
所有表格现在都能正确处理长文本,不会溢出容器
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-14 20:30:22 +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
f9d0a30d46
fix: 修复移动端分享列表长文件名导致UI溢出问题
...
## 问题
在移动端"我的分享"的列表视图下,长文件名会导致:
- 表格宽度被撑开
- 分享链接等内容溢出到容器外
- 页面布局错乱
## 修复
为分享列表的表格添加文字溢出处理:
1. 文件路径列:
- 限制max-width: 200px
- 超出部分显示省略号(text-overflow: ellipsis)
- 鼠标悬停显示完整路径(title属性)
2. 分享链接列:
- 限制max-width: 250px
- 超出部分显示省略号
- 鼠标悬停显示完整链接
## 其他位置检查
- 大图标视图已有溢出处理(-webkit-line-clamp: 2),无需修改
- 文件列表视图也已有完善的溢出处理
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-14 17:12:15 +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
bce225ec5c
feat: 添加管理员可控的F12调试模式开关
...
## 功能说明
- 管理员登录后可在管理后台页面看到"调试模式"卡片
- 点击开关按钮可启用/禁用F12和开发者工具
- 调试模式状态保存在localStorage,页面刷新后保持
- 同时控制主应用(app.html)和分享页面(share.html)的调试权限
## 技术实现
1. app.js新增debugMode配置和toggleDebugMode方法
2. app.html添加调试模式开关UI,并修改防调试代码支持debugMode控制
3. share.html添加防调试代码,受localStorage中的debugMode控制
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-14 16:04:17 +08:00
024e807f75
fix: 优化时间显示逻辑,支持分钟和小时级别的到期提醒
...
问题: 0.01天(约14分钟)显示为"今天过期",不够精确
原因: 使用Math.ceil向上取整,导致小于1天的时间都显示为1天
修复内容:
1. 改用Math.floor向下取整,更准确反映剩余时间
2. 新增diffMinutes和diffHours变量,支持分钟和小时级别显示
3. 优化判断逻辑:
- 0-59分钟: 显示"X分钟后过期"
- 1-23小时: 显示"X小时后过期"
- 1天: 显示"明天过期"
- 2-7天: 显示"X天后过期"
- 7天以上: 显示具体日期时间
修改文件:
- frontend/app.js: formatExpireTime方法(第1317-1335行)
- frontend/share.html: formatExpireTime方法(第836-854行)
测试示例:
- 0.01天(14分钟) → "14分钟后过期 (2025-11-14 12:27)"
- 0.5天(12小时) → "12小时后过期 (2025-11-15 00:00)"
- 1天 → "明天过期 (2025-11-15 12:13)"
- 7天 → "7天后过期 (2025-11-21 12:13)"
关于过期文件清理:
已分析当前机制,过期分享无法访问但记录不会自动删除。
详细分析和解决方案见《分享过期处理机制分析报告.md》。
当前实现是安全的,自动清理功能可作为后续优化。
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-14 15:22:19 +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
692b495005
feat: 添加分享到期时间显示功能
...
新增功能:
- 在分享列表表格中添加"到期时间"列,清晰显示每个分享的有效期
- 在分享创建成功后显示到期时间信息
- 添加友好的时间格式化显示(永久有效/今天过期/明天过期/X天后过期)
- 使用颜色区分不同状态:
* 绿色: 永久有效
* 蓝色: 正常有效期
* 黄色: 即将过期(3天内)
* 红色: 已过期
技术实现:
- frontend/app.html: 添加到期时间显示UI(表格列+分享结果)
- frontend/app.js: 添加3个辅助方法
* formatExpireTime(): 格式化到期时间显示
* isExpiringSoon(): 判断是否即将过期(3天内)
* isExpired(): 判断是否已过期
改进用户体验:
- 用户可以直观看到分享何时过期
- 即将过期的分享会有醒目的黄色提醒
- 鼠标悬停显示完整的ISO时间戳
- 时间显示本地化,使用中文格式
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-14 12:23:41 +08:00
70b03c3c6b
fix: 修复分享页面文件名过长导致布局溢出的问题
...
修改内容:
1. 单文件显示 (.single-file-name):
- 添加 max-width: 100% 限制最大宽度
- 使用 -webkit-line-clamp: 3 限制最多显示3行
- 超出部分显示省略号 (...)
- 改用 word-break: break-word 更优雅的换行
2. 列表视图文件名:
- 添加 .file-name-container 和 .file-name-text 类
- 使用 overflow: hidden 和 text-overflow: ellipsis
- 单行显示,超出显示省略号
- 设置 min-width: 0 确保flex容器正确缩小
修复效果:
- 文件名再长也不会溢出到界面外
- 单文件视图最多显示3行
- 列表视图单行显示带省略号
- 鼠标悬停在网格视图文件名上会显示完整文件名(title属性)
2025-11-14 09:20:13 +08:00
cd79496fc4
fix: 修复分享页面时间显示问题,正确显示本地时间
...
- 修改 share.html 中的 formatDate 函数
- 与 app.js 保持一致的 UTC 时间处理逻辑
- 使用 toLocaleString 格式化为本地时间
- 修复分享页面显示 13号(UTC) 而不是 14号(CST) 的问题
2025-11-14 01:08:47 +08:00
61344756e9
fix: 修复前端时间显示问题,正确处理UTC时间并转换为本地时间(北京时间)
...
- 修改 formatDate 函数,识别 SQLite 返回的 UTC 时间格式
- 自动将 UTC 时间字符串转换为 ISO 格式并添加 'Z' 标记
- JavaScript Date 对象会自动将 UTC 时间转换为本地时间显示
- 修复之前显示 13号(UTC) 而不是 14号(CST) 的问题
2025-11-14 00:51:39 +08:00
927eab2102
test: 添加分享安全性测试脚本
...
功能:
- 测试分享过期时间检查
- 测试分享密码防爆破保护(list接口)
- 提供手动测试指引
使用方法:
./test_share_security.sh
2025-11-14 00:16:05 +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
53be6dc145
test: 添加防爆破保护测试脚本
...
使用方法:
./test_rate_limit.sh
功能:
- 自动测试登录防爆破保护
- 连续5次错误登录
- 第6次应返回封锁提示
2025-11-13 23:22:11 +08:00
f6e88d85e7
fix: 修复防爆破保护不生效的问题
...
问题原因:
- 登录接口缺少recordFailure调用
- 分享密码接口缺少recordFailure和recordSuccess调用
修复内容:
- 在用户不存在时记录失败尝试
- 在密码错误时记录失败尝试
- 在分享密码错误时记录失败尝试
- 在分享密码验证成功时清除失败记录
测试方法:
- 连续5次错误登录后应被封锁30分钟
- 连续10次错误分享密码后应被封锁20分钟
2025-11-13 23:20:25 +08:00
b7ecfa4dff
docs: 添加 v1.1.0 详细更新文档
2025-11-13 23:14:40 +08:00
ac9f1c7052
chore: 发布 v1.1.0 版本
...
新增功能:
- 登录和分享密码防爆破保护
- 更新脚本自动检测和修复上传工具
- 首页界面优化
安全增强:
- 基于IP和用户名的智能限流
- 支持反向代理场景
- 详细的安全日志
2025-11-13 23:13:24 +08:00
72063c56eb
fix: 修复更新脚本导致上传工具丢失的问题
...
- 在更新流程中添加上传工具完整性检查
- 如果上传工具丢失或文件大小异常,自动重新下载
- 使用已有的build_upload_tool函数从直链下载
- 验证文件大小确保下载完整(>30MB)
2025-11-13 22:49:49 +08:00
c439966bc5
feat: 添加登录和分享密码防爆破保护
...
- 新增RateLimiter类实现基于IP和用户名的限流
- 登录接口: 5次失败/15分钟后封锁30分钟
- 分享密码: 10次失败/10分钟后封锁20分钟
- 支持X-Forwarded-For反向代理
- 自动清理过期记录
- 详细的安全日志记录
2025-11-13 22:45:22 +08:00
32e436c978
refactor(frontend): 更新首页内容 - 版本号V1.0 + 双存储模式说明
...
- 修改版本badge: v1.0生产就绪版本 → 版本号 V1.0
- 更新主描述: 支持SFTP远程连接和服务器本地存储两种模式
- Stats区域优化:
* 移除「100%开源免费」和「Docker一键部署」
* 新增「双模式 - SFTP + 本地存储」
- 功能卡片更新:
* 流式下载 → 灵活下载
* 详细说明三种模式: HTTP直链、SFTP流式、本地存储
- 移除CTA区域的「查看源码」按钮
- 简化Footer: 删除所有导航链接,只保留版权信息
- 响应式优化: 调整stats为单列布局(移动端)
2025-11-13 22:13:50 +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
cc3d0d8494
add: 添加分享路径比较修复脚本
...
修复isPathWithinShare函数中路径前缀斜杠不一致导致的匹配失败问题
2025-11-13 19:49:59 +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
d5fada3a26
feat: 移除Certbot方案,统一使用acme.sh + 添加自动续期配置
...
核心改进:
1. 移除Certbot (方案1)
- 原因:Python依赖冲突(urllib3)难以解决
- 用户已用acme.sh成功申请证书
- acme.sh更轻量、更可靠
2. 优化SSL方案选择菜单
- 新方案1:acme.sh + Let's Encrypt (推荐)
- 新方案2:acme.sh + ZeroSSL
- 新方案3:acme.sh + Buypass
- 新方案4-5:阿里云/腾讯云
- 新方案6-7:手动上传/暂不配置
3. 添加自动续期配置功能
- 新增setup_acme_auto_renew()函数
- 自动检查并启动cron服务
- 验证acme.sh自动续期任务
- 显示续期时间和配置信息
- 提供续期检查命令
4. 自动续期特性:
- ✅ 每天自动检查证书
- ✅ 证书到期前30天自动续期
- ✅ 续期后自动重载Nginx
- ✅ 无需手动干预
5. 用户体验改进:
- 显示详细的续期配置信息
- 提供手动续期命令
- 统一的续期管理方式
- 完成提示中显示续期检查命令
技术细节:
- acme.sh安装时自动创建cron任务
- 兼容cron/crond两种服务名
- 支持systemctl和传统service管理
- 显示预计续期时间(从证书配置文件读取)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 15:24:08 +08:00
WanWanYun
691d4ad075
fix: 处理SSL证书已存在的情况,避免重复申请失败
...
核心问题:
- 当证书已存在时,acme.sh会报错"Domains not changed"并拒绝申请
- Certbot同样会拒绝重复申请已有的证书
- 导致用户重新运行脚本时SSL部署总是失败
解决方案:
1. acme.sh方案:
- 申请失败后检查证书是否已在证书列表中
- 如果已存在,直接使用现有证书进行安装
- 避免不必要的重复申请
2. Certbot方案:
- 申请失败后检查 /etc/letsencrypt/live/${DOMAIN} 目录
- 如果证书文件存在,直接创建软链接到nginx目录
- 保证证书可以正常使用
3. 应用范围:
- deploy_certbot() - Certbot方案
- deploy_acme_letsencrypt() - acme.sh + Let's Encrypt
- deploy_acme_zerossl() - acme.sh + ZeroSSL
- deploy_acme_buypass() - acme.sh + Buypass
优点:
- ✅ 支持重复运行脚本而不报错
- ✅ 充分利用已有的有效证书
- ✅ 减少对CA服务器的请求压力
- ✅ 避免触发速率限制
用户体验改进:
- 显示友好的"检测到证书已存在"提示
- 自动继续安装流程,无需用户干预
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 15:16:22 +08:00
WanWanYun
8b9af536c7
fix: 修复SSL证书部署的两个关键问题
...
问题1:acme.sh证书安装时nginx reload失败
- 错误:nginx.service is not active, cannot reload
- 原因:证书安装时nginx服务未运行
- 解决:
1. 在安装证书前检查并启动nginx服务
2. 移除--reloadcmd参数,改为手动reload
3. 兼容systemctl和直接nginx命令两种方式
4. 兼容宝塔面板的nginx路径
问题2:Certbot安装/运行时urllib3依赖冲突
- 错误:ImportError: cannot import name 'appengine' from 'urllib3.contrib'
- 原因:系统的python3-urllib3版本与certbot不兼容
- 解决:
1. 安装certbot前移除冲突的python3-urllib3包
2. 添加已安装certbot的依赖修复逻辑
3. 应用到apt/yum/dnf等所有包管理器
4. 提供详细的错误提示和修复建议
技术改进:
- acme.sh安装证书更可靠(分离安装和reload步骤)
- Certbot依赖检测更完善(检测并修复依赖冲突)
- 错误处理更友好(提示用户尝试其他方案)
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 15:09:25 +08:00
WanWanYun
ab577931c3
fix: 修改acme.sh证书申请方式为webroot模式
...
问题:
- 使用--nginx参数时,acme.sh报错"Cannot find config file for domain"
- nginx模式需要acme.sh能够识别nginx配置文件格式
解决方案:
- 改用--webroot模式,直接使用前端目录作为验证根目录
- webroot模式更可靠,不依赖nginx配置文件解析
- 应用到所有acme.sh方案:Let's Encrypt、ZeroSSL、Buypass
参数变化:
- 旧:--nginx
- 新:--webroot "${PROJECT_DIR}/frontend"
优点:
1. 不需要解析nginx配置文件
2. 直接利用已经配置好的HTTP服务器
3. 兼容性更好,成功率更高
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 15:00:04 +08:00
WanWanYun
410b85f9e1
fix: 彻底修复acme.sh安装失败问题
...
问题描述:
- acme.sh安装后,~/.acme.sh目录被创建但主脚本文件不存在
- 导致后续证书申请和安装失败,提示"主脚本文件不存在"
修复内容:
1. 改用官方推荐的curl管道安装方式(curl https://get.acme.sh | sh)
2. 增加不完整安装的检测和清理逻辑
3. 检查条件从仅检查目录改为同时检查目录和文件
4. 增强错误诊断信息,显示目录内容帮助排查
5. 应用到所有acme.sh方案:Let's Encrypt、ZeroSSL、Buypass
技术改进:
- 从下载到临时文件改为直接curl管道执行(更可靠)
- 添加email参数避免交互式输入
- 完善失败提示,引导用户选择其他方案
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 14:45:14 +08:00
WanWanYun
4bf0cd4edf
fix: 修复SSL证书部署时的文件检查问题
...
修复内容:
1. 修复HTTPS重定向配置 - 根据端口生成正确的重定向URL
2. 增强acme.sh文件存在性检查 - 在申请和安装证书前都检查文件
3. 应用到所有acme.sh方案 - Let's Encrypt、ZeroSSL、Buypass
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude <noreply@anthropic.com >
2025-11-13 14:36:57 +08:00