Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e8a64d1
Update Footer.vue
marktube Aug 8, 2025
02eac8f
Update [[path]].ts
marktube Aug 13, 2025
8b687df
Update [[path]].ts
marktube Aug 13, 2025
f1448f6
Update [[path]].ts
marktube Aug 13, 2025
fbe139d
roll back
marktube Aug 13, 2025
c0337e1
modify children
marktube Aug 13, 2025
3db842e
add new bg;modify footer;add description in README
marktube Aug 13, 2025
8cf9910
compress bg-cat image
marktube Aug 13, 2025
f711841
fix height in filename
marktube Aug 13, 2025
5ed1d55
revert to visitor stat
marktube Aug 14, 2025
b0b6dd4
Update MediaPreview.vue
marktube Aug 29, 2025
9ea722a
Update index.html
marktube Aug 29, 2025
5243ddd
Update MediaPreview.vue
marktube Aug 29, 2025
f634302
Update MediaPreview.vue
marktube Aug 29, 2025
bda27d4
test hide
marktube Aug 30, 2025
bed0d2e
set showBottom true when loading
marktube Aug 30, 2025
af832e3
show bottom control in next and previous
marktube Aug 30, 2025
9b6926f
optimize mobile controls
marktube Aug 31, 2025
aa42309
Update MediaPreview.vue
marktube Aug 31, 2025
d1ae262
Update App.vue
marktube Sep 3, 2025
47ed26a
Update App.vue
marktube Sep 3, 2025
9958964
Update main.css
marktube Sep 4, 2025
a0a347d
add pic size check to show panorama button
marktube Sep 5, 2025
ec82223
fix user-status-text style in apple safari
marktube Sep 5, 2025
944f005
fix user-status-text in mobile device
marktube Sep 5, 2025
dbb604d
fix height in showContextMenu file name on safari
marktube Sep 5, 2025
8386dd6
Update App.vue
marktube Sep 15, 2025
1821674
Enhance folder icon visuals with gradients and shadows
marktube Dec 15, 2025
4532188
Update App.vue
marktube Dec 15, 2025
12491c7
try fix format
marktube Dec 19, 2025
dc637ef
Replace SVG icon in MediaPreview component-panorama
marktube Jan 29, 2026
29b9dc8
add d1 auth & fix secure bug
marktube Sep 10, 2026
6a1119a
Merge branch 'main' of github.com:marktube/FlareDrive-R2
marktube Sep 10, 2026
2f8f9f0
fix video thumbnails & implement recursive deleting folder
marktube Sep 11, 2026
fc9b0fa
fix vercount
marktube Sep 11, 2026
ac71152
fix video thumbnails
marktube Sep 12, 2026
e9fa82b
modify generateThumbnail()
marktube Sep 12, 2026
05e414b
fix is_admin when register
marktube Sep 12, 2026
e16af06
fix isAdmin when register
marktube Sep 13, 2026
f2a43d2
remove r2 public URL
marktube Sep 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 126 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,127 @@ BUCKET

> 📝 详细配置说明请参考 `登录限制功能配置说明.md` 文件

### 6. 重新部署项目
### 6. 配置 D1 数据库账户体系(可选,推荐)

