@syncular/client-plugin-encryption 0.0.1-73 → 0.0.1-89

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.
@@ -12,113 +12,12 @@ import { hkdf } from '@noble/hashes/hkdf.js';
12
12
  import { sha256 } from '@noble/hashes/sha2.js';
13
13
  import { entropyToMnemonic, mnemonicToEntropy } from '@scure/bip39';
14
14
  import { wordlist } from '@scure/bip39/wordlists/english.js';
15
+ import { isRecord } from '@syncular/core';
16
+ import { base64UrlToBytes, bytesToBase64Url, randomBytes, } from './crypto-utils.js';
15
17
  const WORD_SET = new Set(wordlist);
16
18
  // ============================================================================
17
19
  // Utility Functions
18
20
  // ============================================================================
19
- // Base64 lookup tables for universal encoding/decoding (works in all runtimes)
20
- const BASE64_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
21
- const BASE64_LOOKUP = new Uint8Array(256);
22
- for (let i = 0; i < BASE64_CHARS.length; i++) {
23
- BASE64_LOOKUP[BASE64_CHARS.charCodeAt(i)] = i;
24
- }
25
- function randomBytes(length) {
26
- const cryptoObj = globalThis.crypto;
27
- if (!cryptoObj?.getRandomValues) {
28
- throw new Error('Secure random generator is not available (crypto.getRandomValues). ' +
29
- 'Ensure you are running in a secure context or polyfill crypto.');
30
- }
31
- const out = new Uint8Array(length);
32
- cryptoObj.getRandomValues(out);
33
- return out;
34
- }
35
- /**
36
- * Universal base64 encoding that works in all JavaScript runtimes.
37
- * Uses Buffer for Node/Bun (fast), lookup table for others (RN-compatible).
38
- */
39
- function bytesToBase64(bytes) {
40
- // Node/Bun fast path
41
- if (typeof Buffer !== 'undefined') {
42
- return Buffer.from(bytes).toString('base64');
43
- }
44
- // Universal fallback using lookup table (works in RN, browsers, etc.)
45
- let result = '';
46
- const len = bytes.length;
47
- const remainder = len % 3;
48
- // Process 3 bytes at a time
49
- for (let i = 0; i < len - remainder; i += 3) {
50
- const a = bytes[i];
51
- const b = bytes[i + 1];
52
- const c = bytes[i + 2];
53
- result +=
54
- BASE64_CHARS.charAt((a >> 2) & 0x3f) +
55
- BASE64_CHARS.charAt(((a << 4) | (b >> 4)) & 0x3f) +
56
- BASE64_CHARS.charAt(((b << 2) | (c >> 6)) & 0x3f) +
57
- BASE64_CHARS.charAt(c & 0x3f);
58
- }
59
- // Handle remaining bytes
60
- if (remainder === 1) {
61
- const a = bytes[len - 1];
62
- result +=
63
- BASE64_CHARS.charAt((a >> 2) & 0x3f) +
64
- BASE64_CHARS.charAt((a << 4) & 0x3f) +
65
- '==';
66
- }
67
- else if (remainder === 2) {
68
- const a = bytes[len - 2];
69
- const b = bytes[len - 1];
70
- result +=
71
- BASE64_CHARS.charAt((a >> 2) & 0x3f) +
72
- BASE64_CHARS.charAt(((a << 4) | (b >> 4)) & 0x3f) +
73
- BASE64_CHARS.charAt((b << 2) & 0x3f) +
74
- '=';
75
- }
76
- return result;
77
- }
78
- /**
79
- * Universal base64 decoding that works in all JavaScript runtimes.
80
- * Uses Buffer for Node/Bun (fast), lookup table for others (RN-compatible).
81
- */
82
- function base64ToBytes(base64) {
83
- // Node/Bun fast path
84
- if (typeof Buffer !== 'undefined') {
85
- return new Uint8Array(Buffer.from(base64, 'base64'));
86
- }
87
- // Universal fallback using lookup table (works in RN, browsers, etc.)
88
- // Remove padding and calculate output length
89
- const len = base64.length;
90
- let padding = 0;
91
- if (base64[len - 1] === '=')
92
- padding++;
93
- if (base64[len - 2] === '=')
94
- padding++;
95
- const outputLen = (len * 3) / 4 - padding;
96
- const out = new Uint8Array(outputLen);
97
- let outIdx = 0;
98
- for (let i = 0; i < len; i += 4) {
99
- const a = BASE64_LOOKUP[base64.charCodeAt(i)];
100
- const b = BASE64_LOOKUP[base64.charCodeAt(i + 1)];
101
- const c = BASE64_LOOKUP[base64.charCodeAt(i + 2)];
102
- const d = BASE64_LOOKUP[base64.charCodeAt(i + 3)];
103
- out[outIdx++] = (a << 2) | (b >> 4);
104
- if (outIdx < outputLen)
105
- out[outIdx++] = ((b << 4) | (c >> 2)) & 0xff;
106
- if (outIdx < outputLen)
107
- out[outIdx++] = ((c << 6) | d) & 0xff;
108
- }
109
- return out;
110
- }
111
- function bytesToBase64Url(bytes) {
112
- return bytesToBase64(bytes)
113
- .replace(/\+/g, '-')
114
- .replace(/\//g, '_')
115
- .replace(/=+$/g, '');
116
- }
117
- function base64UrlToBytes(base64url) {
118
- const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/');
119
- const padded = base64 + '==='.slice((base64.length + 3) % 4);
120
- return base64ToBytes(padded);
121
- }
122
21
  function concatBytes(...arrays) {
123
22
  const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
124
23
  const result = new Uint8Array(totalLength);
@@ -209,7 +108,11 @@ export function keyToBase64Url(key) {
209
108
  * Decode URL-safe base64 back to key bytes.
210
109
  */
211
110
  export function base64UrlToKey(encoded) {
212
- return base64UrlToBytes(encoded);
111
+ const key = base64UrlToBytes(encoded);
112
+ if (key.length !== 32) {
113
+ throw new Error(`Invalid key length: expected 32 bytes, got ${key.length}`);
114
+ }
115
+ return key;
213
116
  }
214
117
  /**
215
118
  * Generate an X25519 keypair for key exchange.
@@ -355,12 +258,12 @@ export function parseShareUrl(url) {
355
258
  throw new Error('Invalid share URL: missing encoded key data');
356
259
  }
357
260
  if (type === 'k') {
358
- const key = base64UrlToBytes(encoded);
261
+ const key = base64UrlToKey(encoded);
359
262
  const kid = kidEncoded ? decodeURIComponent(kidEncoded) : undefined;
360
263
  return { type: 'symmetric', key, kid };
361
264
  }
362
265
  if (type === 'pk') {
363
- const publicKey = base64UrlToBytes(encoded);
266
+ const publicKey = base64UrlToKey(encoded);
364
267
  return { type: 'publicKey', publicKey };
365
268
  }
366
269
  throw new Error(`Unknown share URL type: ${type}`);
@@ -388,21 +291,42 @@ export function publicKeyToJson(publicKey) {
388
291
  * Parse a JSON key share string.
389
292
  */
390
293
  export function parseKeyShareJson(json) {
391
- const parsed = JSON.parse(json);
392
- const parsedType = parsed.type;
294
+ let parsedValue;
295
+ try {
296
+ parsedValue = JSON.parse(json);
297
+ }
298
+ catch {
299
+ throw new Error('Invalid key share JSON');
300
+ }
301
+ if (!isRecord(parsedValue)) {
302
+ throw new Error('Invalid key share JSON');
303
+ }
304
+ const parsedType = parsedValue.type;
393
305
  if (parsedType === 'symmetric') {
306
+ const keyMaterial = parsedValue.k;
307
+ if (typeof keyMaterial !== 'string') {
308
+ throw new Error('Invalid symmetric key share JSON');
309
+ }
310
+ const kidValue = parsedValue.kid;
311
+ if (kidValue !== undefined && typeof kidValue !== 'string') {
312
+ throw new Error('Invalid symmetric key share JSON');
313
+ }
394
314
  return {
395
315
  type: 'symmetric',
396
- key: base64UrlToBytes(parsed.k),
397
- kid: parsed.kid,
316
+ key: base64UrlToKey(keyMaterial),
317
+ kid: kidValue,
398
318
  };
399
319
  }
400
320
  if (parsedType === 'publicKey') {
321
+ const publicKeyMaterial = parsedValue.pk;
322
+ if (typeof publicKeyMaterial !== 'string') {
323
+ throw new Error('Invalid public key share JSON');
324
+ }
401
325
  return {
402
326
  type: 'publicKey',
403
- publicKey: base64UrlToBytes(parsed.pk),
327
+ publicKey: base64UrlToKey(publicKeyMaterial),
404
328
  };
405
329
  }
406
- throw new Error(`Unknown key share type: ${parsedType}`);
330
+ throw new Error(`Unknown key share type: ${String(parsedType)}`);
407
331
  }
408
332
  //# sourceMappingURL=key-sharing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"key-sharing.js","sourceRoot":"","sources":["../src/key-sharing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"key-sharing.js","sourceRoot":"","sources":["../src/key-sharing.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/client-plugin-encryption",
3
- "version": "0.0.1-73",
3
+ "version": "0.0.1-89",
4
4
  "description": "End-to-end encryption plugin for the Syncular client",
5
5
  "license": "MIT",
6
6
  "author": "Benjamin Kniffler",
@@ -0,0 +1,68 @@
1
+ import { afterEach, describe, expect, test } from 'bun:test';
2
+ import { createStaticFieldEncryptionKeys } from '../index';
3
+
4
+ const VALID_ZERO_KEY_BASE64URL = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
5
+
6
+ let originalBuffer: typeof Buffer | undefined;
7
+ let bufferOverridden = false;
8
+
9
+ function disableBufferRuntime(): void {
10
+ originalBuffer = globalThis.Buffer;
11
+ Object.defineProperty(globalThis, 'Buffer', {
12
+ value: undefined,
13
+ writable: true,
14
+ configurable: true,
15
+ });
16
+ bufferOverridden = true;
17
+ }
18
+
19
+ function restoreBufferRuntime(): void {
20
+ if (!bufferOverridden) return;
21
+ Object.defineProperty(globalThis, 'Buffer', {
22
+ value: originalBuffer,
23
+ writable: true,
24
+ configurable: true,
25
+ });
26
+ bufferOverridden = false;
27
+ }
28
+
29
+ afterEach(() => {
30
+ restoreBufferRuntime();
31
+ });
32
+
33
+ describe('createStaticFieldEncryptionKeys', () => {
34
+ test('rejects malformed base64url key material in non-Buffer runtimes', async () => {
35
+ disableBufferRuntime();
36
+
37
+ const keys = createStaticFieldEncryptionKeys({
38
+ keys: { default: '@@@@' },
39
+ });
40
+
41
+ await expect(keys.getKey('default')).rejects.toThrow(
42
+ 'Invalid base64url string'
43
+ );
44
+ });
45
+
46
+ test('rejects wrong-length decoded key material in non-Buffer runtimes', async () => {
47
+ disableBufferRuntime();
48
+
49
+ const keys = createStaticFieldEncryptionKeys({
50
+ keys: { default: 'QQ' },
51
+ });
52
+
53
+ await expect(keys.getKey('default')).rejects.toThrow(
54
+ 'Encryption key for kid "default" must be 32 bytes (got 1)'
55
+ );
56
+ });
57
+
58
+ test('accepts valid 32-byte base64url keys in non-Buffer runtimes', async () => {
59
+ disableBufferRuntime();
60
+
61
+ const keys = createStaticFieldEncryptionKeys({
62
+ keys: { default: VALID_ZERO_KEY_BASE64URL },
63
+ });
64
+
65
+ const decoded = await keys.getKey('default');
66
+ expect(decoded.length).toBe(32);
67
+ });
68
+ });
@@ -63,6 +63,16 @@ describe('key-sharing', () => {
63
63
  expect(decoded).toEqual(key);
64
64
  });
65
65
 
66
+ test('base64UrlToKey rejects malformed base64url', () => {
67
+ expect(() => base64UrlToKey('@@@@')).toThrow();
68
+ });
69
+
70
+ test('base64UrlToKey rejects wrong-length payloads', () => {
71
+ expect(() => base64UrlToKey('QQ')).toThrow(
72
+ 'Invalid key length: expected 32 bytes, got 1'
73
+ );
74
+ });
75
+
66
76
  test('keyToMnemonic throws for wrong length', () => {
67
77
  expect(() => keyToMnemonic(new Uint8Array(16))).toThrow();
68
78
  });
@@ -164,6 +174,16 @@ describe('key-sharing', () => {
164
174
  expect(() => parseShareUrl('https://example.com')).toThrow();
165
175
  expect(() => parseShareUrl('sync://invalid')).toThrow();
166
176
  });
177
+
178
+ test('parseShareUrl rejects malformed base64url payloads', () => {
179
+ expect(() => parseShareUrl('sync://k/1/@@@@')).toThrow();
180
+ });
181
+
182
+ test('parseShareUrl rejects wrong-length key payloads', () => {
183
+ expect(() => parseShareUrl('sync://pk/1/QQ')).toThrow(
184
+ 'Invalid key length: expected 32 bytes, got 1'
185
+ );
186
+ });
167
187
  });
168
188
 
169
189
  describe('JSON format', () => {
@@ -189,5 +209,17 @@ describe('key-sharing', () => {
189
209
  expect(parsed.publicKey).toEqual(publicKey);
190
210
  }
191
211
  });
212
+
213
+ test('parseKeyShareJson rejects malformed payloads', () => {
214
+ expect(() =>
215
+ parseKeyShareJson(JSON.stringify({ type: 'symmetric', k: '@@@@' }))
216
+ ).toThrow();
217
+ });
218
+
219
+ test('parseKeyShareJson rejects wrong-length payloads', () => {
220
+ expect(() =>
221
+ parseKeyShareJson(JSON.stringify({ type: 'publicKey', pk: 'QQ' }))
222
+ ).toThrow('Invalid key length: expected 32 bytes, got 1');
223
+ });
192
224
  });
