Skip to content

Commit a27d717

Browse files
authored
Merge branch 'ling-drag0n:main' into main
2 parents eba024c + 55f770a commit a27d717

File tree

611 files changed

+5920
-1164
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

611 files changed

+5920
-1164
lines changed

Api-doc.md

Lines changed: 220 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,13 @@ X-Custom-Auth-Key: <api_key>
295295
```json
296296
{
297297
"content": "要分享的文本内容", // 必填
298-
"remark": "备注信息", // 可选
298+
"title": "文本标题", // 可选,用于在列表和前台展示中区分不同文本
299+
"remark": "备注信息", // 可选,用于管理和搜索
299300
"expires_at": "2023-12-31T23:59:59Z", // 可选,过期时间
300301
"max_views": 100, // 可选,最大查看次数
301302
"password": "访问密码", // 可选
302-
"slug": "custom-slug" // 可选,自定义短链接
303+
"slug": "custom-slug", // 可选,自定义短链接
304+
"is_public": true // 可选,是否公开访问,默认 true;false 时仅管理员和创建者可访问
303305
}
304306
```
305307
- 响应:创建的文本分享信息,包含访问链接
@@ -310,11 +312,13 @@ X-Custom-Auth-Key: <api_key>
310312
"data": {
311313
"id": "123",
312314
"slug": "abc123",
313-
"url": "https://example.com/p/abc123",
315+
"title": "文本标题",
316+
"remark": "备注信息",
314317
"expires_at": "2023-12-31T23:59:59Z",
315318
"max_views": 100,
316-
"views": 0,
317-
"has_password": true
319+
"is_public": true,
320+
"hasPassword": true,
321+
"created_at": "2023-05-01T12:00:00Z"
318322
},
319323
"success": true
320324
}
@@ -324,7 +328,53 @@ X-Custom-Auth-Key: <api_key>
324328

325329
- 描述:获取文本分享内容
326330
- 参数:slug - 文本短链接
327-
- 响应:文本分享内容,如果需要密码则返回密码提示
331+
- 访问控制:
332+
- 当 `is_public = true` 时,任何持有链接的用户都可以访问(仍受过期时间、最大查看次数和密码保护限制)。
333+
- 当 `is_public = false` 时,仅管理员和创建者可以访问;其他用户(包括匿名和其他 API 密钥)将收到“不存在或已被删除”的响应(HTTP 404)。
334+
- 响应:
335+
- 如果文本未设置密码且可访问,将直接返回内容:
336+
```json
337+
{
338+
"code": 200,
339+
"message": "获取文本内容成功",
340+
"data": {
341+
"slug": "abc123",
342+
"title": "文本标题",
343+
"content": "要分享的文本内容",
344+
"remark": "备注信息",
345+
"expires_at": "2023-12-31T23:59:59Z",
346+
"max_views": 100,
347+
"views": 1,
348+
"created_at": "2023-05-01T12:00:00Z",
349+
"created_by": "admin",
350+
"is_public": true,
351+
"hasPassword": false,
352+
"isLastView": false
353+
},
354+
"success": true
355+
}
356+
```
357+
- 如果文本已设置密码,则只返回元信息并提示需要密码:
358+
```json
359+
{
360+
"code": 200,
361+
"message": "获取文本信息成功",
362+
"data": {
363+
"slug": "abc123",
364+
"title": "文本标题",
365+
"remark": "备注信息",
366+
"expires_at": "2023-12-31T23:59:59Z",
367+
"max_views": 100,
368+
"views": 0,
369+
"created_at": "2023-05-01T12:00:00Z",
370+
"created_by": "admin",
371+
"is_public": true,
372+
"hasPassword": true,
373+
"requiresPassword": true
374+
},
375+
"success": true
376+
}
377+
```
328378

329379
- `POST /api/paste/:slug`
330380

