@sumicom/quicksave-shared 0.7.0 → 0.8.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.
@@ -0,0 +1,504 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import nacl from 'tweetnacl';
3
+ import { canonicalEnvelopeBody, hashCiphertext, createSignedSyncEnvelope, isSignedSyncEnvelope, } from './syncEnvelope.js';
4
+ // URL-safe base64 decoder for verifying signatures / pubkeys round-tripped
5
+ // through the envelope. The module emits URL-safe base64 without padding.
6
+ function urlSafeB64Decode(s) {
7
+ const pad = s.length % 4 === 0 ? '' : '='.repeat(4 - (s.length % 4));
8
+ const b64 = s.replace(/-/g, '+').replace(/_/g, '/') + pad;
9
+ const bin = typeof atob === 'function'
10
+ ? atob(b64)
11
+ : Buffer.from(b64, 'base64').toString('binary');
12
+ const bytes = new Uint8Array(bin.length);
13
+ for (let i = 0; i < bin.length; i++)
14
+ bytes[i] = bin.charCodeAt(i);
15
+ return bytes;
16
+ }
17
+ describe('canonicalEnvelopeBody', () => {
18
+ it('produces the exact pipe-joined format for a known input', () => {
19
+ const body = canonicalEnvelopeBody({
20
+ action: 'sync-write',
21
+ sigPubkey: 'PUBKEY',
22
+ ts: 1234567890,
23
+ nonce: 'NONCE',
24
+ keyHash: 'KEYHASH',
25
+ ciphertextHash: 'CTHASH',
26
+ });
27
+ expect(body).toBe('sync-write|PUBKEY|1234567890|NONCE|KEYHASH|CTHASH');
28
+ });
29
+ it('uses "|" as the separator in the exact positional order', () => {
30
+ const body = canonicalEnvelopeBody({
31
+ action: 'sync-tombstone',
32
+ sigPubkey: 'A',
33
+ ts: 1,
34
+ nonce: 'B',
35
+ keyHash: 'C',
36
+ ciphertextHash: 'D',
37
+ });
38
+ const parts = body.split('|');
39
+ expect(parts).toEqual(['sync-tombstone', 'A', '1', 'B', 'C', 'D']);
40
+ });
41
+ it('converts numeric ts to its decimal string form', () => {
42
+ const body = canonicalEnvelopeBody({
43
+ action: 'sync-write',
44
+ sigPubkey: 'p',
45
+ ts: 0,
46
+ nonce: 'n',
47
+ keyHash: 'k',
48
+ ciphertextHash: 'c',
49
+ });
50
+ expect(body.split('|')[2]).toBe('0');
51
+ });
52
+ it('stringifies large ts without scientific notation', () => {
53
+ const ts = 1_700_000_000_000; // realistic ms timestamp
54
+ const body = canonicalEnvelopeBody({
55
+ action: 'sync-write',
56
+ sigPubkey: 'p',
57
+ ts,
58
+ nonce: 'n',
59
+ keyHash: 'k',
60
+ ciphertextHash: 'c',
61
+ });
62
+ expect(body.split('|')[2]).toBe('1700000000000');
63
+ });
64
+ it('renders empty ciphertextHash as a trailing empty segment', () => {
65
+ const body = canonicalEnvelopeBody({
66
+ action: 'sync-lock-release',
67
+ sigPubkey: 'p',
68
+ ts: 42,
69
+ nonce: 'n',
70
+ keyHash: 'k',
71
+ ciphertextHash: '',
72
+ });
73
+ expect(body).toBe('sync-lock-release|p|42|n|k|');
74
+ expect(body.endsWith('|')).toBe(true);
75
+ expect(body.split('|').length).toBe(6);
76
+ });
77
+ it('produces different bodies when any single field changes', () => {
78
+ const base = {
79
+ action: 'sync-write',
80
+ sigPubkey: 'p',
81
+ ts: 1,
82
+ nonce: 'n',
83
+ keyHash: 'k',
84
+ ciphertextHash: 'c',
85
+ };
86
+ const baseline = canonicalEnvelopeBody(base);
87
+ expect(canonicalEnvelopeBody({ ...base, action: 'sync-tombstone' })).not.toBe(baseline);
88
+ expect(canonicalEnvelopeBody({ ...base, sigPubkey: 'p2' })).not.toBe(baseline);
89
+ expect(canonicalEnvelopeBody({ ...base, ts: 2 })).not.toBe(baseline);
90
+ expect(canonicalEnvelopeBody({ ...base, nonce: 'n2' })).not.toBe(baseline);
91
+ expect(canonicalEnvelopeBody({ ...base, keyHash: 'k2' })).not.toBe(baseline);
92
+ expect(canonicalEnvelopeBody({ ...base, ciphertextHash: 'c2' })).not.toBe(baseline);
93
+ });
94
+ });
95
+ describe('hashCiphertext', () => {
96
+ it('is deterministic for the same input', () => {
97
+ const input = 'some ciphertext payload';
98
+ expect(hashCiphertext(input)).toBe(hashCiphertext(input));
99
+ });
100
+ it('produces different hashes for different inputs', () => {
101
+ expect(hashCiphertext('a')).not.toBe(hashCiphertext('b'));
102
+ });
103
+ it('is sensitive to single-character differences', () => {
104
+ expect(hashCiphertext('hello world')).not.toBe(hashCiphertext('hello worle'));
105
+ });
106
+ it('outputs URL-safe base64 (no +, /, or = characters)', () => {
107
+ // Try several inputs to shake out any byte combination that might
108
+ // produce padding or non-URL-safe characters.
109
+ const inputs = [
110
+ '',
111
+ 'a',
112
+ 'ab',
113
+ 'abc',
114
+ 'abcd',
115
+ 'hello world',
116
+ '你好世界 🚀',
117
+ 'x'.repeat(1000),
118
+ ];
119
+ for (const input of inputs) {
120
+ const hash = hashCiphertext(input);
121
+ expect(hash).not.toMatch(/\+/);
122
+ expect(hash).not.toMatch(/\//);
123
+ expect(hash).not.toMatch(/=/);
124
+ expect(hash).toMatch(/^[A-Za-z0-9_-]*$/);
125
+ }
126
+ });
127
+ it('is non-empty for non-empty input', () => {
128
+ expect(hashCiphertext('anything').length).toBeGreaterThan(0);
129
+ });
130
+ it('produces a stable hash length for varying input sizes', () => {
131
+ // SHA-512 => 64 bytes => ceil(64*4/3) = 86 chars unpadded.
132
+ const lengths = new Set(['', 'a', 'hello', 'x'.repeat(10_000)].map((s) => hashCiphertext(s).length));
133
+ expect(lengths.size).toBe(1);
134
+ });
135
+ });
136
+ describe('createSignedSyncEnvelope', () => {
137
+ it('returns v: 1', () => {
138
+ const kp = nacl.sign.keyPair();
139
+ const env = createSignedSyncEnvelope({
140
+ action: 'sync-write',
141
+ keyHash: 'kh',
142
+ ciphertext: 'ct',
143
+ signKeyPair: kp,
144
+ });
145
+ expect(env.v).toBe(1);
146
+ });
147
+ it('copies the action from input', () => {
148
+ const kp = nacl.sign.keyPair();
149
+ const actions = [
150
+ 'sync-write',
151
+ 'sync-tombstone',
152
+ 'sync-lock-release',
153
+ ];
154
+ for (const action of actions) {
155
+ const env = createSignedSyncEnvelope({
156
+ action,
157
+ keyHash: 'kh',
158
+ ciphertext: action === 'sync-lock-release' ? undefined : 'ct',
159
+ signKeyPair: kp,
160
+ });
161
+ expect(env.action).toBe(action);
162
+ }
163
+ });
164
+ it('encodes sigPubkey as URL-safe base64 of signKeyPair.publicKey', () => {
165
+ const kp = nacl.sign.keyPair();
166
+ const env = createSignedSyncEnvelope({
167
+ action: 'sync-write',
168
+ keyHash: 'kh',
169
+ ciphertext: 'ct',
170
+ signKeyPair: kp,
171
+ });
172
+ expect(env.sigPubkey).toMatch(/^[A-Za-z0-9_-]+$/);
173
+ expect(urlSafeB64Decode(env.sigPubkey)).toEqual(kp.publicKey);
174
+ });
175
+ it('uses the injected now() for ts', () => {
176
+ const kp = nacl.sign.keyPair();
177
+ const env = createSignedSyncEnvelope({
178
+ action: 'sync-write',
179
+ keyHash: 'kh',
180
+ ciphertext: 'ct',
181
+ signKeyPair: kp,
182
+ now: () => 1234567890,
183
+ });
184
+ expect(env.ts).toBe(1234567890);
185
+ });
186
+ it('falls back to Date.now() when now is not provided', () => {
187
+ const kp = nacl.sign.keyPair();
188
+ const before = Date.now();
189
+ const env = createSignedSyncEnvelope({
190
+ action: 'sync-write',
191
+ keyHash: 'kh',
192
+ ciphertext: 'ct',
193
+ signKeyPair: kp,
194
+ });
195
+ const after = Date.now();
196
+ expect(typeof env.ts).toBe('number');
197
+ expect(env.ts).toBeGreaterThanOrEqual(before);
198
+ expect(env.ts).toBeLessThanOrEqual(after);
199
+ });
200
+ it('produces a URL-safe, non-empty nonce', () => {
201
+ const kp = nacl.sign.keyPair();
202
+ const env = createSignedSyncEnvelope({
203
+ action: 'sync-write',
204
+ keyHash: 'kh',
205
+ ciphertext: 'ct',
206
+ signKeyPair: kp,
207
+ });
208
+ expect(env.nonce).toMatch(/^[A-Za-z0-9_-]+$/);
209
+ expect(env.nonce.length).toBeGreaterThan(0);
210
+ });
211
+ it('generates a fresh nonce on each call', () => {
212
+ const kp = nacl.sign.keyPair();
213
+ const a = createSignedSyncEnvelope({
214
+ action: 'sync-write',
215
+ keyHash: 'kh',
216
+ ciphertext: 'ct',
217
+ signKeyPair: kp,
218
+ });
219
+ const b = createSignedSyncEnvelope({
220
+ action: 'sync-write',
221
+ keyHash: 'kh',
222
+ ciphertext: 'ct',
223
+ signKeyPair: kp,
224
+ });
225
+ expect(a.nonce).not.toBe(b.nonce);
226
+ });
227
+ it('omits ciphertext when not provided (lock-release)', () => {
228
+ const kp = nacl.sign.keyPair();
229
+ const env = createSignedSyncEnvelope({
230
+ action: 'sync-lock-release',
231
+ keyHash: 'kh',
232
+ signKeyPair: kp,
233
+ });
234
+ expect(env.ciphertext).toBeUndefined();
235
+ });
236
+ it('passes through the provided ciphertext verbatim', () => {
237
+ const kp = nacl.sign.keyPair();
238
+ const ciphertext = 'some-encrypted-blob-base64==';
239
+ const env = createSignedSyncEnvelope({
240
+ action: 'sync-write',
241
+ keyHash: 'kh',
242
+ ciphertext,
243
+ signKeyPair: kp,
244
+ });
245
+ expect(env.ciphertext).toBe(ciphertext);
246
+ });
247
+ it('produces a valid Ed25519 signature over the canonical body (sync-write)', () => {
248
+ const kp = nacl.sign.keyPair();
249
+ const keyHash = 'KH-abc';
250
+ const ciphertext = 'ciphertext-payload';
251
+ const env = createSignedSyncEnvelope({
252
+ action: 'sync-write',
253
+ keyHash,
254
+ ciphertext,
255
+ signKeyPair: kp,
256
+ });
257
+ const body = canonicalEnvelopeBody({
258
+ action: env.action,
259
+ sigPubkey: env.sigPubkey,
260
+ ts: env.ts,
261
+ nonce: env.nonce,
262
+ keyHash,
263
+ ciphertextHash: hashCiphertext(ciphertext),
264
+ });
265
+ const bodyBytes = new TextEncoder().encode(body);
266
+ const sigBytes = urlSafeB64Decode(env.sig);
267
+ expect(nacl.sign.detached.verify(bodyBytes, sigBytes, kp.publicKey)).toBe(true);
268
+ });
269
+ it('produces a valid Ed25519 signature for lock-release (empty ciphertextHash)', () => {
270
+ const kp = nacl.sign.keyPair();
271
+ const keyHash = 'KH-lock';
272
+ const env = createSignedSyncEnvelope({
273
+ action: 'sync-lock-release',
274
+ keyHash,
275
+ signKeyPair: kp,
276
+ });
277
+ const body = canonicalEnvelopeBody({
278
+ action: env.action,
279
+ sigPubkey: env.sigPubkey,
280
+ ts: env.ts,
281
+ nonce: env.nonce,
282
+ keyHash,
283
+ ciphertextHash: '',
284
+ });
285
+ const sigBytes = urlSafeB64Decode(env.sig);
286
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), sigBytes, kp.publicKey)).toBe(true);
287
+ });
288
+ it('signature fails verification when action is tampered', () => {
289
+ const kp = nacl.sign.keyPair();
290
+ const env = createSignedSyncEnvelope({
291
+ action: 'sync-write',
292
+ keyHash: 'kh',
293
+ ciphertext: 'ct',
294
+ signKeyPair: kp,
295
+ });
296
+ const body = canonicalEnvelopeBody({
297
+ action: 'sync-tombstone', // tampered
298
+ sigPubkey: env.sigPubkey,
299
+ ts: env.ts,
300
+ nonce: env.nonce,
301
+ keyHash: 'kh',
302
+ ciphertextHash: hashCiphertext('ct'),
303
+ });
304
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
305
+ });
306
+ it('signature fails verification when keyHash is tampered', () => {
307
+ const kp = nacl.sign.keyPair();
308
+ const env = createSignedSyncEnvelope({
309
+ action: 'sync-write',
310
+ keyHash: 'kh',
311
+ ciphertext: 'ct',
312
+ signKeyPair: kp,
313
+ });
314
+ const body = canonicalEnvelopeBody({
315
+ action: env.action,
316
+ sigPubkey: env.sigPubkey,
317
+ ts: env.ts,
318
+ nonce: env.nonce,
319
+ keyHash: 'other-keyhash',
320
+ ciphertextHash: hashCiphertext('ct'),
321
+ });
322
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
323
+ });
324
+ it('signature fails verification when ciphertext is tampered', () => {
325
+ const kp = nacl.sign.keyPair();
326
+ const env = createSignedSyncEnvelope({
327
+ action: 'sync-write',
328
+ keyHash: 'kh',
329
+ ciphertext: 'original',
330
+ signKeyPair: kp,
331
+ });
332
+ const body = canonicalEnvelopeBody({
333
+ action: env.action,
334
+ sigPubkey: env.sigPubkey,
335
+ ts: env.ts,
336
+ nonce: env.nonce,
337
+ keyHash: 'kh',
338
+ ciphertextHash: hashCiphertext('tampered'),
339
+ });
340
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
341
+ });
342
+ it('signature fails verification when ts is tampered', () => {
343
+ const kp = nacl.sign.keyPair();
344
+ const env = createSignedSyncEnvelope({
345
+ action: 'sync-write',
346
+ keyHash: 'kh',
347
+ ciphertext: 'ct',
348
+ signKeyPair: kp,
349
+ now: () => 1000,
350
+ });
351
+ const body = canonicalEnvelopeBody({
352
+ action: env.action,
353
+ sigPubkey: env.sigPubkey,
354
+ ts: 9999, // tampered
355
+ nonce: env.nonce,
356
+ keyHash: 'kh',
357
+ ciphertextHash: hashCiphertext('ct'),
358
+ });
359
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
360
+ });
361
+ it('signature fails verification when nonce is tampered', () => {
362
+ const kp = nacl.sign.keyPair();
363
+ const env = createSignedSyncEnvelope({
364
+ action: 'sync-write',
365
+ keyHash: 'kh',
366
+ ciphertext: 'ct',
367
+ signKeyPair: kp,
368
+ });
369
+ const body = canonicalEnvelopeBody({
370
+ action: env.action,
371
+ sigPubkey: env.sigPubkey,
372
+ ts: env.ts,
373
+ nonce: 'tampered-nonce',
374
+ keyHash: 'kh',
375
+ ciphertextHash: hashCiphertext('ct'),
376
+ });
377
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
378
+ });
379
+ it('signature fails verification when sigPubkey is tampered', () => {
380
+ const kp = nacl.sign.keyPair();
381
+ const env = createSignedSyncEnvelope({
382
+ action: 'sync-write',
383
+ keyHash: 'kh',
384
+ ciphertext: 'ct',
385
+ signKeyPair: kp,
386
+ });
387
+ const body = canonicalEnvelopeBody({
388
+ action: env.action,
389
+ sigPubkey: 'AAAA', // tampered
390
+ ts: env.ts,
391
+ nonce: env.nonce,
392
+ keyHash: 'kh',
393
+ ciphertextHash: hashCiphertext('ct'),
394
+ });
395
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), kp.publicKey)).toBe(false);
396
+ });
397
+ it('signature fails verification under a different signing key', () => {
398
+ const kp = nacl.sign.keyPair();
399
+ const otherKp = nacl.sign.keyPair();
400
+ const env = createSignedSyncEnvelope({
401
+ action: 'sync-write',
402
+ keyHash: 'kh',
403
+ ciphertext: 'ct',
404
+ signKeyPair: kp,
405
+ });
406
+ const body = canonicalEnvelopeBody({
407
+ action: env.action,
408
+ sigPubkey: env.sigPubkey,
409
+ ts: env.ts,
410
+ nonce: env.nonce,
411
+ keyHash: 'kh',
412
+ ciphertextHash: hashCiphertext('ct'),
413
+ });
414
+ expect(nacl.sign.detached.verify(new TextEncoder().encode(body), urlSafeB64Decode(env.sig), otherKp.publicKey)).toBe(false);
415
+ });
416
+ });
417
+ describe('isSignedSyncEnvelope', () => {
418
+ function freshEnvelope() {
419
+ const kp = nacl.sign.keyPair();
420
+ return createSignedSyncEnvelope({
421
+ action: 'sync-write',
422
+ keyHash: 'kh',
423
+ ciphertext: 'ct',
424
+ signKeyPair: kp,
425
+ });
426
+ }
427
+ it('returns true for a fresh envelope from createSignedSyncEnvelope', () => {
428
+ expect(isSignedSyncEnvelope(freshEnvelope())).toBe(true);
429
+ });
430
+ it('returns false for null', () => {
431
+ expect(isSignedSyncEnvelope(null)).toBe(false);
432
+ });
433
+ it('returns false for undefined', () => {
434
+ expect(isSignedSyncEnvelope(undefined)).toBe(false);
435
+ });
436
+ it('returns false for primitive values', () => {
437
+ expect(isSignedSyncEnvelope(42)).toBe(false);
438
+ expect(isSignedSyncEnvelope('string')).toBe(false);
439
+ expect(isSignedSyncEnvelope(true)).toBe(false);
440
+ });
441
+ it('returns false for an empty object', () => {
442
+ expect(isSignedSyncEnvelope({})).toBe(false);
443
+ });
444
+ it('returns false for an array (including an array holding an envelope)', () => {
445
+ // Arrays do not have the required named fields.
446
+ expect(isSignedSyncEnvelope([])).toBe(false);
447
+ expect(isSignedSyncEnvelope([freshEnvelope()])).toBe(false);
448
+ });
449
+ it('returns false when any required field is missing', () => {
450
+ const base = freshEnvelope();
451
+ const fields = [
452
+ 'v',
453
+ 'action',
454
+ 'sigPubkey',
455
+ 'ts',
456
+ 'nonce',
457
+ 'sig',
458
+ ];
459
+ for (const f of fields) {
460
+ const clone = { ...base };
461
+ delete clone[f];
462
+ expect(isSignedSyncEnvelope(clone)).toBe(false);
463
+ }
464
+ });
465
+ it('returns false when v is not 1', () => {
466
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), v: 2 })).toBe(false);
467
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), v: '1' })).toBe(false);
468
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), v: 0 })).toBe(false);
469
+ });
470
+ it('returns false when ts is a string', () => {
471
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), ts: '123' })).toBe(false);
472
+ });
473
+ it('returns false when action is not a string', () => {
474
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), action: 1 })).toBe(false);
475
+ });
476
+ it('returns false when sigPubkey is not a string', () => {
477
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), sigPubkey: 123 })).toBe(false);
478
+ });
479
+ it('returns false when nonce is not a string', () => {
480
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), nonce: null })).toBe(false);
481
+ });
482
+ it('returns false when sig is not a string', () => {
483
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), sig: {} })).toBe(false);
484
+ });
485
+ it('returns true when ciphertext is undefined', () => {
486
+ const env = freshEnvelope();
487
+ const withoutCiphertext = { ...env };
488
+ delete withoutCiphertext.ciphertext;
489
+ expect(isSignedSyncEnvelope(withoutCiphertext)).toBe(true);
490
+ // Explicitly set to undefined should also be accepted.
491
+ expect(isSignedSyncEnvelope({ ...env, ciphertext: undefined })).toBe(true);
492
+ });
493
+ it('returns true when ciphertext is a string', () => {
494
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), ciphertext: 'anything' })).toBe(true);
495
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), ciphertext: '' })).toBe(true);
496
+ });
497
+ it('returns false when ciphertext is a number', () => {
498
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), ciphertext: 123 })).toBe(false);
499
+ });
500
+ it('returns false when ciphertext is an object', () => {
501
+ expect(isSignedSyncEnvelope({ ...freshEnvelope(), ciphertext: {} })).toBe(false);
502
+ });
503
+ });
504
+ //# sourceMappingURL=syncEnvelope.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syncEnvelope.test.js","sourceRoot":"","sources":["../src/syncEnvelope.test.ts"],"names":[],"mappings":"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"}