193
225
  });
@@ -0,0 +1,202 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import type {
3
+ SyncPullRequest,
4
+ SyncPullResponse,
5
+ SyncPushRequest,
6
+ SyncPushResponse,
7
+ } from '@syncular/core';
8
+ import {
9
+ createFieldEncryptionPlugin,
10
+ createStaticFieldEncryptionKeys,
11
+ generateSymmetricKey,
12
+ } from '../index';
13
+
14
+ const keyId = 'scope-resolution';
15
+ const keys = createStaticFieldEncryptionKeys({
16
+ keys: { [keyId]: generateSymmetricKey() },
17
+ encryptionKid: keyId,
18
+ });
19
+
20
+ const plugin = createFieldEncryptionPlugin({
21
+ rules: [
22
+ {
23
+ scope: 'workspace_tasks',
24
+ table: 'tasks',
25
+ fields: ['title'],
26
+ },
27
+ ],
28
+ keys,
29
+ });
30
+
31
+ const context = { actorId: 'actor-1', clientId: 'client-1' };
32
+
33
+ async function buildEncryptedTitle(): Promise<string> {
34
+ const request: SyncPushRequest = {
35
+ clientId: 'client-1',
36
+ clientCommitId: 'commit-1',
37
+ schemaVersion: 1,
38
+ operations: [
39
+ {
40
+ table: 'tasks',
41
+ row_id: 'task-1',
42
+ op: 'upsert',
43
+ payload: {
44
+ id: 'task-1',
45
+ title: 'Secret title',
46
+ },
47
+ base_version: null,
48
+ },
49
+ ],
50
+ };
51
+
52
+ const encrypted = await plugin.beforePush!(context, request);
53
+ const encryptedTitle = encrypted.operations[0]?.payload?.title;
54
+ if (typeof encryptedTitle !== 'string') {
55
+ throw new Error('Expected encrypted title to be a string');
56
+ }
57
+ return encryptedTitle;
58
+ }
59
+
60
+ describe('Field encryption scope/table resolution', () => {
61
+ test('encrypts beforePush when rule scope differs from operation table', async () => {
62
+ const request: SyncPushRequest = {
63
+ clientId: 'client-1',
64
+ clientCommitId: 'commit-1',
65
+ schemaVersion: 1,
66
+ operations: [
67
+ {
68
+ table: 'tasks',
69
+ row_id: 'task-1',
70
+ op: 'upsert',
71
+ payload: {
72
+ id: 'task-1',
73
+ title: 'Secret title',
74
+ completed: false,
75
+ },
76
+ base_version: null,
77
+ },
78
+ ],
79
+ };
80
+
81
+ const encrypted = await plugin.beforePush!(context, request);
82
+ const payload = encrypted.operations[0]?.payload;
83
+ const encryptedTitle = payload?.title;
84
+
85
+ expect(typeof encryptedTitle).toBe('string');
86
+ expect(encryptedTitle).not.toBe('Secret title');
87
+ expect(String(encryptedTitle).startsWith('dgsync:e2ee:1:')).toBe(true);
88
+ expect(payload?.completed).toBe(false);
89
+ });
90
+
91
+ test('decrypts afterPush conflict rows with scope/table mismatch rules', async () => {
92
+ const encryptedTitle = await buildEncryptedTitle();
93
+
94
+ const request: SyncPushRequest = {
95
+ clientId: 'client-1',
96
+ clientCommitId: 'commit-2',
97
+ schemaVersion: 1,
98
+ operations: [
99
+ {
100
+ table: 'tasks',
101
+ row_id: 'task-1',
102
+ op: 'upsert',
103
+ payload: {
104
+ id: 'task-1',
105
+ title: 'Secret title',
106
+ },
107
+ base_version: null,
108
+ },
109
+ ],
110
+ };
111
+
112
+ const response: SyncPushResponse = {
113
+ ok: true,
114
+ status: 'rejected',
115
+ results: [
116
+ {
117
+ opIndex: 0,
118
+ status: 'conflict',
119
+ message: 'conflict',
120
+ server_version: 2,
121
+ server_row: {
122
+ id: 'task-1',
123
+ title: encryptedTitle,
124
+ },
125
+ },
126
+ ],
127
+ };
128
+
129
+ const next = await plugin.afterPush!(context, { request, response });
130
+ const conflict = next.results[0];
131
+
132
+ if (!conflict || conflict.status !== 'conflict') {
133
+ throw new Error('Expected conflict result in afterPush response');
134
+ }
135
+ if (!('server_row' in conflict)) {
136
+ throw new Error('Expected conflict server_row in afterPush response');
137
+ }
138
+ if (
139
+ typeof conflict.server_row !== 'object' ||
140
+ conflict.server_row === null ||
141
+ Array.isArray(conflict.server_row)
142
+ ) {
143
+ throw new Error('Expected conflict server_row to be an object');
144
+ }
145
+ expect(conflict.server_row.title).toBe('Secret title');
146
+ });
147
+
148
+ test('decrypts incremental pull rows when change.table is the scope name', async () => {
149
+ const encryptedTitle = await buildEncryptedTitle();
150
+
151
+ const request: SyncPullRequest = {
152
+ clientId: 'client-1',
153
+ limitCommits: 50,
154
+ subscriptions: [],
155
+ };
156
+
157
+ const response: SyncPullResponse = {
158
+ ok: true,
159
+ subscriptions: [
160
+ {
161
+ id: 'workspace-sub',
162
+ status: 'active',
163
+ scopes: {},
164
+ bootstrap: false,
165
+ nextCursor: 1,
166
+ commits: [
167
+ {
168
+ commitSeq: 1,
169
+ createdAt: new Date(0).toISOString(),
170
+ actorId: 'actor-1',
171
+ changes: [
172
+ {
173
+ table: 'workspace_tasks',
174
+ row_id: 'task-1',
175
+ op: 'upsert',
176
+ row_json: {
177
+ id: 'task-1',
178
+ title: encryptedTitle,
179
+ },
180
+ row_version: 2,
181
+ scopes: {},
182
+ },
183
+ ],
184
+ },
185
+ ],
186
+ },
187
+ ],
188
+ };
189
+
190
+ const next = await plugin.afterPull!(context, { request, response });
191
+ const change =
192
+ next.subscriptions[0]?.commits[0]?.changes[0]?.row_json ?? null;
193
+ if (
194
+ typeof change !== 'object' ||
195
+ change === null ||
196
+ Array.isArray(change)
197
+ ) {
198
+ throw new Error('Expected decrypted change row_json object');
199
+ }
200
+ expect(change.title).toBe('Secret title');
201
+ });
202
+ });
@@ -0,0 +1,84 @@
1
+ import { afterEach, describe, expect, test } from 'bun:test';
2
+ import {
3
+ base64ToBytes,
4
+ base64UrlToBytes,
5
+ bytesToBase64,
6
+ bytesToBase64Url,
7
+ hexToBytes,
8
+ randomBytes,
9
+ } from './crypto-utils';
10
+
11
+ let originalBuffer: typeof Buffer | undefined;
12
+ let bufferOverridden = false;
13
+
14
+ function disableBufferRuntime(): void {
15
+ originalBuffer = globalThis.Buffer;
16
+ Object.defineProperty(globalThis, 'Buffer', {
17
+ value: undefined,
18
+ writable: true,
19
+ configurable: true,
20
+ });
21
+ bufferOverridden = true;
22
+ }
23
+
24
+ function restoreBufferRuntime(): void {
25
+ if (!bufferOverridden) return;
26
+ Object.defineProperty(globalThis, 'Buffer', {
27
+ value: originalBuffer,
28
+ writable: true,
29
+ configurable: true,
30
+ });
31
+ bufferOverridden = false;
32
+ }
33
+
34
+ afterEach(() => {
35
+ restoreBufferRuntime();
36
+ });
37
+
38
+ describe('crypto-utils', () => {
39
+ test('encodes and decodes base64 payloads', () => {
40
+ const bytes = new Uint8Array([0, 1, 2, 253, 254, 255]);
41
+ const encoded = bytesToBase64(bytes);
42
+ const decoded = base64ToBytes(encoded);
43
+ expect(decoded).toEqual(bytes);
44
+ });
45
+
46
+ test('encodes and decodes base64url payloads', () => {
47
+ const bytes = new Uint8Array([0, 1, 2, 253, 254, 255]);
48
+ const encoded = bytesToBase64Url(bytes);
49
+ const decoded = base64UrlToBytes(encoded);
50
+ expect(decoded).toEqual(bytes);
51
+ });
52
+
53
+ test('rejects malformed base64 inputs', () => {
54
+ expect(() => base64ToBytes('@@@@')).toThrow('Invalid base64 string');
55
+ expect(() => base64UrlToBytes('@@@@')).toThrow('Invalid base64url string');
56
+ });
57
+
58
+ test('works when Buffer is unavailable', () => {
59
+ disableBufferRuntime();
60
+
61
+ const bytes = new Uint8Array([0, 1, 2, 253, 254, 255]);
62
+ const encoded = bytesToBase64(bytes);
63
+ const decoded = base64ToBytes(encoded);
64
+ expect(decoded).toEqual(bytes);
65
+
66
+ const encodedUrl = bytesToBase64Url(bytes);
67
+ const decodedUrl = base64UrlToBytes(encodedUrl);
68
+ expect(decodedUrl).toEqual(bytes);
69
+ });
70
+
71
+ test('parses hex strings', () => {
72
+ expect(hexToBytes('00a1ff')).toEqual(new Uint8Array([0, 161, 255]));
73
+ expect(() => hexToBytes('0')).toThrow(
74
+ 'Invalid hex string (length must be even)'
75
+ );
76
+ expect(() => hexToBytes('zz')).toThrow('Invalid hex string');
77
+ });
78
+
79
+ test('creates random byte arrays', () => {
80
+ const bytes = randomBytes(32);
81
+ expect(bytes).toBeInstanceOf(Uint8Array);
82
+ expect(bytes.length).toBe(32);
83
+ });
84
+ });