Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ UI 仿照 [komari-next](https://github.com/tonyliuzj/komari-next) 制作,数
- 首页统计、区域筛选、搜索、网格和表格视图
- CPU、内存、磁盘、网络和流量信息
- 节点详情页与历史负载图表
- 四线路 Ping、丢包、波动和鼠标悬浮数据
- 首页最近 1 小时四线路延迟/丢包时间条,详情页 Ping、丢包、波动和悬浮数据
- WebSocket 实时更新,断线后自动重连
- 多个 Worker 数据合并
- 中文、英文、明暗主题和移动端布局
- Cloudflare Turnstile
- 独立登录授权,可查看非公开站点、隐藏节点和长历史
- 首页右侧主题抽屉:背景 URL/图片上传、独立透明/毛玻璃方案和自定义 CSS
- Cloudflare KV 自动持久化主题设置,不写入上游 D1
- 可选实验性主题后台(节点管理、设置、数据库维护,默认关闭)

## 本地运行
Expand Down Expand Up @@ -85,6 +87,8 @@ npm run dev
4. 构建命令留空,部署命令保持默认的 `npx wrangler deploy`。
5. 保存并部署。

`wrangler.jsonc` 已声明不带资源 ID 的 `THEME_SETTINGS` binding。首次部署时 Wrangler 会自动创建并绑定 KV namespace,不需要提前运行 `wrangler kv namespace create`,也不需要把账户专属 ID 写进仓库。

### Cloudflare Worker 配置

1. 进入 **Settings** → **Variables and Secrets**。
Expand All @@ -102,6 +106,17 @@ CSM_CUSTOM_ADMIN_ENABLED=true

未配置或填写 `false` 时,`/admin` 与 `/admin.html` 也会重定向到原站后台。登录授权查看私有内容不受此开关影响。

### 主题自定义

首页顶部齿轮现在打开右侧“主题自定义”抽屉;登录授权按钮位于最右侧。主题抽屉支持:

- 填写 HTTPS 背景图片地址,或上传不超过 2 MB 的 JPG / PNG / WebP / GIF / AVIF。
- 独立开启界面透明化;可选“柔和透明”(无背景模糊)或“毛玻璃”方案。
- 分别调整透明强度(0%–80%)与毛玻璃强度(0px–30px)。
- 添加最多 20,000 字符的自定义 CSS。

读取主题设置是公开的,修改、上传和删除必须先在主题中登录。Worker 会向选中的 CF-Server-Monitor 后端发送无副作用的认证探测,再写入 CSM-Next 自己的 KV;不会调用上游设置写入接口,也不会增加上游 D1 写入。自定义 CSS 禁止 `@import`、`url()`、脚本和其他外部资源加载方式。

## 测试与构建

```powershell
Expand Down Expand Up @@ -140,9 +155,10 @@ CSM-Next/

## 使用说明

- 首页的线路延迟和丢包来自最近一次采样,不是 24 小时平均值。
- 首页可见节点会按需读取最近 1 小时历史,将其聚合成 24 个真实时间桶;延迟和丢包均使用 CT/CU/CM/BD 实际上报字段,后续由 WebSocket 增量更新。尚未载入历史时只显示当前四线路采样。
- 站点标题默认跟随原 CF-Server-Monitor 的 `site_title`;主题配置中的 `title` / `CSM_SITE_TITLE` 仅作为兜底值。
- 首页和详情页默认读取公开内容;非公开站点、隐藏节点与更长历史可在主题内登录后查看。
- “管理后台”默认打开当前 CF-Server-Monitor Worker 的原生 `/#/admin`。
- 顶部齿轮打开主题自定义抽屉;页脚中的“管理后台”入口默认打开当前 CF-Server-Monitor Worker 的原生 `/#/admin`。
- 设置 `customAdminEnabled: true`(普通静态托管)或 `CSM_CUSTOM_ADMIN_ENABLED=true`(Cloudflare Worker)后,才启用主题自建 `admin.html`。
- CSM-Next 只保存上游签发的站点隔离 JWT,不保存管理密码或 Secret。

Expand All @@ -151,6 +167,7 @@ CSM-Next/
- 后端:[CF-Server-Monitor](https://github.com/huilang-me/CF-Server-Monitor)
- UI 参考:[komari-next](https://github.com/tonyliuzj/komari-next)
- 国旗图标:[flag-icons](https://github.com/lipis/flag-icons)
- 界面图标:[Lucide](https://lucide.dev/)(许可见 [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md))

CSM-Next 是独立的社区项目,与上述项目维护者没有官方隶属关系。

Expand Down
67 changes: 67 additions & 0 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Third-party notices

## Lucide Icons

The inline interface icons marked with `data-lucide` are sourced from
[Lucide](https://lucide.dev/) and used under the ISC License.

ISC License

Copyright (c) 2026 Lucide Icons and Contributors

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

---

The following Lucide icons are derived from the Feather project:

airplay, alert-circle, alert-octagon, alert-triangle, aperture,
arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down,
arrow-left-circle, arrow-left, arrow-right-circle, arrow-right,
arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar,
cast, check, chevron-down, chevron-left, chevron-right, chevron-up,
chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard,
clock, code, columns, command, compass, corner-down-left, corner-down-right,
corner-left-down, corner-left-up, corner-right-down, corner-right-up,
corner-up-left, corner-up-right, crosshair, database, divide-circle,
divide-square, dollar-sign, download, external-link, feather, frown, hash,
headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link,
loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2,
minus-circle, minus-square, minus, monitor, moon, more-horizontal,
more-vertical, move, music, navigation-2, navigation, octagon, pause-circle,
percent, plus-circle, plus-square, plus, power, radio, rss, search, server,
share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet,
target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle,
x-octagon, x-square, x, zoom-in, zoom-out

The MIT License (MIT) (for the icons listed above)

Copyright (c) 2013-present Cole Bemis

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
19 changes: 13 additions & 6 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
## 数据流

```text
Cloudflare Worker / 静态托管主题
CSM-Next Cloudflare Worker / 静态托管主题
├─ GET /api/theme-settings → CSM-Next KV
├─ PUT /api/theme-settings → 验证上游 JWT → CSM-Next KV
├─ GET/PUT /api/theme-background → CSM-Next KV
├─ GET /api/config
├─ GET /api/servers
├─ GET /api/server?id=...
Expand All @@ -13,24 +16,26 @@ Cloudflare Worker / 静态托管主题
CF-Server-Monitor Worker / D1 / Durable Object
```

主题是纯静态前端,不包含代理层,也不保存管理密码。默认管理入口跳转原 CF-Server-Monitor 的 `/#/admin`;主题仅调用登录接口获取 JWT,以读取非公开站点、隐藏节点和长历史。设置 `customAdminEnabled` 后才启用实验性 `admin.html`,其管理 API 仍直接调用原 Worker,不改 D1 / Worker 核心逻辑。
监控页面仍是静态前端,不保存管理密码。Cloudflare 部署额外提供一个很小的主题设置 API:KV 保存外观 JSON 与单张背景图片,写入前通过上游 JWT 验证身份。外观 JSON 分别保存透明化开关、柔和/毛玻璃模式、面板不透明度与模糊强度;旧版只有 `panelOpacity` 的数据会兼容迁移为原有毛玻璃效果。默认管理入口跳转原 CF-Server-Monitor 的 `/#/admin`;设置 `customAdminEnabled` 后才启用实验性 `admin.html`。主题设置不改上游 D1 / Worker 核心逻辑。

通过 Cloudflare Workers 部署时,`worker/index.js` 只负责首页、详情页、后台页和 `config.json` 路由;CSS、JavaScript 等文件由 Workers Static Assets 直接提供。它不会代理监控 API。
首页探针时间条只为进入视口的节点按需请求 `hours=1` 历史,同时最多加载 4 个节点。每个节点在当前页面只初始化一次,并在浏览器会话中短时缓存;随后利用已有 WebSocket 样本维护滚动一小时窗口,普通 60 秒刷新不会重复读取历史。每个时间条由 24 个真实时间桶组成,缺少采样的桶显示为空,不用当前值重复填充。

通过 Cloudflare Workers 部署时,`worker/index.js` 负责页面路由、`config.json`、主题设置和背景图片接口;CSS、JavaScript 等文件由 Workers Static Assets 直接提供。它不会代理监控数据 API,认证探测也不会返回上游设置或 Secret。

## 目录职责

- `src/index.html`、`src/detail.html`:默认页面入口;`src/admin.html` 是开关控制的可选实验后台。
- `src/assets/js/`:仪表盘、详情页与管理后台入口逻辑。
- `src/assets/js/admin/`:管理后台分域模块(i18n / context / api / servers / settings)。
- `src/assets/js/shared/`:跨页共享模块(JWT、HTTP、URL/背景图校验、DOM 转义、i18n、测点字段)。
- `src/assets/js/shared/`:跨页共享模块(JWT、HTTP、主题设置、URL/背景图校验、DOM 转义、i18n、测点字段与探针历史聚合)。
- `src/assets/css/`:共享样式、详情页与后台样式。
- `worker/`:Cloudflare Worker 路由和运行时前端配置
- `worker/`:Cloudflare Worker 路由、运行时配置与 KV 主题设置接口
- `config/`:公开示例配置和被忽略的本地配置。
- `tests/`:无需浏览器依赖的 DOM 冒烟测试。
- `scripts/`:构建与本地静态服务。
- `docs/`:架构、开发和部署说明。
- `dist/`:构建产物,不提交 Git。
- `wrangler.jsonc`:Workers Static Assets 与部署变量。
- `wrangler.jsonc`:Workers Static Assets、自动配置的 KV binding 与部署变量。

## 配置策略

Expand All @@ -42,5 +47,7 @@ CF-Server-Monitor Worker / D1 / Durable Object
- 超过 1 小时的历史需要 JWT。后端只认 `Authorization: Bearer`,不读 Cookie。
- JWT 保存在浏览器 `localStorage`,按域名隔离。主题与原管理端不在同一域名时,原后台登录状态不会自动穿透。
- 首页、详情页与可选主题后台在本主题域名登录:调用原 `/admin/api` 获取 token,写入当前域名 `localStorage`(按 `apiBase` 隔离)。
- 主题设置公开读取;写设置和上传背景必须携带 JWT。Worker 只用未知 action 验证令牌,不调用 `get_settings`,也不读取上游 Secret。
- 自定义 CSS 通过 `textContent` 写入固定 `<style>`,同时拒绝外部资源 URL、`@import` 与样式标签注入。
- 管理 API、JWT Secret 和 Turnstile Secret 不属于主题源码;主题后台只消费原接口,不增加 D1 读写策略。

22 changes: 20 additions & 2 deletions docs/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ CSM-Next 使用 Cloudflare Workers Builds 的 Git 集成。Cloudflare 直接从

`wrangler.jsonc` 已经指定 Worker 入口和静态资源目录,默认部署命令会直接完成发布。之后每次推送到 `main`,Cloudflare 都会自动构建并更新线上 Worker。

配置文件还声明了不带 ID 的 `THEME_SETTINGS` KV binding。Wrangler 的自动资源配置会在首次部署时创建并绑定 namespace;通过 Git 仓库部署时,资源 ID 保留在 Cloudflare 控制台,不会回写仓库。

## 设置后端地址

第一次部署结束后,打开刚创建的 Worker:
Expand All @@ -38,13 +40,27 @@ https://monitor-a.example.workers.dev,https://monitor-b.example.workers.dev

还可以在同一位置添加以下可选变量:

- `CSM_SITE_TITLE`:页面标题
- `CSM_BACKGROUND_IMAGE`:背景图片地址,留空表示不使用
- `CSM_SITE_TITLE`:后端未返回 `site_title` 时使用的兜底页面标题;正常情况下主题跟随原站设置
- `CSM_BACKGROUND_IMAGE`:KV 中还没有主题设置时使用的初始背景图片地址
- `CSM_REFRESH_INTERVAL`:轮询间隔,单位为毫秒,最小 5000。
- `CSM_CUSTOM_ADMIN_ENABLED`:是否启用实验性主题后台;默认 `false`,管理入口会跳转原站 `/#/admin`。

即使关闭主题后台,首页和详情页仍可在当前主题域名完成登录授权,用于读取非公开站点、隐藏节点和长历史数据。该登录需要下文的跨域配置。

## KV 主题设置

首页齿轮打开主题设置抽屉。设置 JSON 与上传背景分别使用 `theme-settings:v1` 和 `theme-assets/background` 两个 KV key:

- 主题设置公开读取,便于所有访客获得统一外观。
- 保存设置和上传背景必须携带主题域名下保存的上游 JWT。
- Worker 通过上游 `/admin/api` 的无副作用未知 action 验证 JWT,不读取上游敏感设置。
- 图片限制为 2 MB,并验证文件 MIME 与实际文件头;SVG 和任意文件不允许上传。
- 透明化开关、柔和/毛玻璃模式、透明强度和模糊强度均保存在同一份主题设置 JSON 中。
- 自定义 CSS 最大 20,000 字符,禁止外部资源和可执行内容。
- KV 是最终一致存储;当前页面保存后立即应用,其他地区的访问最多可能短暂读到旧值。

这些操作只消耗 CSM-Next 自己的 Worker/KV 请求,不写入 CF-Server-Monitor 的 D1。

`wrangler.jsonc` 已启用 `keep_vars`,因此以后 Git 自动部署不会删除这些控制台变量。

## 允许跨域访问
Expand Down Expand Up @@ -97,3 +113,5 @@ npm run build
```

然后上传 `dist/` 中的文件。普通静态托管使用 `config/config.local.json` 或 `config/config.example.json`,与 Worker 的运行时变量是两套独立配置。

主题抽屉的全站保存与文件上传依赖 `worker/index.js` 和 KV binding;纯静态托管只能继续通过 `config.json` 设置背景,不能使用 KV 持久化。
4 changes: 3 additions & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ http://127.0.0.1:4173/admin.html?preview=1
- 仪表盘:`src/index.html`、`src/assets/js/dashboard.js`
- 详情页:`src/detail.html`、`src/assets/js/detail.js`
- 登录授权:`src/assets/js/shared/login.js` 与首页/详情页登录弹窗
- 主题自定义:`src/assets/js/shared/theme.js`、`theme-settings.js`,首页右侧抽屉与 Worker KV 接口
- 首页探针历史:`src/assets/js/shared/probe-history.js` 负责一小时窗口清洗、合并与 24 桶聚合,`dashboard.js` 负责视口懒加载和 WebSocket 增量
- 可选主题后台:`src/admin.html`、`src/assets/js/admin.js`(入口)、`src/assets/js/admin/`(`i18n` / `context` / `api` / `servers` / `settings`)、`src/assets/css/admin.css`;生产环境默认关闭
- 共享模块:`src/assets/js/shared/`(`auth` / `http` / `url` / `dom` / `i18n` / `ping`)
- 共享模块:`src/assets/js/shared/`(`auth` / `http` / `theme` / `title` / `url` / `dom` / `i18n` / `ping` / `probe-history`)
- 公共样式:`src/assets/css/main.css`
- 详情样式:`src/assets/css/detail.css`
- Worker 路由:`worker/index.js`、`wrangler.jsonc`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
"build": "node scripts/build.mjs",
"test": "node --test tests/auth.test.mjs tests/login.test.mjs tests/url.test.mjs tests/http.test.mjs tests/ping.test.mjs tests/i18n.test.mjs tests/dashboard.test.mjs tests/detail.test.mjs tests/admin.test.mjs tests/worker.test.mjs",
"test": "node --test tests/auth.test.mjs tests/login.test.mjs tests/theme-settings.test.mjs tests/title.test.mjs tests/url.test.mjs tests/http.test.mjs tests/ping.test.mjs tests/probe-history.test.mjs tests/i18n.test.mjs tests/dashboard.test.mjs tests/dashboard-history.test.mjs tests/detail.test.mjs tests/admin.test.mjs tests/worker.test.mjs",
"dev": "node scripts/build.mjs && node scripts/serve.mjs",
"preview": "node scripts/serve.mjs",
"cf:dev": "wrangler dev",
Expand Down
Loading
Loading