Files
2026-09-27 20:09:10 +08:00

126 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HookPilot
面向**单管理员、单台 Linux 服务器**的 Webhook 脚本管理平台:在网页上创建多个 Webhook 接口,为每个接口配置参数映射和 Bash 脚本;外部应用调用接口后,平台在宿主机上执行脚本并记录结果。
**一个接口 = 调用地址 + 鉴权凭证 + 参数映射 + Bash 脚本 + 执行策略。**
## 功能
- 单管理员登录、修改用户名与密码,不开放注册
- 接口管理:创建、编辑、复制、启用、停用、删除,支持分组
- 自定义接口标识(`/hooks/<标识>`),GET / POST,独立 Token(只保存哈希,创建时显示一次)
- 参数从 JSON、表单、Query 或指定 Header 提取,必填 / 默认值 / 字符串、数字、布尔、IP 校验,映射为 `HOOK_` 环境变量
- Bash 编辑器(行号、缩进、语法高亮、示例模板),保存即生成脚本版本
- 执行策略:工作目录、超时、同步 / 异步响应、接口并发数
- 在线测试:预览参数映射,或真实执行并实时查看输出
- 执行记录:来源、参数摘要(敏感参数掩码)、脚本版本、状态、耗时、退出码;stdout / stderr 增量查看
- 任务控制:取消排队、终止运行(清理整个进程组)、使用原版本和参数再次执行
- 系统设置:全局并发上限、日志保留天数、输出大小上限
## 技术栈
| 层级 | 技术 |
|---|---|
| 前端 | Vite 8 + Vue 3 + TypeScript + CodeMirror 6 |
| 后端 | Node.js 22 + TypeScript + Fastify 5 |
| 数据库 | SQLite(Node 内置 `node:sqlite`,无原生编译依赖) |
| 执行层 | 宿主机 Bash 子进程,独立进程组 |
| 部署 | systemd + HTTPS 反向代理 |
## 目录结构
```text
server/ 后端(模块化单体)
src/
index.ts 入口:初始化数据目录、恢复任务、启动服务
app.ts Fastify 应用装配、静态文件托管
config.ts 环境变量配置
db.ts SQLite 访问与迁移
settings.ts 系统设置
cli.ts 命令行工具(重置密码)
auth/ 密码哈希、管理员与会话、登录限流
hooks/ 接口配置存储、参数提取与校验
executor/ 任务存储(持久化队列)、调度器、Bash 执行器
routes/ 管理 API 与 Webhook 入口
web/ 前端
src/
api/ 接口类型与请求封装
components/ 布局、脚本编辑器、输出查看器、弹窗等
views/ 页面(接口详情的五个标签页在 views/hook/)
deploy/ systemd 单元、环境变量示例、Nginx / Caddy 示例
docs/ 部署说明、Lucky 对接示例
```
## 本地开发
需要 Node.js 22.13+ 和 Bash(Windows 下可使用 Git Bash,仅用于开发调试;进程组清理等行为以 Linux 为准)。
```bash
npm install
# 终端 1:后端(默认 http://127.0.0.1:8787,数据写入 ./data)
HOOKPILOT_ADMIN_PASSWORD=dev-password npm run dev:server
# 终端 2:前端开发服务器(http://localhost:5173,/api 与 /hooks 代理到后端)
npm run dev:web
```
首次启动若未设置 `HOOKPILOT_ADMIN_PASSWORD`,初始密码会随机生成并打印在后端日志中。
## 构建与运行
```bash
npm run build # 构建 web/dist 与 server/dist
npm start # 后端同时托管前端静态文件
npm run typecheck # 前后端静态类型检查
```
生产部署见 [docs/deployment.md](docs/deployment.md),Lucky 对接见 [docs/lucky.md](docs/lucky.md)。
## 调用接口
```bash
curl -X POST 'https://hooks.example.com/hooks/home-ip' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{"ip":"203.0.113.10"}'
```
Token 也可通过 `X-Hook-Token` 请求头或 `?token=` 传递。
| 结果 | 同步模式 | 异步模式 |
|---|---|---|
| 已接收 | — | `202`,返回任务 ID |
| 脚本成功 | `200` | — |
| 脚本失败 / 超时 / 被终止 | `500` / `504` / `409` | — |
| Token 错误 / 参数无效 / 已停用 / 方法不符 | `401` / `400` / `403` / `405`(不执行脚本) | 同左 |
响应只包含任务 ID、状态与退出码,脚本输出只在管理界面查看。
## 脚本可用的环境变量
| 变量 | 说明 |
|---|---|
| `HOOK_*` | 参数映射得到的变量,名称由管理员配置 |
| `HOOK_EXECUTION_ID` | 任务 ID |
| `HOOK_SLUG` | 接口标识 |
| `HOOK_TRIGGER` | 触发方式:`webhook` / `test` / `rerun` |
| `HOOK_REQUEST_FILE` | 本次任务专属的请求 JSON 文件(method、contentType、query、headers、bodyKind、body),执行结束后删除 |
| `PATH`、`HOME`、`USER`、`LOGNAME`、`SHELL`、`LANG`、`TZ` | 基础运行环境;不继承服务自身的其他环境变量 |
请求数据不会替换进脚本文本,也不会拼接成 Shell 命令;含引号、换行或 Shell 特殊字符的参数都作为数据原样传递。脚本中请始终用双引号引用:`"$HOOK_IP"`。
## 执行规则
- 任务先持久化到 SQLite,再由调度器按接收顺序启动;同时受全局并发(默认 4)与接口并发(默认 1,即串行)限制。
- 入队时固定参数与脚本版本,之后修改脚本不影响已入队任务。
- 默认超时 30 秒;超时或手动终止时向整个进程组发送 SIGTERM,3 秒后 SIGKILL。
- 不自动重试。服务重启后排队任务继续执行,运行中的任务标记为“中断”,不自动重跑。
- 停用接口会拒绝新请求并取消该接口的排队任务;运行中的任务可单独终止。
- 单次执行输出上限默认 5 MiB(stdout + stderr),超出部分继续读取并丢弃,页面标记截断。
- 鉴权头、Cookie 与 query 中的 token 不写入执行记录;敏感参数在界面中以掩码显示,但脚本自己打印的内容仍会出现在输出里。
## 后续扩展(未实现)
第三方签名验证(如 GitHub)、定时执行与通知、可复用脚本库、配置导入导出、多节点与多用户、可视化工作流。