@@ -336,14 +386,15 @@ X-Custom-Auth-Key: <api_key>
336386
"password": "访问密码" // 必填
337387
}
338388
```
339-
- 响应:验证成功后返回文本分享内容
389+
- 响应:验证成功后返回文本分享内容,字段与未加密的 `GET /api/paste/:slug` 响应相同,另外会包含 `plain_password`(仅在需要时返回)
340390

341391
- `GET /api/raw/:slug`
342392

343393
- 描述:获取文本分享的原始内容(纯文本格式)
344394
- 参数:slug - 文本短链接
345395
- 查询参数:
346396
- `password` - 如果文本受密码保护,需提供密码
397+
- 访问控制:与 `GET /api/paste/:slug` 相同,受 `is_public`、过期时间、最大查看次数及密码保护限制
347398
- 响应:纯文本格式的内容,Content-Type 为 text/plain
348399

349400
#### 统一文本管理接口
@@ -361,13 +412,51 @@ X-Custom-Auth-Key: <api_key>
361412
- `limit` - 每页数量,默认为 30
362413
- `offset` - 偏移量,默认为 0
363414
- 响应:文本分享列表和分页信息,API 密钥用户只能看到自己创建的文本
415+
```json
416+
{
417+
"code": 200,
418+
"message": "获取成功",
419+
"data": {
420+
"results": [
421+
{
422+
"id": "123",
423+
"slug": "abc123",
424+
"title": "文本标题",
425+
"remark": "备注信息",
426+
"expires_at": "2023-12-31T23:59:59Z",
427+
"max_views": 100,
428+
"view_count": 5,
429+
"is_public": true,
430+
"created_by": "admin",
431+
"created_at": "2023-05-01T12:00:00Z",
432+
"updated_at": "2023-05-02T08:00:00Z",
433+
"has_password": false,
434+
"content": "完整内容..."
435+
}
436+
],
437+
"pagination": {
438+
"total": 1,
439+
"limit": 10,
440+
"offset": 0,
441+
"hasMore": false,
442+
"page": 1,
443+
"totalPages": 1
444+
}
445+
},
446+
"success": true
447+
}
448+
```
364449

365450
- `GET /api/pastes/:id`
366451

367452
- 描述:获取单个文本详情(统一接口)
368453
- 授权:需要管理员令牌或有文本权限的 API 密钥
369454
- 参数:id - 文本 ID
370-
- 响应:文本分享详细信息,API 密钥用户只能访问自己创建的文本
455+
- 响应:文本分享详细信息,API 密钥用户只能访问自己创建的文本。返回字段包含:
456+
- `id`, `slug`, `title`, `content`, `remark`
457+
- `expires_at`, `max_views`, `views`, `is_public`
458+
- `created_by`, `created_at`, `updated_at`
459+
- `has_password`, `plain_password`(仅在有密码时,并且当前调用者有权限查看明文密码)
371460

372461
- `DELETE /api/pastes/batch-delete`
373462

@@ -385,7 +474,20 @@ X-Custom-Auth-Key: <api_key>
385474
- 描述:更新文本信息(统一接口)
386475
- 授权:需要管理员令牌或有文本权限的 API 密钥
387476
- 参数:slug - 文本短链接
388-
- 请求体:可包含 remark, expires_at, max_views, password 等字段
477+
- 请求体:可包含以下字段(至少需要 content):
478+
```json
479+
{
480+
"content": "更新后的文本内容", // 必填
481+
"title": "更新后的标题", // 可选
482+
"remark": "更新后的备注信息", // 可选
483+
"expires_at": "2024-01-31T23:59:59Z", // 可选
484+
"max_views": 50, // 可选
485+
"password": "新密码", // 可选
486+
"clearPassword": true, // 可选,true 时清除密码
487+
"newSlug": "new-slug", // 可选,更新短链接
488+
"is_public": false // 可选,是否公开访问,false 表示仅管理员和创建者可访问
489+
}
490+
```
389491
- 响应:更新后的文本信息,API 密钥用户只能更新自己创建的文本
390492

391493
#### 管理员专用接口
@@ -1080,6 +1182,22 @@ X-Custom-Auth-Key: <api_key>
10801182
- `path` - 要列出内容的目录路径,默认为根目录("/")
10811183
- 响应:目录内容列表,包含文件和子目录信息
10821184
- 权限:API 密钥用户只能访问其 basic_path 权限范围内的目录
1185+
- 路径密码行为(如启用目录密码):
1186+
- 额外请求头(可选):
1187+
```http
1188+
X-FS-Path-Token: encrypted:...
1189+
```
1190+
- 该 token 由 `POST /api/fs/meta/password/verify` 接口返回;
1191+
- 用于访问设置了路径密码的目录及其子目录。
1192+
- 当目标路径未配置路径密码时:
1193+
- 与原行为完全一致,不需要该头。
1194+
- 当目标路径配置了路径密码时:
1195+
- 管理员用户:
1196+
- 不检查路径密码,直接放行(只要管理员登录有效)。
1197+
- 非管理员用户(API Key 等):
1198+
- 未提供 token 或 token 无效 / 过期时:
1199+
- 返回 `403`,`code = "FS_PATH_PASSWORD_REQUIRED"`;
1200+
- 前端应据此弹出路径密码输入框,重新验证密码。
10831201

10841202
- `GET /api/fs/get`
10851203

@@ -1629,3 +1747,96 @@ X-Custom-Auth-Key: <api_key>
16291747
- 文件操作(上传、删除、重命名等)会自动清理相关的搜索缓存
16301748
- 搜索缓存支持按挂载点和用户维度进行清理
16311749
- 管理员可以通过 `/api/admin/cache/stats` 查看搜索缓存统计信息
1750+
1751+
---
1752+
1753+
## 目录 Meta 管理 API(FS Meta)
1754+
1755+
> 用于在管理后台配置目录级元信息:顶部/底部 README、隐藏文件规则、路径密码等。
1756+
> 所有接口均 **仅限管理员** 使用。
1757+
1758+
- `GET /api/fs-meta/list`
1759+
1760+
- 描述:获取所有目录元信息配置列表
1761+
- 授权:需要管理员令牌
1762+
- 查询参数:无
1763+
- 响应:
1764+
```json
1765+
{
1766+
"code": 200,
1767+
"message": "获取元信息列表成功",
1768+
"success": true,
1769+
"data": [
1770+
{
1771+
"id": 1,
1772+
"path": "/claw",
1773+
"headerMarkdown": "# 说明",
1774+
"headerInherit": true,
1775+
"footerMarkdown": null,
1776+
"footerInherit": false,
1777+
"hidePatterns": ["^README\\.md$"],
1778+
"hideInherit": true,
1779+
"password": "1234",
1780+
"hasPassword": true,
1781+
"passwordInherit": true,
1782+
"createdAt": "2025-11-19T10:00:00.000Z",
1783+
"updatedAt": "2025-11-19T10:10:00.000Z"
1784+
}
1785+
]
1786+
}
1787+
```
1788+
1789+
- `GET /api/fs-meta/:id`
1790+
1791+
- 描述:获取单条目录元信息配置
1792+
- 授权:需要管理员令牌
1793+
- 路径参数:
1794+
- `id` - 元信息记录 ID
1795+
- 响应:结构与列表中的单条记录相同
1796+
1797+
- `POST /api/fs-meta/create`
1798+
1799+
- 描述:为指定路径创建新的目录元信息配置
1800+
- 授权:需要管理员令牌
1801+
- 请求体示例:
1802+
```json
1803+
{
1804+
"path": "/claw",
1805+
"headerMarkdown": "# 目录说明",
1806+
"headerInherit": true,
1807+
"footerMarkdown": "",
1808+
"footerInherit": false,
1809+
"hidePatterns": ["^README\\.md$", "^top\\.md$"],
1810+
"hideInherit": true,
1811+
"password": "1234",
1812+
"passwordInherit": true
1813+
}
1814+
```
1815+
1816+
- `PUT /api/fs-meta/:id`
1817+
1818+
- 描述:更新指定 ID 的目录元信息配置
1819+
- 授权:需要管理员令牌
1820+
- 路径参数:
1821+
- `id` - 元信息记录 ID
1822+
- 请求体:与 `create` 基本一致,所有字段均为可选,未提供的字段保持不变
1823+
```json
1824+
{
1825+
"path": "/claw/image",
1826+
"headerMarkdown": "子目录说明",
1827+
"headerInherit": false,
1828+
"footerMarkdown": null,
1829+
"footerInherit": false,
1830+
"hidePatterns": [],
1831+
"hideInherit": false,
1832+
"password": "9999",
1833+
"passwordInherit": true
1834+
}
1835+
```
1836+
1837+
- `DELETE /api/fs-meta/:id`
1838+
1839+
- 描述:删除指定 ID 的目录元信息记录
1840+
- 授权:需要管理员令牌
1841+
- 路径参数:
1842+
- `id` - 元信息记录 ID

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cloudpaste-api",
3-
"version": "0.8.9",
3+
"version": "0.9.0",
44
"description": "CloudPaste API基于Cloudflare Workers和D1数据库",
55
"main": "workers.js",
66
"scripts": {

backend/schema.sql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ CREATE TABLE pastes (
1717
id TEXT PRIMARY KEY,
1818
slug TEXT UNIQUE NOT NULL,
1919
content TEXT NOT NULL,
20+
title TEXT,
2021
remark TEXT,
2122
password TEXT,
2223
expires_at DATETIME,
2324
max_views INTEGER,
2425
views INTEGER DEFAULT 0,
26+
is_public BOOLEAN NOT NULL DEFAULT 1,
2527
created_by TEXT, -- 创建者标识(管理员ID或API密钥ID)
2628
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
2729
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
@@ -31,6 +33,7 @@ CREATE TABLE pastes (
3133
CREATE INDEX idx_pastes_slug ON pastes(slug);
3234
CREATE INDEX idx_pastes_created_at ON pastes(created_at DESC);
3335
CREATE INDEX idx_pastes_created_by ON pastes(created_by); -- 添加创建者索引
36+
CREATE INDEX idx_pastes_is_public ON pastes(is_public);
3437

3538

3639

@@ -136,6 +139,30 @@ CREATE INDEX idx_files_file_path ON files(file_path);
136139
CREATE INDEX idx_files_created_at ON files(created_at);
137140
CREATE INDEX idx_files_expires_at ON files(expires_at);
138141

142+
CREATE TABLE fs_meta (
143+
id INTEGER PRIMARY KEY AUTOINCREMENT,
144+
path TEXT NOT NULL, -- 虚拟路径,如 "/", "/public", "/private/docs"
145+
146+
header_markdown TEXT NULL, -- 顶部 README markdown 内容(inline)
147+
header_inherit BOOLEAN NOT NULL DEFAULT 0,
148+
149+
footer_markdown TEXT NULL, -- 底部 README markdown 内容(inline)
150+
footer_inherit BOOLEAN NOT NULL DEFAULT 0,
151+
152+
hide_patterns TEXT NULL, -- JSON 数组字符串,如 ["^README\\.md$", "^top\\.md$"]
153+
hide_inherit BOOLEAN NOT NULL DEFAULT 0,
154+
155+
password TEXT NULL, -- 目录访问密码(明文,为空表示未设置)
156+
password_inherit BOOLEAN NOT NULL DEFAULT 0,
157+
158+
extra JSON NULL, -- 预留扩展字段
159+
160+
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
161+
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
162+
);
163+
164+
CREATE INDEX idx_fs_meta_path ON fs_meta(path);
165+
139166
-- 创建file_passwords表 - 存储文件密码
140167
CREATE TABLE file_passwords (
141168
file_id TEXT PRIMARY KEY,

backend/src/constants/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const DbTables = {
1515
SYSTEM_SETTINGS: "system_settings", // 系统设置表
1616
PASTE_PASSWORDS: "paste_passwords", // 文本密码表
1717
STORAGE_MOUNTS: "storage_mounts", // 存储挂载表
18+
FS_META: "fs_meta", // 目录 Meta 配置表
1819
};
1920

2021
// 默认的最大上传大小(MB)

backend/src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import systemRoutes from "./routes/systemRoutes.js";
99
import mountRoutes from "./routes/mountRoutes.js";
1010
import webdavRoutes from "./routes/webdavRoutes.js";
1111
import fsRoutes from "./routes/fsRoutes.js";
12+
import fsMetaRoutes from "./routes/fsMetaRoutes.js";
1213
import { DbTables, ApiStatus, UserType } from "./constants/index.js";
1314
import { createErrorResponse, jsonOk } from "./utils/common.js";
1415
import filesRoutes from "./routes/filesRoutes.js";
@@ -126,6 +127,7 @@ app.use("*", async (c, next) => {
126127
"Content-Type",
127128
"Authorization",
128129
"X-API-KEY",
130+
"X-FS-Path-Token",
129131
"Depth",
130132
"Destination",
131133
"Overwrite",
@@ -180,6 +182,7 @@ app.route("/", systemRoutes);
180182
app.route("/", mountRoutes);
181183
app.route("/", webdavRoutes);
182184
app.route("/", fsRoutes);
185+
app.route("/", fsMetaRoutes);
183186
app.route("/", fsProxyRoutes);
184187

185188
// 健康检查路由

0 commit comments

Comments
 (0)