@keyneom/sync-kit 0.2.0-rc.1 → 0.2.0-rc.11

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 (40) hide show
  1. package/README.md +8 -3
  2. package/dist/sharing/appdata-identity-store.d.ts +36 -0
  3. package/dist/sharing/appdata-identity-store.d.ts.map +1 -0
  4. package/dist/sharing/appdata-identity-store.js +49 -0
  5. package/dist/sharing/appdata-identity-store.js.map +1 -0
  6. package/dist/sharing/control.d.ts +136 -0
  7. package/dist/sharing/control.d.ts.map +1 -0
  8. package/dist/sharing/control.js +486 -0
  9. package/dist/sharing/control.js.map +1 -0
  10. package/dist/sharing/controller.d.ts +79 -3
  11. package/dist/sharing/controller.d.ts.map +1 -1
  12. package/dist/sharing/controller.js +340 -117
  13. package/dist/sharing/controller.js.map +1 -1
  14. package/dist/sharing/index.d.ts +2 -0
  15. package/dist/sharing/index.d.ts.map +1 -1
  16. package/dist/sharing/index.js +2 -0
  17. package/dist/sharing/index.js.map +1 -1
  18. package/dist/sharing/link-exchange.d.ts +51 -0
  19. package/dist/sharing/link-exchange.d.ts.map +1 -0
  20. package/dist/sharing/link-exchange.js +131 -0
  21. package/dist/sharing/link-exchange.js.map +1 -0
  22. package/dist/sharing/migrating-identity-store.d.ts +29 -0
  23. package/dist/sharing/migrating-identity-store.d.ts.map +1 -0
  24. package/dist/sharing/migrating-identity-store.js +37 -0
  25. package/dist/sharing/migrating-identity-store.js.map +1 -0
  26. package/dist/sharing/transport.d.ts +2 -0
  27. package/dist/sharing/transport.d.ts.map +1 -1
  28. package/dist/stores/google-drive/index.d.ts +20 -0
  29. package/dist/stores/google-drive/index.d.ts.map +1 -1
  30. package/dist/stores/google-drive/index.js +64 -0
  31. package/dist/stores/google-drive/index.js.map +1 -1
  32. package/dist/stores/google-drive/picker.d.ts +20 -0
  33. package/dist/stores/google-drive/picker.d.ts.map +1 -1
  34. package/dist/stores/google-drive/picker.js +64 -0
  35. package/dist/stores/google-drive/picker.js.map +1 -1
  36. package/dist/stores/google-drive/sharing.d.ts +2 -0
  37. package/dist/stores/google-drive/sharing.d.ts.map +1 -1
  38. package/dist/stores/google-drive/sharing.js +83 -6
  39. package/dist/stores/google-drive/sharing.js.map +1 -1
  40. package/package.json +20 -3
