first commit
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
# 文件传输自动化系统
|
||||
|
||||
飞书审批驱动的企业文件传输与权限自动化管理系统。
|
||||
|
||||
## 系统架构
|
||||
|
||||
```
|
||||
飞书审批事件 ──→ Express 服务 ──→ 群晖 NAS API(文件复制)
|
||||
│ ──→ JumpServer API(远程命令)
|
||||
│ ──→ Nextcloud API(文件共享)
|
||||
│
|
||||
├── SQLite(操作日志)
|
||||
├── 管理后台(Web UI)
|
||||
└── 飞书机器人(告警通知)
|
||||
```
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 环境要求
|
||||
|
||||
- Node.js >= 18
|
||||
- 可访问群晖 NAS、JumpServer、Nextcloud 的网络
|
||||
- 公网 IP 或域名(用于飞书事件回调)
|
||||
|
||||
### 2. 安装部署
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone <your-repo> file-transfer-automation
|
||||
cd file-transfer-automation
|
||||
|
||||
# 安装依赖
|
||||
npm install
|
||||
|
||||
# 复制配置文件并填写
|
||||
cp .env.example .env
|
||||
# 编辑 .env 填入实际的 API 密钥和地址
|
||||
|
||||
# 启动
|
||||
npm start
|
||||
```
|
||||
|
||||
或使用 Docker:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# 编辑 .env
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 3. 验证
|
||||
|
||||
访问 `http://你的服务器IP:3000/health` 确认服务正常。
|
||||
|
||||
---
|
||||
|
||||
## 飞书应用创建指南(从零开始)
|
||||
|
||||
### 第一步:创建企业自建应用
|
||||
|
||||
1. 打开 [飞书开放平台](https://open.feishu.cn/app),用管理员账号登录
|
||||
2. 点击「创建企业自建应用」
|
||||
3. 填写应用名称(如"文件传输自动化")和描述
|
||||
4. 创建后进入应用详情页,记录 **App ID** 和 **App Secret**
|
||||
|
||||
### 第二步:配置权限
|
||||
|
||||
在应用详情页 →「权限管理」中,搜索并开通以下权限:
|
||||
|
||||
| 权限名称 | 权限标识 | 用途 |
|
||||
|---------|---------|------|
|
||||
| 获取审批实例详情 | approval:instance:read | 读取审批表单内容 |
|
||||
| 同意审批 | approval:instance:approve | 自动提交审批意见 |
|
||||
| 查看审批定义 | approval:approval:read | 获取审批配置 |
|
||||
| 添加审批评论 | approval:instance:comment | 添加审批评论 |
|
||||
|
||||
### 第三步:配置事件订阅
|
||||
|
||||
1. 进入应用详情页 →「事件订阅」
|
||||
2. 请求地址填写:`http://你的公网IP:3000/api/feishu/event`
|
||||
3. 系统会发送验证请求,确保服务已启动
|
||||
4. 添加事件:搜索「审批实例状态变更」(`approval_instance`)
|
||||
5. 记录 **Verification Token**(页面顶部显示)
|
||||
|
||||
> 注意:飞书要求回调地址必须是公网可访问的 HTTP/HTTPS 地址。
|
||||
|
||||
### 第四步:发布应用
|
||||
|
||||
1. 进入「版本管理与发布」
|
||||
2. 创建版本 → 提交审核
|
||||
3. 管理员在飞书管理后台审核通过
|
||||
|
||||
### 第五步:配置审批流程
|
||||
|
||||
在飞书管理后台 → 审批管理中:
|
||||
|
||||
1. 创建/编辑三个审批表单(文件传入、文件传出、红区组权限)
|
||||
2. 在审批流程设计中,添加「机器人审批」节点(让应用自动处理)
|
||||
3. 记录每个审批的 **审批定义 Code**(在审批设置页面的 URL 中可以看到)
|
||||
|
||||
### 第六步:配置告警机器人
|
||||
|
||||
1. 在飞书中创建一个告警通知群
|
||||
2. 群设置 → 群机器人 → 添加机器人 → 自定义机器人
|
||||
3. 记录 Webhook 地址,填入 `.env` 的 `FEISHU_ALERT_WEBHOOK`
|
||||
|
||||
---
|
||||
|
||||
## API 接入说明
|
||||
|
||||
### 群晖 NAS (Synology DSM)
|
||||
|
||||
**前提条件:**
|
||||
- DSM 6.0+ 或 7.0+
|
||||
- 开启 FileStation API(默认开启)
|
||||
- 准备一个有文件管理权限的账号
|
||||
|
||||
**获取配置:**
|
||||
- `SYNOLOGY_HOST`: NAS 地址,如 `https://192.168.1.100:5001`
|
||||
- 使用自签证书时设 `SYNOLOGY_SKIP_TLS=true`
|
||||
- 确保运行本服务的服务器能访问 NAS 的 5001 端口
|
||||
|
||||
**验证连接:**
|
||||
```bash
|
||||
curl -k "https://NAS_IP:5001/webapi/auth.cgi?api=SYNO.API.Auth&version=6&method=login&account=admin&passwd=xxx&format=sid"
|
||||
```
|
||||
|
||||
### JumpServer 3.x
|
||||
|
||||
**前提条件:**
|
||||
- JumpServer 3.x 版本
|
||||
- 有 API Key 权限(在 JumpServer 控制台 → 系统设置 → API Key 中创建)
|
||||
- ic1 服务器已作为资产录入 JumpServer
|
||||
|
||||
**获取配置:**
|
||||
- `JUMPSERVER_HOST`: JumpServer 地址
|
||||
- `JUMPSERVER_KEY_ID` / `JUMPSERVER_KEY_SECRET`: API Key
|
||||
- `JUMPSERVER_ASSET_IC1`: 在 JumpServer 控制台 → 资产管理 → 找到 ic1 → URL 中的 UUID
|
||||
- `JUMPSERVER_SYSTEM_USER`: 连接 ic1 使用的系统用户(如 root)
|
||||
|
||||
**验证连接:**
|
||||
```bash
|
||||
curl -H "Authorization: Token KEY_ID:KEY_SECRET" https://JUMPSERVER_HOST/api/v1/assets/hosts/
|
||||
```
|
||||
|
||||
### Nextcloud
|
||||
|
||||
**前提条件:**
|
||||
- Nextcloud 已启用 WebDAV(默认启用)
|
||||
- 准备一个有文件管理权限的账号
|
||||
- 如需共享功能,确保 files_sharing 应用已启用
|
||||
|
||||
**获取配置:**
|
||||
- `NEXTCLOUD_HOST`: Nextcloud 地址
|
||||
- 用户名/密码用于 WebDAV 认证
|
||||
|
||||
**验证连接:**
|
||||
```bash
|
||||
curl -u user:pass https://NEXTCLOUD_HOST/remote.php/dav/files/user/ -X PROPFIND
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署方案
|
||||
|
||||
### 方案 A:公网 IP 服务器(推荐)
|
||||
|
||||
本服务非常轻量(Node.js + SQLite,内存占用约 50-100MB),适合部署在有公网 IP 的服务器上。
|
||||
|
||||
```bash
|
||||
# 使用 Docker 部署
|
||||
docker-compose up -d
|
||||
|
||||
# 或直接运行
|
||||
npm install --production
|
||||
NODE_ENV=production node src/index.js
|
||||
```
|
||||
|
||||
配合 Nginx 反向代理(可选,用于 HTTPS):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name automation.yourcompany.com;
|
||||
|
||||
ssl_certificate /path/to/cert.pem;
|
||||
ssl_certificate_key /path/to/key.pem;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 方案 B:无公网 IP 的内网服务器
|
||||
|
||||
如果服务必须部署在内网(比如需要直接访问群晖 NAS),有两种方式接收飞书事件:
|
||||
|
||||
**方式 1:内网穿透(frp)**
|
||||
|
||||
在公网服务器上部署 frps,内网服务器部署 frpc:
|
||||
|
||||
```ini
|
||||
# frpc.ini(内网服务器)
|
||||
[server]
|
||||
server_addr = 公网服务器IP
|
||||
server_port = 7000
|
||||
|
||||
[file-automation]
|
||||
type = http
|
||||
local_port = 3000
|
||||
custom_domains = automation.yourcompany.com
|
||||
```
|
||||
|
||||
飞书事件回调地址填:`http://automation.yourcompany.com/api/feishu/event`
|
||||
|
||||
**方式 2:飞书长连接模式(推荐)**
|
||||
|
||||
飞书支持 WebSocket 长连接模式,不需要公网回调地址。修改事件接收方式:
|
||||
|
||||
```javascript
|
||||
// 使用 @larksuiteoapi/node-sdk 的长连接模式
|
||||
const { Client, EventDispatcher } = require('@larksuiteoapi/node-sdk');
|
||||
|
||||
const client = new Client({ appId, appSecret });
|
||||
const wsClient = client.event.wsClient; // WebSocket 长连接
|
||||
wsClient.start(); // 主动连接飞书,无需公网IP
|
||||
```
|
||||
|
||||
> 长连接模式需要安装 `@larksuiteoapi/node-sdk` 包,适合内网部署场景。
|
||||
|
||||
### 方案 C:混合部署
|
||||
|
||||
公网服务器放一个轻量转发层(只接收飞书回调),内网服务器跑主业务逻辑:
|
||||
|
||||
```
|
||||
飞书 ──→ 公网服务器(转发) ──→ 内网服务器(业务处理) ──→ 群晖/JumpServer/Nextcloud
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 审批表单字段设计
|
||||
|
||||
为了让自动化系统正确解析,审批表单字段名需要与代码中的映射一致:
|
||||
|
||||
### 文件传入审批
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| 申请人 | 文本/人员 | 申请人姓名 |
|
||||
| 文件名称 | 文本 | 要传入的文件名 |
|
||||
|
||||
### 文件传出审批
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| 申请人 | 文本/人员 | 申请人姓名 |
|
||||
| 文件路径 | 文本 | 文件在服务器上的完整路径 |
|
||||
| 传出目的 | 单选 | 内部使用 / 客户发布 |
|
||||
| 客户名缩写 | 文本 | 仅客户发布时填写 |
|
||||
| 文件过期日期 | 日期 | 仅客户发布时填写 |
|
||||
|
||||
### 红区组权限审批
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| 待添加人员 | 文本/人员 | 人员姓名 |
|
||||
| 申请类型 | 单选 | 添加至已有group / 新建group |
|
||||
| group名称 | 文本 | Linux 组名 |
|
||||
|
||||
> 如果你的表单字段名不同,修改 `src/routes/feishu-event.js` 中的字段映射即可。
|
||||
|
||||
---
|
||||
|
||||
## 管理后台
|
||||
|
||||
访问 `http://服务器IP:3000/admin`,使用 `.env` 中配置的 `ADMIN_PASSWORD` 登录。
|
||||
|
||||
功能包括:
|
||||
- 仪表盘:今日操作统计、系统状态
|
||||
- 操作日志:按类型/状态/时间/关键词筛选,保留30天
|
||||
- 预设命令:管理可在 ic1 上执行的预设命令
|
||||
- API配置:动态管理配置项
|
||||
|
||||
---
|
||||
|
||||
## 安全机制
|
||||
|
||||
1. **白名单目录**:所有文件操作路径必须在白名单内(`/IN_R`, `/OUT_R`, `/OUT`, `/wingsemi`, `/WCPS-Files`, `/OUT-RED`)
|
||||
2. **路径穿越防护**:自动规范化路径,阻止 `../` 攻击
|
||||
3. **命令注入防护**:禁止 `;`、`$(`、反引号、`rm -rf` 等危险模式
|
||||
4. **审批绑定**:每次操作记录审批单号、申请人、时间,保留一个月
|
||||
5. **防重复处理**:同一审批实例不会重复执行
|
||||
6. **管理接口限速**:15分钟内最多100次请求
|
||||
|
||||
---
|
||||
|
||||
## 日志
|
||||
|
||||
- 运行日志:`data/logs/combined.log`(自动轮转,单文件10MB)
|
||||
- 错误日志:`data/logs/error.log`
|
||||
- 操作记录:SQLite 数据库 `data/automation.db`(可通过管理后台查看)
|
||||
|
||||
---
|
||||
|
||||
## 故障排查
|
||||
|
||||
| 问题 | 可能原因 | 解决方法 |
|
||||
|------|---------|---------|
|
||||
| 飞书事件收不到 | 回调地址不通/应用未发布 | 检查公网访问、确认应用已审核通过 |
|
||||
| 群晖操作失败 | Session 过期/权限不足 | 检查账号权限、确认 FileStation API 开启 |
|
||||
| JumpServer 命令超时 | 资产连接慢/网络问题 | 增加 timeout、检查 ic1 连通性 |
|
||||
| Nextcloud 403 | 权限不足/共享功能未启用 | 检查用户权限、启用 files_sharing |
|
||||
| 审批意见提交失败 | 无待处理任务 | 确认审批流程中有机器人审批节点 |
|
||||
Reference in New Issue
Block a user