asai-nodejs-hostweb 0.2.14 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +795 -0
- package/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
# asai-nodejs-hostweb — Web 管理后端插件
|
|
2
|
+
|
|
3
|
+
## 功能概述
|
|
4
|
+
|
|
5
|
+
`asai-nodejs-hostweb` 是一个**综合性的 Web 管理后端插件**,为 AsaiWeb 系统提供完整的 RESTful API 服务、系统管理接口和 WebSocket 通信服务。它包含四大模块:
|
|
6
|
+
|
|
7
|
+
| 模块 | 路径 | 说明 |
|
|
8
|
+
|------|------|------|
|
|
9
|
+
| **API 服务** | `api/` | RESTful 接口层,处理 `/api/*` 请求 |
|
|
10
|
+
| **系统服务** | `sys/` | 系统管理功能,处理 `/sys/*` 请求 |
|
|
11
|
+
| **WebSocket 服务** | `ws/` | WS 通信层,处理实时消息 |
|
|
12
|
+
| **库文件** | `lib-install/` | 基础工具库、加解密、数据库通道 |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 文件结构
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
asai-nodejs-hostweb/
|
|
20
|
+
├── README.md
|
|
21
|
+
└── asai-nodejs-hostweb/
|
|
22
|
+
├── index.ts ← 入口文件
|
|
23
|
+
│
|
|
24
|
+
├── api/Index.ts ← API 路由注册中心
|
|
25
|
+
├── api/init/code.ts ← 初始化码生成
|
|
26
|
+
├── api/user/userinfo.ts ← 用户信息 API(登录验证)
|
|
27
|
+
├── api/common/ ← API 管理模块
|
|
28
|
+
│ ├── utils/reqWork.ts ← 请求工具函数
|
|
29
|
+
│ ├── dirmanage.ts ← 目录管理
|
|
30
|
+
│ ├── filemanage.ts ← 文件管理
|
|
31
|
+
│ ├── jsonmanage.ts ← JSON 管理
|
|
32
|
+
│ ├── logmanage.ts ← 日志管理
|
|
33
|
+
│ ├── mmmanage.ts ← 加密文件管理
|
|
34
|
+
│ ├── shellmanage.ts ← Shell 命令执行
|
|
35
|
+
│ ├── sqlitemanage.ts ← SQLite 数据管理
|
|
36
|
+
│ └── zipmanage.ts ← ZIP 压缩管理
|
|
37
|
+
├── api/channel/ ← 数据通道模块
|
|
38
|
+
│ ├── channelfileserver.ts ← 文件通道
|
|
39
|
+
│ ├── channeljsonserver.ts ← JSON 通道
|
|
40
|
+
│ └── channelsqliteserver.ts ← SQLite 通道
|
|
41
|
+
│
|
|
42
|
+
├── sys/Index.ts ← 系统路由注册中心
|
|
43
|
+
├── sys/common/ ← 系统管理功能
|
|
44
|
+
│ ├── file.ts ← 系统文件管理
|
|
45
|
+
│ ├── json.ts ← 系统 JSON 编辑
|
|
46
|
+
│ ├── upload.ts ← 系统文件上传
|
|
47
|
+
│ ├── update.ts ← 系统更新(上传+解压)
|
|
48
|
+
│ ├── upgrade.ts ← 系统升级(部署)
|
|
49
|
+
│ ├── guard.ts ← 守护服务控制台
|
|
50
|
+
│ ├── info.ts ← 系统信息
|
|
51
|
+
│ ├── shell.ts ← 系统 Shell 执行
|
|
52
|
+
│ └── zip.ts ← 系统 ZIP 管理
|
|
53
|
+
│
|
|
54
|
+
├── ws/Index.ts ← WS 路由注册中心
|
|
55
|
+
├── ws/common/ping.ts ← WS 心跳 Ping
|
|
56
|
+
├── ws/user/login.ts ← WS 用户登录
|
|
57
|
+
├── ws/user/exit.ts ← WS 用户退出
|
|
58
|
+
├── ws/user/online.ts ← WS 在线用户列表
|
|
59
|
+
├── ws/chat/web.ts ← WS Web 聊天
|
|
60
|
+
│
|
|
61
|
+
└── lib-install/ ← 基础库(挂载到 $asai.$lib)
|
|
62
|
+
├── Index.ts ← 库入口(汇总导出)
|
|
63
|
+
├── common/
|
|
64
|
+
│ ├── As.ts ← 通用工具(响应封装、UUID、防抖节流)
|
|
65
|
+
│ ├── AsAES.ts ← AES 加解密
|
|
66
|
+
│ ├── AsCode.ts ← 自定义编码加密
|
|
67
|
+
│ ├── AsNodeTool.ts ← Node 工具(Shell、二进制上传、守护进程)
|
|
68
|
+
│ ├── AsDb.ts ← 数据库服务封装
|
|
69
|
+
│ ├── AsDbChannelFile.ts ← 文件通道数据操作
|
|
70
|
+
│ ├── AsDbPlugs.ts ← 数据库插件扩展
|
|
71
|
+
│ └── AsSys.ts ← 系统工具(读写文件、ZIP、关闭服务)
|
|
72
|
+
└── server/
|
|
73
|
+
├── Api.ts ← API 请求分发引擎
|
|
74
|
+
├── Sys.ts ← 系统请求分发引擎
|
|
75
|
+
├── Ws.ts ← WebSocket 消息分发引擎
|
|
76
|
+
└── WsClient.ts ← WebSocket 客户端
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 一、入口文件分析 — `index.ts`
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
module.exports = {
|
|
85
|
+
...require('./lib-install/Index.ts'), // 基础库
|
|
86
|
+
api: require('./api/Index.ts'), // API 路由
|
|
87
|
+
sys: require('./sys/Index.ts'), // 系统路由
|
|
88
|
+
ws: require('./ws/Index.ts'), // WS 路由
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
将四大模块合并导出,其中 `lib-install/Index.ts` 的所有导出被展开在顶层。
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 二、基础库 (`lib-install/`)
|
|
97
|
+
|
|
98
|
+
### `lib-install/Index.ts` — 库入口
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
module.exports = {
|
|
102
|
+
As: require('./common/As.ts'),
|
|
103
|
+
AsSys: require('./common/AsSys.ts'),
|
|
104
|
+
AsNodeTool: require('./common/AsNodeTool.ts'),
|
|
105
|
+
AsCode: require('./common/AsCode.ts'),
|
|
106
|
+
AsAES: require('./common/AsAES.ts'),
|
|
107
|
+
AsDb: require('./common/AsDb.ts'),
|
|
108
|
+
ServerApi: require('./server/Api.ts'),
|
|
109
|
+
ServerWs: require('./server/Ws.ts'),
|
|
110
|
+
ServerSys: require('./server/Sys.ts'),
|
|
111
|
+
WsClient: require('./server/WsClient.ts'),
|
|
112
|
+
};
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
### `common/As.ts` — 通用工具库
|
|
118
|
+
|
|
119
|
+
| 函数 | 说明 |
|
|
120
|
+
|------|------|
|
|
121
|
+
| `ctxSuccess(val, opt)` | 成功响应 `{ code: 909, data: val }` |
|
|
122
|
+
| `ctxFail(val)` | 失败响应 `{ code: 907, data: val }` |
|
|
123
|
+
| `ctxEmpty(val)` | 空响应 `{ code: 908, data: val }` |
|
|
124
|
+
| `getPath(str)` | 净化路径(仅保留字母数字和 `./\-_`) |
|
|
125
|
+
| `getName(str)` | 净化文件名(仅保留字母数字和 `.-_`) |
|
|
126
|
+
| `toDirPath(relativePath)` | 相对路径 → 目录路径 |
|
|
127
|
+
| `toAbsolutePath(relativePath)` | 相对路径 → 绝对路径(基于 `cwd()`) |
|
|
128
|
+
| `ensureDir(fs, relativePath)` | 同步创建多层文件夹 |
|
|
129
|
+
| `makeDir(fs, filePaths)` | Promise 版创建文件夹 |
|
|
130
|
+
| `getFilePath(str)` | 获取文件路径(上传专用) |
|
|
131
|
+
| `debounce(fn, opt)` | 防抖 |
|
|
132
|
+
| `throttle(fn, opt)` | 节流 |
|
|
133
|
+
| `Uuid(startsWord, index, hex)` | 生成 12-16 位唯一 ID |
|
|
134
|
+
| `getIp(req)` | 获取请求 IP |
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### `common/AsAES.ts` — AES 加解密
|
|
139
|
+
|
|
140
|
+
基于 Node.js `crypto` 模块,使用 `aes-256-gcm` 算法。
|
|
141
|
+
|
|
142
|
+
| 函数 | 说明 |
|
|
143
|
+
|------|------|
|
|
144
|
+
| `encrypt(plaintext)` | 加密字符串,返回 `{ data, iv, auth }` |
|
|
145
|
+
| `decrypt(encrypto)` | 解密,接收 `{ data, iv, auth }` |
|
|
146
|
+
| `reqAES(opt, fn)` | 请求解密自动处理 |
|
|
147
|
+
| `resAES(data)` | 响应加密自动处理 |
|
|
148
|
+
|
|
149
|
+
**配置**(`$asai.hostconfig.aes`):
|
|
150
|
+
| 参数 | 说明 |
|
|
151
|
+
|------|------|
|
|
152
|
+
| `keybase64` | 密钥(Base64 编码) |
|
|
153
|
+
| `aad` | 附加认证数据 |
|
|
154
|
+
| `ivlength` | 初始向量长度(默认16) |
|
|
155
|
+
| `algorithm` | 加密算法(默认 `aes-256-gcm`) |
|
|
156
|
+
| `lv` | 加密等级(>1 时全局启用) |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### `common/AsCode.ts` — 自定义编码加密
|
|
161
|
+
|
|
162
|
+
一种基于字符置换的自编加密算法,用于编码敏感信息(如用户信息、Token)。
|
|
163
|
+
|
|
164
|
+
| 函数 | 说明 |
|
|
165
|
+
|------|------|
|
|
166
|
+
| `asencode(str, keys)` | 加密字符串,返回值:每 4 字符一组(3 位数据 + 1 位随机) |
|
|
167
|
+
| `asdecode(str, keys)` | 解密字符串 |
|
|
168
|
+
| `getCodeData(data, keys)` | 解码嵌套加密的数据 |
|
|
169
|
+
| `sendCodeData(data, keys, code)` | 编码嵌套数据 |
|
|
170
|
+
| `asnewkey(str)` | 打乱字符串字符顺序(用于生成新密钥) |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### `common/AsNodeTool.ts` — Node 工具函数
|
|
175
|
+
|
|
176
|
+
| 函数 | 说明 |
|
|
177
|
+
|------|------|
|
|
178
|
+
| `upBinary(req)` | 解析 multipart/form-data 上传,提取二进制文件数据。支持进度日志 |
|
|
179
|
+
| `doShell(cmd)` | 执行 Shell 命令(支持中文编码 cp936),超时 600 秒 |
|
|
180
|
+
| `saveData(fs, filePaths, data)` | 保存数据到文件 |
|
|
181
|
+
| `startGuardServer($asai, config, opt)` | 启动守护子进程,支持自动重启(指数退避) |
|
|
182
|
+
|
|
183
|
+
**`startGuardServer()` 配置**:
|
|
184
|
+
| 参数 | 说明 |
|
|
185
|
+
|------|------|
|
|
186
|
+
| `app` | 子进程入口文件路径 |
|
|
187
|
+
| `ispath` | 是否基于 `__dirname` 解析路径 |
|
|
188
|
+
| `isexe` | 是否可执行文件 |
|
|
189
|
+
| `cfg` | `spawn` 配置参数 |
|
|
190
|
+
| `trymax` | 最大重试次数 |
|
|
191
|
+
| `trytm` | 初始重试延迟(ms) |
|
|
192
|
+
| `tryft` | 重试延迟增长因子 |
|
|
193
|
+
| `maxtm` | 最大重试延迟(ms) |
|
|
194
|
+
| `isoff` | 是否关闭守护 |
|
|
195
|
+
| `log` | 是否输出日志 |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### `common/AsDb.ts` — 数据库服务封装
|
|
200
|
+
|
|
201
|
+
将 HTTP 请求参数转换为 `Idb` 结构并执行数据库操作。
|
|
202
|
+
|
|
203
|
+
**核心功能**:
|
|
204
|
+
| 函数 | 说明 |
|
|
205
|
+
|------|------|
|
|
206
|
+
| `getSqlParamsByUrl(req, opt)` | 从 URL 和请求体中提取 SQL 参数 |
|
|
207
|
+
| `reqfield(queryData)` | 提取查询字段 |
|
|
208
|
+
| `reqwhere(queryData)` | 构建 WHERE 条件(支持等级、分类、搜索) |
|
|
209
|
+
| `reqorder(queryData)` | 构建 ORDER 排序 |
|
|
210
|
+
| `reqlimit(queryData)` | 构建 LIMIT 限制(支持分页) |
|
|
211
|
+
| `post(req, res, hostdir, opt)` | POST 请求处理 |
|
|
212
|
+
| `get(req, res, hostdir, opt)` | GET 请求处理 |
|
|
213
|
+
| `dbFresh(req, resdb)` | 特殊请求封装(如 selectlist) |
|
|
214
|
+
| `dbCodePm(req, resdb)` | 加密返回数据 |
|
|
215
|
+
|
|
216
|
+
**URL 路由模式**:
|
|
217
|
+
```
|
|
218
|
+
/api/{table}/{action}/{key}
|
|
219
|
+
```
|
|
220
|
+
- `action` = `insert`, `update`, `delete`, `select`(留空默认 select)
|
|
221
|
+
- `key` 为主键值(指定单条记录)
|
|
222
|
+
|
|
223
|
+
**自定义处理器**:通过 `cfg.post` 和 `cfg.get` 可扩展自定义逻辑。
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### `common/AsDbChannelFile.ts` — 文件通道数据操作
|
|
228
|
+
|
|
229
|
+
用于管理基于文件系统的内容通道数据(分类数据 + 内容文件):
|
|
230
|
+
|
|
231
|
+
| 函数 | 说明 |
|
|
232
|
+
|------|------|
|
|
233
|
+
| `getFileList(req, res, hostdir, opt, field, query)` | 获取文件列表(支持搜索、排序、分页) |
|
|
234
|
+
| `editFileData(req, res, hostdir, opt, field, query)` | 编辑文件内容(含分类 JSON 和内容文件) |
|
|
235
|
+
| `delFileData(req, res, hostdir, opt, field, query)` | 删除文件内容 |
|
|
236
|
+
|
|
237
|
+
**数据存储结构**:
|
|
238
|
+
```
|
|
239
|
+
{dir}/
|
|
240
|
+
├── class/{fl}.json ← 分类数据(JSON 列表)
|
|
241
|
+
└── file/{sn}.txt ← 具体内容文件
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**缓存机制**:`$asai.channel` 缓存分类列表数据
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### `common/AsDbPlugs.ts` — 数据库插件扩展
|
|
249
|
+
|
|
250
|
+
提供基于文件通道的扩展查询功能:
|
|
251
|
+
|
|
252
|
+
| 函数 | 说明 |
|
|
253
|
+
|------|------|
|
|
254
|
+
| `getFileChannel(req, res, hostdir, opt, field, query)` | 文件通道查询(支持过滤、排序、分页、字段选择) |
|
|
255
|
+
| `getFileList(req, res, hostdir, opt, field, query)` | 文件列表查询(基于分类 JSON) |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### `common/AsSys.ts` — 系统工具
|
|
260
|
+
|
|
261
|
+
| 函数 | 说明 |
|
|
262
|
+
|------|------|
|
|
263
|
+
| `fsReadFile(filePaths, res)` | 读取文件并响应 |
|
|
264
|
+
| `fsWriteFile(filePaths, data, res)` | 写入文件并响应 |
|
|
265
|
+
| `zipWork(workcfg)` | ZIP 压缩解压工作流(支持预清理、文件复制) |
|
|
266
|
+
| `copyFileWork(workcfg)` | 文件复制工作流(支持文件和目录级别的复制) |
|
|
267
|
+
| `closeConnections(servername, callback)` | 优雅关闭服务(WS → HTTP → 回调) |
|
|
268
|
+
|
|
269
|
+
**`zipWork()` 配置**:
|
|
270
|
+
| 参数 | 说明 |
|
|
271
|
+
|------|------|
|
|
272
|
+
| `type` | `'zip'` 或 `'unzip'` |
|
|
273
|
+
| `zipfile` | ZIP 文件路径 |
|
|
274
|
+
| `zipdir` | 压缩源目录(zip 模式) |
|
|
275
|
+
| `unzipdir` | 解压目标目录(unzip 模式) |
|
|
276
|
+
| `clean` | 是否先清空目标目录 |
|
|
277
|
+
| `files` | 文件复制列表 `[src, dest, type]` |
|
|
278
|
+
| `dirs` | 目录复制列表 |
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### `server/Api.ts` — API 请求分发引擎
|
|
283
|
+
|
|
284
|
+
处理所有 `/api/*` 请求的核心路由引擎。
|
|
285
|
+
|
|
286
|
+
**功能**:
|
|
287
|
+
1. **CORS 处理**:支持跨域白名单和预检请求
|
|
288
|
+
2. **URL 解析**:支持 GET 参数的 `pm` 加密、AES 加密
|
|
289
|
+
3. **POST 处理**:支持普通 JSON、AES 加密、`AsCode` 加密、二进制上传
|
|
290
|
+
4. **路由匹配**:前缀匹配式路由查找
|
|
291
|
+
|
|
292
|
+
**AES 加密请求处理**:
|
|
293
|
+
- GET:`?aes={data, iv, auth}` 格式
|
|
294
|
+
- POST:`{"aes": 1/2, "data": "...", "iv": "...", "auth": "..."}` 格式
|
|
295
|
+
|
|
296
|
+
**用户信息处理**:从 `Userinfo` 请求头获取解码后的用户身份,用于数据权限控制。
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
### `server/Sys.ts` — 系统请求分发引擎
|
|
301
|
+
|
|
302
|
+
处理所有 `/sys/*` 请求的路由引擎。
|
|
303
|
+
|
|
304
|
+
- 前缀匹配式路由查找
|
|
305
|
+
- 返回 `handler.show()` 处理结果
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
### `server/Ws.ts` — WebSocket 消息分发引擎
|
|
310
|
+
|
|
311
|
+
处理所有 WebSocket 消息的路由引擎。
|
|
312
|
+
|
|
313
|
+
**消息解析**:
|
|
314
|
+
1. Buffer → string → JSON parse
|
|
315
|
+
2. 检查 `msg.ty` 前缀匹配路由
|
|
316
|
+
3. 如无匹配,转交 `$asai.asaimock.wsWorkMock()` 处理
|
|
317
|
+
|
|
318
|
+
**AES 解密**:自动检测 `msg.db.aes` 字段,调用 `aesfns.reqAES()` 解密。
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### `server/WsClient.ts` — WebSocket 客户端
|
|
323
|
+
|
|
324
|
+
用于作为客户端连接其他 WebSocket 服务器。
|
|
325
|
+
|
|
326
|
+
| 函数 | 说明 |
|
|
327
|
+
|------|------|
|
|
328
|
+
| `clientwsInit()` | 初始化 WebSocket 连接 |
|
|
329
|
+
| `clientwsSend(message)` | 发送消息 |
|
|
330
|
+
| `clientwsApi(messageData)` | 发送请求并等待响应(Promise) |
|
|
331
|
+
| `clientwsWatch(messageData, cb)` | 注册监听回调 |
|
|
332
|
+
| `clientwsWatchOff(messageData)` | 取消监听 |
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## 三、API 管理模块 (`api/common/`)
|
|
337
|
+
|
|
338
|
+
### `utils/reqWork.ts` — 共享工具函数
|
|
339
|
+
|
|
340
|
+
为所有管理模块提供统一的请求处理工具:
|
|
341
|
+
|
|
342
|
+
| 函数 | 说明 |
|
|
343
|
+
|------|------|
|
|
344
|
+
| `getPathFromOpt(opt)` | 从请求选项中提取并解码文件路径 |
|
|
345
|
+
| `sendSuccess(res, data, opt)` | 发送成功响应 |
|
|
346
|
+
| `sendFail(res, err, opt)` | 发送失败响应 |
|
|
347
|
+
| `mnLog(...arg)` | 统一日志输出 |
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### `dirmanage.ts` — 目录管理
|
|
352
|
+
|
|
353
|
+
| 路由 | 方法 | 功能 |
|
|
354
|
+
|------|------|------|
|
|
355
|
+
| `/api/asaidir/manage/select/{path}` | GET | 读取目录内容列表 |
|
|
356
|
+
| `/api/asaidir/manage/delete/{path}` | GET | 删除目录 |
|
|
357
|
+
| `/api/asaidir/manage/update/{path}` | POST | 清空目录 |
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
### `filemanage.ts` — 文件管理
|
|
362
|
+
|
|
363
|
+
| 路由 | 方法 | 功能 |
|
|
364
|
+
|------|------|------|
|
|
365
|
+
| `/api/asaifile/manage/copy/{path}` | POST | 复制文件/目录 |
|
|
366
|
+
| `/api/asaifile/manage/update/{path}` | POST | 更新文件内容 |
|
|
367
|
+
| `/api/asaifile/manage/upbase64/{path}` | POST | Base64 上传文件 |
|
|
368
|
+
| `/api/asaifile/manage/upbinary/{path}` | POST | 二进制上传文件 |
|
|
369
|
+
| `/api/asaifile/manage/upbase64batch/{path}` | POST | 批量 Base64 上传 |
|
|
370
|
+
| `/api/asaifile/manage/upbinarybatch/{path}` | POST | 批量二进制上传 |
|
|
371
|
+
| `/api/asaifile/manage/once/{path}` | GET | 读取文件(带缓存) |
|
|
372
|
+
| `/api/asaifile/manage/select/{path}` | GET | 读取文件 |
|
|
373
|
+
| `/api/asaifile/manage/delete/{path}` | GET | 删除文件 |
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### `jsonmanage.ts` — JSON 管理
|
|
378
|
+
|
|
379
|
+
| 路由 | 方法 | 功能 |
|
|
380
|
+
|------|------|------|
|
|
381
|
+
| `/api/asaijson/manage/rankings/{path}` | POST | 排行榜数据更新 |
|
|
382
|
+
| `/api/asaijson/manage/update/{path}` | POST | 更新 JSON 文件 |
|
|
383
|
+
| `/api/asaijson/manage/upbatch/{path}` | POST | 批量更新 JSON |
|
|
384
|
+
| `/api/asaijson/manage/add/{path}` | POST | 追加数据到 JSON |
|
|
385
|
+
| `/api/asaijson/manage/select/{path}` | GET | 读取 JSON 文件 |
|
|
386
|
+
| `/api/asaijson/manage/delete/{path}` | GET | 删除 JSON 文件 |
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### `logmanage.ts` — 日志管理
|
|
391
|
+
|
|
392
|
+
| 路由 | 方法 | 功能 |
|
|
393
|
+
|------|------|------|
|
|
394
|
+
| `/api/asailog/manage/addclient/{path}` | POST | 添加客户端日志 |
|
|
395
|
+
| `/api/asailog/manage/add/{path}` | POST | 添加服务器日志 |
|
|
396
|
+
| `/api/asailog/manage/update/{path}` | POST | 更新日志文件 |
|
|
397
|
+
| `/api/asailog/manage/selectlist/{path}` | GET | 列出日志目录 |
|
|
398
|
+
| `/api/asailog/manage/select/{path}` | GET | 读取日志文件 |
|
|
399
|
+
| `/api/asailog/manage/delete/{path}` | GET | 删除日志文件 |
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
### `mmmanage.ts` — 加密文件管理 (`asaimm/manage`)
|
|
404
|
+
|
|
405
|
+
| 路由 | 方法 | 功能 |
|
|
406
|
+
|------|------|------|
|
|
407
|
+
| `/api/asaimm/manage/update/{path}` | POST | 更新加密文件 |
|
|
408
|
+
| `/api/asaimm/manage/selectlist/{path}` | GET | 读取目录中所有文件(AES 解密后,敏感字段置空) |
|
|
409
|
+
| `/api/asaimm/manage/select/{path}` | GET | 读取单个文件 |
|
|
410
|
+
| `/api/asaimm/manage/delete/{path}` | GET | 删除文件 |
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
### `shellmanage.ts` — Shell 命令管理
|
|
415
|
+
|
|
416
|
+
| 路由 | 方法 | 功能 |
|
|
417
|
+
|------|------|------|
|
|
418
|
+
| `/api/asaishell/manage/post/{path}` | POST | 执行 Shell 命令 |
|
|
419
|
+
| `/api/asaishell/manage/get/{path}` | GET | 执行 Shell 命令 |
|
|
420
|
+
| `/api/asaishell/manage/gettm/{path}` | GET | 获取当前时间戳 |
|
|
421
|
+
|
|
422
|
+
---
|
|
423
|
+
|
|
424
|
+
### `sqlitemanage.ts` — SQLite 数据管理
|
|
425
|
+
|
|
426
|
+
| 路由 | 方法 | 功能 |
|
|
427
|
+
|------|------|------|
|
|
428
|
+
| `/api/asaisqlite/manage/post` | POST | 自定义处理器 |
|
|
429
|
+
| `/api/asaisqlite/manage/get` | GET | 查询表数据 |
|
|
430
|
+
|
|
431
|
+
**数据库配置**:`./webdata/webdb/testkdd/sqlite/asaisqlitetest.db`
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### `zipmanage.ts` — ZIP 压缩管理
|
|
436
|
+
|
|
437
|
+
| 路由 | 方法 | 功能 |
|
|
438
|
+
|------|------|------|
|
|
439
|
+
| `/api/asaizip/manage/post` | POST | 执行压缩/解压工作 |
|
|
440
|
+
| `/api/asaizip/manage/get` | GET | 执行压缩/解压工作 |
|
|
441
|
+
| `/api/asaizip/manage/zipdir` | GET | 直接压缩目录 |
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## 四、数据通道 (`api/channel/`)
|
|
446
|
+
|
|
447
|
+
### `channelfileserver.ts` — 文件通道
|
|
448
|
+
|
|
449
|
+
提供基于文件系统的内容管理通道:
|
|
450
|
+
|
|
451
|
+
| 参数 | 默认值 | 说明 |
|
|
452
|
+
|------|--------|------|
|
|
453
|
+
| `model` | `'asai'` | 模型名称 |
|
|
454
|
+
| `channel` | `'asaichannel'` | 通道名称 |
|
|
455
|
+
| `field` | 参考 query | 数据字段 |
|
|
456
|
+
| `path` | — | 自定义存储目录 |
|
|
457
|
+
| `key` | `sn` | 主键字段 |
|
|
458
|
+
| `class` | `class` | 分类字段 |
|
|
459
|
+
|
|
460
|
+
**数据目录**:`webdata/webdb/channelfile/{model}/channel/{channel}/`
|
|
461
|
+
|
|
462
|
+
**文件结构**:
|
|
463
|
+
```
|
|
464
|
+
{dir}/
|
|
465
|
+
├── class/{fl}.json ← 分类索引
|
|
466
|
+
└── file/{sn}.txt ← 内容
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
### `channeljsonserver.ts` — JSON 通道
|
|
472
|
+
|
|
473
|
+
基于文件系统的纯 JSON 数据通道:
|
|
474
|
+
|
|
475
|
+
| 参数 | 说明 |
|
|
476
|
+
|------|------|
|
|
477
|
+
| `as` | 固定为 2(JSON 解析模式) |
|
|
478
|
+
| `type` | `'file'` |
|
|
479
|
+
|
|
480
|
+
**数据目录**:`webdata/webdb/channeljson/{model}/channel/{channel}/`
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
### `channelsqliteserver.ts` — SQLite 通道
|
|
485
|
+
|
|
486
|
+
基于 SQLite 的数据通道:
|
|
487
|
+
|
|
488
|
+
| 参数 | 说明 |
|
|
489
|
+
|------|------|
|
|
490
|
+
| `type` | `'sqlite'` |
|
|
491
|
+
| `field.data` | 默认 `['sn', 'tit', 'class', 'us']` |
|
|
492
|
+
|
|
493
|
+
**数据库路径**:`./webdata/webdb/channelsqlite/{model}/channel/{channel}/sqlite.db`
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## 五、API 基础服务 (`api/`)
|
|
498
|
+
|
|
499
|
+
### `api/init/code.ts` — 初始化码
|
|
500
|
+
|
|
501
|
+
| 路由 | 方法 | 功能 |
|
|
502
|
+
|------|------|------|
|
|
503
|
+
| `/api/init/code` | GET/POST | 返回初始化加密码(基于 `asaisn` 序列号) |
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
### `api/user/userinfo.ts` — 用户信息
|
|
508
|
+
|
|
509
|
+
基于 `AsDb` 封装,提供用户数据管理:
|
|
510
|
+
|
|
511
|
+
| 配置项 | 说明 |
|
|
512
|
+
|--------|------|
|
|
513
|
+
| 存储类型 | 默认 `file`(JSON 文件) |
|
|
514
|
+
| 存储目录 | `webdata/webdbuser/` |
|
|
515
|
+
| 数据字段 | `['us', 'pw', 'lv']`(用户名、密码、等级) |
|
|
516
|
+
| 主键 | `us`(用户名) |
|
|
517
|
+
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
## 六、系统管理 (`sys/`)
|
|
521
|
+
|
|
522
|
+
所有系统管理接口均需在 URL 中传递密码:`/sys/{name}/submit/{password}/...`
|
|
523
|
+
|
|
524
|
+
### `sys/common/file.ts` — 系统文件管理
|
|
525
|
+
|
|
526
|
+
| 路由 | 功能 |
|
|
527
|
+
|------|------|
|
|
528
|
+
| `/sys/file/delete/{pwd}/?fpath=` | 删除文件 |
|
|
529
|
+
| `/sys/file/manage/{pwd}/?fpath=` | 读取目录内容 |
|
|
530
|
+
| `/sys/file/submit/{pwd}/?fpath=` | 读取/写入文件 |
|
|
531
|
+
|
|
532
|
+
### `sys/common/json.ts` — 系统 JSON 编辑
|
|
533
|
+
|
|
534
|
+
| 路由 | 功能 |
|
|
535
|
+
|------|------|
|
|
536
|
+
| `/sys/json/submit/{pwd}/?fpath=` | 读取/写入 JSON 文件,自动格式化 |
|
|
537
|
+
|
|
538
|
+
### `sys/common/upload.ts` — 系统文件上传
|
|
539
|
+
|
|
540
|
+
| 路由 | 功能 |
|
|
541
|
+
|------|------|
|
|
542
|
+
| `/sys/upload/submit/{pwd}/?uppath=` | 上传二进制文件到指定路径 |
|
|
543
|
+
|
|
544
|
+
### `sys/common/update.ts` — 系统更新
|
|
545
|
+
|
|
546
|
+
| 路由 | 功能 |
|
|
547
|
+
|------|------|
|
|
548
|
+
| `/sys/update/submit/{pwd}/?unzippath=` | 上传 ZIP 包并解压到指定目录 |
|
|
549
|
+
|
|
550
|
+
### `sys/common/upgrade.ts` — 系统升级
|
|
551
|
+
|
|
552
|
+
| 路由 | 功能 |
|
|
553
|
+
|------|------|
|
|
554
|
+
| `/sys/upgrade/msg` | 获取升级日志 |
|
|
555
|
+
| `/sys/upgrade/submit/{pwd}/work` | 提交升级配置并执行部署 |
|
|
556
|
+
| `/sys/upgrade/submit/{pwd}/upload` | 上传升级包 ZIP |
|
|
557
|
+
|
|
558
|
+
**升级流程**:上传 ZIP → 解压到 `webdata/upload/upgrade/` → 读取 `config.json` → 执行文件复制部署
|
|
559
|
+
|
|
560
|
+
### `sys/common/guard.ts` — 守护服务
|
|
561
|
+
|
|
562
|
+
| 路由 | 功能 |
|
|
563
|
+
|------|------|
|
|
564
|
+
| `/sys/guard/msg` | 获取守护进程日志 |
|
|
565
|
+
| `/sys/guard/login/{pwd}` | 登录验证 |
|
|
566
|
+
| `/sys/guard/work/{pwd}/?fpath=` | 读取/写入守护配置 |
|
|
567
|
+
| `/sys/guard/submit/{pwd}/?pm=` | 重启/关闭指定站点 |
|
|
568
|
+
|
|
569
|
+
### `sys/common/info.ts` — 系统信息
|
|
570
|
+
|
|
571
|
+
| 路由 | 功能 |
|
|
572
|
+
|------|------|
|
|
573
|
+
| `/sys/info/map` | 获取系统服务映射 |
|
|
574
|
+
| `/sys/info/submit/{pwd}` | 获取系统性能信息(带密码:详细性能数据;无密码:基本系统信息) |
|
|
575
|
+
|
|
576
|
+
**返回数据**包括:CPU 使用率、内存占用、堆内存、系统负载、进程信息、网络接口等。
|
|
577
|
+
|
|
578
|
+
### `sys/common/shell.ts` — 系统 Shell
|
|
579
|
+
|
|
580
|
+
| 路由 | 功能 |
|
|
581
|
+
|------|------|
|
|
582
|
+
| `/sys/shell/submit/{pwd}/?cmd=` | 执行 Shell 命令 |
|
|
583
|
+
|
|
584
|
+
### `sys/common/zip.ts` — 系统 ZIP 管理
|
|
585
|
+
|
|
586
|
+
| 路由 | 功能 |
|
|
587
|
+
|------|------|
|
|
588
|
+
| `/sys/zip/msg` | 获取 ZIP 操作日志 |
|
|
589
|
+
| `/sys/zip/submit/{pwd}/?fpath=` | 读取/写入 ZIP 配置并执行压缩 |
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## 七、WebSocket 服务 (`ws/`)
|
|
594
|
+
|
|
595
|
+
### `ws/common/ping.ts` — 心跳检测
|
|
596
|
+
|
|
597
|
+
| 消息类型 | 响应 |
|
|
598
|
+
|----------|------|
|
|
599
|
+
| `ping` | 返回 `pong` |
|
|
600
|
+
|
|
601
|
+
### `ws/user/login.ts` — WebSocket 登录
|
|
602
|
+
|
|
603
|
+
验证用户身份并同步连接状态,处理同一账号多端登录的踢下线逻辑。
|
|
604
|
+
|
|
605
|
+
### `ws/user/exit.ts` — WebSocket 退出
|
|
606
|
+
|
|
607
|
+
| 消息类型 | 行为 |
|
|
608
|
+
|----------|------|
|
|
609
|
+
| `user/exit` | 返回空数据确认退出 |
|
|
610
|
+
|
|
611
|
+
### `ws/user/online.ts` — 在线用户列表
|
|
612
|
+
|
|
613
|
+
| 消息类型 | 响应 |
|
|
614
|
+
|----------|------|
|
|
615
|
+
| `user/online` | 返回所有在线用户名列表 |
|
|
616
|
+
|
|
617
|
+
### `ws/chat/web.ts` — Web 聊天
|
|
618
|
+
|
|
619
|
+
| 消息类型 | 说明 |
|
|
620
|
+
|----------|------|
|
|
621
|
+
| `chat/web/send` | 进入消息广播模式,收集消息后节流广播 |
|
|
622
|
+
| `chat/web/broadcast` | 自动发送的广播消息 |
|
|
623
|
+
|
|
624
|
+
**支持房间功能**:通过 `msgdata.db.room` 指定聊天室。
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## 配置参考
|
|
629
|
+
|
|
630
|
+
### API 服务配置 (`$asai.hostconfig`)
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
{
|
|
634
|
+
// API 安全
|
|
635
|
+
password: 'admin123', // 系统管理密码
|
|
636
|
+
asaisn: 'SN-2024-001', // 序列号(用于加解密)
|
|
637
|
+
oncors: true, // 是否启用严格 CORS 校验
|
|
638
|
+
website: {
|
|
639
|
+
title: 'AsaiWeb',
|
|
640
|
+
ver: '1.0.0'
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
// ZIP 配置
|
|
644
|
+
zip: {
|
|
645
|
+
zipFileNameEncoding: 'gbk'
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### 响应格式
|
|
651
|
+
|
|
652
|
+
所有 API 响应均为 JSON 格式:
|
|
653
|
+
```javascript
|
|
654
|
+
{ code: 909, data: ... } // 成功
|
|
655
|
+
{ code: 907, data: ... } // 失败
|
|
656
|
+
{ code: 908, data: ... } // 空
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
## 使用示例
|
|
662
|
+
|
|
663
|
+
### API 请求示例
|
|
664
|
+
|
|
665
|
+
```bash
|
|
666
|
+
# 初始化码
|
|
667
|
+
GET /api/init/code
|
|
668
|
+
→ {"code": 909, "data": ["abc123", "加密后的初始化码"]}
|
|
669
|
+
|
|
670
|
+
# 读取 JSON 文件
|
|
671
|
+
GET /api/asaijson/manage/select/webdata/config/setting.json
|
|
672
|
+
→ {"code": 909, "data": {...}}
|
|
673
|
+
|
|
674
|
+
# 更新文件(POST)
|
|
675
|
+
POST /api/asaifile/manage/update/webdata/config/setting.json
|
|
676
|
+
Body: {"key": "value"}
|
|
677
|
+
|
|
678
|
+
# 目录管理
|
|
679
|
+
GET /api/asaidir/manage/select/webdata/config/
|
|
680
|
+
→ {"code": 909, "data": { "name": "config", "children": [...] }}
|
|
681
|
+
|
|
682
|
+
# 执行 Shell 命令
|
|
683
|
+
POST /api/asaishell/manage/post/
|
|
684
|
+
Body: {"cmd": "node -v"}
|
|
685
|
+
→ {"code": 909, "data": "v18.12.0\n"}
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
---
|
|
689
|
+
|
|
690
|
+
## 注意事项
|
|
691
|
+
|
|
692
|
+
1. 所有 `/sys/*` 路由需要在 URL 中明文传递系统密码,建议在生产环境限制访问
|
|
693
|
+
2. `AsCode` 加密算法为自己的实现,非标准加密算法
|
|
694
|
+
3. WS 消息的 `ty` 字段是路由匹配的关键字
|
|
695
|
+
4. 数据通道(Channel)的 `as=2` 模式将数据作为 JSON 解析
|
|
696
|
+
5. `mmmanage` 返回数据时敏感字段(`pw`、`mm`)会被自动置空
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
## 代码分析与优化建议
|
|
701
|
+
|
|
702
|
+
### 一、安全相关问题 🔴
|
|
703
|
+
|
|
704
|
+
#### 1. 系统密码明文传输 🔴 严重
|
|
705
|
+
|
|
706
|
+
**当前问题**:所有 `/sys/*` 路由的密码通过 URL 明文传递,如 `/sys/file/delete/{password}/?fpath=...`。密码会记录在服务器日志、浏览器历史、反向代理日志中。
|
|
707
|
+
|
|
708
|
+
**建议方案**:
|
|
709
|
+
- 改用请求头传递密码(如 `Authorization: Bearer {token}`)
|
|
710
|
+
- 或使用 `POST` + 请求体传递密码
|
|
711
|
+
- 增加 Session/Token 机制,一次认证多次使用
|
|
712
|
+
|
|
713
|
+
**优化收益**:消除密码泄露风险。
|
|
714
|
+
|
|
715
|
+
---
|
|
716
|
+
|
|
717
|
+
#### 2. AsCode 加密是自定义算法,非标准加密 🔴 严重
|
|
718
|
+
|
|
719
|
+
**当前问题**:`AsCode.ts` 实现的 `asencode/asdecode` 是自研的字符置换算法,没有经过密码学安全性验证,存在可预测风险。
|
|
720
|
+
|
|
721
|
+
**建议**:
|
|
722
|
+
- 传输层敏感数据(如 Token)应使用标准 AES(`AsAES.ts` 已实现)
|
|
723
|
+
- `AsCode` 仅作为数据混淆使用(如隐藏 URL 参数),不做安全加密
|
|
724
|
+
- 在文档中明确标注 `AsCode` 不是安全加密算法
|
|
725
|
+
|
|
726
|
+
---
|
|
727
|
+
|
|
728
|
+
#### 3. 路径遍历攻击风险 🟡 中
|
|
729
|
+
|
|
730
|
+
**当前问题**:多个 API 和系统接口直接拼接用户输入的 `fpath` 参数到文件路径中,未做充分的路径白名单校验。
|
|
731
|
+
|
|
732
|
+
**建议**:增加路径白名单校验:
|
|
733
|
+
```typescript
|
|
734
|
+
function sanitizePath(inputPath: string, allowedBase: string): string {
|
|
735
|
+
const resolved = path.resolve(allowedBase, inputPath);
|
|
736
|
+
if (!resolved.startsWith(path.resolve(allowedBase))) {
|
|
737
|
+
throw new Error('Path traversal detected');
|
|
738
|
+
}
|
|
739
|
+
return resolved;
|
|
740
|
+
}
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
---
|
|
744
|
+
|
|
745
|
+
### ✅ 已优化项目
|
|
746
|
+
|
|
747
|
+
#### 9. CPU 百分比计算不准确(info.ts)✅
|
|
748
|
+
|
|
749
|
+
**优化内容**:`getSystemPerformance()` 中 CPU 百分比计算增加 `os.cpus().length` 核心数校准,使用更准确的分母。
|
|
750
|
+
|
|
751
|
+
```typescript
|
|
752
|
+
// 优化前:
|
|
753
|
+
((cpuUsage.user + cpuUsage.system) / (1000 * 1000 * os.uptime()) * 100).toFixed(2)
|
|
754
|
+
// 优化后(增加核心数校准):
|
|
755
|
+
((cpuUsage.user + cpuUsage.system) / (1000 * 1000 * os.uptime() * os.cpus().length) * 100).toFixed(2)
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
#### 10. `AsNodeTool.doShell()` 动态选择编码 ✅
|
|
761
|
+
|
|
762
|
+
**优化内容**:根据平台动态选择编码(Windows `cp936` / Linux `utf-8`),使用 `encoding: 'buffer'` 替代已废弃的 `'binary'` 编码。
|
|
763
|
+
|
|
764
|
+
```typescript
|
|
765
|
+
// 优化后:
|
|
766
|
+
const encoding = process.platform === 'win32' ? 'cp936' : 'utf-8';
|
|
767
|
+
exec(cmd, { encoding: 'buffer', timeout: 600000 }, (error, stdout, stderr) => {
|
|
768
|
+
if (error) reject(error);
|
|
769
|
+
resolve(iconv.decode(stdout, encoding));
|
|
770
|
+
});
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
### 待优化项目
|
|
776
|
+
|
|
777
|
+
| 优先级 | 问题 | 影响 |
|
|
778
|
+
|--------|------|------|
|
|
779
|
+
| 🔴 P0 | 密码明文传输、AsCode 安全、路径遍历 | 严重安全风险 |
|
|
780
|
+
| 🟡 P1 | 路由匹配、通道缓存、频率限制 | 功能健壮性 |
|
|
781
|
+
| 🟢 P2 | 聊天室限制 | 准确性/安全性 |
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
### 八、全插件通用优化建议
|
|
786
|
+
|
|
787
|
+
以下优化建议适用于本插件乃至整个 `plugs` 目录下的所有插件:
|
|
788
|
+
|
|
789
|
+
| 改进项 | 说明 | 工作量 |
|
|
790
|
+
|--------|------|--------|
|
|
791
|
+
| **TypeScript 严格模式** | 所有文件从 `any` 改为精确类型 | 大 |
|
|
792
|
+
| **统一错误处理中间件** | 统一 `ctxSuccess`/`ctxFail` 风格,增加错误码枚举 | 中 |
|
|
793
|
+
| **日志可追踪 ID** | 每次请求生成 `traceId`,贯穿所有日志 | 中 |
|
|
794
|
+
| **配置式路由** | 用声明式路由表替代 `if/else` 链 | 中 |
|
|
795
|
+
| **单元测试覆盖** | 为核心模块(Sql.ts、As.ts、Api.ts)增加 Jest 测试 | 大 |
|