@interop/was-client 0.30.0 → 0.32.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.
Files changed (56) hide show
  1. package/README.md +25 -0
  2. package/dist/codec.d.ts +1 -1
  3. package/dist/edv/descriptorStore.d.ts +13 -9
  4. package/dist/edv/descriptorStore.d.ts.map +1 -1
  5. package/dist/edv/descriptorStore.js +5 -3
  6. package/dist/edv/descriptorStore.js.map +1 -1
  7. package/dist/edv/epochKeys.d.ts.map +1 -1
  8. package/dist/edv/epochKeys.js +10 -46
  9. package/dist/edv/epochKeys.js.map +1 -1
  10. package/dist/edv/index.d.ts +0 -2
  11. package/dist/edv/index.d.ts.map +1 -1
  12. package/dist/edv/index.js +0 -1
  13. package/dist/edv/index.js.map +1 -1
  14. package/dist/edv/recipients.d.ts +5 -24
  15. package/dist/edv/recipients.d.ts.map +1 -1
  16. package/dist/edv/recipients.js +18 -90
  17. package/dist/edv/recipients.js.map +1 -1
  18. package/dist/errors.d.ts +10 -0
  19. package/dist/errors.d.ts.map +1 -1
  20. package/dist/errors.js +10 -0
  21. package/dist/errors.js.map +1 -1
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +1 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/internal/conditional.d.ts +3 -3
  27. package/dist/internal/conditional.d.ts.map +1 -1
  28. package/dist/internal/conditional.js +4 -4
  29. package/dist/internal/conditional.js.map +1 -1
  30. package/dist/log/index.d.ts +24 -0
  31. package/dist/log/index.d.ts.map +1 -0
  32. package/dist/log/index.js +22 -0
  33. package/dist/log/index.js.map +1 -0
  34. package/dist/log/jsonl.d.ts +49 -0
  35. package/dist/log/jsonl.d.ts.map +1 -0
  36. package/dist/log/jsonl.js +60 -0
  37. package/dist/log/jsonl.js.map +1 -0
  38. package/dist/log/logStore.d.ts +95 -0
  39. package/dist/log/logStore.d.ts.map +1 -0
  40. package/dist/log/logStore.js +123 -0
  41. package/dist/log/logStore.js.map +1 -0
  42. package/dist/sync/index.d.ts +1 -1
  43. package/dist/sync/index.d.ts.map +1 -1
  44. package/dist/sync/index.js +1 -1
  45. package/dist/sync/index.js.map +1 -1
  46. package/dist/sync/port.d.ts +2 -2
  47. package/dist/sync/port.d.ts.map +1 -1
  48. package/dist/sync/port.js +2 -2
  49. package/dist/sync/port.js.map +1 -1
  50. package/dist/types.d.ts +1 -1
  51. package/dist/types.d.ts.map +1 -1
  52. package/package.json +8 -2
  53. package/dist/edv/epochMac.d.ts +0 -56
  54. package/dist/edv/epochMac.d.ts.map +0 -1
  55. package/dist/edv/epochMac.js +0 -148
  56. package/dist/edv/epochMac.js.map +0 -1
