现在比较晚了,我打算早上再折腾一下好好写一下这篇文章
不过我做了个演示站可以看看
Demo user name: [email protected]
Demo user password: Demo@Acgbyte2026
站点在这里,后续会关闭并清空:https://leilei.xyz/
目前还有不完善的地方在继续做继续完善。
先来讲讲目前做了什么:
1.恢复原有的捐赠版功能(这个不必再说)
2.新增API接口,这个接口并不是根据原本的接口做的,他是独立于原本的接口,管理员可以在后台配置是否开启全站的API权限,用户侧才能够正常使用,网页端可以做的事情我全部都引出了接口,使用jwt鉴权。
3.引出主题接口,前两天写komari主题上头了,我觉得还是需要完善的一些针对于前端样式的接口,并且格式要求比较严格,不允许夹带私货(虽然减少了可玩性,但我感觉还行)可以直接上传主题包(这玩意儿最大的作用就是替换掉原本的登录页,我已经不想吐槽原本的登录页修改起来很麻烦了)另外一种则是直接上传css
4.原本的离线下载就是一个aria2,但我不满意,把qBittorrent也加进去了。
5.忘了,好像弄了不少的东西,总之先这样吧,丢几个开发文档放这里先看看
Acgbyte 公共 API 开发文档
公共 API 是独立兼容层,不会替代网页和客户端使用的 /api/v3 接口。
一、开启公共 API
管理员进入:
管理控制台 -> 站点设置 -> 用户与验证码 -> 启用公共 API 与 JWT 令牌
关闭总开关后,所有 /api/open/v1/* 请求和新的令牌创建都会返回 CodeFeatureNotEnabled。已有令牌不会删除,重新开启后继续可用。
二、创建令牌
登录网页后进入:
账户设置 -> API 令牌
创建请求:
POST /api/v3/user/setting/api-token
Content-Type: application/json
{
"name": "自动化任务",
"expires_days": 30
}
令牌值只返回一次。服务端保存 SHA-256 哈希,可单个撤销。
三、认证
Authorization: Bearer <jwt>
示例:
curl \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
https://example.com/api/open/v1/user/storage
服务端会校验:
Bearer 方案,大小写不敏感。
- HS256 签名算法。
- JWT issuer。
- 令牌是否过期、是否撤销。
- 令牌哈希是否匹配。
四、接口范围
公共 API 会复用网页接口的权限检查和业务逻辑:
GET /api/open/v1/site/config
GET /api/open/v1/site/themes
GET /api/open/v1/user/storage
GET /api/open/v1/user/setting
GET /api/open/v1/user/setting/policies
PATCH /api/open/v1/user/setting/policy
GET|PUT|PATCH|DELETE /api/open/v1/directory*
GET|POST|PUT|PATCH|DELETE /api/open/v1/object*
GET|POST|PUT|PATCH|DELETE /api/open/v1/file*
GET|POST|PUT|PATCH|DELETE /api/open/v1/share*
GET|POST|PUT|PATCH|DELETE /api/open/v1/vas*
GET|POST|PUT|PATCH|DELETE /api/open/v1/webdav*
GET|POST|PUT|PATCH|DELETE /api/open/v1/aria2*
管理接口、从机接口、回调接口、WOPI 内部接口和验证码验证接口不会开放。
五、示例
列出根目录:
curl \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
"https://example.com/api/open/v1/directory/"
创建目录:
curl -X PUT \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"/API/Projects"}' \
https://example.com/api/open/v1/directory
创建文本文件:
curl -X POST \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"path":"/API/Projects/readme.txt"}' \
https://example.com/api/open/v1/file/create
添加离线下载任务:
curl -X POST \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url":["magnet:?xt=urn:btih:..."],"dst":"/Downloads"}' \
https://example.com/api/open/v1/aria2/url
查询会员商品并购买:
curl \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
https://example.com/api/open/v1/vas/product
curl -X POST \
-H "Authorization: Bearer $ACGBYTE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"action":"pack","method":"score","id":1,"num":1}' \
https://example.com/api/open/v1/vas/order
六、完整主题桥接
沙箱主题通过 postMessage 使用同一组允许路径,不需要也不应该获取 JWT。完整协议见 THEME_DEVELOPMENT.md。
七、安全规则
- 令牌继承用户组权限和存储策略权限。
- 请求路径会被规范化,编码目录穿越、反斜杠、空字节和未知路径会被拒绝。
- 管理接口永远不会被代理。
- 撤销令牌后,下一次请求立即失效。
- 不要把令牌写入前端源码、日志、截图或公开地址。
Acgbyte 主题开发文档
Acgbyte 支持两类主题包:
tokens:CSS 变量主题,扩展内置 Vue 界面。
bundle:完整 HTML/CSS/JavaScript 主题,在隔离 iframe 中运行,并通过受控消息桥调用允许的前台 API。
一、主题包目录
仓库内附带了可直接上传的测试包:theme-packages/。其中包括变量主题、完整应用主题、登录文案主题和仅登录页主题。
变量主题
theme.zip
├── theme.json
├── theme.css
└── assets/
├── preview.webp
└── custom-font.woff2
theme.json 示例:
{
"id": "my-theme",
"name": "我的主题",
"version": "1.0.0",
"author": "作者",
"description": "主题说明",
"mode": "light",
"type": "tokens",
"preview": "assets/preview.webp",
"copy": {
"brand.tagline": "Acgbyte Cloud",
"hero.title": "让文件协作更从容",
"form.title": "登录你的空间",
"form.submit": "进入空间"
}
}
完整页面主题
full-theme.zip
├── theme.json
├── theme.css
├── index.html
├── theme.js
└── assets/
└── cover.webp
theme.json 示例:
{
"id": "full-theme",
"name": "完整页面主题",
"version": "1.0.0",
"author": "作者",
"description": "独立前端主题",
"mode": "dark",
"type": "bundle",
"entry": "index.html",
"surfaces": ["app", "login"]
}
二、包格式与校验规则
id 只能使用小写字母、数字和连字符,匹配 [a-z][a-z0-9-]{1,39}。
tech、anime、minimal 是内置主题 ID,不能覆盖。
mode 可为 light、dark 或 auto。
type 可为 tokens 或 bundle。
tokens 必须包含 theme.json 和 theme.css。
bundle 还必须包含入口 HTML,默认入口为 index.html。
- 静态资源必须位于
assets/ 下,允许 PNG、JPG、JPEG、WEBP、SVG、WOFF、WOFF2、TTF、JSON。
- ZIP 最大 8 MB,解压后最大 24 MB,最多 64 个文件。
- CSS 不允许
@import、外链 HTTP/HTTPS、javascript:、expression()、behavior:、-moz-binding。
三、登录页文案接口
内置登录页提供稳定的语义钩子:
<main data-page="login" data-surface="login" data-theme-id="my-theme">
<span data-theme-copy="hero.title">...</span>
</main>
变量主题可以在 theme.json 的 copy 中覆盖以下文案:
文案键 |
用途 |
|---|
brand.tagline |
品牌副标题 |
hero.badge |
登录主标题上方标签 |
hero.title |
登录主标题 |
hero.description |
登录介绍 |
feature.security.title |
安全功能标题 |
feature.security.description |
安全功能说明 |
feature.login.title |
登录功能标题 |
feature.login.description |
登录功能说明 |
feature.transfer.title |
传输功能标题 |
feature.transfer.description |
传输功能说明 |
form.title |
登录表单标题 |
form.description |
登录表单说明 |
form.emailLabel |
邮箱字段标题 |
form.emailPlaceholder |
邮箱占位文字 |
form.passwordLabel |
密码字段标题 |
form.passwordPlaceholder |
密码占位文字 |
form.captchaLabel |
人机验证字段标题 |
form.captchaReady |
验证完成文案 |
form.captchaRequired |
待验证文案 |
form.submit |
登录按钮 |
form.forgotPassword |
找回密码链接 |
form.noAccount |
注册提示 |
form.createAccount |
注册链接 |
form.twoFactorTitle |
两步验证标题 |
form.twoFactorDescription |
两步验证说明 |
form.twoFactorPlaceholder |
两步验证码占位文字 |
form.twoFactorSubmit |
两步验证提交按钮 |
form.twoFactorBack |
返回密码登录 |
footer.brand |
桌面端页脚品牌文字 |
文案只能使用纯文本,不能包含控制字符;未知键或超长内容会被拒绝。
四、CSS 变量接口
主题 CSS 应作用在主题 ID 上:
[data-app-theme="my-theme"] {
--background: #f5f7ff;
--foreground: #172033;
--surface: #ffffff;
--surface-muted: #eef1fa;
--surface-raised: #ffffff;
--muted: #68708a;
--border: #dce1ef;
--primary: #3157d5;
--primary-strong: #2446b8;
--primary-foreground: #ffffff;
--accent: #ef6c5a;
--accent-soft: #fff0ed;
--danger: #c63e4a;
--danger-soft: #fff0f2;
--success: #2f8a63;
--warning: #a77924;
--ring: rgba(49, 87, 213, 0.24);
--shadow-sm: 0 1px 2px rgba(15, 24, 52, 0.06);
--shadow-md: 0 20px 48px rgba(15, 24, 52, 0.12);
--radius: 0.75rem;
--page-background: #f5f7ff;
--panel-texture: none;
--display-font: "Noto Sans SC", sans-serif;
}
动画变量:
[data-app-theme="my-theme"] {
--motion-fast: 150ms;
--motion-normal: 240ms;
--ease-standard: cubic-bezier(0.2, 0.8, 0.2, 1);
--ease-emphasized: cubic-bezier(0.16, 1, 0.3, 1);
}
主题资源地址:
[data-app-theme="my-theme"] .theme-panel {
background-image: url("/api/v3/site/theme-asset/my-theme/assets/texture.webp");
}
五、完整主题运行环境
surfaces 控制主题接管范围:
app:登录后的应用页面。
login:登录、注册、找回密码和重置密码页面。
管理控制台始终使用内置界面,不会加载完整主题。
完整主题 iframe 使用:
sandbox="allow-scripts allow-forms allow-modals"
主题不能读取 Cookie、localStorage、父页面 DOM,也不能直接发起外部网络请求。服务端同时下发 CSP、禁止对象嵌入和顶部跳转。
六、主题消息桥
主题脚本发送 ready:
parent.postMessage({ source: "acgbyte-theme", type: "ready" }, "*");
宿主会发送 context,包含 siteConfig、user、storage 和 theme。上下文也会在 iframe load 时发送。
调用允许的前台接口:
const requestId = crypto.randomUUID();
window.addEventListener("message", (event) => {
if (
event.data?.source === "acgbyte-host" &&
event.data?.type === "response" &&
event.data.requestId === requestId
) {
const response = event.data.data;
console.log(response?.data ?? response);
}
});
parent.postMessage({
source: "acgbyte-theme",
type: "request",
requestId,
method: "GET",
path: "/site/config"
}, "*");
桥接响应保留普通 /api/v3 响应结构。读取 code 判断状态,读取 data 获取业务数据。
允许的接口前缀:
/site/
/user/
/directory
/object/
/file/
/share/
/vas/
/webdav/
/aria2/
管理接口、从机接口、回调接口、验证码验证接口和内部接口始终禁止访问。桥接会拒绝外部地址、编码目录穿越、反斜杠、空字节和过大的请求体。
主题页面导航:
parent.postMessage({
source: "acgbyte-theme",
type: "navigate",
path: "/home"
}, "*");
七、管理接口
GET /api/v3/site/themes:已安装主题和当前默认主题。
GET /api/v3/site/theme.css?id=my-theme:读取变量主题 CSS。
GET /api/v3/site/theme-bundle/:id/:path:读取完整主题文件。
GET /api/v3/admin/themes:后台主题列表。
POST /api/v3/admin/theme/upload:上传 ZIP,字段名 file。
PATCH /api/v3/admin/theme/activate/:id:设为默认主题。
DELETE /api/v3/admin/theme/:id:删除上传主题。
八、安装主题
进入 管理控制台 -> 站点设置 -> 主题与视图 -> 主题包,上传 ZIP,然后选择 设为默认。内置主题始终保留,不能删除。