feat: initial commit for HookPilot

This commit is contained in:
吴璨
2026-09-27 20:09:10 +08:00
commit e998d4defc
73 changed files with 10782 additions and 0 deletions
+189
View File
@@ -0,0 +1,189 @@
# Webhook 脚本管理平台:功能列表与架构设计
## 1. 项目定位与技术方案
面向**单管理员、单台 Linux 服务器**,通过网页创建多个 Webhook 接口,为每个接口配置参数和 Bash 脚本。外部应用发起请求后,平台执行脚本并记录结果,脚本可以直接操作宿主机。
核心模型:
**一个接口 = 调用地址 + 鉴权凭证 + 参数映射 + Bash 脚本 + 执行策略。**
| 层级 | 技术选择 | 职责 |
|---|---|---|
| 前端 | Vite 8 + Vue 3 + TypeScript | 接口配置、脚本编辑、执行记录 |
| 后端 | Node.js + TypeScript + Fastify | 管理 API、Webhook 接收、鉴权、参数处理 |
| 数据库 | SQLite | 接口配置、脚本版本、任务和执行记录 |
| 执行层 | 宿主机 Bash 子进程 | 执行脚本、收集输出、处理超时 |
| 部署 | Linux 原生部署,以 systemd 管理服务 | 开机启动、进程管理 |
| 入口 | HTTPS 反向代理 | 提供统一域名,转发到后端 |
前端采用 Vue 单文件组件与 Composition API。生产环境由后端托管构建后的静态文件;Vite 用于开发和构建,`vite preview` 不作为生产服务器。[Vue 官方文档](https://vuejs.org/guide/quick-start)、[Vite 8 部署文档](https://github.com/vitejs/vite/blob/v8.0.10/docs/guide/static-deploy.md)
## 2. 功能列表
### 首版功能
| 模块 | 功能 |
|---|---|
| 管理员登录 | 单管理员账户、登录退出、修改密码;不开放注册 |
| 概览 | 接口数量、运行中任务、近期成功与失败记录 |
| 接口管理 | 创建、编辑、复制、启用、停用、删除;支持名称、描述和分组 |
| 接口地址 | 自定义唯一标识,如 `aaa`,生成 `/hooks/aaa` |
| 请求方式 | 每个接口选择 GET 或 POST;默认 POST |
| 接口鉴权 | 每个接口独立 Token,支持重新生成;创建时展示一次 |
| 参数配置 | 从 JSON、表单、Query 或指定 Header 提取参数,映射成脚本环境变量 |
| 参数校验 | 必填、默认值,以及字符串、数字、布尔值、IP 类型校验 |
| 脚本编辑 | 多行 Bash 编辑器,提供行号、缩进和示例模板 |
| 脚本版本 | 保存时生成版本;执行记录关联当时使用的版本 |
| 执行配置 | 工作目录、超时时间、同步或异步响应、接口并发数 |
| 在线测试 | 填写模拟请求,预览参数映射;点击执行后真实运行脚本 |
| 执行记录 | 请求来源、参数摘要、脚本版本、状态、耗时、退出码 |
| 输出查看 | 分别查看 stdout、stderr,支持执行期间增量查看 |
| 任务控制 | 取消排队任务、终止运行任务、手动再次执行 |
| 系统设置 | 全局并发上限、日志保留天数、任务输出大小上限 |
参数来源由管理员明确选择,避免同名参数在 Body、Query、Header 之间产生隐式覆盖。
“在线测试”和“再次执行”都会实际操作服务器,页面必须清楚标明这一点;再次执行创建新任务并保留来源记录。
### 后续扩展
第一版预留扩展位置,暂不实现:
- 第三方服务专用签名验证,如 GitHub Webhook 签名。
- 定时执行、成功或失败通知。
- 可复用脚本库、配置导入导出。
- 多服务器节点、多用户与权限管理。
- 可视化工作流和多步骤任务。
## 3. 架构与执行流程
```mermaid
flowchart TD
A[管理员浏览器<br/>Vue 3 管理界面] --> B[HTTPS 入口]
C[Lucky / 其他外部应用] --> B
B --> D[Node.js + Fastify]
D --> E[管理 API<br/>登录、配置、执行记录]
D --> F[Webhook 接收<br/>鉴权、参数提取与校验]
E --> G[(SQLite)]
F --> H[任务调度模块]
H --> G
H --> I[执行器模块]
I --> J[宿主机 Bash 子进程]
J --> K[文件 / 系统服务 / 其他命令]
I --> G
G --> L[状态与输出查询]
L --> A
```
**首版采用模块化单体后端。** 管理 API、任务调度和执行器在同一个项目内分模块实现,每个任务启动独立 Bash 子进程。SQLite 保存待执行任务,不额外引入 Redis 或消息队列。
创建接口时只保存配置。后端统一注册 `/hooks/:slug` 路由,请求到来时读取对应配置,因此新增或修改接口无需重启服务。Fastify 负责 HTTP 路由及基础请求校验。[Fastify 官方文档](https://github.com/fastify/fastify/blob/main/docs/Reference/Validation-and-Serialization.md)
每次调用依次完成:
1. 根据接口标识查找配置,检查启用状态和请求方式。
2. 验证接口 Token,限制请求大小。
3. 提取参数并校验,生成执行所需环境变量。
4. 保存任务,固定本次使用的参数和脚本版本。
5. 调度器按并发限制启动 Bash。
6. 收集输出、退出码和耗时,更新执行状态。
7. 根据同步或异步模式返回结果。
### 参数如何进入脚本
以家庭 IP 更新为例:
| 配置项 | 示例 |
|---|---|
| 接口 | `POST /hooks/home-ip` |
| 请求体 | `{"ip":"203.0.113.10"}` |
| 提取来源 | JSON 中的 `ip` |
| 校验 | 必填、合法 IP |
| 脚本变量 | `HOOK_IP` |
| 执行模式 | 同步 |
| 并发 | 1,按接收顺序执行 |
脚本通过 `"$HOOK_IP"` 获取参数。复杂请求内容另存为任务专属 JSON 文件,通过 `HOOK_REQUEST_FILE` 提供路径。
**请求数据不替换进脚本文本,也不拼接成 Shell 命令。** 执行器启动保存好的脚本文件,并显式传入参数环境;自定义变量统一使用 `HOOK_` 前缀,避免覆盖 `PATH` 等运行环境。
### 执行与失败处理
- 默认每个接口串行执行,全局最多同时运行 4 个任务,均可配置。
- 默认脚本超时 30 秒;超时或终止时清理任务进程组。
- 不自动重试脚本,避免重复部署、重启服务等副作用。
- 服务异常退出后,未开始的任务继续排队;执行中的任务标记为“中断”,不自动重跑。
- 停用接口后拒绝新请求,并取消该接口尚未开始的任务;已运行任务可单独终止。
- 修改脚本不改变已入队任务使用的脚本版本。
- 终止任务只能停止后续执行,不能撤销已写入文件等操作。
### 宿主机操作权限
服务直接运行在宿主机上,脚本继承服务账户的权限,可访问该账户有权限访问的文件与命令。
默认使用专用服务账户;确实需要重启系统服务或修改受保护文件时,由部署者按实际命令配置提权权限。页面中不提供任意切换系统用户的功能。
管理端通过登录会话访问,Webhook 通过独立 Token 调用;两种凭证分开。执行子进程使用明确构造的环境,不继承后台的全部配置和凭证。该平台面向可信管理员,不将任意 Bash 脚本视为可隔离的不可信代码。
## 4. 页面、接口与数据设计
前端导航保持五个入口:
```text
概览
接口管理
└─ 接口详情:基本配置 / 参数 / 脚本 / 执行策略 / 测试
执行记录
└─ 执行详情:请求摘要 / 脚本版本 / 输出 / 结果
系统设置
账户设置
```
主要 HTTP 接口:
| 接口 | 用途 |
|---|---|
| `/api/auth/*` | 管理员登录、退出和账户操作 |
| `/api/hooks`、`/api/hooks/:id` | 接口列表与配置管理 |
| `/api/hooks/:id/versions` | 脚本版本记录 |
| `/api/hooks/:id/test` | 从管理界面创建测试任务 |
| `/api/executions`、`/api/executions/:id` | 查询执行记录与详情 |
| `/api/executions/:id/logs` | 按偏移量增量读取输出 |
| `/api/executions/:id/cancel` | 取消或终止任务 |
| `/api/executions/:id/rerun` | 使用原脚本版本和参数创建新任务 |
| `/hooks/:slug` | 外部 Webhook 调用入口 |
所有 `/api/*` 管理接口都要求管理员身份,登录入口除外;外部调用方不通过这些接口查询日志。
同步模式等待执行结束,成功返回 HTTP 200 与任务 ID,脚本失败返回非成功状态;异步模式在任务持久化后返回 HTTP 202 与任务 ID,仅表示已接收。脚本输出默认只在管理界面查看,不返回给外部调用方。
SQLite 保存六类数据:管理员与会话、接口配置、脚本版本、执行任务、分块执行输出、系统设置。任务本身兼作持久化队列,保存参数及配置快照。
默认请求体上限 1 MiB,单次执行输出保留上限 5 MiB,执行记录保留 30 天。超限输出继续读取并丢弃,避免阻塞脚本,同时在页面标记截断。鉴权头不写入执行记录;敏感参数在界面隐藏,但脚本主动打印出的内容仍可能出现在输出中。
## 5. 实施顺序与验收场景
按以下顺序实现:
1. 登录、接口管理、配置存储。
2. Webhook 接收、参数映射、Bash 执行。
3. 持久化队列、同步与异步响应、超时和取消。
4. 执行记录、输出查看、脚本版本、在线测试。
5. 宿主机部署说明与 Lucky 对接示例。
主要验收场景:
- 创建 `home-ip` 接口,合法请求执行脚本并更新指定文件。
- Token 错误、参数缺失或 IP 非法时,不执行脚本。
- 多个接口分别运行自己的脚本,参数和输出互不混用。
- 含引号、换行或 Shell 特殊字符的参数仍作为数据传递。
- 同一接口的连续请求按照配置排队;脚本修改不影响已入队任务。
- 非零退出码、超时、手动终止、输出超限均能正确显示。
- 重启服务后,排队和中断任务状态符合设计。
- 未登录者不能读取脚本、修改接口或查询执行输出。
本次只确定设计,不修改文件。后续验收由你执行,不替你运行静态类型检查或运行监测。