[#6-配置-d1-数据库账户体系可选推荐](#6-配置-d1-数据库账户体系可选推荐)

默认情况下,账户仍然使用第 3 步中基于环境变量的 `username:password=dir1/,dir2/` 配置方式(无需任何改动即可继续使用)。

增强版额外支持将账户存储在 **Cloudflare D1** 数据库中,优点是:

- ✅ 用户可以**自助修改密码**,无需管理员改环境变量、重新部署
- ✅ 密码使用 PBKDF2-SHA256 加盐哈希存储,不落明文
- ✅ 登录时优先查询 D1,查不到再自动回退到旧版环境变量账户,**文件读写权限层面两种方式可以混用,完全向后兼容**

⚠️ **账户管理权限(管理员)和文件权限是两回事**:环境变量账户不管配置了什么权限(哪怕是 `"*"`),都**不具备**调用 `/api/auth/register`、`/api/auth/unban`、`/api/auth/ban-status` 这些管理接口的能力——这些接口只认 D1 数据库里 `is_admin = 1` 的账户。第一个管理员账户需要直接用 `wrangler d1` 命令写入数据库,见下面 6.4。

#### 6.1 创建 D1 数据库

1. 进入 Cloudflare 控制台 → **Workers & Pages** → **D1 SQL Database**
2. 点击 **Create Database**,输入一个名称(例如 `flaredrive-users`)

#### 6.2 绑定 D1 到项目

1. 进入 Pages 项目设置 → **Settings** → **Functions**
2. 在 **D1 database bindings** 部分点击 **Add binding**
3. **Variable name**:`DB`(必须叫这个名字,代码里写死了这个绑定名)
4. **D1 database**:选择刚创建的数据库

#### 6.3 初始化表结构

在本地使用 Wrangler 执行仓库自带的迁移文件:

```bash
# 首次在本地测试可以不加 --remote,先在本地模拟数据库里建表
wrangler d1 execute flaredrive-users --file=./migrations/0001_create_users.sql

# 确认无误后,对线上(生产)数据库执行:
wrangler d1 execute flaredrive-users --file=./migrations/0001_create_users.sql --remote
```

`flaredrive-users` 替换成你实际的数据库名称。

#### 6.4 创建第一个管理员账户

D1 里还没有任何账户时无法直接调用 `/api/auth/register`(它本身要求调用者已经是管理员)。**第一个管理员账户必须直接用 `wrangler d1` 命令写进数据库**,不再依赖环境变量账户来"引导"——因为数据库里的密码是加盐哈希存的,没法手写一条 SQL 就把明文密码塞进去,仓库自带了一个小脚本帮你算出正确的哈希:

```bash
node scripts/create-admin-sql.js admin "一个强密码" > admin.sql
wrangler d1 execute flaredrive-users --file=./admin.sql --remote
rm admin.sql # 里面包含密码哈希,用完记得删掉
```

- 第二个参数是密码,第三个参数(可选)是权限,默认 `"*"`(全部目录)
- 加 `--readonly` 参数可以创建只读管理员(能管理账户,但不能写文件)
- `flaredrive-users` 换成你实际的数据库名称

登录这个账户之后,就可以用它调用 `/api/auth/register` 创建更多账户了:

```bash
curl -X POST https://你的域名/api/auth/register \
-H "Authorization: Basic $(echo -n 'admin:一个强密码' | base64)" \
-H "Content-Type: application/json" \
-d '{
"username": "alice",
"password": "至少6位的密码",
"permissions": ["personal/", "work/"],
"isReadOnly": false,
"isAdmin": false
}'
```

- `permissions` 只代表文件目录权限,传 `["*"]` 表示能读写所有目录,**不代表管理员**
- `isAdmin` 为 `true` 时才会创建出真正的管理员账户(能调用 register/unban/ban-status),只有调用者自己已经是管理员时才生效,默认为 `false`
- `isReadOnly` 为 `true` 时创建只读账户

**用户名重复时**,接口会返回 `409 Conflict` 和如下结构,方便前端直接判断并提示:

```json
{
"success": false,
"code": "USERNAME_TAKEN",
"message": "用户名 \"alice\" 已存在,请换一个用户名"
}
```

重复判定包含两种情况:D1 数据库里已有同名账户,或环境变量里已配置同名账户(因为登录时优先匹配 D1 账户,同名会导致原有的环境变量账户失效)。

创建成功后,该用户就可以像环境变量账户一样正常登录、上传、下载了,同时还能使用第 6.5 节的接口自助改密码。

#### 6.5 用户自助修改密码

已登录用户可以调用 `/api/auth/change-password` 接口修改自己的密码(仅对 D1 账户生效,环境变量账户请管理员直接改环境变量):

```bash
curl -X POST https://你的域名/api/auth/change-password \
-H "Authorization: Basic $(echo -n 'alice:旧密码' | base64)" \
-H "Content-Type: application/json" \
-d '{ "newPassword": "至少6位的新密码" }'
```

前端登录后,点击右上角用户菜单里的「修改密码」即可打开对话框完成上述操作,无需手动调用接口。

> ⚠️ D1 与环境变量账户可以同名同时存在,此时登录会优先匹配 D1 中的账户。建议不要让两者重名,避免混淆。

### 🔒 安全加固说明

本次改动顺带修复了几个安全问题,升级时请留意:

1. **未鉴权的文件写入(严重)**:`/api/write/items/[[path]].ts` 的分片上传接口(`POST ?uploads` 创建、`POST ?uploadId` 完成)此前完全没有做权限校验,配合已有鉴权的 `PUT` 分片上传步骤,任何人不登录即可写入任意目录。现已补上校验,与 `PUT`/`DELETE` 保持一致。
2. **`/raw/` 文件预览的存储型 XSS**:上传一个 `Content-Type` 为 `text/html`(或 `.svg` 等)的文件后,通过 `/raw/文件路径` 直接打开会在本域名下执行其中的脚本,从而窃取保存在 `localStorage` 里的登录凭据。现已给 `/raw/` 响应统一加上 `X-Content-Type-Options: nosniff` 和 `Content-Security-Policy: sandbox`(彻底禁止脚本执行、表单提交等,不影响图片/视频/音频的正常预览),并对 `text/html`、`image/svg+xml` 等类型额外强制 `Content-Disposition: attachment`。
3. **游客缩略图写入范围过大**:只要配置了 `GUEST` 环境变量(不论允许哪些目录),未登录用户此前都能写入共享的 `_$flaredrive$/thumbnails/` 目录。现在缩略图路径和普通文件一样,按 `GUEST` 配置的具体目录做匹配,需要显式在 `GUEST` 里加上该路径(或 `*`)才允许游客写入。
4. **Basic Auth 凭据被跨站请求利用的风险**:写操作接口此前在 401 响应里带有 `WWW-Authenticate` 头,会导致浏览器弹出原生登录框并缓存凭据,而缓存后的 Basic 凭据会被浏览器自动附加到**任意来源**发起的同域请求上,构成 CSRF 隐患。现已移除该响应头,并为 `PUT`/`POST`/`DELETE` 增加了 `Origin` 同源校验(仅在请求带有 `Origin` 且与当前域名不一致时才拒绝,不影响 curl 等不带 `Origin` 头的合法调用)。
5. **权限校验路径与实际写入路径解码方式不一致**、以及仓库里附带的 `test-permission.html` / `test-login-limit.html` 调试页面此前会被一起部署到线上、且没有任何鉴权:已将权限校验路径改为与实际写入路径一致的解码方式,并移除了这两个调试页面(如果你本地还需要用它们做权限测试,可以从 Git 历史中找回,但不建议再部署到线上)。
6. **D1 账户越权成为管理员(严重)**:`isAdmin` 之前的判断逻辑是 `is_admin 列 || permissions 包含 "*"`。由于 `is_admin` 列此前从来没有任何代码路径会把它设成 1(`/api/auth/register` 一直硬编码 `isAdmin: false`),这个 `||` 分支实际上是 D1 账户唯一能拿到管理员权限的途径——只要给某个账户配置了 `"*"` 目录权限(哪怕它同时被标成 `isReadOnly: true`,本意只是"能看所有目录但不能写"),它就会被当成真正的管理员,能调用 `/api/auth/register`、`/api/auth/unban`、`/api/auth/ban-status` 这些本该只有管理员才能用的接口,创建新账户、封禁/解封用户。现在 `isAdmin` 只看 `is_admin` 这一个独立字段,不再和目录权限挂钩,也**不再允许环境变量账户具备任何账户管理能力**(哪怕配置了 `"*"`)——管理员权限现在完全只属于 D1 里 `is_admin = 1` 的账户,第一个管理员账户需要直接用 `wrangler d1` 命令写入数据库(见「配置 D1 数据库账户体系」6.4 节和仓库自带的 `scripts/create-admin-sql.js`),之后才能用它通过 `/api/auth/register` 的 `isAdmin: true` 字段创建更多管理员。

⚠️ **如果你已经部署过 D1 账户体系,请务必检查**:升级后,任何此前依赖"给账户配置 `*` 权限"来获得管理员能力的 D1 账户,都会**立刻失去**调用上述管理接口的权限,而且**不能再用环境变量账户去重新授予**(环境变量账户现在完全没有管理员能力了)。如果你确实需要某个账户保留管理员能力,直接执行:
```bash
wrangler d1 execute <YOUR_DB_NAME> --command="UPDATE users SET is_admin = 1 WHERE username = '你的账户名'" --remote
```

如果你是从旧版本升级,建议同时检查一下自己的 `GUEST` 环境变量配置是否符合预期(第 3 条的行为变化可能影响到依赖旧行为的部署),并按第 6 条检查是否有账户需要重新授予管理员权限。

### 8. 重新部署项目

完成所有设置后,回到 Pages 控制台,点击「Deployments」页面右上角的「Trigger Redeploy」以重新部署服务。

Expand Down Expand Up @@ -469,3 +589,8 @@ GUEST=public/
- 确认已先复制文件到剪贴板
- 检查用户权限是否允许写操作
- 移动端查看底部是否显示粘贴工具栏

---

+ **当前版本修复了只读用户显示所有目录的bug,只显示权限目录**
+ **文件名高度不够,已修复**
Loading