@h-ai/audit 1.0.0-beta.2 → 1.0.0-beta.21
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.en.md +120 -50
- package/README.ja.md +129 -61
- package/README.md +130 -62
- package/dist/index.d.ts +2 -1
- package/dist/index.js +727 -224
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -4,33 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
[框架首页](../../README.md) · 相关模块:[@h-ai/core](../core/README.md) · [@h-ai/reldb](../reldb/README.md)
|
|
6
6
|
|
|
7
|
-
## 简介
|
|
8
|
-
|
|
9
7
|
统一审计日志模块,通过 `audit` 对象提供审计日志的记录、查询、清理与统计功能,基于 `@h-ai/reldb` 实现持久化。
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## 核心功能清单
|
|
14
|
-
|
|
15
|
-
- 记录用户操作与安全事件,支持按用户、时间和操作筛选。
|
|
16
|
-
- 查询分页日志与操作统计,并按保留天数清理。
|
|
17
|
-
- 使用关系数据库持久化,写入前隐藏凭证类字段。
|
|
18
|
-
|
|
19
|
-
## 使用入门
|
|
9
|
+
## 快速开始
|
|
20
10
|
|
|
21
11
|
### 依赖
|
|
22
12
|
|
|
23
13
|
- `@h-ai/reldb` — 数据库(审计日志持久化),**需在 audit.init() 前初始化**
|
|
24
14
|
|
|
25
|
-
### 适用场景
|
|
26
|
-
|
|
27
|
-
- 用户操作审计(登录、登出、注册、密码重置等)
|
|
28
|
-
- CRUD 操作审计(创建、读取、更新、删除资源)
|
|
29
|
-
- 安全事件追踪与合规审计
|
|
30
|
-
- 运营数据统计(操作频次、活跃用户等)
|
|
31
|
-
|
|
32
|
-
### 快速开始
|
|
33
|
-
|
|
34
15
|
```ts
|
|
35
16
|
import { audit } from '@h-ai/audit'
|
|
36
17
|
import { reldb } from '@h-ai/reldb'
|
|
@@ -54,7 +35,13 @@ await audit.log({
|
|
|
54
35
|
|
|
55
36
|
// 4. 使用便捷方法
|
|
56
37
|
await audit.helper.login('user_1', '127.0.0.1')
|
|
57
|
-
await audit.helper.crud({
|
|
38
|
+
await audit.helper.crud({
|
|
39
|
+
userId: 'user_1',
|
|
40
|
+
action: 'create',
|
|
41
|
+
resource: 'users',
|
|
42
|
+
resourceId: 'user_2',
|
|
43
|
+
details: { name: '张三' }
|
|
44
|
+
})
|
|
58
45
|
|
|
59
46
|
// 5. 查询日志
|
|
60
47
|
const logs = await audit.list({ pageSize: 20, action: 'login' })
|
|
@@ -72,21 +59,75 @@ if (!closeResult.success) {
|
|
|
72
59
|
}
|
|
73
60
|
```
|
|
74
61
|
|
|
75
|
-
|
|
62
|
+
## 功能
|
|
76
63
|
|
|
77
|
-
|
|
78
|
-
// 默认配置(无需传参)
|
|
79
|
-
await audit.init()
|
|
64
|
+
SQLite、PostgreSQL、MySQL 的读取结果保持同一契约:`createdAt` 为 `Date`,`details` 为 JSON 字符串或 `null`,缺失的可空字段返回 `null`。日期筛选与写入使用相同的驱动日期转换;统计数量为安全整数,超出范围返回 `STATS_FAILED`。
|
|
80
65
|
|
|
81
|
-
|
|
82
|
-
await audit.init({
|
|
83
|
-
userTable: 'hai_iam_users', // 用户表名(默认 'hai_iam_users')
|
|
84
|
-
userIdColumn: 'id', // 用户表主键列名(默认 'id')
|
|
85
|
-
userNameColumn: 'username', // 用户表用户名列名(默认 'username')
|
|
86
|
-
})
|
|
87
|
-
```
|
|
66
|
+
### 功能输入输出
|
|
88
67
|
|
|
89
|
-
|
|
68
|
+
以下片段依赖本节完整初始化流程。示例中的业务值由宿主校验和授权后传入;异步领域结果先判断 success,再读取 data。表中 void 表示操作已完成且没有返回数据,null 表示不存在;同步工厂/工具直接返回表中类型。
|
|
69
|
+
|
|
70
|
+
#### audit
|
|
71
|
+
|
|
72
|
+
记录结构化事件。log 输入事件及可选 tx 返回已保存记录;capture 按读写策略返回 void;withContext 输入可信关联信息及回调,直接返回回调值并隔离上下文。
|
|
73
|
+
|
|
74
|
+
| 入口 | 输入参数 | 成功结果 | 调用示例 |
|
|
75
|
+
| ------------------- | ------------------ | ---------- | ----------------------------------------------------------- |
|
|
76
|
+
| `audit.log` | input, tx | `AuditLog` | `await audit.log(event)` |
|
|
77
|
+
| `audit.capture` | input, options | `void` | `await audit.capture(event)` |
|
|
78
|
+
| `audit.withContext` | context, operation | `T` | `audit.withContext(trustedAuditContext, () => saveOrder())` |
|
|
79
|
+
|
|
80
|
+
#### audit
|
|
81
|
+
|
|
82
|
+
检索/保留:过滤分页返回带用户信息的页,用户 ID/limit 返回近期数组,days/filters 返回统计数组,cleanup 保留天数返回删除数。
|
|
83
|
+
|
|
84
|
+
| 入口 | 输入参数 | 成功结果 | 调用示例 |
|
|
85
|
+
| --------------------- | ------------- | ----------------------------------- | --------------------------------------------- |
|
|
86
|
+
| `audit.list` | options | `PaginatedResult<AuditLogWithUser>` | `await audit.list({ page: 1, pageSize: 20 })` |
|
|
87
|
+
| `audit.getUserRecent` | userId, limit | `AuditLog[]` | `await audit.getUserRecent(userId, 20)` |
|
|
88
|
+
| `audit.getStats` | days, filters | `AuditStatItem[]` | `await audit.getStats(7)` |
|
|
89
|
+
| `audit.cleanup` | olderThanDays | `number` | `await audit.cleanup(90)` |
|
|
90
|
+
|
|
91
|
+
#### audit.helper
|
|
92
|
+
|
|
93
|
+
常见事件封装。用户 ID(重置请求为 email)及可选 IP/UA,或 CRUD 事件输入,返回 void HaiResult;敏感字段仍脱敏。
|
|
94
|
+
|
|
95
|
+
| 入口 | 输入参数 | 成功结果 | 调用示例 |
|
|
96
|
+
| ------------------------------------ | -------------- | -------- | -------------------------------------------------- |
|
|
97
|
+
| `audit.helper.login` | userId, ip, ua | `void` | `await audit.helper.login(userId)` |
|
|
98
|
+
| `audit.helper.logout` | userId, ip, ua | `void` | `await audit.helper.logout(userId)` |
|
|
99
|
+
| `audit.helper.register` | userId, ip, ua | `void` | `await audit.helper.register(userId)` |
|
|
100
|
+
| `audit.helper.passwordResetRequest` | email, ip, ua | `void` | `await audit.helper.passwordResetRequest(email)` |
|
|
101
|
+
| `audit.helper.passwordResetComplete` | userId, ip, ua | `void` | `await audit.helper.passwordResetComplete(userId)` |
|
|
102
|
+
| `audit.helper.crud` | input | `void` | `await audit.helper.crud(crudEvent)` |
|
|
103
|
+
|
|
104
|
+
#### audit.backup
|
|
105
|
+
|
|
106
|
+
私有归档。run 接收筛选/期限/取消选项,verify 接收对象 key;返回归档信息并校验内容完整性,不公开对象。
|
|
107
|
+
|
|
108
|
+
| 入口 | 输入参数 | 成功结果 | 调用示例 |
|
|
109
|
+
| --------------------- | ------------ | ----------------- | --------------------------------------- |
|
|
110
|
+
| `audit.backup.run` | options | `AuditBackupInfo` | `await audit.backup.run()` |
|
|
111
|
+
| `audit.backup.verify` | key, options | `AuditBackupInfo` | `await audit.backup.verify(archiveKey)` |
|
|
112
|
+
|
|
113
|
+
#### audit
|
|
114
|
+
|
|
115
|
+
定时检查异常,输入可选 signal,返回规则命中及通知结果;交由 scheduler 编排而非自行假设后台已启动。
|
|
116
|
+
|
|
117
|
+
| 入口 | 输入参数 | 成功结果 | 调用示例 |
|
|
118
|
+
| ------------------- | -------- | ------------------ | --------------------------- |
|
|
119
|
+
| `audit.checkAlerts` | options | `AuditAlertReport` | `await audit.checkAlerts()` |
|
|
120
|
+
|
|
121
|
+
- 记录用户操作与安全事件,支持按用户、时间和操作筛选。
|
|
122
|
+
- 查询分页日志与操作统计,并按保留天数清理。
|
|
123
|
+
- 使用关系数据库持久化,写入前隐藏凭证类字段。
|
|
124
|
+
|
|
125
|
+
### 适用场景
|
|
126
|
+
|
|
127
|
+
- 用户操作审计(登录、登出、注册、密码重置等)
|
|
128
|
+
- CRUD 操作审计(创建、读取、更新、删除资源)
|
|
129
|
+
- 安全事件追踪与合规审计
|
|
130
|
+
- 运营数据统计(操作频次、活跃用户等)
|
|
90
131
|
|
|
91
132
|
### API 概览
|
|
92
133
|
|
|
@@ -110,31 +151,7 @@ await audit.init({
|
|
|
110
151
|
- `audit.cleanup(days)`:`days`(如传入)必须为非负整数。
|
|
111
152
|
- `audit.getStats(days)`:`days`(如传入)必须为非负整数。
|
|
112
153
|
|
|
113
|
-
###
|
|
114
|
-
|
|
115
|
-
业务数据操作返回 `HaiResult<T>`,常用错误码如下:
|
|
116
|
-
|
|
117
|
-
| 错误码 | code | 说明 |
|
|
118
|
-
| -------------------------------- | --------------- | ---------------------- |
|
|
119
|
-
| `HaiAuditError.LOG_FAILED` | `hai:audit:001` | 记录失败 |
|
|
120
|
-
| `HaiAuditError.QUERY_FAILED` | `hai:audit:002` | 查询失败 |
|
|
121
|
-
| `HaiAuditError.CLEANUP_FAILED` | `hai:audit:003` | 清理失败 |
|
|
122
|
-
| `HaiAuditError.STATS_FAILED` | `hai:audit:004` | 统计失败 |
|
|
123
|
-
| `HaiAuditError.INIT_IN_PROGRESS` | `hai:audit:005` | 初始化进行中 |
|
|
124
|
-
| `HaiAuditError.NOT_INITIALIZED` | `hai:audit:010` | 模块未初始化 |
|
|
125
|
-
| `HaiAuditError.CONFIG_ERROR` | `hai:audit:012` | 配置错误 |
|
|
126
|
-
| `HaiAuditError.BACKUP_DISABLED` | `hai:audit:020` | 备份未启用 |
|
|
127
|
-
| `HaiAuditError.BACKUP_FAILED` | `hai:audit:021` | 备份或校验失败 |
|
|
128
|
-
| `HaiAuditError.BACKUP_INVALID` | `hai:audit:022` | 备份输入无效 |
|
|
129
|
-
| `HaiAuditError.BACKUP_CONFLICT` | `hai:audit:023` | 备份编号与导出条件冲突 |
|
|
130
|
-
| `HaiAuditError.ALERTS_DISABLED` | `hai:audit:024` | 告警未启用 |
|
|
131
|
-
| `HaiAuditError.ALERTS_FAILED` | `hai:audit:025` | 告警检查或通知失败 |
|
|
132
|
-
|
|
133
|
-
> 说明:`audit.close()` 也返回 `HaiResult<void>`;`audit.helper.passwordResetRequest()` 的邮箱详情默认经过业务隐私脱敏。
|
|
134
|
-
|
|
135
|
-
`audit.init()` 会等待自动建表和仓库就绪才返回成功;DDL 失败保持 `isInitialized=false`,修正数据库后可重试。自定义 JOIN、统计和清理也使用同一就绪屏障;初始化期间关闭会使迟到结果失效。先检查 init 的 HaiResult,再立即记录或查询;audit 不拥有共享 RelDB 的连接,关闭 audit 后再关闭数据库。
|
|
136
|
-
|
|
137
|
-
## 事件上下文、隐私与保留
|
|
154
|
+
### 事件上下文、隐私与保留
|
|
138
155
|
|
|
139
156
|
审计 createdAt、告警窗口与归档截止共用数据库时钟,不以各节点系统钟作为共享真值。备份与告警调度任务使用已验证的持久去重保障声明幂等;失败不会被错误地当作非幂等未知任务而阻塞后续调度。
|
|
140
157
|
|
|
@@ -152,7 +169,7 @@ await audit.init({
|
|
|
152
169
|
|
|
153
170
|
脱敏匹配整个字段:对象、数组以及自定义 JSON 投影内的敏感值同样隐藏。关闭或尚未初始化 Audit 时,capture 返回未初始化失败;只有已初始化模块的关闭采集配置才跳过自动事件。
|
|
154
171
|
|
|
155
|
-
|
|
172
|
+
### 私有备份与定时归档
|
|
156
173
|
|
|
157
174
|
`backup.enabled` 默认关闭。开启时向 `audit.init({ storage, backup: { enabled: true } })` 注入已经初始化的 `StorageFunctions`;数据库仍先初始化。`backup.batchSize` 控制扫描批量(默认200),`maxRecordBytes` 限制单条 UTF-8 记录(默认1 MiB),超限返回失败并保留原始审计,不截断证据。
|
|
158
175
|
|
|
@@ -165,7 +182,10 @@ await audit.init({
|
|
|
165
182
|
```ts
|
|
166
183
|
const plan = audit.schedulerPlan
|
|
167
184
|
if (plan) {
|
|
168
|
-
const initialized = await scheduler.init({
|
|
185
|
+
const initialized = await scheduler.init({
|
|
186
|
+
...schedulerSettings,
|
|
187
|
+
...plan
|
|
188
|
+
})
|
|
169
189
|
if (!initialized.success)
|
|
170
190
|
throw new Error(initialized.error.message)
|
|
171
191
|
const started = scheduler.start()
|
|
@@ -176,7 +196,7 @@ if (plan) {
|
|
|
176
196
|
|
|
177
197
|
上例由宿主导入 `audit`、`scheduler` 并提供已校验的 schedulerSettings,Audit/Storage/RelDB 已初始化。归档使用私有存储,开启备份时拒绝配置了公开 publicUrl 的 S3;部署仍须限制桶/CDN访问。公开静态文件入口应仅开放指定资源;管理示例与 fullstack 仅公开规范头像路径,如提供归档下载,须通过审计授权接口处理,关闭备份也不改变已有文件的私有边界。
|
|
178
198
|
|
|
179
|
-
|
|
199
|
+
### 分级异常告警
|
|
180
200
|
|
|
181
201
|
`alerts.enabled` 默认关闭。开启时注入已初始化的 Reach:`audit.init({ reach, alerts: { enabled: true, rules: [...] } })`。规则通过稳定 id、actions(精确事件名)、可选 resource、outcomes、minimumSeverity 筛选事件,threshold/windowSeconds 指定固定窗口阈值,severity 指定通知等级,targets 中的 id/provider/to 指定人员或目标。默认窗口300秒,范围60–86400秒;默认仅失败/拒绝,空 outcomes 表示所有结果。规则和目标 id 必须各自唯一;provider 须已在 Reach 注册。不将具体业务角色写入框架。
|
|
182
202
|
|
|
@@ -186,13 +206,61 @@ if (plan) {
|
|
|
186
206
|
|
|
187
207
|
`alerts.schedule` 可独立启用,默认每分钟、UTC。`audit.schedulerPlan` 合并已启用的备份和告警任务,由宿主显式交给 Scheduler;计划没有自动任务时为 null。调度回调在检查失败或 failed>0 时准确失败。先关闭 Scheduler,再关闭 Audit 和 Reach;关闭 Audit 取消后续领取并等待在途通知完成(受 Reach Provider 超时约束),不关闭宿主 Reach。数据库查询/审计失败返回失败;通知业务失败在成功检查报告的 failed 字段体现,调用方必须检查。
|
|
188
208
|
|
|
209
|
+
## 配置
|
|
210
|
+
|
|
211
|
+
生命周期:init 输入后端/业务配置,成功后才能使用;close 在释放借用依赖前等待完成。返回值以快速开始示例和公开签名为准。
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
// 默认配置(无需传参)
|
|
215
|
+
await audit.init()
|
|
216
|
+
|
|
217
|
+
// 自定义用户表映射
|
|
218
|
+
await audit.init({
|
|
219
|
+
userTable: 'hai_iam_users', // 用户表名(默认 'hai_iam_users')
|
|
220
|
+
userIdColumn: 'id', // 用户表主键列名(默认 'id')
|
|
221
|
+
userNameColumn: 'username', // 用户表用户名列名(默认 'username')
|
|
222
|
+
})
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
审计日志固定存储在 `hai_audit_logs` 表中,依赖 `@h-ai/reldb` 已初始化。
|
|
226
|
+
|
|
227
|
+
配置由宿主加载和校验,再传入本模块;私密值放服务端私有环境,不传到浏览器。按实际使用场景逐项选择后端、容量、期限和日志策略,修改后重新初始化并核验成功结果。
|
|
228
|
+
|
|
229
|
+
[逐项配置说明、适用场景和示例](../../docs/usage/configuration/operations.md).
|
|
230
|
+
|
|
231
|
+
## 错误处理
|
|
232
|
+
|
|
233
|
+
领域操作先判断 `result.success`,失败按本模块错误定义与安全提示处理,服务端保留错误码、关联编号和脱敏原因。同步工具、工厂、流迭代及生命周期按各自签名处理,不把 Promise 完成视为业务成功。具体失败与恢复边界见对应功能。
|
|
234
|
+
|
|
235
|
+
业务数据操作返回 `HaiResult<T>`,常用错误码如下:
|
|
236
|
+
|
|
237
|
+
| 错误码 | code | 说明 |
|
|
238
|
+
| -------------------------------- | --------------- | ---------------------- |
|
|
239
|
+
| `HaiAuditError.LOG_FAILED` | `hai:audit:001` | 记录失败 |
|
|
240
|
+
| `HaiAuditError.QUERY_FAILED` | `hai:audit:002` | 查询失败 |
|
|
241
|
+
| `HaiAuditError.CLEANUP_FAILED` | `hai:audit:003` | 清理失败 |
|
|
242
|
+
| `HaiAuditError.STATS_FAILED` | `hai:audit:004` | 统计失败 |
|
|
243
|
+
| `HaiAuditError.INIT_IN_PROGRESS` | `hai:audit:005` | 初始化进行中 |
|
|
244
|
+
| `HaiAuditError.NOT_INITIALIZED` | `hai:audit:010` | 模块未初始化 |
|
|
245
|
+
| `HaiAuditError.CONFIG_ERROR` | `hai:audit:012` | 配置错误 |
|
|
246
|
+
| `HaiAuditError.BACKUP_DISABLED` | `hai:audit:020` | 备份未启用 |
|
|
247
|
+
| `HaiAuditError.BACKUP_FAILED` | `hai:audit:021` | 备份或校验失败 |
|
|
248
|
+
| `HaiAuditError.BACKUP_INVALID` | `hai:audit:022` | 备份输入无效 |
|
|
249
|
+
| `HaiAuditError.BACKUP_CONFLICT` | `hai:audit:023` | 备份编号与导出条件冲突 |
|
|
250
|
+
| `HaiAuditError.ALERTS_DISABLED` | `hai:audit:024` | 告警未启用 |
|
|
251
|
+
| `HaiAuditError.ALERTS_FAILED` | `hai:audit:025` | 告警检查或通知失败 |
|
|
252
|
+
|
|
253
|
+
> 说明:`audit.close()` 也返回 `HaiResult<void>`;`audit.helper.passwordResetRequest()` 的邮箱详情默认经过业务隐私脱敏。
|
|
254
|
+
|
|
255
|
+
`audit.init()` 会等待自动建表和仓库就绪才返回成功;DDL 失败保持 `isInitialized=false`,修正数据库后可重试。自定义 JOIN、统计和清理也使用同一就绪屏障;初始化期间关闭会使迟到结果失效。先检查 init 的 HaiResult,再立即记录或查询;audit 不拥有共享 RelDB 的连接,关闭 audit 后再关闭数据库。
|
|
256
|
+
|
|
189
257
|
## 开发测试
|
|
190
258
|
|
|
191
259
|
```bash
|
|
192
260
|
pnpm --filter @h-ai/audit test
|
|
193
261
|
```
|
|
194
262
|
|
|
195
|
-
审计源码示例明确先初始化 RelDB、检查审计写入结果,再按依赖反序检查关闭结果;参见[模块 JSDoc 约定](../../.agents/instructions/module-conventions.md#jsdoc-与示例验证)
|
|
263
|
+
审计源码示例明确先初始化 RelDB、检查审计写入结果,再按依赖反序检查关闭结果;参见[模块 JSDoc 约定](../../.agents/instructions/module-conventions.md#jsdoc-与示例验证).
|
|
196
264
|
|
|
197
265
|
## 许可证
|
|
198
266
|
|
package/dist/index.d.ts
CHANGED
|
@@ -645,4 +645,5 @@ declare function migrateAudit(options?: {
|
|
|
645
645
|
dryRun?: boolean;
|
|
646
646
|
}): Promise<HaiResult<_h_ai_reldb.SchemaMigrationPlan>>;
|
|
647
647
|
|
|
648
|
-
export { AUDIT_BACKUP_PREFIX,
|
|
648
|
+
export { AUDIT_BACKUP_PREFIX, AuditInitConfigSchema, HaiAuditError, audit, migrateAudit };
|
|
649
|
+
export type { AuditActorSnapshot, AuditAlertReport, AuditBackupInfo, AuditBackupOperations, AuditBackupOptions, AuditContext, AuditEventFields, AuditFunctions, AuditHelper, AuditInitConfig, AuditInitConfigInput, AuditLog, AuditLogWithUser, AuditStatItem, CreateAuditLogInput, CrudAuditInput, ListAuditLogsOptions };
|