@@ -1,148 +0,0 @@
1
- /*!
2
- * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
- */
4
- /**
5
- * Authenticated epoch configuration for multi-recipient encrypted Collections:
6
- * a MAC over a Collection `encryption` descriptor's epoch configuration, keyed
7
- * from the current epoch's secret (which the server never holds). It lets a
8
- * reader detect a server-side rollback of `currentEpoch` or a fabricated epoch
9
- * list -- a malicious server cannot forge a valid MAC without the epoch secret.
10
- *
11
- * The MAC covers only `scheme`, `version`, `currentEpoch`, and the ordered list
12
- * of epoch ids -- deliberately NOT the recipient entries, so adding a recipient
13
- * (which cannot be forged without the epoch secret anyway) does not invalidate
14
- * the MAC. Covering `version` makes stripping the descriptor's scheme version
15
- * MAC-detectable.
16
- *
17
- * Documented limitation (mirrors Cryptomator's versionMac): a server can still
18
- * replay an ENTIRE prior consistent configuration (an old epoch list with its
19
- * matching old MAC). Detecting that needs client-side monotonic state, which is
20
- * out of scope here.
21
- */
22
- import { base64urlnopad } from '@scure/base';
23
- import { ENCODER } from '../internal/content.js';
24
- /**
25
- * The HKDF `info` string binding the derived key to this MAC construction.
26
- */
27
- const MAC_KEY_INFO = ENCODER.encode('was-epoch-config-mac/v1');
28
- /**
29
- * The domain-separation prefix prepended to the JSON payload before it is MACed.
30
- */
31
- const MAC_PAYLOAD_PREFIX = 'was-epoch-config/v1.';
32
- /**
33
- * The domain-separation prefix of the detached `epochsSig` signature payload --
34
- * distinct from the MAC prefix so a signature can never be replayed as a MAC
35
- * input or vice versa.
36
- */
37
- const SIG_PAYLOAD_PREFIX = 'was-epoch-config-sig/v1.';
38
- /**
39
- * Derives the HMAC-SHA256 key from a 32-byte epoch secret:
40
- * HKDF-SHA256(ikm = the epoch secret, salt = empty, info =
41
- * "was-epoch-config-mac/v1", length 32 bytes). Uses WebCrypto (`crypto.subtle`)
42
- * so it works unchanged in Node 24 and browsers.
43
- *
44
- * @param epochSecret {Uint8Array} the 32-byte current epoch secret
45
- * @returns {Promise<CryptoKey>} the derived HMAC key (sign + verify)
46
- */
47
- async function deriveMacKey(epochSecret) {
48
- const ikm = await crypto.subtle.importKey('raw', epochSecret, 'HKDF', false, ['deriveKey']);
49
- return crypto.subtle.deriveKey({
50
- name: 'HKDF',
51
- hash: 'SHA-256',
52
- salt: new Uint8Array(0),
53
- info: MAC_KEY_INFO
54
- }, ikm, { name: 'HMAC', hash: 'SHA-256', length: 256 }, false, ['sign', 'verify']);
55
- }
56
- /**
57
- * The canonical JSON text of a descriptor's epoch configuration -- the part
58
- * both the MAC and the detached signature cover: `{ scheme, version,
59
- * currentEpoch, epochs }`, with `version` normalized to `null` when absent and
60
- * `epochs` the ordered list of epoch id strings. The object member order is
61
- * fixed so both sides serialize identically.
62
- *
63
- * @param descriptor {CollectionEncryption} the descriptor whose epoch
64
- * configuration is being authenticated
65
- * @returns {string}
66
- */
67
- function epochsConfigJson(descriptor) {
68
- return JSON.stringify({
69
- scheme: descriptor.scheme,
70
- version: descriptor.version ?? null,
71
- currentEpoch: descriptor.currentEpoch,
72
- epochs: (descriptor.epochs ?? []).map(epoch => epoch.id)
73
- });
74
- }
75
- /**
76
- * Builds the MACed payload bytes for a descriptor's epoch configuration:
77
- * `UTF8("was-epoch-config/v1." + epochsConfigJson(descriptor))`.
78
- *
79
- * @param descriptor {CollectionEncryption} the descriptor whose epoch configuration is
80
- * being authenticated
81
- * @returns {ArrayBuffer}
82
- */
83
- function macPayload(descriptor) {
84
- const bytes = ENCODER.encode(MAC_PAYLOAD_PREFIX + epochsConfigJson(descriptor));
85
- return bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
86
- }
87
- /**
88
- * Builds the payload bytes an `epochsSig` signs: `UTF8(
89
- * "was-epoch-config-sig/v1." + epochsConfigJson(descriptor))` -- the same
90
- * epoch configuration the MAC covers, under its own domain-separation prefix.
91
- * Exported so a signing caller and a verifying reader construct
92
- * byte-identical input from the descriptor alone.
93
- *
94
- * @param descriptor {CollectionEncryption} the descriptor whose epoch
95
- * configuration is being signed or verified
96
- * @returns {Uint8Array}
97
- */
98
- export function epochsSigPayload(descriptor) {
99
- return ENCODER.encode(SIG_PAYLOAD_PREFIX + epochsConfigJson(descriptor));
100
- }
101
- /**
102
- * Computes the `epochsMac` field for a descriptor under the current epoch's
103
- * secret. Compute this over the exact descriptor state being written (member
104
- * fields already stamped), since a compare-and-swap retry re-reads the
105
- * descriptor.
106
- *
107
- * @param options {object}
108
- * @param options.descriptor {CollectionEncryption} the descriptor being written
109
- * @param options.epochSecret {Uint8Array} the 32-byte current epoch secret
110
- * @returns {Promise<CollectionEncryptionEpochsMac>}
111
- */
112
- export async function computeEpochsMac({ descriptor, epochSecret }) {
113
- const key = await deriveMacKey(epochSecret);
114
- const signature = await crypto.subtle.sign('HMAC', key, macPayload(descriptor));
115
- return {
116
- v: 1,
117
- alg: 'HS256',
118
- mac: base64urlnopad.encode(new Uint8Array(signature))
119
- };
120
- }
121
- /**
122
- * Verifies a descriptor's `epochsMac` against a recomputation from the current
123
- * epoch's secret. Returns `false` on any mismatch (or a malformed `mac`); the
124
- * caller decides the error semantics. The MAC construction's own version/alg
125
- * (`v` / `alg`) is validated by the caller before this is called.
126
- *
127
- * @param options {object}
128
- * @param options.descriptor {CollectionEncryption} the descriptor to verify (its
129
- * `epochsMac.mac` is the tag under test)
130
- * @param options.epochSecret {Uint8Array} the 32-byte current epoch secret
131
- * @returns {Promise<boolean>}
132
- */
133
- export async function verifyEpochsMac({ descriptor, epochSecret }) {
134
- const epochsMac = descriptor.epochsMac;
135
- if (!epochsMac) {
136
- return false;
137
- }
138
- let mac;
139
- try {
140
- mac = base64urlnopad.decode(epochsMac.mac);
141
- }
142
- catch {
143
- return false;
144
- }
145
- const key = await deriveMacKey(epochSecret);
146
- return crypto.subtle.verify('HMAC', key, mac, macPayload(descriptor));
147
- }
148
- //# sourceMappingURL=epochMac.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"epochMac.js","sourceRoot":"","sources":["../../src/edv/epochMac.ts"],"names":[],"mappings":"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"}