@@ -0,0 +1,486 @@
1
+ import { SyncKitError } from "../core/errors.js";
2
+ import { base64UrlToBytes, bytesToBase64Url } from "../crypto/base64url.js";
3
+ import { canonicalAad, canonicalJson, compareUtf16CodeUnits } from "../crypto/canonical.js";
4
+ import { copyBuffer } from "../crypto/runtime.js";
5
+ import { createSharingPublicKeyV1, } from "./web-crypto.js";
6
+ /**
7
+ * An encrypted, merge-safe coordination dataset. It is intentionally separate
8
+ * from application data so every profile participant may acknowledge a
9
+ * migration without being allowed to modify the data being migrated.
10
+ */
11
+ export const SHARING_CONTROL_KIND = "sync-kit-sharing-control";
12
+ export const SHARING_CONTROL_EVENT_KIND = "sync-kit-sharing-control-event";
13
+ /**
14
+ * Creates a codec whose merge is an event-id union. Signature and authority
15
+ * validation is intentionally asynchronous and is performed by
16
+ * `verifySharingControlStateV1` before callers act on the state.
17
+ */
18
+ export function createSharingControlCodec() {
19
+ return {
20
+ serialize: (value) => parseSharingControlStateV1(value),
21
+ parse: parseSharingControlStateV1,
22
+ merge: mergeSharingControlStates,
23
+ fingerprint: canonicalJson,
24
+ };
25
+ }
26
+ export function parseSharingControlStateV1(value) {
27
+ const state = object(value, "control state");
28
+ exact(state.schemaVersion, 1, "control state schemaVersion");
29
+ exact(state.kind, SHARING_CONTROL_KIND, "control state kind");
30
+ nonEmpty(state.profileId, "control state profileId");
31
+ if (!Array.isArray(state.events)) {
32
+ throw new SyncKitError("compatibility", "Control state events must be an array.");
33
+ }
34
+ const events = state.events.map(parseSharingControlEventV1);
35
+ const eventIds = new Set();
36
+ for (const event of events) {
37
+ if (event.profileId !== state.profileId) {
38
+ throw new SyncKitError("compatibility", "A control event belongs to another profile.");
39
+ }
40
+ if (eventIds.has(event.eventId)) {
41
+ throw new SyncKitError("compatibility", `Duplicate control event ${event.eventId}.`);
42
+ }
43
+ eventIds.add(event.eventId);
44
+ }
45
+ return { schemaVersion: 1, kind: SHARING_CONTROL_KIND, profileId: state.profileId, events: sortEvents(events) };
46
+ }
47
+ export function parseSharingControlEventV1(value) {
48
+ const event = object(value, "control event");
49
+ exact(event.schemaVersion, 1, "control event schemaVersion");
50
+ exact(event.kind, SHARING_CONTROL_EVENT_KIND, "control event kind");
51
+ for (const key of ["eventId", "profileId", "actorKeyId", "createdAt", "signature"]) {
52
+ nonEmpty(event[key], `control event ${key}`);
53
+ }
54
+ if (!Number.isSafeInteger(event.sequence) || event.sequence < 0) {
55
+ throw new SyncKitError("compatibility", "control event sequence must be a non-negative integer.");
56
+ }
57
+ validTime(event.createdAt, "control event createdAt");
58
+ const base = {
59
+ schemaVersion: 1,
60
+ kind: SHARING_CONTROL_EVENT_KIND,
61
+ eventId: event.eventId,
62
+ profileId: event.profileId,
63
+ actorKeyId: event.actorKeyId,
64
+ sequence: event.sequence,
65
+ createdAt: event.createdAt,
66
+ signature: event.signature,
67
+ };
68
+ switch (event.type) {
69
+ case "member-upsert":
70
+ return { ...base, type: "member-upsert", member: parseMember(event.member) };
71
+ case "migration-announced":
72
+ return { ...base, type: "migration-announced", migration: parseMigration(event.migration) };
73
+ case "migration-acknowledged":
74
+ nonEmpty(event.migrationId, "control acknowledgement migrationId");
75
+ return {
76
+ ...base,
77
+ type: "migration-acknowledged",
78
+ migrationId: event.migrationId,
79
+ openedFileIds: stringArray(event.openedFileIds, "control acknowledgement openedFileIds"),
80
+ };
81
+ case "migration-closed":
82
+ nonEmpty(event.migrationId, "control close migrationId");
83
+ if (event.forced !== undefined && typeof event.forced !== "boolean") {
84
+ throw new SyncKitError("compatibility", "control close forced must be a boolean.");
85
+ }
86
+ return {
87
+ ...base,
88
+ type: "migration-closed",
89
+ migrationId: event.migrationId,
90
+ ...(event.forced === undefined ? {} : { forced: event.forced }),
91
+ };
92
+ default:
93
+ throw new SyncKitError("compatibility", "Unsupported control event type.");
94
+ }
95
+ }
96
+ export function mergeSharingControlStates(local, remote) {
97
+ const left = parseSharingControlStateV1(local);
98
+ const right = parseSharingControlStateV1(remote);
99
+ if (left.profileId !== right.profileId) {
100
+ throw new SyncKitError("compatibility", "Cannot merge control states for different profiles.");
101
+ }
102
+ const events = new Map();
103
+ for (const event of [...left.events, ...right.events]) {
104
+ const existing = events.get(event.eventId);
105
+ if (existing && canonicalJson(existing) !== canonicalJson(event)) {
106
+ throw new SyncKitError("conflict", `Control event ${event.eventId} has conflicting contents.`);
107
+ }
108
+ events.set(event.eventId, event);
109
+ }
110
+ return { schemaVersion: 1, kind: SHARING_CONTROL_KIND, profileId: left.profileId, events: sortEvents([...events.values()]) };
111
+ }
112
+ export async function verifySharingControlStateV1(input, cryptoImplementation = globalThis.crypto, options = {}) {
113
+ const state = parseSharingControlStateV1(input);
114
+ const members = new Map();
115
+ const migrations = new Map();
116
+ const acknowledgements = new Map();
117
+ const closedMigrations = new Set();
118
+ const events = sortEvents(state.events);
119
+ const genesis = events[0];
120
+ if (genesis?.sequence !== 0 || genesis.type !== "member-upsert" || genesis.actorKeyId !== genesis.member.publicKey.keyId) {
121
+ throw new SyncKitError("authorization", "The first control event must be a self-signed owner member record.");
122
+ }
123
+ const ownerKeyId = genesis.actorKeyId;
124
+ if (options.trustedOwnerKeyId && ownerKeyId !== options.trustedOwnerKeyId) {
125
+ throw new SyncKitError("authorization", "The control ledger owner does not match the pinned dataset owner.");
126
+ }
127
+ for (const event of events) {
128
+ const actor = members.get(event.actorKeyId) ??
129
+ (event === genesis ? genesis.member : undefined);
130
+ if (!actor) {
131
+ throw new SyncKitError("authorization", `Control event ${event.eventId} has an unknown actor.`);
132
+ }
133
+ await verifyEvent(event, actor.publicKey, cryptoImplementation);
134
+ if (event.type === "member-upsert") {
135
+ if (event.actorKeyId !== ownerKeyId) {
136
+ throw new SyncKitError("authorization", "Only the control owner may publish membership records.");
137
+ }
138
+ members.set(event.member.publicKey.keyId, event.member);
139
+ continue;
140
+ }
141
+ if (event.type === "migration-announced") {
142
+ if (event.actorKeyId !== ownerKeyId) {
143
+ throw new SyncKitError("authorization", "Only the control owner may announce a migration.");
144
+ }
145
+ if (migrations.has(event.migration.migrationId)) {
146
+ throw new SyncKitError("conflict", `Migration ${event.migration.migrationId} was announced twice.`);
147
+ }
148
+ for (const requirement of event.migration.requiredAcks) {
149
+ if (!members.has(requirement.keyId)) {
150
+ throw new SyncKitError("authorization", `Migration ${event.migration.migrationId} requires an unknown member.`);
151
+ }
152
+ }
153
+ migrations.set(event.migration.migrationId, event.migration);
154
+ continue;
155
+ }
156
+ if (event.type === "migration-acknowledged") {
157
+ const migration = migrations.get(event.migrationId);
158
+ if (!migration) {
159
+ throw new SyncKitError("state", `Acknowledgement references unknown migration ${event.migrationId}.`);
160
+ }
161
+ const requirement = migration.requiredAcks.find((candidate) => candidate.keyId === event.actorKeyId);
162
+ if (!requirement) {
163
+ throw new SyncKitError("authorization", "This member is not required to acknowledge the migration.");
164
+ }
165
+ if (closedMigrations.has(event.migrationId)) {
166
+ throw new SyncKitError("state", "A closed migration cannot receive another acknowledgement.");
167
+ }
168
+ if (missingSharingControlPickerFiles(requirement, event.openedFileIds).length > 0) {
169
+ throw new SyncKitError("state", "Migration acknowledgement omits one or more required Picker files.");
170
+ }
171
+ if (unexpectedPickerFiles(requirement, event.openedFileIds).length > 0) {
172
+ throw new SyncKitError("state", "Migration acknowledgement includes an unexpected Picker file.");
173
+ }
174
+ const acknowledgementsForMigration = acknowledgements.get(event.migrationId) ??
175
+ new Map();
176
+ acknowledgementsForMigration.set(event.actorKeyId, event);
177
+ acknowledgements.set(event.migrationId, acknowledgementsForMigration);
178
+ continue;
179
+ }
180
+ const migration = migrations.get(event.migrationId);
181
+ if (!migration) {
182
+ throw new SyncKitError("state", `Close references unknown migration ${event.migrationId}.`);
183
+ }
184
+ if (event.actorKeyId !== ownerKeyId) {
185
+ throw new SyncKitError("authorization", "Only the control owner may close a migration.");
186
+ }
187
+ const pending = migration.requiredAcks.filter((requirement) => !acknowledgements.get(event.migrationId)?.has(requirement.keyId));
188
+ if (pending.length > 0 && !event.forced) {
189
+ throw new SyncKitError("state", "A migration cannot close before every required acknowledgement arrives.");
190
+ }
191
+ closedMigrations.add(event.migrationId);
192
+ }
193
+ return { state, ownerKeyId, members, migrations, acknowledgements, closedMigrations };
194
+ }
195
+ export function missingSharingControlPickerFiles(requirement, openedFileIds) {
196
+ const opened = new Set(openedFileIds);
197
+ return requirement.targetFileIds.filter((fileId) => !opened.has(fileId));
198
+ }
199
+ export class SharingControlDataset {
200
+ options;
201
+ constructor(options) {
202
+ this.options = options;
203
+ nonEmpty(options.datasetId, "control datasetId");
204
+ nonEmpty(options.profileId, "control profileId");
205
+ }
206
+ async create(owner = {}) {
207
+ const identity = await this.options.identity();
208
+ const event = await this.sign({
209
+ type: "member-upsert",
210
+ member: { publicKey: identity.publicKey, ...owner },
211
+ }, identity, 0);
212
+ return this.options.controller.createDataset(this.options.datasetId, {
213
+ schemaVersion: 1,
214
+ kind: SHARING_CONTROL_KIND,
215
+ profileId: this.options.profileId,
216
+ events: [event],
217
+ });
218
+ }
219
+ async read() {
220
+ const trust = await this.options.controller.getDatasetTrust(this.options.datasetId);
221
+ const loaded = await this.options.controller.loadDataset(this.options.datasetId);
222
+ return verifySharingControlStateV1(loaded.value, this.crypto(), trust);
223
+ }
224
+ addMember(member) {
225
+ return this.publish(() => ({ type: "member-upsert", member }), identityMustBeOwner);
226
+ }
227
+ /**
228
+ * Mirrors cryptographically accepted control-file participants into the
229
+ * signed directory. Call this after accepting a join response; `metadata`
230
+ * supplies the application-visible email/Drive details that envelopes do
231
+ * not contain.
232
+ */
233
+ async synchronizeMembers(metadata = {}) {
234
+ const verified = await this.read();
235
+ const identity = await this.options.identity();
236
+ identityMustBeOwner(verified, identity);
237
+ const participants = await this.options.controller.getDatasetParticipants(this.options.datasetId);
238
+ let last = null;
239
+ for (const participant of participants.participants) {
240
+ const current = verified.members.get(participant.keyId);
241
+ const details = metadata[participant.keyId] ?? {};
242
+ const member = {
243
+ publicKey: {
244
+ keyId: participant.keyId,
245
+ encryptionAlgorithm: participant.encryptionAlgorithm,
246
+ encryptionPublicKey: participant.encryptionPublicKey,
247
+ signatureAlgorithm: participant.signatureAlgorithm,
248
+ signingPublicKey: participant.signingPublicKey,
249
+ },
250
+ ...details,
251
+ };
252
+ if (!current || canonicalJson(current) !== canonicalJson(member)) {
253
+ last = await this.addMember(member);
254
+ }
255
+ }
256
+ return last;
257
+ }
258
+ announceMigration(migration) {
259
+ return this.publish(() => ({ type: "migration-announced", migration }), identityMustBeOwner);
260
+ }
261
+ acknowledgeMigration(input) {
262
+ return this.publish(() => ({
263
+ type: "migration-acknowledged",
264
+ migrationId: input.migrationId,
265
+ openedFileIds: [...new Set(input.openedFileIds)].sort(compareUtf16CodeUnits),
266
+ }), (verified, identity) => {
267
+ const migration = verified.migrations.get(input.migrationId);
268
+ const requirement = migration?.requiredAcks.find((candidate) => candidate.keyId === identity.publicKey.keyId);
269
+ if (!requirement) {
270
+ throw new SyncKitError("authorization", "This identity is not required to acknowledge this migration.");
271
+ }
272
+ const missing = missingSharingControlPickerFiles(requirement, input.openedFileIds);
273
+ if (missing.length > 0) {
274
+ throw new SyncKitError("state", `Select every required migration file before acknowledging: ${missing.join(", ")}.`);
275
+ }
276
+ const unexpected = unexpectedPickerFiles(requirement, input.openedFileIds);
277
+ if (unexpected.length > 0) {
278
+ throw new SyncKitError("state", `Do not acknowledge unexpected Picker files: ${unexpected.join(", ")}.`);
279
+ }
280
+ });
281
+ }
282
+ closeMigration(input) {
283
+ return this.publish(() => ({ type: "migration-closed", migrationId: input.migrationId, ...(input.force ? { forced: true } : {}) }), (verified, identity) => {
284
+ identityMustBeOwner(verified, identity);
285
+ const migration = verified.migrations.get(input.migrationId);
286
+ if (!migration)
287
+ throw new SyncKitError("not-found", `Migration ${input.migrationId} was not found.`);
288
+ if (!input.force) {
289
+ const pending = migration.requiredAcks.filter((requirement) => !verified.acknowledgements.get(input.migrationId)?.has(requirement.keyId));
290
+ if (pending.length > 0) {
291
+ throw new SyncKitError("state", `Migration still awaits: ${pending.map((entry) => entry.keyId).join(", ")}.`);
292
+ }
293
+ }
294
+ });
295
+ }
296
+ async migrationStatus(migrationId) {
297
+ const verified = await this.read();
298
+ const migration = verified.migrations.get(migrationId);
299
+ if (!migration)
300
+ throw new SyncKitError("not-found", `Migration ${migrationId} was not found.`);
301
+ const acknowledgements = verified.acknowledgements.get(migrationId) ??
302
+ new Map();
303
+ const pendingKeyIds = migration.requiredAcks
304
+ .filter((requirement) => !acknowledgements.has(requirement.keyId))
305
+ .map((requirement) => requirement.keyId);
306
+ return {
307
+ migration,
308
+ acknowledgedKeyIds: [...acknowledgements.keys()].sort(compareUtf16CodeUnits),
309
+ pendingKeyIds,
310
+ closed: verified.closedMigrations.has(migrationId),
311
+ };
312
+ }
313
+ async publish(build, authorize) {
314
+ const attempts = this.options.maxPublishAttempts ?? 3;
315
+ let lastError;
316
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
317
+ try {
318
+ const trust = await this.options.controller.getDatasetTrust(this.options.datasetId);
319
+ const loaded = await this.options.controller.loadDataset(this.options.datasetId);
320
+ const verified = await verifySharingControlStateV1(loaded.value, this.crypto(), trust);
321
+ const identity = await this.options.identity();
322
+ await authorize(verified, identity);
323
+ const sequence = Math.max(...loaded.value.events.map((event) => event.sequence), -1) + 1;
324
+ const event = await this.sign(build(identity), identity, sequence);
325
+ return await this.options.controller.syncDataset(this.options.datasetId, {
326
+ ...loaded.value,
327
+ events: [...loaded.value.events, event],
328
+ });
329
+ }
330
+ catch (error) {
331
+ lastError = error;
332
+ if (!(error instanceof SyncKitError) || error.code !== "conflict" || attempt + 1 >= attempts)
333
+ throw error;
334
+ }
335
+ }
336
+ throw lastError;
337
+ }
338
+ async sign(event, identity, sequence) {
339
+ const unsigned = {
340
+ schemaVersion: 1,
341
+ kind: SHARING_CONTROL_EVENT_KIND,
342
+ eventId: this.randomUUID(),
343
+ profileId: this.options.profileId,
344
+ actorKeyId: identity.publicKey.keyId,
345
+ sequence,
346
+ createdAt: this.now().toISOString(),
347
+ ...event,
348
+ };
349
+ const signature = new Uint8Array(await this.crypto().subtle.sign({ name: "ECDSA", hash: "SHA-256" }, identity.signingPrivateKey, copyBuffer(canonicalAad(unsigned))));
350
+ return parseSharingControlEventV1({ ...unsigned, signature: bytesToBase64Url(signature) });
351
+ }
352
+ now() {
353
+ return (this.options.now ?? (() => new Date()))();
354
+ }
355
+ randomUUID() {
356
+ const value = this.options.randomUUID ?? globalThis.crypto?.randomUUID?.bind(globalThis.crypto);
357
+ if (!value)
358
+ throw new SyncKitError("configuration", "Secure UUID generation is unavailable.");
359
+ return value();
360
+ }
361
+ crypto() {
362
+ const value = this.options.crypto ?? globalThis.crypto;
363
+ if (!value?.subtle)
364
+ throw new SyncKitError("configuration", "WebCrypto is required for sharing control.");
365
+ return value;
366
+ }
367
+ }
368
+ export function createSharingControlDataset(options) {
369
+ return new SharingControlDataset(options);
370
+ }
371
+ function identityMustBeOwner(verified, identity) {
372
+ if (verified.ownerKeyId !== identity.publicKey.keyId) {
373
+ throw new SyncKitError("authorization", "Only the control owner may perform this operation.");
374
+ }
375
+ }
376
+ async function verifyEvent(event, publicKey, cryptoImplementation) {
377
+ const expected = await createSharingPublicKeyV1(publicKey.encryptionPublicKey, publicKey.signingPublicKey, cryptoImplementation);
378
+ if (expected.keyId !== publicKey.keyId) {
379
+ throw new SyncKitError("key", `Control member ${publicKey.keyId} has an invalid fingerprint.`);
380
+ }
381
+ const { signature, ...unsigned } = event;
382
+ const signingKey = await cryptoImplementation.subtle.importKey("raw", copyBuffer(base64UrlToBytes(publicKey.signingPublicKey)), { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
383
+ const valid = await cryptoImplementation.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, signingKey, copyBuffer(base64UrlToBytes(signature)), copyBuffer(canonicalAad(unsigned)));
384
+ if (!valid)
385
+ throw new SyncKitError("crypto", `Control event ${event.eventId} has an invalid signature.`);
386
+ }
387
+ function parseMember(value) {
388
+ const member = object(value, "control member");
389
+ const publicKey = object(member.publicKey, "control member publicKey");
390
+ for (const key of ["keyId", "encryptionAlgorithm", "encryptionPublicKey", "signatureAlgorithm", "signingPublicKey"]) {
391
+ nonEmpty(publicKey[key], `control member publicKey ${key}`);
392
+ }
393
+ if (member.email !== undefined)
394
+ nonEmpty(member.email, "control member email");
395
+ if (member.googleSubject !== undefined)
396
+ nonEmpty(member.googleSubject, "control member googleSubject");
397
+ if (member.drivePermissionId !== undefined)
398
+ nonEmpty(member.drivePermissionId, "control member drivePermissionId");
399
+ return {
400
+ publicKey: {
401
+ keyId: publicKey.keyId,
402
+ encryptionAlgorithm: publicKey.encryptionAlgorithm,
403
+ encryptionPublicKey: publicKey.encryptionPublicKey,
404
+ signatureAlgorithm: publicKey.signatureAlgorithm,
405
+ signingPublicKey: publicKey.signingPublicKey,
406
+ },
407
+ ...(member.email === undefined ? {} : { email: member.email }),
408
+ ...(member.googleSubject === undefined ? {} : { googleSubject: member.googleSubject }),
409
+ ...(member.drivePermissionId === undefined ? {} : { drivePermissionId: member.drivePermissionId }),
410
+ };
411
+ }
412
+ function parseMigration(value) {
413
+ const migration = object(value, "control migration");
414
+ nonEmpty(migration.migrationId, "control migrationId");
415
+ exact(migration.mode, "hard-cutover", "control migration mode");
416
+ const sourceDatasetIds = stringArray(migration.sourceDatasetIds, "control sourceDatasetIds");
417
+ const targets = array(migration.targets, "control targets").map((value) => {
418
+ const target = object(value, "control migration target");
419
+ nonEmpty(target.datasetId, "control target datasetId");
420
+ nonEmpty(target.fileId, "control target fileId");
421
+ if (target.revisionId !== undefined)
422
+ nonEmpty(target.revisionId, "control target revisionId");
423
+ return {
424
+ datasetId: target.datasetId,
425
+ fileId: target.fileId,
426
+ ...(target.revisionId === undefined ? {} : { revisionId: target.revisionId }),
427
+ };
428
+ });
429
+ const requiredAcks = array(migration.requiredAcks, "control requiredAcks").map((value) => {
430
+ const requirement = object(value, "control acknowledgement requirement");
431
+ nonEmpty(requirement.keyId, "control acknowledgement keyId");
432
+ return { keyId: requirement.keyId, targetFileIds: stringArray(requirement.targetFileIds, "control acknowledgement targetFileIds") };
433
+ });
434
+ unique(sourceDatasetIds, "control source dataset");
435
+ unique(targets.map((target) => target.fileId), "control target file");
436
+ unique(requiredAcks.map((requirement) => requirement.keyId), "control acknowledgement member");
437
+ return { migrationId: migration.migrationId, sourceDatasetIds, targets, requiredAcks, mode: "hard-cutover" };
438
+ }
439
+ function sortEvents(events) {
440
+ return [...events].sort((left, right) => left.sequence === right.sequence
441
+ ? compareUtf16CodeUnits(left.eventId, right.eventId)
442
+ : left.sequence - right.sequence);
443
+ }
444
+ function unexpectedPickerFiles(requirement, openedFileIds) {
445
+ const expected = new Set(requirement.targetFileIds);
446
+ return openedFileIds.filter((fileId) => !expected.has(fileId));
447
+ }
448
+ function object(value, name) {
449
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
450
+ throw new SyncKitError("compatibility", `${name} must be an object.`);
451
+ }
452
+ return value;
453
+ }
454
+ function array(value, name) {
455
+ if (!Array.isArray(value))
456
+ throw new SyncKitError("compatibility", `${name} must be an array.`);
457
+ return value;
458
+ }
459
+ function stringArray(value, name) {
460
+ const values = array(value, name);
461
+ const result = values.map((entry) => {
462
+ nonEmpty(entry, name);
463
+ return entry;
464
+ });
465
+ unique(result, name);
466
+ return result.sort(compareUtf16CodeUnits);
467
+ }
468
+ function unique(values, name) {
469
+ if (new Set(values).size !== values.length) {
470
+ throw new SyncKitError("compatibility", `${name} contains duplicates.`);
471
+ }
472
+ }
473
+ function nonEmpty(value, name) {
474
+ if (typeof value !== "string" || !value.trim()) {
475
+ throw new SyncKitError("compatibility", `${name} must be a non-empty string.`);
476
+ }
477
+ }
478
+ function exact(value, expected, name) {
479
+ if (value !== expected)
480
+ throw new SyncKitError("compatibility", `${name} is unsupported.`);
481
+ }
482
+ function validTime(value, name) {
483
+ if (Number.isNaN(Date.parse(value)))
484
+ throw new SyncKitError("compatibility", `${name} must be an ISO timestamp.`);
485
+ }
486
+ //# sourceMappingURL=control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control.js","sourceRoot":"","sources":["../../src/sharing/control.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { type SharedBackupCodec, type SharingAccountBindingV1, type SharingDatasetGrantV1, type SharingInvitationV1, type SharingRole } from "./index.js";
1
+ import { type SharedBackupCodec, type SharingAccountBindingV1, type SharingDatasetGrantV1, type SharingInvitationV1, type SharingPublicKeyResponseV1, type SharingRole, type SharedBackupParticipantV1 } from "./index.js";
2
+ import type { SharingDatasetFileV1 } from "./link-exchange.js";
2
3
  import type { SharedBackupStorage, SharedBackupTransport, SharedDatasetFile, SharedExchangeFile } from "./transport.js";
