comisai 1.0.10 → 1.0.12
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 +3 -3
- package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +1 -4
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/dist/wizard/steps/06-channels.js +88 -11
- package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +4 -0
- package/node_modules/@comis/cli/dist/wizard/types.d.ts +1 -0
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/package.json +1 -1
- package/package.json +18 -18
- package/node_modules/@comis/core/dist/approval/approval-gate.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/approval/approval-gate.test.js +0 -1003
- package/node_modules/@comis/core/dist/bootstrap.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/bootstrap.test.js +0 -150
- package/node_modules/@comis/core/dist/config/backup.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/backup.test.js +0 -160
- package/node_modules/@comis/core/dist/config/env-substitution.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/env-substitution.test.js +0 -259
- package/node_modules/@comis/core/dist/config/field-metadata.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/field-metadata.test.js +0 -72
- package/node_modules/@comis/core/dist/config/git-manager.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/git-manager.test.js +0 -1042
- package/node_modules/@comis/core/dist/config/immutable-keys.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/immutable-keys.test.js +0 -283
- package/node_modules/@comis/core/dist/config/include-resolver.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/include-resolver.test.js +0 -292
- package/node_modules/@comis/core/dist/config/layered.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/layered.test.js +0 -211
- package/node_modules/@comis/core/dist/config/loader.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/loader.test.js +0 -300
- package/node_modules/@comis/core/dist/config/migrate.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/migrate.test.js +0 -244
- package/node_modules/@comis/core/dist/config/partial-validator.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/partial-validator.test.js +0 -98
- package/node_modules/@comis/core/dist/config/schema-agent-model.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-agent-model.test.js +0 -279
- package/node_modules/@comis/core/dist/config/schema-agent-session.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-agent-session.test.js +0 -242
- package/node_modules/@comis/core/dist/config/schema-agent.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-agent.test.js +0 -645
- package/node_modules/@comis/core/dist/config/schema-channel.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-channel.test.js +0 -341
- package/node_modules/@comis/core/dist/config/schema-coalescer.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-coalescer.test.js +0 -51
- package/node_modules/@comis/core/dist/config/schema-context-engine.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-context-engine.test.js +0 -797
- package/node_modules/@comis/core/dist/config/schema-context-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-context-guard.test.js +0 -111
- package/node_modules/@comis/core/dist/config/schema-daemon.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-daemon.test.js +0 -107
- package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-delivery-timing.test.js +0 -51
- package/node_modules/@comis/core/dist/config/schema-documentation.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-documentation.test.js +0 -63
- package/node_modules/@comis/core/dist/config/schema-gateway.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-gateway.test.js +0 -219
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.test.js +0 -41
- package/node_modules/@comis/core/dist/config/schema-integrations.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-integrations.test.js +0 -92
- package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-lifecycle-reactions.test.js +0 -61
- package/node_modules/@comis/core/dist/config/schema-misc.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-misc.test.js +0 -394
- package/node_modules/@comis/core/dist/config/schema-observability.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-observability.test.js +0 -76
- package/node_modules/@comis/core/dist/config/schema-providers.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-providers.test.js +0 -294
- package/node_modules/@comis/core/dist/config/schema-queue.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-queue.test.js +0 -234
- package/node_modules/@comis/core/dist/config/schema-response-prefix.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-response-prefix.test.js +0 -36
- package/node_modules/@comis/core/dist/config/schema-security.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-security.test.js +0 -54
- package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-sender-trust-display.test.js +0 -60
- package/node_modules/@comis/core/dist/config/schema-serializer.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-serializer.test.js +0 -73
- package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/config/schema-telegram-file-guard.test.js +0 -39
- package/node_modules/@comis/core/dist/context/context.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/context/context.test.js +0 -276
- package/node_modules/@comis/core/dist/domain/agent-response.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/agent-response.test.js +0 -159
- package/node_modules/@comis/core/dist/domain/credential-mapping.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/credential-mapping.test.js +0 -135
- package/node_modules/@comis/core/dist/domain/delivery-origin.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/delivery-origin.test.js +0 -68
- package/node_modules/@comis/core/dist/domain/execution-graph.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/execution-graph.test.js +0 -441
- package/node_modules/@comis/core/dist/domain/memory-entry.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/memory-entry.test.js +0 -193
- package/node_modules/@comis/core/dist/domain/normalized-message.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/normalized-message.test.js +0 -255
- package/node_modules/@comis/core/dist/domain/session-key.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/session-key.test.js +0 -291
- package/node_modules/@comis/core/dist/domain/subagent-context-config.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/subagent-context-config.test.js +0 -131
- package/node_modules/@comis/core/dist/domain/subagent-context-types.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/domain/subagent-context-types.test.js +0 -182
- package/node_modules/@comis/core/dist/event-bus/bus.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/bus.test.js +0 -152
- package/node_modules/@comis/core/dist/event-bus/events-agent.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/events-agent.test.js +0 -409
- package/node_modules/@comis/core/dist/event-bus/events-channel.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/events-channel.test.js +0 -240
- package/node_modules/@comis/core/dist/event-bus/events-infra.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/events-infra.test.js +0 -416
- package/node_modules/@comis/core/dist/event-bus/events-messaging.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/events-messaging.test.js +0 -433
- package/node_modules/@comis/core/dist/event-bus/events.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/event-bus/events.test.js +0 -93
- package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/hooks/hook-runner-global.test.js +0 -29
- package/node_modules/@comis/core/dist/hooks/hook-runner.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/hooks/hook-runner.test.js +0 -490
- package/node_modules/@comis/core/dist/hooks/hook-strategies.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/hooks/hook-strategies.test.js +0 -209
- package/node_modules/@comis/core/dist/hooks/integration.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/hooks/integration.test.js +0 -235
- package/node_modules/@comis/core/dist/hooks/plugin-registry.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/hooks/plugin-registry.test.js +0 -470
- package/node_modules/@comis/core/dist/load-env.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/load-env.test.js +0 -21
- package/node_modules/@comis/core/dist/security/action-classifier.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/action-classifier.test.js +0 -298
- package/node_modules/@comis/core/dist/security/audit-aggregator.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/audit-aggregator.test.js +0 -128
- package/node_modules/@comis/core/dist/security/audit.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/audit.test.js +0 -154
- package/node_modules/@comis/core/dist/security/canary-token.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/canary-token.test.js +0 -45
- package/node_modules/@comis/core/dist/security/config-redaction.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/config-redaction.test.js +0 -107
- package/node_modules/@comis/core/dist/security/external-content.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/external-content.test.js +0 -210
- package/node_modules/@comis/core/dist/security/injection-patterns.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/injection-patterns.test.js +0 -213
- package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/injection-rate-limiter.test.js +0 -194
- package/node_modules/@comis/core/dist/security/input-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/input-guard.test.js +0 -215
- package/node_modules/@comis/core/dist/security/input-security-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/input-security-guard.test.js +0 -215
- package/node_modules/@comis/core/dist/security/input-validator.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/input-validator.test.js +0 -133
- package/node_modules/@comis/core/dist/security/log-sanitizer.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/log-sanitizer.test.js +0 -260
- package/node_modules/@comis/core/dist/security/memory-write-validator.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/memory-write-validator.test.js +0 -62
- package/node_modules/@comis/core/dist/security/output-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/output-guard.test.js +0 -397
- package/node_modules/@comis/core/dist/security/safe-path.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/safe-path.test.js +0 -95
- package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/scoped-secret-manager.test.js +0 -231
- package/node_modules/@comis/core/dist/security/secret-access.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/secret-access.test.js +0 -41
- package/node_modules/@comis/core/dist/security/secret-crypto.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/secret-crypto.test.js +0 -113
- package/node_modules/@comis/core/dist/security/secret-manager.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/secret-manager.test.js +0 -394
- package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/secret-ref-resolver.test.js +0 -268
- package/node_modules/@comis/core/dist/security/secrets-audit.test.d.ts +0 -10
- package/node_modules/@comis/core/dist/security/secrets-audit.test.js +0 -295
- package/node_modules/@comis/core/dist/security/ssrf-guard.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/ssrf-guard.test.js +0 -127
- package/node_modules/@comis/core/dist/security/token-generator.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/security/token-generator.test.js +0 -35
- package/node_modules/@comis/core/dist/tool-metadata.test.d.ts +0 -1
- package/node_modules/@comis/core/dist/tool-metadata.test.js +0 -112
- package/node_modules/@comis/memory/dist/compaction.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/compaction.test.js +0 -298
- package/node_modules/@comis/memory/dist/context-schema.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/context-schema.test.js +0 -246
- package/node_modules/@comis/memory/dist/context-store.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/context-store.test.js +0 -708
- package/node_modules/@comis/memory/dist/credential-mapping-schema.test.d.ts +0 -7
- package/node_modules/@comis/memory/dist/credential-mapping-schema.test.js +0 -73
- package/node_modules/@comis/memory/dist/credential-mapping-store.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/credential-mapping-store.test.js +0 -340
- package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/delivery-mirror-adapter.test.js +0 -165
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.test.js +0 -263
- package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-batch-indexer.test.js +0 -202
- package/node_modules/@comis/memory/dist/embedding-cache-lru.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-cache-lru.test.js +0 -241
- package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/embedding-cache-sqlite.test.js +0 -678
- package/node_modules/@comis/memory/dist/embedding-cache.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-cache.test.js +0 -213
- package/node_modules/@comis/memory/dist/embedding-fingerprint.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-fingerprint.test.js +0 -87
- package/node_modules/@comis/memory/dist/embedding-hash.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-hash.test.js +0 -31
- package/node_modules/@comis/memory/dist/embedding-integration.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/embedding-integration.test.js +0 -232
- package/node_modules/@comis/memory/dist/embedding-provider-factory.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-provider-factory.test.js +0 -176
- package/node_modules/@comis/memory/dist/embedding-provider-local.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/embedding-provider-local.test.js +0 -76
- package/node_modules/@comis/memory/dist/embedding-provider-openai.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/embedding-provider-openai.test.js +0 -100
- package/node_modules/@comis/memory/dist/embedding-queue.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/embedding-queue.test.js +0 -236
- package/node_modules/@comis/memory/dist/hybrid-search.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/hybrid-search.test.js +0 -476
- package/node_modules/@comis/memory/dist/identity-link-store.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/identity-link-store.test.js +0 -88
- package/node_modules/@comis/memory/dist/memory-api.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/memory-api.test.js +0 -495
- package/node_modules/@comis/memory/dist/memory-concurrency.test.d.ts +0 -20
- package/node_modules/@comis/memory/dist/memory-concurrency.test.js +0 -222
- package/node_modules/@comis/memory/dist/named-graph-store.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/named-graph-store.test.js +0 -227
- package/node_modules/@comis/memory/dist/observability-store.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/observability-store.test.js +0 -704
- package/node_modules/@comis/memory/dist/row-mapper.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/row-mapper.test.js +0 -409
- package/node_modules/@comis/memory/dist/schema.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/schema.test.js +0 -240
- package/node_modules/@comis/memory/dist/secret-store-schema.test.d.ts +0 -7
- package/node_modules/@comis/memory/dist/secret-store-schema.test.js +0 -90
- package/node_modules/@comis/memory/dist/session-store.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/session-store.test.js +0 -262
- package/node_modules/@comis/memory/dist/setup-secrets.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/setup-secrets.test.js +0 -140
- package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.d.ts +0 -1
- package/node_modules/@comis/memory/dist/sqlite-memory-adapter.test.js +0 -888
- package/node_modules/@comis/memory/dist/sqlite-secret-store.test.d.ts +0 -8
- package/node_modules/@comis/memory/dist/sqlite-secret-store.test.js +0 -245
- package/node_modules/@comis/shared/dist/abort.test.d.ts +0 -1
- package/node_modules/@comis/shared/dist/abort.test.js +0 -71
- package/node_modules/@comis/shared/dist/result.test.d.ts +0 -1
- package/node_modules/@comis/shared/dist/result.test.js +0 -178
- package/node_modules/@comis/shared/dist/suppress-error.test.d.ts +0 -1
- package/node_modules/@comis/shared/dist/suppress-error.test.js +0 -50
- package/node_modules/@comis/shared/dist/timeout.test.d.ts +0 -1
- package/node_modules/@comis/shared/dist/timeout.test.js +0 -75
- package/node_modules/@comis/shared/dist/ttl-cache.test.d.ts +0 -1
- package/node_modules/@comis/shared/dist/ttl-cache.test.js +0 -81
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for secret store schema DDL and canary validation.
|
|
3
|
-
*
|
|
4
|
-
* Uses in-memory SQLite databases and real crypto from @comis/core
|
|
5
|
-
* to validate schema creation and master key mismatch detection.
|
|
6
|
-
*/
|
|
7
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
8
|
-
import Database from "better-sqlite3";
|
|
9
|
-
import { randomBytes } from "node:crypto";
|
|
10
|
-
import { createSecretsCrypto } from "@comis/core";
|
|
11
|
-
import { initSecretSchema, validateCanary, CANARY_NAME, } from "./secret-store-schema.js";
|
|
12
|
-
function makeCrypto() {
|
|
13
|
-
const key = randomBytes(32);
|
|
14
|
-
return createSecretsCrypto(key);
|
|
15
|
-
}
|
|
16
|
-
describe("initSecretSchema", () => {
|
|
17
|
-
let db;
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
db = new Database(":memory:");
|
|
20
|
-
});
|
|
21
|
-
it("creates secrets table with expected columns", () => {
|
|
22
|
-
initSecretSchema(db);
|
|
23
|
-
const columns = db
|
|
24
|
-
.prepare("PRAGMA table_info(secrets)")
|
|
25
|
-
.all();
|
|
26
|
-
const columnNames = columns.map((c) => c.name);
|
|
27
|
-
expect(columnNames).toContain("name");
|
|
28
|
-
expect(columnNames).toContain("ciphertext");
|
|
29
|
-
expect(columnNames).toContain("iv");
|
|
30
|
-
expect(columnNames).toContain("auth_tag");
|
|
31
|
-
expect(columnNames).toContain("salt");
|
|
32
|
-
expect(columnNames).toContain("provider");
|
|
33
|
-
expect(columnNames).toContain("description");
|
|
34
|
-
expect(columnNames).toContain("expires_at");
|
|
35
|
-
expect(columnNames).toContain("last_used_at");
|
|
36
|
-
expect(columnNames).toContain("usage_count");
|
|
37
|
-
expect(columnNames).toContain("created_at");
|
|
38
|
-
expect(columnNames).toContain("updated_at");
|
|
39
|
-
// Should have exactly 12 columns
|
|
40
|
-
expect(columns).toHaveLength(12);
|
|
41
|
-
// Verify BLOB types for encrypted fields
|
|
42
|
-
const blobColumns = columns.filter((c) => c.type === "BLOB");
|
|
43
|
-
expect(blobColumns.map((c) => c.name).sort()).toEqual(["auth_tag", "ciphertext", "iv", "salt"]);
|
|
44
|
-
// Verify name is primary key
|
|
45
|
-
const pkColumn = columns.find((c) => c.pk === 1);
|
|
46
|
-
expect(pkColumn?.name).toBe("name");
|
|
47
|
-
});
|
|
48
|
-
it("is idempotent (safe to call multiple times)", () => {
|
|
49
|
-
initSecretSchema(db);
|
|
50
|
-
initSecretSchema(db);
|
|
51
|
-
const columns = db
|
|
52
|
-
.prepare("PRAGMA table_info(secrets)")
|
|
53
|
-
.all();
|
|
54
|
-
expect(columns).toHaveLength(12);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
describe("validateCanary", () => {
|
|
58
|
-
let db;
|
|
59
|
-
beforeEach(() => {
|
|
60
|
-
db = new Database(":memory:");
|
|
61
|
-
initSecretSchema(db);
|
|
62
|
-
});
|
|
63
|
-
it("creates canary row on fresh database", () => {
|
|
64
|
-
const crypto = makeCrypto();
|
|
65
|
-
validateCanary(db, crypto);
|
|
66
|
-
const row = db
|
|
67
|
-
.prepare("SELECT name FROM secrets WHERE name = ?")
|
|
68
|
-
.get(CANARY_NAME);
|
|
69
|
-
expect(row).toBeDefined();
|
|
70
|
-
expect(row.name).toBe(CANARY_NAME);
|
|
71
|
-
});
|
|
72
|
-
it("succeeds silently on existing database with correct key", () => {
|
|
73
|
-
const crypto = makeCrypto();
|
|
74
|
-
// First call: creates canary
|
|
75
|
-
validateCanary(db, crypto);
|
|
76
|
-
// Second call: validates canary (should not throw)
|
|
77
|
-
expect(() => validateCanary(db, crypto)).not.toThrow();
|
|
78
|
-
});
|
|
79
|
-
it("throws DECRYPTION_FAILED with wrong master key", () => {
|
|
80
|
-
const crypto1 = makeCrypto();
|
|
81
|
-
const crypto2 = makeCrypto();
|
|
82
|
-
// Create canary with key 1
|
|
83
|
-
validateCanary(db, crypto1);
|
|
84
|
-
// Validate with key 2 -- should fail
|
|
85
|
-
expect(() => validateCanary(db, crypto2)).toThrow(/DECRYPTION_FAILED/);
|
|
86
|
-
});
|
|
87
|
-
it("exports CANARY_NAME for downstream exclusion", () => {
|
|
88
|
-
expect(CANARY_NAME).toBe("__comis_canary__");
|
|
89
|
-
});
|
|
90
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { formatSessionKey } from "@comis/core";
|
|
2
|
-
import Database from "better-sqlite3";
|
|
3
|
-
import { randomUUID } from "node:crypto";
|
|
4
|
-
import { tmpdir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
7
|
-
import { initSchema } from "./schema.js";
|
|
8
|
-
import { createSessionStore, MAX_SESSION_BYTES } from "./session-store.js";
|
|
9
|
-
describe("createSessionStore", () => {
|
|
10
|
-
let db;
|
|
11
|
-
let store;
|
|
12
|
-
const testKey = {
|
|
13
|
-
tenantId: "default",
|
|
14
|
-
userId: "user-1",
|
|
15
|
-
channelId: "telegram",
|
|
16
|
-
};
|
|
17
|
-
const otherKey = {
|
|
18
|
-
tenantId: "default",
|
|
19
|
-
userId: "user-2",
|
|
20
|
-
channelId: "discord",
|
|
21
|
-
};
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
db = new Database(":memory:");
|
|
24
|
-
initSchema(db, 1536);
|
|
25
|
-
store = createSessionStore(db);
|
|
26
|
-
});
|
|
27
|
-
it("save and load roundtrip -- messages array preserved exactly", () => {
|
|
28
|
-
const messages = [
|
|
29
|
-
{ role: "user", content: "Hello" },
|
|
30
|
-
{ role: "assistant", content: "Hi there!" },
|
|
31
|
-
];
|
|
32
|
-
store.save(testKey, messages);
|
|
33
|
-
const loaded = store.load(testKey);
|
|
34
|
-
expect(loaded).toBeDefined();
|
|
35
|
-
expect(loaded.messages).toEqual(messages);
|
|
36
|
-
});
|
|
37
|
-
it("save with metadata -- metadata object preserved", () => {
|
|
38
|
-
const messages = [{ role: "user", content: "test" }];
|
|
39
|
-
const metadata = { model: "gpt-4", temperature: 0.7, tags: ["debug"] };
|
|
40
|
-
store.save(testKey, messages, metadata);
|
|
41
|
-
const loaded = store.load(testKey);
|
|
42
|
-
expect(loaded).toBeDefined();
|
|
43
|
-
expect(loaded.metadata).toEqual(metadata);
|
|
44
|
-
});
|
|
45
|
-
it("load returns undefined for non-existent session", () => {
|
|
46
|
-
const result = store.load({
|
|
47
|
-
tenantId: "default",
|
|
48
|
-
userId: "nobody",
|
|
49
|
-
channelId: "nowhere",
|
|
50
|
-
});
|
|
51
|
-
expect(result).toBeUndefined();
|
|
52
|
-
});
|
|
53
|
-
it("save overwrites existing session (upsert) -- messages updated", () => {
|
|
54
|
-
const original = [{ role: "user", content: "first" }];
|
|
55
|
-
const updated = [
|
|
56
|
-
{ role: "user", content: "first" },
|
|
57
|
-
{ role: "assistant", content: "reply" },
|
|
58
|
-
];
|
|
59
|
-
store.save(testKey, original);
|
|
60
|
-
store.save(testKey, updated);
|
|
61
|
-
const loaded = store.load(testKey);
|
|
62
|
-
expect(loaded).toBeDefined();
|
|
63
|
-
expect(loaded.messages).toEqual(updated);
|
|
64
|
-
});
|
|
65
|
-
it("save preserves createdAt on update (only updatedAt changes)", () => {
|
|
66
|
-
store.save(testKey, [{ msg: "first" }]);
|
|
67
|
-
const first = store.load(testKey);
|
|
68
|
-
// Small delay to ensure different timestamps
|
|
69
|
-
const createdAt = first.createdAt;
|
|
70
|
-
// Manually set a known created_at in the past for deterministic testing
|
|
71
|
-
db.prepare("UPDATE sessions SET created_at = 1000, updated_at = 1000 WHERE session_key = ?").run("default:user-1:telegram");
|
|
72
|
-
store.save(testKey, [{ msg: "second" }]);
|
|
73
|
-
const second = store.load(testKey);
|
|
74
|
-
// createdAt should stay at 1000 (the original ON CONFLICT preserves it)
|
|
75
|
-
expect(second.createdAt).toBe(1000);
|
|
76
|
-
// updatedAt should be fresh (not 1000)
|
|
77
|
-
expect(second.updatedAt).toBeGreaterThan(1000);
|
|
78
|
-
});
|
|
79
|
-
it("list returns sessions ordered by updatedAt DESC", () => {
|
|
80
|
-
// Insert with explicit timestamps for deterministic ordering
|
|
81
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
82
|
-
VALUES ('s1', 'default', 'u1', 'ch1', '[]', 1000, 1000, '{}')`).run();
|
|
83
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
84
|
-
VALUES ('s2', 'default', 'u2', 'ch2', '[]', 2000, 3000, '{}')`).run();
|
|
85
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
86
|
-
VALUES ('s3', 'default', 'u3', 'ch3', '[]', 1500, 2000, '{}')`).run();
|
|
87
|
-
const list = store.list();
|
|
88
|
-
expect(list).toHaveLength(3);
|
|
89
|
-
expect(list[0].sessionKey).toBe("s2"); // updatedAt 3000
|
|
90
|
-
expect(list[1].sessionKey).toBe("s3"); // updatedAt 2000
|
|
91
|
-
expect(list[2].sessionKey).toBe("s1"); // updatedAt 1000
|
|
92
|
-
});
|
|
93
|
-
it("list with tenantId filter returns only matching sessions", () => {
|
|
94
|
-
const tenantAKey = { tenantId: "tenant-a", userId: "u1", channelId: "ch1" };
|
|
95
|
-
const tenantBKey = { tenantId: "tenant-b", userId: "u2", channelId: "ch2" };
|
|
96
|
-
store.save(tenantAKey, [{ msg: "a" }]);
|
|
97
|
-
store.save(tenantBKey, [{ msg: "b" }]);
|
|
98
|
-
const filtered = store.list("tenant-a");
|
|
99
|
-
expect(filtered).toHaveLength(1);
|
|
100
|
-
expect(filtered[0].sessionKey).toContain("tenant-a");
|
|
101
|
-
});
|
|
102
|
-
it("delete removes session and returns true", () => {
|
|
103
|
-
store.save(testKey, [{ msg: "test" }]);
|
|
104
|
-
const deleted = store.delete(testKey);
|
|
105
|
-
expect(deleted).toBe(true);
|
|
106
|
-
const loaded = store.load(testKey);
|
|
107
|
-
expect(loaded).toBeUndefined();
|
|
108
|
-
});
|
|
109
|
-
it("delete returns false for non-existent session", () => {
|
|
110
|
-
const deleted = store.delete({
|
|
111
|
-
tenantId: "default",
|
|
112
|
-
userId: "nonexistent",
|
|
113
|
-
channelId: "none",
|
|
114
|
-
});
|
|
115
|
-
expect(deleted).toBe(false);
|
|
116
|
-
});
|
|
117
|
-
it("deleteStale removes sessions older than threshold", () => {
|
|
118
|
-
// Insert sessions with specific updatedAt timestamps
|
|
119
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
120
|
-
VALUES ('old-session', 'default', 'u1', 'ch1', '[]', 1000, 1000, '{}')`).run();
|
|
121
|
-
store.save(testKey, [{ msg: "fresh" }]); // This will have a current timestamp
|
|
122
|
-
// Delete sessions older than 1 hour (the old session at timestamp 1000ms will be deleted)
|
|
123
|
-
const deleted = store.deleteStale(60 * 60 * 1000);
|
|
124
|
-
expect(deleted).toBe(1);
|
|
125
|
-
// Fresh session should survive
|
|
126
|
-
const loaded = store.load(testKey);
|
|
127
|
-
expect(loaded).toBeDefined();
|
|
128
|
-
});
|
|
129
|
-
it("deleteStale returns count of deleted sessions", () => {
|
|
130
|
-
// Insert multiple old sessions
|
|
131
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
132
|
-
VALUES ('old1', 'default', 'u1', 'ch1', '[]', 100, 100, '{}')`).run();
|
|
133
|
-
db.prepare(`INSERT INTO sessions (session_key, tenant_id, user_id, channel_id, messages, created_at, updated_at, metadata)
|
|
134
|
-
VALUES ('old2', 'default', 'u2', 'ch2', '[]', 200, 200, '{}')`).run();
|
|
135
|
-
const deleted = store.deleteStale(60 * 60 * 1000);
|
|
136
|
-
expect(deleted).toBe(2);
|
|
137
|
-
});
|
|
138
|
-
it("session survives db close/reopen cycle (file-backed)", () => {
|
|
139
|
-
const dbPath = join(tmpdir(), `comis-test-${randomUUID()}.db`);
|
|
140
|
-
// Create and populate
|
|
141
|
-
const fileDb = new Database(dbPath);
|
|
142
|
-
initSchema(fileDb, 1536);
|
|
143
|
-
const fileStore = createSessionStore(fileDb);
|
|
144
|
-
const messages = [
|
|
145
|
-
{ role: "user", content: "persist me" },
|
|
146
|
-
{ role: "assistant", content: "I will be remembered" },
|
|
147
|
-
];
|
|
148
|
-
fileStore.save(testKey, messages, { persistent: true });
|
|
149
|
-
fileDb.close();
|
|
150
|
-
// Reopen and verify
|
|
151
|
-
const reopened = new Database(dbPath);
|
|
152
|
-
initSchema(reopened, 1536); // Safe to call again (idempotent)
|
|
153
|
-
const reopenedStore = createSessionStore(reopened);
|
|
154
|
-
const loaded = reopenedStore.load(testKey);
|
|
155
|
-
expect(loaded).toBeDefined();
|
|
156
|
-
expect(loaded.messages).toEqual(messages);
|
|
157
|
-
expect(loaded.metadata).toEqual({ persistent: true });
|
|
158
|
-
reopened.close();
|
|
159
|
-
// Cleanup
|
|
160
|
-
try {
|
|
161
|
-
const { unlinkSync } = require("node:fs");
|
|
162
|
-
unlinkSync(dbPath);
|
|
163
|
-
unlinkSync(dbPath + "-wal");
|
|
164
|
-
unlinkSync(dbPath + "-shm");
|
|
165
|
-
}
|
|
166
|
-
catch {
|
|
167
|
-
// Ignore cleanup errors
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
it("multiple sessions with different keys are independent", () => {
|
|
171
|
-
const msgs1 = [{ msg: "session 1" }];
|
|
172
|
-
const msgs2 = [{ msg: "session 2" }];
|
|
173
|
-
store.save(testKey, msgs1);
|
|
174
|
-
store.save(otherKey, msgs2);
|
|
175
|
-
const loaded1 = store.load(testKey);
|
|
176
|
-
const loaded2 = store.load(otherKey);
|
|
177
|
-
expect(loaded1.messages).toEqual(msgs1);
|
|
178
|
-
expect(loaded2.messages).toEqual(msgs2);
|
|
179
|
-
});
|
|
180
|
-
it("empty messages array is valid (new session with no history)", () => {
|
|
181
|
-
store.save(testKey, []);
|
|
182
|
-
const loaded = store.load(testKey);
|
|
183
|
-
expect(loaded).toBeDefined();
|
|
184
|
-
expect(loaded.messages).toEqual([]);
|
|
185
|
-
});
|
|
186
|
-
it("default metadata is empty object when not provided", () => {
|
|
187
|
-
store.save(testKey, [{ msg: "test" }]);
|
|
188
|
-
const loaded = store.load(testKey);
|
|
189
|
-
expect(loaded).toBeDefined();
|
|
190
|
-
expect(loaded.metadata).toEqual({});
|
|
191
|
-
});
|
|
192
|
-
describe("loadByFormattedKey", () => {
|
|
193
|
-
it("loads session by formatted key string", () => {
|
|
194
|
-
const key = { tenantId: "default", userId: "u1", channelId: "c1" };
|
|
195
|
-
store.save(key, [{ role: "user", content: "hello" }], { foo: "bar" });
|
|
196
|
-
const formatted = formatSessionKey(key);
|
|
197
|
-
const data = store.loadByFormattedKey(formatted);
|
|
198
|
-
expect(data).toBeDefined();
|
|
199
|
-
expect(data.messages).toEqual([{ role: "user", content: "hello" }]);
|
|
200
|
-
expect(data.metadata).toEqual({ foo: "bar" });
|
|
201
|
-
});
|
|
202
|
-
it("returns undefined for non-existent key", () => {
|
|
203
|
-
expect(store.loadByFormattedKey("nonexistent:key:string")).toBeUndefined();
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
// ── DATA-07: session size limits ────────────────────────────────
|
|
207
|
-
describe("session size limits", () => {
|
|
208
|
-
it("saves session with small messages successfully", () => {
|
|
209
|
-
const messages = [{ role: "user", content: "hello" }];
|
|
210
|
-
expect(() => store.save(testKey, messages)).not.toThrow();
|
|
211
|
-
const loaded = store.load(testKey);
|
|
212
|
-
expect(loaded).toBeDefined();
|
|
213
|
-
expect(loaded.messages).toEqual(messages);
|
|
214
|
-
});
|
|
215
|
-
it("throws when messages JSON exceeds 10MB", () => {
|
|
216
|
-
// Create a message array that exceeds 10MB when serialized
|
|
217
|
-
const largeContent = "x".repeat(11 * 1024 * 1024); // 11MB string
|
|
218
|
-
const messages = [{ role: "user", content: largeContent }];
|
|
219
|
-
expect(() => store.save(testKey, messages)).toThrow(/Session data exceeds maximum size/);
|
|
220
|
-
expect(() => store.save(testKey, messages)).toThrow(/10MB limit/);
|
|
221
|
-
});
|
|
222
|
-
it("saves session right at the limit", () => {
|
|
223
|
-
// Create messages that are close to but under 10MB
|
|
224
|
-
// MAX_SESSION_BYTES = 10 * 1024 * 1024 = 10485760
|
|
225
|
-
// We need messages + metadata JSON to be <= 10485760 bytes
|
|
226
|
-
// JSON overhead: {"role":"user","content":"..."} -> ~30 bytes + content
|
|
227
|
-
// Outer array: [...] -> ~2 bytes
|
|
228
|
-
// metadata: {} -> 2 bytes
|
|
229
|
-
const targetContentSize = MAX_SESSION_BYTES - 100; // leave room for JSON overhead + metadata
|
|
230
|
-
const content = "a".repeat(targetContentSize);
|
|
231
|
-
const messages = [{ content }];
|
|
232
|
-
expect(() => store.save(testKey, messages)).not.toThrow();
|
|
233
|
-
});
|
|
234
|
-
it("MAX_SESSION_BYTES is 10MB", () => {
|
|
235
|
-
expect(MAX_SESSION_BYTES).toBe(10 * 1024 * 1024);
|
|
236
|
-
});
|
|
237
|
-
});
|
|
238
|
-
describe("listDetailed", () => {
|
|
239
|
-
it("returns detailed session entries with metadata", () => {
|
|
240
|
-
const key1 = { tenantId: "t1", userId: "u1", channelId: "c1" };
|
|
241
|
-
const key2 = { tenantId: "t1", userId: "u2", channelId: "c2" };
|
|
242
|
-
store.save(key1, [], { parentSessionKey: "some-parent" });
|
|
243
|
-
store.save(key2, [], {});
|
|
244
|
-
const entries = store.listDetailed("t1");
|
|
245
|
-
expect(entries).toHaveLength(2);
|
|
246
|
-
// Most recent first
|
|
247
|
-
const subAgent = entries.find(e => e.metadata.parentSessionKey !== undefined);
|
|
248
|
-
expect(subAgent).toBeDefined();
|
|
249
|
-
expect(subAgent.userId).toBe("u1");
|
|
250
|
-
expect(subAgent.metadata.parentSessionKey).toBe("some-parent");
|
|
251
|
-
});
|
|
252
|
-
it("filters by tenantId", () => {
|
|
253
|
-
const key1 = { tenantId: "t1", userId: "u1", channelId: "c1" };
|
|
254
|
-
const key2 = { tenantId: "t2", userId: "u2", channelId: "c2" };
|
|
255
|
-
store.save(key1, []);
|
|
256
|
-
store.save(key2, []);
|
|
257
|
-
expect(store.listDetailed("t1")).toHaveLength(1);
|
|
258
|
-
expect(store.listDetailed("t2")).toHaveLength(1);
|
|
259
|
-
expect(store.listDetailed()).toHaveLength(2);
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { randomBytes } from "node:crypto";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { setupSecrets } from "./setup-secrets.js";
|
|
5
|
-
// Generate valid test keys
|
|
6
|
-
const VALID_HEX_KEY = randomBytes(32).toString("hex"); // 64 hex chars = 32 bytes
|
|
7
|
-
const VALID_BASE64_KEY = randomBytes(32).toString("base64"); // 44+ base64 chars = 32+ bytes
|
|
8
|
-
describe("setupSecrets", () => {
|
|
9
|
-
// -----------------------------------------------------------
|
|
10
|
-
// Branch 1: SECRETS_MASTER_KEY absent → ok(null) (legacy mode)
|
|
11
|
-
// -----------------------------------------------------------
|
|
12
|
-
describe("when SECRETS_MASTER_KEY is absent", () => {
|
|
13
|
-
it("returns ok(null) when env has no SECRETS_MASTER_KEY", () => {
|
|
14
|
-
const result = setupSecrets({ env: {}, dataDir: tmpdir() });
|
|
15
|
-
expect(result.ok).toBe(true);
|
|
16
|
-
expect(result.ok && result.value).toBeNull();
|
|
17
|
-
});
|
|
18
|
-
it("returns ok(null) when SECRETS_MASTER_KEY is undefined", () => {
|
|
19
|
-
const result = setupSecrets({
|
|
20
|
-
env: { SECRETS_MASTER_KEY: undefined },
|
|
21
|
-
dataDir: tmpdir(),
|
|
22
|
-
});
|
|
23
|
-
expect(result.ok).toBe(true);
|
|
24
|
-
expect(result.ok && result.value).toBeNull();
|
|
25
|
-
});
|
|
26
|
-
it("returns ok(null) when SECRETS_MASTER_KEY is empty string", () => {
|
|
27
|
-
const result = setupSecrets({
|
|
28
|
-
env: { SECRETS_MASTER_KEY: "" },
|
|
29
|
-
dataDir: tmpdir(),
|
|
30
|
-
});
|
|
31
|
-
expect(result.ok).toBe(true);
|
|
32
|
-
expect(result.ok && result.value).toBeNull();
|
|
33
|
-
});
|
|
34
|
-
it("returns ok(null) when SECRETS_MASTER_KEY is whitespace-only", () => {
|
|
35
|
-
const result = setupSecrets({
|
|
36
|
-
env: { SECRETS_MASTER_KEY: " " },
|
|
37
|
-
dataDir: tmpdir(),
|
|
38
|
-
});
|
|
39
|
-
expect(result.ok).toBe(true);
|
|
40
|
-
expect(result.ok && result.value).toBeNull();
|
|
41
|
-
});
|
|
42
|
-
});
|
|
43
|
-
// -----------------------------------------------------------
|
|
44
|
-
// Branch 2: SECRETS_MASTER_KEY set but invalid → err()
|
|
45
|
-
// -----------------------------------------------------------
|
|
46
|
-
describe("when SECRETS_MASTER_KEY is invalid", () => {
|
|
47
|
-
it("returns err() for too-short key", () => {
|
|
48
|
-
const result = setupSecrets({
|
|
49
|
-
env: { SECRETS_MASTER_KEY: "abc" },
|
|
50
|
-
dataDir: tmpdir(),
|
|
51
|
-
});
|
|
52
|
-
expect(result.ok).toBe(false);
|
|
53
|
-
if (!result.ok) {
|
|
54
|
-
expect(result.error.message).toContain("Invalid SECRETS_MASTER_KEY");
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
it("returns err() for invalid encoding", () => {
|
|
58
|
-
const result = setupSecrets({
|
|
59
|
-
env: { SECRETS_MASTER_KEY: "!!not-valid!!" },
|
|
60
|
-
dataDir: tmpdir(),
|
|
61
|
-
});
|
|
62
|
-
expect(result.ok).toBe(false);
|
|
63
|
-
if (!result.ok) {
|
|
64
|
-
expect(result.error.message).toContain("Invalid SECRETS_MASTER_KEY");
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
it("includes actionable guidance in error message", () => {
|
|
68
|
-
const result = setupSecrets({
|
|
69
|
-
env: { SECRETS_MASTER_KEY: "short" },
|
|
70
|
-
dataDir: tmpdir(),
|
|
71
|
-
});
|
|
72
|
-
expect(result.ok).toBe(false);
|
|
73
|
-
if (!result.ok) {
|
|
74
|
-
expect(result.error.message).toMatch(/hex.*64\+|base64.*44\+/i);
|
|
75
|
-
expect(result.error.message).toContain("legacy mode");
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
// -----------------------------------------------------------
|
|
80
|
-
// Branch 3: SECRETS_MASTER_KEY set and valid → ok({ crypto, dbPath })
|
|
81
|
-
// -----------------------------------------------------------
|
|
82
|
-
describe("when SECRETS_MASTER_KEY is valid", () => {
|
|
83
|
-
it("returns ok({ crypto, dbPath }) for valid hex key", () => {
|
|
84
|
-
const result = setupSecrets({
|
|
85
|
-
env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
|
|
86
|
-
dataDir: tmpdir(),
|
|
87
|
-
});
|
|
88
|
-
expect(result.ok).toBe(true);
|
|
89
|
-
if (result.ok) {
|
|
90
|
-
expect(result.value).not.toBeNull();
|
|
91
|
-
expect(result.value.crypto).toBeDefined();
|
|
92
|
-
expect(result.value.dbPath).toBeDefined();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
it("returns ok({ crypto, dbPath }) for valid base64 key", () => {
|
|
96
|
-
const result = setupSecrets({
|
|
97
|
-
env: { SECRETS_MASTER_KEY: VALID_BASE64_KEY },
|
|
98
|
-
dataDir: tmpdir(),
|
|
99
|
-
});
|
|
100
|
-
expect(result.ok).toBe(true);
|
|
101
|
-
if (result.ok) {
|
|
102
|
-
expect(result.value).not.toBeNull();
|
|
103
|
-
expect(result.value.crypto).toBeDefined();
|
|
104
|
-
expect(result.value.dbPath).toBeDefined();
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
it("computes dbPath from dataDir ending with secrets.db", () => {
|
|
108
|
-
const dataDir = tmpdir();
|
|
109
|
-
const result = setupSecrets({
|
|
110
|
-
env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
|
|
111
|
-
dataDir,
|
|
112
|
-
});
|
|
113
|
-
expect(result.ok).toBe(true);
|
|
114
|
-
if (result.ok && result.value) {
|
|
115
|
-
expect(result.value.dbPath).toMatch(/secrets\.db$/);
|
|
116
|
-
expect(result.value.dbPath).toContain(dataDir);
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
it("returned crypto can encrypt and decrypt a round-trip value", () => {
|
|
120
|
-
const result = setupSecrets({
|
|
121
|
-
env: { SECRETS_MASTER_KEY: VALID_HEX_KEY },
|
|
122
|
-
dataDir: tmpdir(),
|
|
123
|
-
});
|
|
124
|
-
expect(result.ok).toBe(true);
|
|
125
|
-
if (result.ok && result.value) {
|
|
126
|
-
const { crypto } = result.value;
|
|
127
|
-
const plaintext = "my-secret-api-key-12345";
|
|
128
|
-
const encResult = crypto.encrypt(plaintext);
|
|
129
|
-
expect(encResult.ok).toBe(true);
|
|
130
|
-
if (encResult.ok) {
|
|
131
|
-
const decResult = crypto.decrypt(encResult.value);
|
|
132
|
-
expect(decResult.ok).toBe(true);
|
|
133
|
-
if (decResult.ok) {
|
|
134
|
-
expect(decResult.value).toBe(plaintext);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|