@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.
- package/README.md +25 -0
- package/dist/codec.d.ts +1 -1
- package/dist/edv/descriptorStore.d.ts +13 -9
- package/dist/edv/descriptorStore.d.ts.map +1 -1
- package/dist/edv/descriptorStore.js +5 -3
- package/dist/edv/descriptorStore.js.map +1 -1
- package/dist/edv/epochKeys.d.ts.map +1 -1
- package/dist/edv/epochKeys.js +10 -46
- package/dist/edv/epochKeys.js.map +1 -1
- package/dist/edv/index.d.ts +0 -2
- package/dist/edv/index.d.ts.map +1 -1
- package/dist/edv/index.js +0 -1
- package/dist/edv/index.js.map +1 -1
- package/dist/edv/recipients.d.ts +5 -24
- package/dist/edv/recipients.d.ts.map +1 -1
- package/dist/edv/recipients.js +18 -90
- package/dist/edv/recipients.js.map +1 -1
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/internal/conditional.d.ts +3 -3
- package/dist/internal/conditional.d.ts.map +1 -1
- package/dist/internal/conditional.js +4 -4
- package/dist/internal/conditional.js.map +1 -1
- package/dist/log/index.d.ts +24 -0
- package/dist/log/index.d.ts.map +1 -0
- package/dist/log/index.js +22 -0
- package/dist/log/index.js.map +1 -0
- package/dist/log/jsonl.d.ts +49 -0
- package/dist/log/jsonl.d.ts.map +1 -0
- package/dist/log/jsonl.js +60 -0
- package/dist/log/jsonl.js.map +1 -0
- package/dist/log/logStore.d.ts +95 -0
- package/dist/log/logStore.d.ts.map +1 -0
- package/dist/log/logStore.js +123 -0
- package/dist/log/logStore.js.map +1 -0
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/port.d.ts +2 -2
- package/dist/sync/port.d.ts.map +1 -1
- package/dist/sync/port.js +2 -2
- package/dist/sync/port.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -2
- package/dist/edv/epochMac.d.ts +0 -56
- package/dist/edv/epochMac.d.ts.map +0 -1
- package/dist/edv/epochMac.js +0 -148
- package/dist/edv/epochMac.js.map +0 -1
package/dist/edv/epochMac.js
DELETED
|
@@ -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
|
package/dist/edv/epochMac.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"epochMac.js","sourceRoot":"","sources":["../../src/edv/epochMac.ts"],"names":[],"mappings":"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"}
|