3
4
  import { type WebCryptoSharingIdentity } from "./web-crypto.js";
4
5
  export { IndexedDbSharedBackupRegistry } from "./registry-indexeddb.js";
@@ -30,7 +31,7 @@ export type SharedDatasetResult<T> = {
30
31
  fileId: string;
31
32
  revisionId: string;
32
33
  value: T;
33
- outcome: "created" | "loaded" | "updated" | "unchanged";
34
+ outcome: "created" | "adopted" | "loaded" | "updated" | "unchanged";
34
35
  };
35
36
  export type SharingInvitationResult = {
36
37
  invitation: SharingInvitationV1;
@@ -74,6 +75,13 @@ export type DrivePermissionReconciliationResult = {
74
75
  export type SharedBackupControllerOptions<T> = {
75
76
  appId: string;
76
77
  codec: SharedBackupControllerCodec<T>;
78
+ /**
79
+ * Optional codec override for a protocol-owned companion dataset such as a
80
+ * sharing control ledger. It lets one signed invitation accept several
81
+ * application datasets plus that ledger without treating the ledger as app
82
+ * payload. Ordinary create/load/sync calls continue to use `codec`.
83
+ */
84
+ codecForDataset?(datasetId: string): SharedBackupControllerCodec<unknown> | undefined;
77
85
  identity(): Promise<WebCryptoSharingIdentity>;
78
86
  transport: SharedBackupTransport;
79
87
  registry: SharedBackupRegistry;
@@ -112,7 +120,33 @@ export declare class SharedBackupController<T> {
112
120
  constructor(options: SharedBackupControllerOptions<T>);
113
121
  ensureStorage(): Promise<SharedBackupStorage>;
114
122
  listDatasets(): Promise<SharedDatasetFile[]>;
123
+ /** Returns the locally pinned genesis owner for a previously trusted dataset. */
124
+ getDatasetTrust(datasetId: string): Promise<{
125
+ trustedOwnerKeyId: string;
126
+ }>;
127
+ /**
128
+ * Reads the verified cryptographic membership for a dataset. This is useful
129
+ * for a companion control ledger that mirrors key provenance and user-facing
130
+ * contact metadata without making application payloads authoritative.
131
+ */
132
+ getDatasetParticipants(datasetId: string): Promise<{
133
+ trustedOwnerKeyId: string;
134
+ participants: SharedBackupParticipantV1[];
135
+ }>;
115
136
  createDataset(datasetId: string, value: T): Promise<SharedDatasetResult<T>>;
137
+ /**
138
+ * Reconnect to an existing dataset this identity can already decrypt —
139
+ * e.g. after a reinstall, or when an interrupted setup left the remote
140
+ * file without a local registry record. The owner key is pinned from the
141
+ * envelope itself (trust-on-first-use), so callers recovering their own
142
+ * dataset should pass `requireOwned` to insist this identity is the
143
+ * dataset's owner.
144
+ */
145
+ adoptDataset(datasetId: string, options?: {
146
+ requireOwned?: boolean;
147
+ }): Promise<SharedDatasetResult<T>>;
148
+ /** Delete a dataset file from the transport and forget its local record. */
149
+ deleteDataset(datasetId: string): Promise<void>;
116
150
  loadDataset(datasetId: string): Promise<SharedDatasetResult<T>>;
117
151
  syncDataset(datasetId: string, localValue: T): Promise<SharedDatasetResult<T>>;
118
152
  inviteParticipant(input: {
@@ -140,6 +174,46 @@ export declare class SharedBackupController<T> {
140
174
  responseFileId: string;
141
175
  recipientEmailAddress: string;
142
176
  }): Promise<AcceptedDatasetResult[]>;
177
+ /**
178
+ * Applies verified acceptance grants to each dataset: add the participant,
179
+ * re-encrypt, write, and per-email-share the dataset file. Shared by the
180
+ * Drive-file accept path and the link-payload accept path.
181
+ */
182
+ private applyAcceptedGrants;
183
+ /**
184
+ * Owner side of the link-carried exchange. Shares each granted dataset file
185
+ * with the recipient's email (so it lands in their Picker) and returns the
186
+ * signed invitation plus the file list to embed in the join link. Unlike
187
+ * {@link inviteParticipant} it writes no Drive `exchanges/` invitation file.
188
+ */
189
+ inviteParticipantForLink(input: {
190
+ emailAddress: string;
191
+ requestedGrants: SharingDatasetGrantV1[];
192
+ expiresAt?: string;
193
+ }): Promise<{
194
+ invitation: SharingInvitationV1;
195
+ files: SharingDatasetFileV1[];
196
+ }>;
197
+ /**
198
+ * Recipient side of the link-carried exchange. Verifies the invitation carried
199
+ * in the join link, registers the granted datasets with their file ids (so
200
+ * later reads/writes resolve without listing the owner's folder), and returns
201
+ * a signed key response to send back to the owner. Reads/writes no Drive
202
+ * `exchanges/` file.
203
+ */
204
+ submitKeyResponseFromInvitation(invitation: SharingInvitationV1, datasetFiles: SharingDatasetFileV1[]): Promise<SharingPublicKeyResponseV1>;
205
+ /**
206
+ * Owner side. Accepts a key response carried in a response link (no Drive
207
+ * `exchanges/` read), adds the recipient to each granted dataset, and
208
+ * per-email shares the dataset files (re-affirming the invite-time share).
209
+ * The invitation must be supplied by the caller (persisted at invite time,
210
+ * keyed by exchange id).
211
+ */
212
+ acceptKeyResponseFromPayload(input: {
213
+ invitation: SharingInvitationV1;
214
+ response: SharingPublicKeyResponseV1;
215
+ recipientEmailAddress: string;
216
+ }): Promise<AcceptedDatasetResult[]>;
143
217
  setDatasetRole(input: {
144
218
  datasetId: string;
145
219
  keyId: string;
@@ -149,19 +223,21 @@ export declare class SharedBackupController<T> {
149
223
  revokeDatasetKey(input: {
150
224
  datasetId: string;
151
225
  keyId: string;
226
+ emailAddress?: string;
152
227
  }): Promise<SharedDatasetResult<T>>;
228
+ private findDirectDatasetPermission;
153
229
  rotateLocalKey(replacementIdentity: WebCryptoSharingIdentity, datasetIds: string[]): Promise<RotatedDatasetResult[]>;
154
230
  reconcileDrivePermissions(input: {
155
231
  datasetId: string;
156
232
  participantEmails: Record<string, string>;
157
233
  }): Promise<DrivePermissionReconciliationResult>;
158
- private changeParticipants;
159
234
  private readDatasetById;
160
235
  private requiredRegistry;
161
236
  private verifyHead;
162
237
  private initialOwnerRecord;
163
238
  private persistHead;
164
239
  private crypto;
240
+ private codecForDataset;
165
241
  private cryptoOptions;
166
242
  private serialized;
167
243
  }