@agentvault/secure-channel 0.1.1 → 0.2.0

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/dist/state.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import type { PersistedState } from "./types.js";
2
2
  export declare function saveState(dataDir: string, state: PersistedState): Promise<void>;
3
- export declare function loadState(dataDir: string): Promise<PersistedState | null>;
3
+ /**
4
+ * Load raw persisted state from disk.
5
+ * Returns the raw parsed JSON — caller is responsible for migration
6
+ * from legacy format to current PersistedState.
7
+ */
8
+ export declare function loadState(dataDir: string): Promise<any | null>;
4
9
  export declare function clearState(dataDir: string): Promise<void>;
5
10
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/D"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,GAEd,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAQrB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO/D"}
package/dist/types.d.ts CHANGED
@@ -13,7 +13,28 @@ export interface MessageMetadata {
13
13
  conversationId: string;
14
14
  timestamp: string;
15
15
  }
16
+ export interface DeviceSession {
17
+ ownerDeviceId: string;
18
+ ratchetState: string;
19
+ }
16
20
  export interface PersistedState {
21
+ deviceId: string;
22
+ deviceJwt: string;
23
+ primaryConversationId: string;
24
+ sessions: Record<string, DeviceSession>;
25
+ identityKeypair: {
26
+ publicKey: string;
27
+ privateKey: string;
28
+ };
29
+ ephemeralKeypair: {
30
+ publicKey: string;
31
+ privateKey: string;
32
+ };
33
+ fingerprint: string;
34
+ lastMessageTimestamp?: string;
35
+ }
36
+ /** Legacy state format for backward compatibility */
37
+ export interface LegacyPersistedState {
17
38
  deviceId: string;
18
39
  deviceJwt: string;
19
40
  conversationId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,WAAW,GACX,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,OAAO,GACP,cAAc,GACd,OAAO,CAAC;AAEZ,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,gBAAgB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,WAAW,GACX,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,OAAO,GACP,cAAc,GACd,OAAO,CAAC;AAEZ,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACxC,eAAe,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,gBAAgB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,gBAAgB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5D,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B"}
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "@agentvault/secure-channel",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
7
13
  "license": "MIT",
8
14
  "scripts": {
9
- "build": "tsc",
15
+ "build": "tsc --emitDeclarationOnly && node build.mjs",
10
16
  "test": "vitest run",
11
17
  "test:watch": "vitest"
12
18
  },
@@ -21,14 +27,15 @@
21
27
  "access": "public"
22
28
  },
23
29
  "dependencies": {
24
- "@agentvault/crypto": "^0.1.0",
25
- "libsodium-wrappers-sumo": "^0.7.15",
26
30
  "ws": "^8.16.0"
27
31
  },
28
32
  "devDependencies": {
29
- "typescript": "^5.4.0",
30
- "vitest": "^2.0.0",
33
+ "@agentvault/crypto": "^0.1.0",
34
+ "@types/libsodium-wrappers-sumo": "^0.7.8",
31
35
  "@types/ws": "^8.5.10",
32
- "@types/libsodium-wrappers-sumo": "^0.7.8"
36
+ "esbuild": "^0.27.3",
37
+ "libsodium-wrappers-sumo": "^0.7.15",
38
+ "typescript": "^5.4.0",
39
+ "vitest": "^2.0.0"
33
40
  }
34
41
  }
