airlock-bot 0.2.36 → 0.2.38
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 +34 -7
- package/dist/activity/stream.d.ts +29 -0
- package/dist/activity/stream.d.ts.map +1 -0
- package/dist/activity/stream.js +36 -0
- package/dist/activity/stream.js.map +1 -0
- package/dist/airlock/context.d.ts +12 -0
- package/dist/airlock/context.d.ts.map +1 -0
- package/dist/airlock/context.js +32 -0
- package/dist/airlock/context.js.map +1 -0
- package/dist/airlock/tools.d.ts +7 -0
- package/dist/airlock/tools.d.ts.map +1 -0
- package/dist/airlock/tools.js +13 -0
- package/dist/airlock/tools.js.map +1 -0
- package/dist/allowlist/engine.d.ts +12 -0
- package/dist/allowlist/engine.d.ts.map +1 -1
- package/dist/allowlist/engine.js +40 -15
- package/dist/allowlist/engine.js.map +1 -1
- package/dist/audit/api.d.ts +2 -0
- package/dist/audit/api.d.ts.map +1 -1
- package/dist/audit/api.js.map +1 -1
- package/dist/audit/db.d.ts +16 -0
- package/dist/audit/db.d.ts.map +1 -1
- package/dist/audit/db.js +73 -0
- package/dist/audit/db.js.map +1 -1
- package/dist/audit/logger.d.ts +8 -1
- package/dist/audit/logger.d.ts.map +1 -1
- package/dist/audit/logger.js +21 -0
- package/dist/audit/logger.js.map +1 -1
- package/dist/backend/airlock-adapter.d.ts +22 -0
- package/dist/backend/airlock-adapter.d.ts.map +1 -0
- package/dist/backend/airlock-adapter.js +136 -0
- package/dist/backend/airlock-adapter.js.map +1 -0
- package/dist/backend/factory.d.ts +5 -1
- package/dist/backend/factory.d.ts.map +1 -1
- package/dist/backend/factory.js +5 -5
- package/dist/backend/factory.js.map +1 -1
- package/dist/backend/mcp-adapter.d.ts.map +1 -1
- package/dist/backend/mcp-adapter.js +28 -4
- package/dist/backend/mcp-adapter.js.map +1 -1
- package/dist/backend/openapi/adapter.d.ts.map +1 -1
- package/dist/backend/openapi/adapter.js +33 -13
- package/dist/backend/openapi/adapter.js.map +1 -1
- package/dist/config/loader.d.ts +12 -1
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +799 -23
- package/dist/config/loader.js.map +1 -1
- package/dist/config/profiles.d.ts +46 -8
- package/dist/config/profiles.d.ts.map +1 -1
- package/dist/config/profiles.js +367 -23
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/schema.d.ts +3542 -174
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +292 -63
- package/dist/config/schema.js.map +1 -1
- package/dist/configure-web/cli.d.ts +13 -0
- package/dist/configure-web/cli.d.ts.map +1 -1
- package/dist/configure-web/cli.js +570 -80
- package/dist/configure-web/cli.js.map +1 -1
- package/dist/gateway.d.ts +16 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +263 -57
- package/dist/gateway.js.map +1 -1
- package/dist/hitl/api.d.ts +2 -0
- package/dist/hitl/api.d.ts.map +1 -1
- package/dist/hitl/api.js +8 -0
- package/dist/hitl/api.js.map +1 -1
- package/dist/hitl/approval-dashboard.d.ts +5 -9
- package/dist/hitl/approval-dashboard.d.ts.map +1 -1
- package/dist/hitl/approval-dashboard.js +8 -55
- package/dist/hitl/approval-dashboard.js.map +1 -1
- package/dist/hitl/approval-stream.d.ts +34 -0
- package/dist/hitl/approval-stream.d.ts.map +1 -0
- package/dist/hitl/approval-stream.js +111 -0
- package/dist/hitl/approval-stream.js.map +1 -0
- package/dist/hitl/engine.d.ts +16 -7
- package/dist/hitl/engine.d.ts.map +1 -1
- package/dist/hitl/engine.js +109 -35
- package/dist/hitl/engine.js.map +1 -1
- package/dist/hitl/formatter.d.ts.map +1 -1
- package/dist/hitl/formatter.js +2 -0
- package/dist/hitl/formatter.js.map +1 -1
- package/dist/hitl/provider-factory.d.ts +8 -2
- package/dist/hitl/provider-factory.d.ts.map +1 -1
- package/dist/hitl/provider-factory.js +23 -2
- package/dist/hitl/provider-factory.js.map +1 -1
- package/dist/hitl/providers/composite.d.ts +9 -0
- package/dist/hitl/providers/composite.d.ts.map +1 -1
- package/dist/hitl/providers/composite.js +14 -0
- package/dist/hitl/providers/composite.js.map +1 -1
- package/dist/hitl/providers/dashboard.d.ts +12 -2
- package/dist/hitl/providers/dashboard.d.ts.map +1 -1
- package/dist/hitl/providers/dashboard.js +11 -5
- package/dist/hitl/providers/dashboard.js.map +1 -1
- package/dist/hitl/providers/ios.d.ts +23 -0
- package/dist/hitl/providers/ios.d.ts.map +1 -0
- package/dist/hitl/providers/ios.js +183 -0
- package/dist/hitl/providers/ios.js.map +1 -0
- package/dist/hitl/providers/macos.d.ts.map +1 -1
- package/dist/hitl/providers/macos.js +8 -4
- package/dist/hitl/providers/macos.js.map +1 -1
- package/dist/hitl/providers/openclaw.js +2 -2
- package/dist/hitl/providers/openclaw.js.map +1 -1
- package/dist/hitl/providers/stdio.js +2 -2
- package/dist/hitl/providers/stdio.js.map +1 -1
- package/dist/hitl/providers/telegram.js +2 -2
- package/dist/hitl/providers/telegram.js.map +1 -1
- package/dist/hitl/providers/tui.d.ts.map +1 -1
- package/dist/hitl/providers/tui.js +8 -2
- package/dist/hitl/providers/tui.js.map +1 -1
- package/dist/hitl/providers/types.d.ts +14 -0
- package/dist/hitl/providers/types.d.ts.map +1 -1
- package/dist/hook/api.d.ts +2 -0
- package/dist/hook/api.d.ts.map +1 -1
- package/dist/hook/api.js.map +1 -1
- package/dist/hook/normalizer.js +2 -2
- package/dist/hook/normalizer.js.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/introspect/cli.d.ts +31 -0
- package/dist/introspect/cli.d.ts.map +1 -0
- package/dist/introspect/cli.js +756 -0
- package/dist/introspect/cli.js.map +1 -0
- package/dist/middleware/chain-builder.d.ts +1 -1
- package/dist/middleware/chain-builder.d.ts.map +1 -1
- package/dist/middleware/chain-builder.js +8 -4
- package/dist/middleware/chain-builder.js.map +1 -1
- package/dist/middleware/core/allowlist.d.ts.map +1 -1
- package/dist/middleware/core/allowlist.js +14 -0
- package/dist/middleware/core/allowlist.js.map +1 -1
- package/dist/middleware/core/arg-policy.d.ts +13 -0
- package/dist/middleware/core/arg-policy.d.ts.map +1 -0
- package/dist/middleware/core/arg-policy.js +201 -0
- package/dist/middleware/core/arg-policy.js.map +1 -0
- package/dist/middleware/core/exec-policy.d.ts.map +1 -1
- package/dist/middleware/core/exec-policy.js +16 -1
- package/dist/middleware/core/exec-policy.js.map +1 -1
- package/dist/middleware/core/execute.d.ts.map +1 -1
- package/dist/middleware/core/execute.js +6 -2
- package/dist/middleware/core/execute.js.map +1 -1
- package/dist/middleware/core/hitl-gate.d.ts.map +1 -1
- package/dist/middleware/core/hitl-gate.js +15 -4
- package/dist/middleware/core/hitl-gate.js.map +1 -1
- package/dist/middleware/core/schema-validator.d.ts.map +1 -1
- package/dist/middleware/core/schema-validator.js +7 -3
- package/dist/middleware/core/schema-validator.js.map +1 -1
- package/dist/middleware/post/canary-token-injector.d.ts +4 -1
- package/dist/middleware/post/canary-token-injector.d.ts.map +1 -1
- package/dist/middleware/post/canary-token-injector.js +5 -1
- package/dist/middleware/post/canary-token-injector.js.map +1 -1
- package/dist/middleware/post/untrusted-envelope.d.ts.map +1 -1
- package/dist/middleware/post/untrusted-envelope.js +7 -1
- package/dist/middleware/post/untrusted-envelope.js.map +1 -1
- package/dist/mobile/api.d.ts +20 -0
- package/dist/mobile/api.d.ts.map +1 -0
- package/dist/mobile/api.js +255 -0
- package/dist/mobile/api.js.map +1 -0
- package/dist/mobile/apns.d.ts +68 -0
- package/dist/mobile/apns.d.ts.map +1 -0
- package/dist/mobile/apns.js +321 -0
- package/dist/mobile/apns.js.map +1 -0
- package/dist/pool/http-client.d.ts +3 -1
- package/dist/pool/http-client.d.ts.map +1 -1
- package/dist/pool/http-client.js +5 -2
- package/dist/pool/http-client.js.map +1 -1
- package/dist/pool/oauth-provider.d.ts +2 -0
- package/dist/pool/oauth-provider.d.ts.map +1 -1
- package/dist/pool/oauth-provider.js +23 -4
- package/dist/pool/oauth-provider.js.map +1 -1
- package/dist/pool/pool.d.ts +2 -1
- package/dist/pool/pool.d.ts.map +1 -1
- package/dist/pool/pool.js +2 -2
- package/dist/pool/pool.js.map +1 -1
- package/dist/pool/sse-client.d.ts +3 -1
- package/dist/pool/sse-client.d.ts.map +1 -1
- package/dist/pool/sse-client.js +5 -2
- package/dist/pool/sse-client.js.map +1 -1
- package/dist/pool/stdio-client.d.ts +3 -1
- package/dist/pool/stdio-client.d.ts.map +1 -1
- package/dist/pool/stdio-client.js +5 -2
- package/dist/pool/stdio-client.js.map +1 -1
- package/dist/registry/airlock-policy.d.ts +3 -0
- package/dist/registry/airlock-policy.d.ts.map +1 -0
- package/dist/registry/airlock-policy.js +50 -0
- package/dist/registry/airlock-policy.js.map +1 -0
- package/dist/registry/registry.d.ts +2 -0
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +19 -13
- package/dist/registry/registry.js.map +1 -1
- package/dist/security/blocked-hosts.d.ts +2 -0
- package/dist/security/blocked-hosts.d.ts.map +1 -1
- package/dist/security/blocked-hosts.js +61 -7
- package/dist/security/blocked-hosts.js.map +1 -1
- package/dist/security/request.d.ts +2 -0
- package/dist/security/request.d.ts.map +1 -1
- package/dist/security/request.js +6 -2
- package/dist/security/request.js.map +1 -1
- package/dist/security/secrets.d.ts +12 -0
- package/dist/security/secrets.d.ts.map +1 -0
- package/dist/security/secrets.js +138 -0
- package/dist/security/secrets.js.map +1 -0
- package/dist/setup-openclaw/cli.js +1 -1
- package/dist/stdio-mode.d.ts.map +1 -1
- package/dist/stdio-mode.js +125 -24
- package/dist/stdio-mode.js.map +1 -1
- package/dist/tools/api.d.ts +4 -1
- package/dist/tools/api.d.ts.map +1 -1
- package/dist/tools/api.js +58 -7
- package/dist/tools/api.js.map +1 -1
- package/dist/tools/exec.d.ts +2 -1
- package/dist/tools/exec.d.ts.map +1 -1
- package/dist/tools/exec.js +4 -3
- package/dist/tools/exec.js.map +1 -1
- package/dist/tools/http.d.ts.map +1 -1
- package/dist/tools/http.js +4 -7
- package/dist/tools/http.js.map +1 -1
- package/dist/transport/agent-server.d.ts +4 -0
- package/dist/transport/agent-server.d.ts.map +1 -1
- package/dist/transport/agent-server.js +23 -11
- package/dist/transport/agent-server.js.map +1 -1
- package/dist/transport/http-server.d.ts +2 -0
- package/dist/transport/http-server.d.ts.map +1 -1
- package/dist/transport/http-server.js +10 -6
- package/dist/transport/http-server.js.map +1 -1
- package/dist/transport/sse-server.d.ts +2 -0
- package/dist/transport/sse-server.d.ts.map +1 -1
- package/dist/transport/sse-server.js +10 -6
- package/dist/transport/sse-server.js.map +1 -1
- package/dist/transport/stdio-server.d.ts.map +1 -1
- package/dist/transport/stdio-server.js +4 -0
- package/dist/transport/stdio-server.js.map +1 -1
- package/dist/util/id.d.ts +1 -1
- package/dist/util/id.d.ts.map +1 -1
- package/dist/util/id.js +3 -3
- package/dist/util/id.js.map +1 -1
- package/examples/claude-code-setup.md +0 -2
- package/examples/docker-compose.yaml +4 -3
- package/examples/docker-gateway.yaml +8 -3
- package/examples/gateway.yaml +8 -5
- package/examples/profiles.yaml +4 -4
- package/extensions/openclaw/index.ts +9 -6
- package/extensions/openclaw/openclaw.plugin.json +5 -5
- package/package.json +3 -1
- package/schema.json +658 -8
package/README.md
CHANGED
|
@@ -184,7 +184,7 @@ apis:
|
|
|
184
184
|
Interactively assign allow/ask/deny to tools discovered from your live MCP servers:
|
|
185
185
|
|
|
186
186
|
```bash
|
|
187
|
-
|
|
187
|
+
airlock configure-agent --config ./airlock.yaml --agent claude-code
|
|
188
188
|
```
|
|
189
189
|
|
|
190
190
|
Navigate with `j/k`, set permissions with `a`/`s`/`d` (per tool or bulk per provider), then `Enter` to edit config directly, copy to clipboard, or print YAML.
|
|
@@ -263,7 +263,6 @@ agents:
|
|
|
263
263
|
extends: [readonly]
|
|
264
264
|
exec:
|
|
265
265
|
allow: ['git status', 'git diff*', 'npm test']
|
|
266
|
-
deny: ['*']
|
|
267
266
|
|
|
268
267
|
approvals:
|
|
269
268
|
provider:
|
|
@@ -415,7 +414,7 @@ See [`examples/sandbox-presets.yaml`](examples/sandbox-presets.yaml) for a fulle
|
|
|
415
414
|
| --------------- | ------------- | ------------------------------------------------------------------------------------------------- |
|
|
416
415
|
| TUI | `tui` | Terminal UI on stderr — `[a]pprove` / `[d]eny` with `j/k` navigation via `/dev/tty` |
|
|
417
416
|
| macOS dialog | `macos` | Native approve/deny popup via `osascript` — best for local dev on Mac |
|
|
418
|
-
| Dashboard | `dashboard` |
|
|
417
|
+
| Dashboard | `dashboard` | Browser UI with live SSE updates; runs in-process or as a standalone admin dashboard |
|
|
419
418
|
| Telegram bot | `telegram` | Long-polls for replies; reply `approve ABC123` or `deny ABC123` |
|
|
420
419
|
| Slack webhook | `slack` | Incoming webhook, fire-and-forget; pair with slash commands for approvals |
|
|
421
420
|
| Generic webhook | `webhook` | POSTs `{requests, text}` JSON; configurable headers |
|
|
@@ -424,17 +423,39 @@ See [`examples/sandbox-presets.yaml`](examples/sandbox-presets.yaml) for a fulle
|
|
|
424
423
|
|
|
425
424
|
## API
|
|
426
425
|
|
|
427
|
-
When running in gateway mode, Airlock
|
|
426
|
+
When running in gateway mode, Airlock can expose a separate management API
|
|
427
|
+
listener for operator/control-plane routes. It is disabled by default and binds
|
|
428
|
+
to `127.0.0.1:4113` when enabled:
|
|
429
|
+
|
|
430
|
+
```yaml
|
|
431
|
+
server:
|
|
432
|
+
api_secret: ${AIRLOCK_API_SECRET}
|
|
433
|
+
management_api:
|
|
434
|
+
enabled: true
|
|
435
|
+
api_secret: ${MANAGEMENT_API_SECRET}
|
|
436
|
+
```
|
|
428
437
|
|
|
429
438
|
```
|
|
430
439
|
GET /health — MCP health, pending HITL count, uptime
|
|
431
440
|
GET /hitl/pending — list pending approval requests
|
|
432
|
-
POST /hitl/approve/:id — approve a request
|
|
433
|
-
POST /hitl/deny/:id — deny
|
|
441
|
+
POST /hitl/approve/:id — approve a request by canonical approval ID
|
|
442
|
+
POST /hitl/deny/:id — deny by canonical approval ID (body: {"reason": "..."})
|
|
434
443
|
GET /audit?agent=&tool=&since=&limit= — query audit log
|
|
444
|
+
GET /events — dashboard approval event stream
|
|
445
|
+
POST /approve?code=ABC123 — approve via manual-entry approval code
|
|
446
|
+
POST /deny?code=ABC123 — deny via manual-entry approval code
|
|
447
|
+
GET /admin/tools — dashboard tool catalog
|
|
435
448
|
```
|
|
436
449
|
|
|
437
|
-
All management endpoints require `Authorization: Bearer <
|
|
450
|
+
All management endpoints require `Authorization: Bearer <management_api.api_secret>`.
|
|
451
|
+
If `management_api.api_secret` is unset, Airlock temporarily falls back to
|
|
452
|
+
`server.api_secret` and emits a deprecation warning so existing deployments keep
|
|
453
|
+
working while operators split the control-plane secret from the data-plane
|
|
454
|
+
fallback.
|
|
455
|
+
The management listener must use a different port than the agent MCP
|
|
456
|
+
data-plane listener (`server.port`, default `4111`). Binding the management API
|
|
457
|
+
beyond loopback requires the explicit `management_api.insecure_remote_bind: true`
|
|
458
|
+
opt-in and trusted network controls.
|
|
438
459
|
|
|
439
460
|
## Testing
|
|
440
461
|
|
|
@@ -471,15 +492,21 @@ Airlock can also run as a containerized gateway:
|
|
|
471
492
|
|
|
472
493
|
```bash
|
|
473
494
|
docker build -t airlock-bot .
|
|
495
|
+
mkdir -p airlock-config
|
|
496
|
+
cp examples/docker-gateway.yaml airlock-config/airlock.yaml
|
|
474
497
|
docker run --rm \
|
|
475
498
|
--env-file .env \
|
|
476
499
|
-v "$PWD/airlock-config:/config" \
|
|
477
500
|
-v airlock-data:/data \
|
|
478
501
|
-p 127.0.0.1:4111:4111 \
|
|
502
|
+
-p 127.0.0.1:4113:4113 \
|
|
479
503
|
-p 127.0.0.1:4112:4112 \
|
|
480
504
|
airlock-bot
|
|
481
505
|
```
|
|
482
506
|
|
|
507
|
+
The dashboard edits `/config/airlock.yaml` and writes `/config/airlock.bak`, so
|
|
508
|
+
mount a config directory when dashboard editing is enabled.
|
|
509
|
+
|
|
483
510
|
See [`examples/docker-compose.yaml`](examples/docker-compose.yaml) and
|
|
484
511
|
[`docs/guides/docker-deploy.md`](docs/guides/docker-deploy.md) for a VPS or
|
|
485
512
|
reverse-proxy deployment. The compose example uses split mode: the gateway mounts
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type AirlockActivityKind = 'notification' | 'log';
|
|
2
|
+
export type AirlockActivitySeverity = 'info' | 'success' | 'warning' | 'error';
|
|
3
|
+
export interface AirlockActivityEvent {
|
|
4
|
+
id: string;
|
|
5
|
+
kind: AirlockActivityKind;
|
|
6
|
+
agentId: string;
|
|
7
|
+
title: string;
|
|
8
|
+
body: string;
|
|
9
|
+
severity: AirlockActivitySeverity;
|
|
10
|
+
createdAt: string;
|
|
11
|
+
}
|
|
12
|
+
type ActivityListener = (event: AirlockActivityEvent) => void;
|
|
13
|
+
export declare class ActivityStream {
|
|
14
|
+
private maxEvents;
|
|
15
|
+
private events;
|
|
16
|
+
private listeners;
|
|
17
|
+
constructor(maxEvents?: number);
|
|
18
|
+
emit(params: {
|
|
19
|
+
kind: AirlockActivityKind;
|
|
20
|
+
agentId: string;
|
|
21
|
+
title: string;
|
|
22
|
+
body: string;
|
|
23
|
+
severity?: AirlockActivitySeverity;
|
|
24
|
+
}): AirlockActivityEvent;
|
|
25
|
+
recent(): AirlockActivityEvent[];
|
|
26
|
+
subscribe(listener: ActivityListener): () => void;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/activity/stream.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,KAAK,CAAC;AACzD,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE/E,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,uBAAuB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,gBAAgB,GAAG,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,CAAC;AAE9D,qBAAa,cAAc;IAIb,OAAO,CAAC,SAAS;IAH7B,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,SAAS,CAA+B;gBAE5B,SAAS,SAAM;IAEnC,IAAI,CAAC,MAAM,EAAE;QACX,IAAI,EAAE,mBAAmB,CAAC;QAC1B,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,uBAAuB,CAAC;KACpC,GAAG,oBAAoB;IAqBxB,MAAM,IAAI,oBAAoB,EAAE;IAIhC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,IAAI;CAIlD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { generateId } from '../util/id.js';
|
|
2
|
+
export class ActivityStream {
|
|
3
|
+
maxEvents;
|
|
4
|
+
events = [];
|
|
5
|
+
listeners = new Set();
|
|
6
|
+
constructor(maxEvents = 200) {
|
|
7
|
+
this.maxEvents = maxEvents;
|
|
8
|
+
}
|
|
9
|
+
emit(params) {
|
|
10
|
+
const event = {
|
|
11
|
+
id: generateId(),
|
|
12
|
+
kind: params.kind,
|
|
13
|
+
agentId: params.agentId,
|
|
14
|
+
title: params.title,
|
|
15
|
+
body: params.body,
|
|
16
|
+
severity: params.severity ?? 'info',
|
|
17
|
+
createdAt: new Date().toISOString(),
|
|
18
|
+
};
|
|
19
|
+
this.events.unshift(event);
|
|
20
|
+
if (this.events.length > this.maxEvents) {
|
|
21
|
+
this.events = this.events.slice(0, this.maxEvents);
|
|
22
|
+
}
|
|
23
|
+
for (const listener of this.listeners) {
|
|
24
|
+
listener(event);
|
|
25
|
+
}
|
|
26
|
+
return event;
|
|
27
|
+
}
|
|
28
|
+
recent() {
|
|
29
|
+
return [...this.events];
|
|
30
|
+
}
|
|
31
|
+
subscribe(listener) {
|
|
32
|
+
this.listeners.add(listener);
|
|
33
|
+
return () => this.listeners.delete(listener);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/activity/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAiB3C,MAAM,OAAO,cAAc;IAIL;IAHZ,MAAM,GAA2B,EAAE,CAAC;IACpC,SAAS,GAAG,IAAI,GAAG,EAAoB,CAAC;IAEhD,YAAoB,YAAY,GAAG;QAAf,cAAS,GAAT,SAAS,CAAM;IAAG,CAAC;IAEvC,IAAI,CAAC,MAMJ;QACC,MAAM,KAAK,GAAyB;YAClC,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,MAAM;YACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACrD,CAAC;QACD,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,SAAS,CAAC,QAA0B;QAClC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const AIRLOCK_CONTEXT_KEY = "_airlock";
|
|
2
|
+
export declare const AIRLOCK_REASON_MAX_LENGTH = 500;
|
|
3
|
+
export interface AirlockCallContext {
|
|
4
|
+
reason?: string;
|
|
5
|
+
note?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function extractAirlockContext(args: Record<string, unknown>): {
|
|
8
|
+
args: Record<string, unknown>;
|
|
9
|
+
context?: AirlockCallContext;
|
|
10
|
+
};
|
|
11
|
+
export declare function requireAirlockReason(context: AirlockCallContext | undefined): string | undefined;
|
|
12
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/airlock/context.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,aAAa,CAAC;AAC9C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;IACpE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,kBAAkB,CAAC;CAC9B,CAoBA;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGhG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const AIRLOCK_CONTEXT_KEY = '_airlock';
|
|
2
|
+
export const AIRLOCK_REASON_MAX_LENGTH = 500;
|
|
3
|
+
export function extractAirlockContext(args) {
|
|
4
|
+
const raw = args[AIRLOCK_CONTEXT_KEY];
|
|
5
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
6
|
+
return { args };
|
|
7
|
+
}
|
|
8
|
+
const source = raw;
|
|
9
|
+
const context = {};
|
|
10
|
+
if (typeof source.reason === 'string') {
|
|
11
|
+
context.reason = clampHumanText(source.reason);
|
|
12
|
+
}
|
|
13
|
+
if (typeof source.note === 'string') {
|
|
14
|
+
context.note = clampHumanText(source.note);
|
|
15
|
+
}
|
|
16
|
+
const { [AIRLOCK_CONTEXT_KEY]: _ignored, ...cleanArgs } = args;
|
|
17
|
+
return {
|
|
18
|
+
args: cleanArgs,
|
|
19
|
+
...(context.reason || context.note ? { context } : {}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function requireAirlockReason(context) {
|
|
23
|
+
const reason = context?.reason?.trim();
|
|
24
|
+
return reason ? reason : undefined;
|
|
25
|
+
}
|
|
26
|
+
function clampHumanText(value) {
|
|
27
|
+
const trimmed = value.trim();
|
|
28
|
+
return trimmed.length > AIRLOCK_REASON_MAX_LENGTH
|
|
29
|
+
? trimmed.slice(0, AIRLOCK_REASON_MAX_LENGTH)
|
|
30
|
+
: trimmed;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/airlock/context.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAC;AAO7C,MAAM,UAAU,qBAAqB,CAAC,IAA6B;IAIjE,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,GAA8B,CAAC;IAC9C,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,CAAC,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,EAAE,CAAC,mBAAmB,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI,CAAC;IAC/D,OAAO;QACL,IAAI,EAAE,SAAS;QACf,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAuC;IAC1E,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACvC,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACrC,CAAC;AAED,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,MAAM,GAAG,yBAAyB;QAC/C,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,yBAAyB,CAAC;QAC7C,CAAC,CAAC,OAAO,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const AIRLOCK_PROVIDER_ID = "airlock";
|
|
2
|
+
export declare const AIRLOCK_ASK_USER_TOOL = "airlock/ask_user";
|
|
3
|
+
export declare const AIRLOCK_NOTIFY_USER_TOOL = "airlock/notify_user";
|
|
4
|
+
export declare const AIRLOCK_LOG_TOOL = "airlock/log";
|
|
5
|
+
export declare const AIRLOCK_NON_ASK_TOOLS: readonly ["airlock/ask_user", "airlock/notify_user", "airlock/log"];
|
|
6
|
+
export declare function isAirlockNonAskTool(toolName: string): boolean;
|
|
7
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/airlock/tools.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AACxD,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,eAAO,MAAM,gBAAgB,gBAAgB,CAAC;AAE9C,eAAO,MAAM,qBAAqB,qEAIxB,CAAC;AAEX,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const AIRLOCK_PROVIDER_ID = 'airlock';
|
|
2
|
+
export const AIRLOCK_ASK_USER_TOOL = 'airlock/ask_user';
|
|
3
|
+
export const AIRLOCK_NOTIFY_USER_TOOL = 'airlock/notify_user';
|
|
4
|
+
export const AIRLOCK_LOG_TOOL = 'airlock/log';
|
|
5
|
+
export const AIRLOCK_NON_ASK_TOOLS = [
|
|
6
|
+
AIRLOCK_ASK_USER_TOOL,
|
|
7
|
+
AIRLOCK_NOTIFY_USER_TOOL,
|
|
8
|
+
AIRLOCK_LOG_TOOL,
|
|
9
|
+
];
|
|
10
|
+
export function isAirlockNonAskTool(toolName) {
|
|
11
|
+
return AIRLOCK_NON_ASK_TOOLS.includes(toolName);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/airlock/tools.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAC;AACxD,MAAM,CAAC,MAAM,wBAAwB,GAAG,qBAAqB,CAAC;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,qBAAqB;IACrB,wBAAwB;IACxB,gBAAgB;CACR,CAAC;AAEX,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,OAAQ,qBAA2C,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import type { AgentConfig } from '../config/schema.js';
|
|
2
2
|
export type Decision = 'allow' | 'ask' | 'deny';
|
|
3
|
+
export type DetailedDecision = Decision | 'default-deny';
|
|
4
|
+
export interface AllowlistMatch {
|
|
5
|
+
pattern: string;
|
|
6
|
+
specificity: number;
|
|
7
|
+
source: 'deny' | 'remember_allow' | 'ask' | 'allow';
|
|
8
|
+
}
|
|
9
|
+
export interface AllowlistEvaluation {
|
|
10
|
+
decision: DetailedDecision;
|
|
11
|
+
match?: AllowlistMatch;
|
|
12
|
+
candidates: AllowlistMatch[];
|
|
13
|
+
}
|
|
3
14
|
export declare class AllowlistEngine {
|
|
4
15
|
private agents;
|
|
5
16
|
constructor(agents: Record<string, AgentConfig>);
|
|
6
17
|
reload(agents: Record<string, AgentConfig>): void;
|
|
7
18
|
evaluate(agentId: string, toolName: string): Decision;
|
|
19
|
+
evaluateDetailed(agentId: string, toolName: string): AllowlistEvaluation;
|
|
8
20
|
}
|
|
9
21
|
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/allowlist/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/allowlist/engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAChD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,cAAc,CAAC;AAEzD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,KAAK,GAAG,OAAO,CAAC;CACrD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,UAAU,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC;IAEvD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,IAAI;IAIjD,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ;IAKrD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,mBAAmB;CA8CzE"}
|
package/dist/allowlist/engine.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bestSpecificity } from './pattern.js';
|
|
1
|
+
import { bestSpecificity, specificity } from './pattern.js';
|
|
2
2
|
export class AllowlistEngine {
|
|
3
3
|
agents;
|
|
4
4
|
constructor(agents) {
|
|
@@ -8,30 +8,55 @@ export class AllowlistEngine {
|
|
|
8
8
|
this.agents = agents;
|
|
9
9
|
}
|
|
10
10
|
evaluate(agentId, toolName) {
|
|
11
|
+
const result = this.evaluateDetailed(agentId, toolName);
|
|
12
|
+
return result.decision === 'default-deny' ? 'deny' : result.decision;
|
|
13
|
+
}
|
|
14
|
+
evaluateDetailed(agentId, toolName) {
|
|
11
15
|
const agent = this.agents[agentId];
|
|
12
16
|
if (!agent)
|
|
13
|
-
return 'deny';
|
|
17
|
+
return { decision: 'default-deny', candidates: [] };
|
|
14
18
|
// Pure specificity: most specific matching pattern wins across all tiers.
|
|
15
19
|
// Ties break deny > remembered allow > ask > allow. Remembered allow is an
|
|
16
20
|
// operator-approved exception that can override an exact ask rule, either
|
|
17
21
|
// permanently or until it expires.
|
|
18
|
-
const
|
|
19
|
-
const rememberedAllowSpec = bestSpecificity((agent.remember_allow ?? [])
|
|
22
|
+
const rememberedAllow = (agent.remember_allow ?? [])
|
|
20
23
|
.filter((rule) => !rule.expires_at || Date.parse(rule.expires_at) > Date.now())
|
|
21
|
-
.map((rule) => rule.tool)
|
|
24
|
+
.map((rule) => rule.tool);
|
|
25
|
+
const candidates = [
|
|
26
|
+
...matchingPatterns(agent.deny, toolName, 'deny'),
|
|
27
|
+
...matchingPatterns(rememberedAllow, toolName, 'remember_allow'),
|
|
28
|
+
...matchingPatterns(agent.ask, toolName, 'ask'),
|
|
29
|
+
...matchingPatterns(agent.allow, toolName, 'allow'),
|
|
30
|
+
];
|
|
31
|
+
const denySpec = bestSpecificity(agent.deny, toolName);
|
|
32
|
+
const rememberedAllowSpec = bestSpecificity(rememberedAllow, toolName);
|
|
22
33
|
const askSpec = bestSpecificity(agent.ask, toolName);
|
|
23
34
|
const allowSpec = bestSpecificity(agent.allow, toolName);
|
|
24
35
|
const best = Math.max(denySpec, rememberedAllowSpec, askSpec, allowSpec);
|
|
25
|
-
if (best < 0)
|
|
26
|
-
return 'deny'
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
if (best < 0) {
|
|
37
|
+
return { decision: 'default-deny', candidates };
|
|
38
|
+
}
|
|
39
|
+
const winningSource = denySpec === best
|
|
40
|
+
? 'deny'
|
|
41
|
+
: rememberedAllowSpec === best
|
|
42
|
+
? 'remember_allow'
|
|
43
|
+
: askSpec === best
|
|
44
|
+
? 'ask'
|
|
45
|
+
: 'allow';
|
|
46
|
+
const match = candidates
|
|
47
|
+
.filter((candidate) => candidate.source === winningSource && candidate.specificity === best)
|
|
48
|
+
.sort((a, b) => b.pattern.length - a.pattern.length)[0];
|
|
49
|
+
return {
|
|
50
|
+
decision: winningSource === 'remember_allow' ? 'allow' : winningSource,
|
|
51
|
+
match,
|
|
52
|
+
candidates,
|
|
53
|
+
};
|
|
35
54
|
}
|
|
36
55
|
}
|
|
56
|
+
function matchingPatterns(patterns, toolName, source) {
|
|
57
|
+
return patterns
|
|
58
|
+
.map((pattern) => ({ pattern, specificity: specificity(pattern, toolName), source }))
|
|
59
|
+
.filter((match) => match.specificity >= 0 &&
|
|
60
|
+
(source === 'deny' || source === 'remember_allow' || source === 'ask' || source === 'allow'));
|
|
61
|
+
}
|
|
37
62
|
//# sourceMappingURL=engine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/allowlist/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/allowlist/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/audit/api.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { FastifyInstance } from 'fastify';
|
|
2
2
|
import type { AuditLogger } from './logger.js';
|
|
3
|
+
import { type RequestSecurityOptions } from '../security/request.js';
|
|
3
4
|
export declare function auditApiPlugin(app: FastifyInstance, opts: {
|
|
4
5
|
auditLogger: AuditLogger;
|
|
5
6
|
secret?: string;
|
|
6
7
|
authRequired?: boolean;
|
|
7
8
|
allowedOrigins?: string[];
|
|
9
|
+
getRequestSecurity?: () => RequestSecurityOptions;
|
|
8
10
|
}): Promise<void>;
|
|
9
11
|
//# sourceMappingURL=api.d.ts.map
|
package/dist/audit/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/audit/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/audit/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAwB,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,wBAAsB,cAAc,CAClC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE;IACJ,WAAW,EAAE,WAAW,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,sBAAsB,CAAC;CACnD,GACD,OAAO,CAAC,IAAI,CAAC,CAmBf"}
|
package/dist/audit/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/audit/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/audit/api.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAA+B,MAAM,wBAAwB,CAAC;AAE3F,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAoB,EACpB,IAME;IAEF,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAE7B,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACjD,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO;QACT,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;QACzC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,KAA+B,CAAC;QAC9E,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC;YAChC,KAAK;YACL,IAAI;YACJ,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG;SACzC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/audit/db.d.ts
CHANGED
|
@@ -20,6 +20,16 @@ export interface HitlQueueEntry {
|
|
|
20
20
|
created_at: string;
|
|
21
21
|
resolved_at?: string;
|
|
22
22
|
}
|
|
23
|
+
export interface MobileDeviceEntry {
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
platform: 'ios';
|
|
27
|
+
push_token: string;
|
|
28
|
+
auth_token_hash: string;
|
|
29
|
+
created_at: string;
|
|
30
|
+
updated_at: string;
|
|
31
|
+
revoked_at?: string;
|
|
32
|
+
}
|
|
23
33
|
export declare class AuditDb {
|
|
24
34
|
private db;
|
|
25
35
|
private stmts;
|
|
@@ -38,6 +48,12 @@ export declare class AuditDb {
|
|
|
38
48
|
getHitlByCode(code: string): HitlQueueEntry | undefined;
|
|
39
49
|
getHitlById(id: string): HitlQueueEntry | undefined;
|
|
40
50
|
getPendingHitl(): HitlQueueEntry[];
|
|
51
|
+
getHitlHistory(limit?: number): HitlQueueEntry[];
|
|
52
|
+
upsertMobileDevice(entry: Omit<MobileDeviceEntry, 'revoked_at'>): void;
|
|
53
|
+
updateMobileDevicePushToken(id: string, pushToken: string): void;
|
|
54
|
+
getMobileDeviceByAuthTokenHash(authTokenHash: string): MobileDeviceEntry | undefined;
|
|
55
|
+
getActiveMobileDevices(): MobileDeviceEntry[];
|
|
56
|
+
revokeMobileDevice(id: string): void;
|
|
41
57
|
cleanup(retentionDays: number): void;
|
|
42
58
|
close(): void;
|
|
43
59
|
}
|
package/dist/audit/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/audit/db.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/audit/db.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,OAAO;IAClB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,KAAK,CAeX;gBAEU,MAAM,EAAE,MAAM;IAM1B,OAAO,CAAC,IAAI;IA6CZ,OAAO,CAAC,iBAAiB;IA+DzB,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,IAAI;IAShD,UAAU,CAAC,OAAO,EAAE;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,UAAU,EAAE;IA0BhB,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAIvC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IASrF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIvD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAInD,cAAc,IAAI,cAAc,EAAE;IAIlC,cAAc,CAAC,KAAK,SAAK,GAAG,cAAc,EAAE;IAK5C,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG,IAAI;IAItE,2BAA2B,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQhE,8BAA8B,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAMpF,sBAAsB,IAAI,iBAAiB,EAAE;IAI7C,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIpC,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAMpC,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/audit/db.js
CHANGED
|
@@ -37,6 +37,18 @@ export class AuditDb {
|
|
|
37
37
|
);
|
|
38
38
|
CREATE INDEX IF NOT EXISTS idx_hitl_status ON hitl_queue(status);
|
|
39
39
|
CREATE INDEX IF NOT EXISTS idx_hitl_code ON hitl_queue(code);
|
|
40
|
+
|
|
41
|
+
CREATE TABLE IF NOT EXISTS mobile_devices (
|
|
42
|
+
id TEXT PRIMARY KEY,
|
|
43
|
+
name TEXT NOT NULL,
|
|
44
|
+
platform TEXT NOT NULL,
|
|
45
|
+
push_token TEXT NOT NULL,
|
|
46
|
+
auth_token_hash TEXT NOT NULL UNIQUE,
|
|
47
|
+
created_at TEXT NOT NULL,
|
|
48
|
+
updated_at TEXT NOT NULL,
|
|
49
|
+
revoked_at TEXT
|
|
50
|
+
);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_mobile_devices_revoked ON mobile_devices(revoked_at);
|
|
40
52
|
`);
|
|
41
53
|
}
|
|
42
54
|
prepareStatements() {
|
|
@@ -55,6 +67,44 @@ export class AuditDb {
|
|
|
55
67
|
getHitlByCode: this.db.prepare('SELECT * FROM hitl_queue WHERE code = ?'),
|
|
56
68
|
getHitlById: this.db.prepare('SELECT * FROM hitl_queue WHERE id = ?'),
|
|
57
69
|
getPendingHitl: this.db.prepare("SELECT * FROM hitl_queue WHERE status = 'pending' ORDER BY created_at ASC"),
|
|
70
|
+
getHitlHistory: this.db.prepare(`
|
|
71
|
+
SELECT * FROM hitl_queue
|
|
72
|
+
WHERE status != 'pending'
|
|
73
|
+
ORDER BY COALESCE(resolved_at, created_at) DESC
|
|
74
|
+
LIMIT ?
|
|
75
|
+
`),
|
|
76
|
+
insertMobileDevice: this.db.prepare(`
|
|
77
|
+
INSERT INTO mobile_devices (
|
|
78
|
+
id, name, platform, push_token, auth_token_hash, created_at, updated_at, revoked_at
|
|
79
|
+
)
|
|
80
|
+
VALUES (
|
|
81
|
+
@id, @name, @platform, @push_token, @auth_token_hash, @created_at, @updated_at, NULL
|
|
82
|
+
)
|
|
83
|
+
ON CONFLICT(auth_token_hash) DO UPDATE SET
|
|
84
|
+
name = excluded.name,
|
|
85
|
+
push_token = excluded.push_token,
|
|
86
|
+
updated_at = excluded.updated_at,
|
|
87
|
+
revoked_at = NULL
|
|
88
|
+
`),
|
|
89
|
+
updateMobileDevicePushToken: this.db.prepare(`
|
|
90
|
+
UPDATE mobile_devices
|
|
91
|
+
SET push_token = @push_token, updated_at = @updated_at
|
|
92
|
+
WHERE id = @id AND revoked_at IS NULL
|
|
93
|
+
`),
|
|
94
|
+
getMobileDeviceByAuthTokenHash: this.db.prepare(`
|
|
95
|
+
SELECT * FROM mobile_devices
|
|
96
|
+
WHERE auth_token_hash = ? AND revoked_at IS NULL
|
|
97
|
+
`),
|
|
98
|
+
getActiveMobileDevices: this.db.prepare(`
|
|
99
|
+
SELECT * FROM mobile_devices
|
|
100
|
+
WHERE revoked_at IS NULL
|
|
101
|
+
ORDER BY created_at ASC
|
|
102
|
+
`),
|
|
103
|
+
revokeMobileDevice: this.db.prepare(`
|
|
104
|
+
UPDATE mobile_devices
|
|
105
|
+
SET revoked_at = @revoked_at, updated_at = @revoked_at
|
|
106
|
+
WHERE id = @id AND revoked_at IS NULL
|
|
107
|
+
`),
|
|
58
108
|
cleanupAudit: this.db.prepare('DELETE FROM audit_log WHERE ts < ?'),
|
|
59
109
|
cleanupHitl: this.db.prepare("DELETE FROM hitl_queue WHERE status != 'pending' AND resolved_at < ?"),
|
|
60
110
|
};
|
|
@@ -109,6 +159,29 @@ export class AuditDb {
|
|
|
109
159
|
getPendingHitl() {
|
|
110
160
|
return this.stmts.getPendingHitl.all();
|
|
111
161
|
}
|
|
162
|
+
getHitlHistory(limit = 50) {
|
|
163
|
+
const boundedLimit = Math.max(1, Math.min(limit, 500));
|
|
164
|
+
return this.stmts.getHitlHistory.all(boundedLimit);
|
|
165
|
+
}
|
|
166
|
+
upsertMobileDevice(entry) {
|
|
167
|
+
this.stmts.insertMobileDevice.run(entry);
|
|
168
|
+
}
|
|
169
|
+
updateMobileDevicePushToken(id, pushToken) {
|
|
170
|
+
this.stmts.updateMobileDevicePushToken.run({
|
|
171
|
+
id,
|
|
172
|
+
push_token: pushToken,
|
|
173
|
+
updated_at: new Date().toISOString(),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
getMobileDeviceByAuthTokenHash(authTokenHash) {
|
|
177
|
+
return this.stmts.getMobileDeviceByAuthTokenHash.get(authTokenHash);
|
|
178
|
+
}
|
|
179
|
+
getActiveMobileDevices() {
|
|
180
|
+
return this.stmts.getActiveMobileDevices.all();
|
|
181
|
+
}
|
|
182
|
+
revokeMobileDevice(id) {
|
|
183
|
+
this.stmts.revokeMobileDevice.run({ id, revoked_at: new Date().toISOString() });
|
|
184
|
+
}
|
|
112
185
|
cleanup(retentionDays) {
|
|
113
186
|
const cutoff = new Date(Date.now() - retentionDays * 86400_000).toISOString();
|
|
114
187
|
this.stmts.cleanupAudit.run(cutoff);
|
package/dist/audit/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/audit/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/audit/db.ts"],"names":[],"mappings":"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"}
|
package/dist/audit/logger.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuditEntry, HitlQueueEntry } from './db.js';
|
|
1
|
+
import type { AuditEntry, HitlQueueEntry, MobileDeviceEntry } from './db.js';
|
|
2
2
|
import type { AuditConfig } from '../config/schema.js';
|
|
3
3
|
export declare class AuditLogger {
|
|
4
4
|
private db;
|
|
@@ -7,6 +7,7 @@ export declare class AuditLogger {
|
|
|
7
7
|
private cleanupTimer?;
|
|
8
8
|
constructor(config: AuditConfig);
|
|
9
9
|
log(entry: Omit<AuditEntry, 'id' | 'ts'>): void;
|
|
10
|
+
redactArgs(args: Record<string, unknown>): Record<string, unknown>;
|
|
10
11
|
recent(n: number): AuditEntry[];
|
|
11
12
|
query(filters: {
|
|
12
13
|
agent?: string;
|
|
@@ -19,6 +20,12 @@ export declare class AuditLogger {
|
|
|
19
20
|
getHitlByCode(code: string): HitlQueueEntry | undefined;
|
|
20
21
|
getHitlById(id: string): HitlQueueEntry | undefined;
|
|
21
22
|
getPendingHitl(): HitlQueueEntry[];
|
|
23
|
+
getHitlHistory(limit?: number): HitlQueueEntry[];
|
|
24
|
+
upsertMobileDevice(entry: Omit<MobileDeviceEntry, 'revoked_at'>): void;
|
|
25
|
+
updateMobileDevicePushToken(id: string, pushToken: string): void;
|
|
26
|
+
getMobileDeviceByAuthTokenHash(authTokenHash: string): MobileDeviceEntry | undefined;
|
|
27
|
+
getActiveMobileDevices(): MobileDeviceEntry[];
|
|
28
|
+
revokeMobileDevice(id: string): void;
|
|
22
29
|
startDailyCleanup(): void;
|
|
23
30
|
stop(): void;
|
|
24
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAU;IACpB,OAAO,CAAC,cAAc,CAAW;IACjC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAC,CAAiB;gBAE1B,MAAM,EAAE,WAAW;IAM/B,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC,GAAG,IAAI;IAY/C,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIlE,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE;IAI/B,KAAK,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE;IAK/F,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAGvC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAGrF,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAGvD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAGnD,cAAc,IAAI,cAAc,EAAE;IAGlC,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAGhD,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,GAAG,IAAI;IAGtE,2BAA2B,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAGhE,8BAA8B,CAAC,aAAa,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAGpF,sBAAsB,IAAI,iBAAiB,EAAE;IAG7C,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIpC,iBAAiB,IAAI,IAAI;IAOzB,IAAI,IAAI,IAAI;CAIb"}
|
package/dist/audit/logger.js
CHANGED
|
@@ -22,6 +22,9 @@ export class AuditLogger {
|
|
|
22
22
|
}
|
|
23
23
|
this.db.insertAudit({ ...entry, args, ts: new Date().toISOString() });
|
|
24
24
|
}
|
|
25
|
+
redactArgs(args) {
|
|
26
|
+
return redactFields(args, this.redactPatterns);
|
|
27
|
+
}
|
|
25
28
|
recent(n) {
|
|
26
29
|
return this.db.queryAudit({ limit: n });
|
|
27
30
|
}
|
|
@@ -44,6 +47,24 @@ export class AuditLogger {
|
|
|
44
47
|
getPendingHitl() {
|
|
45
48
|
return this.db.getPendingHitl();
|
|
46
49
|
}
|
|
50
|
+
getHitlHistory(limit) {
|
|
51
|
+
return this.db.getHitlHistory(limit);
|
|
52
|
+
}
|
|
53
|
+
upsertMobileDevice(entry) {
|
|
54
|
+
this.db.upsertMobileDevice(entry);
|
|
55
|
+
}
|
|
56
|
+
updateMobileDevicePushToken(id, pushToken) {
|
|
57
|
+
this.db.updateMobileDevicePushToken(id, pushToken);
|
|
58
|
+
}
|
|
59
|
+
getMobileDeviceByAuthTokenHash(authTokenHash) {
|
|
60
|
+
return this.db.getMobileDeviceByAuthTokenHash(authTokenHash);
|
|
61
|
+
}
|
|
62
|
+
getActiveMobileDevices() {
|
|
63
|
+
return this.db.getActiveMobileDevices();
|
|
64
|
+
}
|
|
65
|
+
revokeMobileDevice(id) {
|
|
66
|
+
this.db.revokeMobileDevice(id);
|
|
67
|
+
}
|
|
47
68
|
startDailyCleanup() {
|
|
48
69
|
this.cleanupTimer = setInterval(() => {
|
|
49
70
|
this.db.cleanup(this.retentionDays);
|