@@ -1,73 +0,0 @@
1
- import { describe, it, expect, beforeAll } from "vitest";
2
- import sodium from "libsodium-wrappers-sumo";
3
- import { hexToBytes, bytesToHex, base64ToBytes, bytesToBase64, encryptedMessageToTransport, transportToEncryptedMessage, } from "../crypto-helpers.js";
4
- beforeAll(async () => {
5
- await sodium.ready;
6
- });
7
- describe("hex conversion", () => {
8
- it("round-trips hex encoding", () => {
9
- const original = sodium.randombytes_buf(32);
10
- const hex = bytesToHex(original);
11
- const decoded = hexToBytes(hex);
12
- expect(decoded).toEqual(original);
13
- });
14
- it("handles known value", () => {
15
- const bytes = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);
16
- expect(bytesToHex(bytes)).toBe("deadbeef");
17
- expect(hexToBytes("deadbeef")).toEqual(bytes);
18
- });
19
- });
20
- describe("base64 conversion", () => {
21
- it("round-trips base64 encoding", () => {
22
- const original = sodium.randombytes_buf(48);
23
- const b64 = bytesToBase64(original);
24
- const decoded = base64ToBytes(b64);
25
- expect(decoded).toEqual(original);
26
- });
27
- });
28
- describe("transport format", () => {
29
- it("round-trips EncryptedMessage through transport format", () => {
30
- const msg = {
31
- header: {
32
- dhPublicKey: sodium.randombytes_buf(32),
33
- previousChainLength: 3,
34
- messageNumber: 7,
35
- },
36
- headerSignature: sodium.randombytes_buf(64),
37
- nonce: sodium.randombytes_buf(24),
38
- ciphertext: sodium.randombytes_buf(128),
39
- };
40
- const transport = encryptedMessageToTransport(msg);
41
- const restored = transportToEncryptedMessage(transport);
42
- expect(restored.header.dhPublicKey).toEqual(msg.header.dhPublicKey);
43
- expect(restored.header.previousChainLength).toBe(msg.header.previousChainLength);
44
- expect(restored.header.messageNumber).toBe(msg.header.messageNumber);
45
- expect(restored.headerSignature).toEqual(msg.headerSignature);
46
- expect(restored.nonce).toEqual(msg.nonce);
47
- expect(restored.ciphertext).toEqual(msg.ciphertext);
48
- });
49
- it("produces expected transport structure", () => {
50
- const msg = {
51
- header: {
52
- dhPublicKey: sodium.randombytes_buf(32),
53
- previousChainLength: 0,
54
- messageNumber: 0,
55
- },
56
- headerSignature: sodium.randombytes_buf(64),
57
- nonce: sodium.randombytes_buf(24),
58
- ciphertext: sodium.randombytes_buf(16),
59
- };
60
- const transport = encryptedMessageToTransport(msg);
61
- expect(typeof transport.header_blob).toBe("string");
62
- expect(typeof transport.ciphertext).toBe("string");
63
- // header_blob should be base64-encoded JSON
64
- const headerJson = new TextDecoder().decode(base64ToBytes(transport.header_blob));
65
- const headerObj = JSON.parse(headerJson);
66
- expect(headerObj).toHaveProperty("dhPublicKey");
67
- expect(headerObj).toHaveProperty("previousChainLength");
68
- expect(headerObj).toHaveProperty("messageNumber");
69
- expect(headerObj).toHaveProperty("headerSignature");
70
- expect(headerObj).toHaveProperty("nonce");
71
- });
72
- });
73
- //# sourceMappingURL=crypto-helpers.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"crypto-helpers.test.js","sourceRoot":"","sources":["../../src/__tests__/crypto-helpers.test.ts"],"names":[],"mappings":"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"}
@@ -1,58 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
- import { mkdtemp, rm } from "node:fs/promises";
3
- import { join } from "node:path";
4
- import { tmpdir } from "node:os";
5
- import { saveState, loadState, clearState } from "../state.js";
6
- const makeState = () => ({
7
- deviceId: "d1234567-1234-1234-1234-123456789abc",
8
- deviceJwt: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.test.sig",
9
- conversationId: "c1234567-1234-1234-1234-123456789abc",
10
- identityKeypair: {
11
- publicKey: "aabb".repeat(16),
12
- privateKey: "ccdd".repeat(16),
13
- },
14
- ephemeralKeypair: {
15
- publicKey: "eeff".repeat(16),
16
- privateKey: "1122".repeat(16),
17
- },
18
- fingerprint: "aa:bb:cc:dd:ee:ff:00:11",
19
- ratchetState: '{"rootKey":"deadbeef"}',
20
- });
21
- let tempDir;
22
- beforeEach(async () => {
23
- tempDir = await mkdtemp(join(tmpdir(), "av-state-test-"));
24
- });
25
- afterEach(async () => {
26
- await rm(tempDir, { recursive: true, force: true });
27
- });
28
- describe("state persistence", () => {
29
- it("round-trips state through save/load", async () => {
30
- const state = makeState();
31
- await saveState(tempDir, state);
32
- const loaded = await loadState(tempDir);
33
- expect(loaded).toEqual(state);
34
- });
35
- it("returns null for missing state file", async () => {
36
- const loaded = await loadState(tempDir);
37
- expect(loaded).toBeNull();
38
- });
39
- it("clearState removes the state file", async () => {
40
- const state = makeState();
41
- await saveState(tempDir, state);
42
- await clearState(tempDir);
43
- const loaded = await loadState(tempDir);
44
- expect(loaded).toBeNull();
45
- });
46
- it("clearState is safe when file doesn't exist", async () => {
47
- // Should not throw
48
- await clearState(tempDir);
49
- });
50
- it("creates dataDir if it doesn't exist", async () => {
51
- const nestedDir = join(tempDir, "nested", "deep");
52
- const state = makeState();
53
- await saveState(nestedDir, state);
54
- const loaded = await loadState(nestedDir);
55
- expect(loaded).toEqual(state);
56
- });
57
- });
58
- //# sourceMappingURL=state.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"state.test.js","sourceRoot":"","sources":["../../src/__tests__/state.test.ts"],"names":[],"mappings":"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"}
@@ -1,101 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- import { enrollDevice, pollDeviceStatus, activateDevice, } from "../transport.js";
3
- const mockFetch = vi.fn();
4
- beforeEach(() => {
5
- vi.stubGlobal("fetch", mockFetch);
6
- });
7
- afterEach(() => {
8
- vi.restoreAllMocks();
9
- });
10
- const API = "http://localhost:8000";
11
- describe("enrollDevice", () => {
12
- it("sends correct request and returns response", async () => {
13
- const body = {
14
- device_id: "d1234567-1234-1234-1234-123456789abc",
15
- fingerprint: "aa:bb:cc:dd",
16
- status: "PENDING",
17
- };
18
- mockFetch.mockResolvedValueOnce({
19
- ok: true,
20
- json: async () => body,
21
- });
22
- const result = await enrollDevice(API, "invite-token-123", "aabb".repeat(16), "ccdd".repeat(16), "eeff".repeat(32));
23
- expect(mockFetch).toHaveBeenCalledOnce();
24
- const [url, opts] = mockFetch.mock.calls[0];
25
- expect(url).toBe(`${API}/api/v1/enroll`);
26
- expect(opts.method).toBe("POST");
27
- expect(JSON.parse(opts.body)).toEqual({
28
- invite_token: "invite-token-123",
29
- identity_public_key: "aabb".repeat(16),
30
- ephemeral_public_key: "ccdd".repeat(16),
31
- proof_of_possession: "eeff".repeat(32),
32
- platform: "node",
33
- });
34
- expect(result).toEqual(body);
35
- });
36
- it("throws on non-ok response", async () => {
37
- mockFetch.mockResolvedValueOnce({
38
- ok: false,
39
- status: 400,
40
- text: async () => "Bad request",
41
- });
42
- await expect(enrollDevice(API, "bad", "aa", "bb", "cc")).rejects.toThrow("Enrollment failed (400)");
43
- });
44
- });
45
- describe("pollDeviceStatus", () => {
46
- it("sends GET and returns status", async () => {
47
- const body = {
48
- device_id: "d1234567-1234-1234-1234-123456789abc",
49
- status: "PENDING",
50
- fingerprint: "aa:bb:cc:dd",
51
- };
52
- mockFetch.mockResolvedValueOnce({
53
- ok: true,
54
- json: async () => body,
55
- });
56
- const result = await pollDeviceStatus(API, "d1234567-1234-1234-1234-123456789abc");
57
- expect(mockFetch).toHaveBeenCalledOnce();
58
- const [url] = mockFetch.mock.calls[0];
59
- expect(url).toBe(`${API}/api/v1/devices/d1234567-1234-1234-1234-123456789abc/status`);
60
- expect(result).toEqual(body);
61
- });
62
- it("throws on non-ok response", async () => {
63
- mockFetch.mockResolvedValueOnce({
64
- ok: false,
65
- status: 429,
66
- text: async () => "Rate limited",
67
- });
68
- await expect(pollDeviceStatus(API, "xxx")).rejects.toThrow("Status poll failed (429)");
69
- });
70
- });
71
- describe("activateDevice", () => {
72
- it("sends POST and returns activation data", async () => {
73
- const body = {
74
- device_id: "d1234567-1234-1234-1234-123456789abc",
75
- conversation_id: "c1234567-1234-1234-1234-123456789abc",
76
- status: "ACTIVE",
77
- device_jwt: "eyJ0eXAi.test.sig",
78
- owner_identity_public_key: "aabb".repeat(16),
79
- owner_ephemeral_public_key: "ccdd".repeat(16),
80
- };
81
- mockFetch.mockResolvedValueOnce({
82
- ok: true,
83
- json: async () => body,
84
- });
85
- const result = await activateDevice(API, "d1234567-1234-1234-1234-123456789abc");
86
- expect(mockFetch).toHaveBeenCalledOnce();
87
- const [url, opts] = mockFetch.mock.calls[0];
88
- expect(url).toBe(`${API}/api/v1/devices/d1234567-1234-1234-1234-123456789abc/activate`);
89
- expect(opts.method).toBe("POST");
90
- expect(result).toEqual(body);
91
- });
92
- it("throws on non-ok response", async () => {
93
- mockFetch.mockResolvedValueOnce({
94
- ok: false,
95
- status: 409,
96
- text: async () => "Conflict",
97
- });
98
- await expect(activateDevice(API, "xxx")).rejects.toThrow("Activation failed (409)");
99
- });
100
- });
101
- //# sourceMappingURL=transport.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"transport.test.js","sourceRoot":"","sources":["../../src/__tests__/transport.test.ts"],"names":[],"mappings":"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"}