@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
package/README.md CHANGED
@@ -121,6 +121,8 @@ Available exports:
121
121
  - `/sharing/controller` — headless multi-dataset orchestration, owner pinning,
122
122
  serialized writes, exchange processing, roles, revocation, Drive permission
123
123
  reconciliation, and optional IndexedDB registry persistence
124
+ - `/sharing/control` — encrypted, signed coordination ledgers for Picker
125
+ enrollment, participant provenance, and hard-cutover migration acknowledgements
124
126
  - `/sharing/web-passkey` — passkey-encrypted sharing identities with
125
127
  non-extractable runtime keys and optional IndexedDB ciphertext storage
126
128
  - `/sharing/account-binding` — backendless Google ID-token and WebAuthn
@@ -209,9 +211,11 @@ frontend can execute the protocol directly against Google Drive; an
209
211
  application-owned server is neither a trust root nor a deployment requirement.
210
212
 
211
213
  Shared files use normal Google Drive storage with the per-file `drive.file`
212
- scope. A recipient can select the shared app folder once through Google Picker,
213
- after which the app reuses its ID for app-created children; broad access to
214
- Drive is not required. `appDataFolder` files cannot be shared.
214
+ scope. A recipient must select every required shared data/control file through
215
+ Google Picker; selecting the parent folder does not grant recursive child-file
216
+ access. The app persists the folder ID for profile routing and compares Picker
217
+ results to the signed expected file IDs; broad access to Drive is not required.
218
+ `appDataFolder` files cannot be shared.
215
219
 
216
220
  New integrations can use `GoogleDriveFileSnapshotStore`, which defaults to an
217
221
  app-owned top-level folder:
@@ -235,6 +239,7 @@ sharing or limited-access subfolders.
235
239
  See the [protocol and threat model](docs/shared-backups.md),
236
240
  [authoritative implementation handoff](docs/sharing-implementation-handoff.md),
237
241
  [consumer responsibilities](docs/consumer-responsibilities.md), and
242
+ [control dataset and topology migration guide](docs/sharing-control-datasets.md),
238
243
  [background notifications](docs/background-notifications.md). The phased gates
239
244
  remain in the [sharing execution plan](docs/sharing-execution-plan.md). The crypto and
240
245
  per-file transport, Picker, protected identity, account binding, signed
@@ -0,0 +1,36 @@
1
+ import type { Authorization } from "../core/types.js";
2
+ import { GoogleDriveAppDataStore } from "../stores/google-drive/index.js";
3
+ import { type ProtectedSharingIdentityStore, type ProtectedSharingIdentityV1 } from "./web-passkey.js";
4
+ export type DriveAppDataProtectedSharingIdentityStoreOptions = {
5
+ /**
6
+ * Supplies a Drive authorization scoped to `drive.appdata`. The same Google
7
+ * account on any device returns the same private app-data folder, which is
8
+ * how a single sharing identity follows the user across devices.
9
+ */
10
+ authorization(): Promise<Authorization>;
11
+ /** Overrides the app-data filename derived from the app id. */
12
+ filename?(appId: string): string;
13
+ drive?: GoogleDriveAppDataStore;
14
+ };
15
+ /**
16
+ * Hosts the passkey-wrapped sharing identity in the signed-in Google account's
17
+ * private `drive.appdata` folder instead of device-local storage. Because the
18
+ * record is already AES-GCM-encrypted with the passkey PRF secret, app-data is
19
+ * a plaintext-safe transport: Drive only ever sees an opaque JSON blob whose
20
+ * `encryptedPrivateKeys` field it cannot read.
21
+ *
22
+ * The single-user, multi-device continuity this restores is deliberately
23
+ * distinct from the sharing (multi-user) protocol: the identity here is one
24
+ * account's own key, replicated to its own devices, never granted to another
25
+ * participant.
26
+ */
27
+ export declare class DriveAppDataProtectedSharingIdentityStore implements ProtectedSharingIdentityStore {
28
+ private readonly options;
29
+ private readonly drive;
30
+ constructor(options: DriveAppDataProtectedSharingIdentityStoreOptions);
31
+ load(appId: string): Promise<ProtectedSharingIdentityV1 | null>;
32
+ save(record: ProtectedSharingIdentityV1): Promise<void>;
33
+ delete(appId: string): Promise<void>;
34
+ private filename;
35
+ }
36
+ //# sourceMappingURL=appdata-identity-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appdata-identity-store.d.ts","sourceRoot":"","sources":["../../src/sharing/appdata-identity-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAChC,MAAM,kBAAkB,CAAC;AAE1B,MAAM,MAAM,gDAAgD,GAAG;IAC7D;;;;OAIG;IACH,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IACxC,+DAA+D;IAC/D,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,KAAK,CAAC,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAAa,yCACX,YAAW,6BAA6B;IAKtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAH1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;gBAG7B,OAAO,EAAE,gDAAgD;IAKtE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC;IAQ/D,IAAI,CAAC,MAAM,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAUvD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1C,OAAO,CAAC,QAAQ;CAKjB"}
@@ -0,0 +1,49 @@
1
+ import { GoogleDriveAppDataStore } from "../stores/google-drive/index.js";
2
+ import { parseProtectedSharingIdentityV1, } from "./web-passkey.js";
3
+ /**
4
+ * Hosts the passkey-wrapped sharing identity in the signed-in Google account's
5
+ * private `drive.appdata` folder instead of device-local storage. Because the
6
+ * record is already AES-GCM-encrypted with the passkey PRF secret, app-data is
7
+ * a plaintext-safe transport: Drive only ever sees an opaque JSON blob whose
8
+ * `encryptedPrivateKeys` field it cannot read.
9
+ *
10
+ * The single-user, multi-device continuity this restores is deliberately
11
+ * distinct from the sharing (multi-user) protocol: the identity here is one
12
+ * account's own key, replicated to its own devices, never granted to another
13
+ * participant.
14
+ */
15
+ export class DriveAppDataProtectedSharingIdentityStore {
16
+ options;
17
+ drive;
18
+ constructor(options) {
19
+ this.options = options;
20
+ this.drive = options.drive ?? new GoogleDriveAppDataStore();
21
+ }
22
+ async load(appId) {
23
+ const authorization = await this.options.authorization();
24
+ const found = await this.drive.find(this.filename(appId), authorization);
25
+ if (!found)
26
+ return null;
27
+ const text = await this.drive.readText(found.fileId, authorization);
28
+ return parseProtectedSharingIdentityV1(text);
29
+ }
30
+ async save(record) {
31
+ const authorization = await this.options.authorization();
32
+ const name = this.filename(record.appId);
33
+ const found = await this.drive.find(name, authorization);
34
+ await this.drive.write(name, JSON.stringify(record), authorization, {
35
+ ...(found ? { existingId: found.fileId } : {}),
36
+ contentType: "application/json",
37
+ });
38
+ }
39
+ async delete(appId) {
40
+ const authorization = await this.options.authorization();
41
+ const found = await this.drive.find(this.filename(appId), authorization);
42
+ if (found)
43
+ await this.drive.delete(found.fileId, authorization);
44
+ }
45
+ filename(appId) {
46
+ return (this.options.filename?.(appId) ?? `sync-kit-sharing-identity-${appId}.json`);
47
+ }
48
+ }
49
+ //# sourceMappingURL=appdata-identity-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appdata-identity-store.js","sourceRoot":"","sources":["../../src/sharing/appdata-identity-store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAC1E,OAAO,EACL,+BAA+B,GAGhC,MAAM,kBAAkB,CAAC;AAc1B;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,yCAAyC;IAMjC;IAHF,KAAK,CAA0B;IAEhD,YACmB,OAAyD;QAAzD,YAAO,GAAP,OAAO,CAAkD;QAE1E,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,uBAAuB,EAAE,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACpE,OAAO,+BAA+B,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,MAAkC;QAC3C,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE;YAClE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,WAAW,EAAE,kBAAkB;SAChC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa;QACxB,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;QACzD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,CAAC;QACzE,IAAI,KAAK;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAClE,CAAC;IAEO,QAAQ,CAAC,KAAa;QAC5B,OAAO,CACL,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,6BAA6B,KAAK,OAAO,CAC5E,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,136 @@
1
+ import type { SharingPublicKeyV1 } from "./index.js";
2
+ import { type WebCryptoSharingIdentity } from "./web-crypto.js";
3
+ import type { SharedBackupController, SharedBackupControllerCodec, SharedDatasetResult } from "./controller.js";
4
+ /**
5
+ * An encrypted, merge-safe coordination dataset. It is intentionally separate
6
+ * from application data so every profile participant may acknowledge a
7
+ * migration without being allowed to modify the data being migrated.
8
+ */
9
+ export declare const SHARING_CONTROL_KIND: "sync-kit-sharing-control";
10
+ export declare const SHARING_CONTROL_EVENT_KIND: "sync-kit-sharing-control-event";
11
+ export type SharingControlMemberV1 = {
12
+ publicKey: SharingPublicKeyV1;
13
+ email?: string;
14
+ googleSubject?: string;
15
+ drivePermissionId?: string;
16
+ };
17
+ export type SharingControlMigrationTargetV1 = {
18
+ datasetId: string;
19
+ fileId: string;
20
+ revisionId?: string;
21
+ };
22
+ export type SharingControlMigrationRequirementV1 = {
23
+ keyId: string;
24
+ targetFileIds: string[];
25
+ };
26
+ export type SharingControlMigrationV1 = {
27
+ migrationId: string;
28
+ sourceDatasetIds: string[];
29
+ targets: SharingControlMigrationTargetV1[];
30
+ requiredAcks: SharingControlMigrationRequirementV1[];
31
+ mode: "hard-cutover";
32
+ };
33
+ type SharingControlEventBaseV1 = {
34
+ schemaVersion: 1;
35
+ kind: typeof SHARING_CONTROL_EVENT_KIND;
36
+ eventId: string;
37
+ profileId: string;
38
+ actorKeyId: string;
39
+ sequence: number;
40
+ createdAt: string;
41
+ signature: string;
42
+ };
43
+ export type SharingControlMemberUpsertEventV1 = SharingControlEventBaseV1 & {
44
+ type: "member-upsert";
45
+ member: SharingControlMemberV1;
46
+ };
47
+ export type SharingControlMigrationAnnouncedEventV1 = SharingControlEventBaseV1 & {
48
+ type: "migration-announced";
49
+ migration: SharingControlMigrationV1;
50
+ };
51
+ export type SharingControlMigrationAcknowledgedEventV1 = SharingControlEventBaseV1 & {
52
+ type: "migration-acknowledged";
53
+ migrationId: string;
54
+ openedFileIds: string[];
55
+ };
56
+ export type SharingControlMigrationClosedEventV1 = SharingControlEventBaseV1 & {
57
+ type: "migration-closed";
58
+ migrationId: string;
59
+ forced?: boolean;
60
+ };
61
+ export type SharingControlEventV1 = SharingControlMemberUpsertEventV1 | SharingControlMigrationAnnouncedEventV1 | SharingControlMigrationAcknowledgedEventV1 | SharingControlMigrationClosedEventV1;
62
+ export type SharingControlStateV1 = {
63
+ schemaVersion: 1;
64
+ kind: typeof SHARING_CONTROL_KIND;
65
+ profileId: string;
66
+ events: SharingControlEventV1[];
67
+ };
68
+ export type VerifiedSharingControlStateV1 = {
69
+ state: SharingControlStateV1;
70
+ ownerKeyId: string;
71
+ members: Map<string, SharingControlMemberV1>;
72
+ migrations: Map<string, SharingControlMigrationV1>;
73
+ acknowledgements: Map<string, Map<string, SharingControlMigrationAcknowledgedEventV1>>;
74
+ closedMigrations: Set<string>;
75
+ };
76
+ export type SharingControlMigrationStatusV1 = {
77
+ migration: SharingControlMigrationV1;
78
+ acknowledgedKeyIds: string[];
79
+ pendingKeyIds: string[];
80
+ closed: boolean;
81
+ };
82
+ export type SharingControlDatasetOptions = {
83
+ controller: SharedBackupController<SharingControlStateV1>;
84
+ datasetId: string;
85
+ profileId: string;
86
+ identity(): Promise<WebCryptoSharingIdentity>;
87
+ crypto?: Crypto;
88
+ now?: () => Date;
89
+ randomUUID?: () => string;
90
+ maxPublishAttempts?: number;
91
+ };
92
+ /**
93
+ * Creates a codec whose merge is an event-id union. Signature and authority
94
+ * validation is intentionally asynchronous and is performed by
95
+ * `verifySharingControlStateV1` before callers act on the state.
96
+ */
97
+ export declare function createSharingControlCodec(): SharedBackupControllerCodec<SharingControlStateV1>;
98
+ export declare function parseSharingControlStateV1(value: unknown): SharingControlStateV1;
99
+ export declare function parseSharingControlEventV1(value: unknown): SharingControlEventV1;
100
+ export declare function mergeSharingControlStates(local: SharingControlStateV1, remote: SharingControlStateV1): SharingControlStateV1;
101
+ export declare function verifySharingControlStateV1(input: SharingControlStateV1, cryptoImplementation?: Crypto, options?: {
102
+ trustedOwnerKeyId?: string;
103
+ }): Promise<VerifiedSharingControlStateV1>;
104
+ export declare function missingSharingControlPickerFiles(requirement: SharingControlMigrationRequirementV1, openedFileIds: readonly string[]): string[];
105
+ export declare class SharingControlDataset {
106
+ private readonly options;
107
+ constructor(options: SharingControlDatasetOptions);
108
+ create(owner?: Omit<SharingControlMemberV1, "publicKey">): Promise<SharedDatasetResult<SharingControlStateV1>>;
109
+ read(): Promise<VerifiedSharingControlStateV1>;
110
+ addMember(member: SharingControlMemberV1): Promise<SharedDatasetResult<SharingControlStateV1>>;
111
+ /**
112
+ * Mirrors cryptographically accepted control-file participants into the
113
+ * signed directory. Call this after accepting a join response; `metadata`
114
+ * supplies the application-visible email/Drive details that envelopes do
115
+ * not contain.
116
+ */
117
+ synchronizeMembers(metadata?: Record<string, Omit<SharingControlMemberV1, "publicKey">>): Promise<SharedDatasetResult<SharingControlStateV1> | null>;
118
+ announceMigration(migration: SharingControlMigrationV1): Promise<SharedDatasetResult<SharingControlStateV1>>;
119
+ acknowledgeMigration(input: {
120
+ migrationId: string;
121
+ openedFileIds: string[];
122
+ }): Promise<SharedDatasetResult<SharingControlStateV1>>;
123
+ closeMigration(input: {
124
+ migrationId: string;
125
+ force?: boolean;
126
+ }): Promise<SharedDatasetResult<SharingControlStateV1>>;
127
+ migrationStatus(migrationId: string): Promise<SharingControlMigrationStatusV1>;
128
+ private publish;
129
+ private sign;
130
+ private now;
131
+ private randomUUID;
132
+ private crypto;
133
+ }
134
+ export declare function createSharingControlDataset(options: SharingControlDatasetOptions): SharingControlDataset;
135
+ export {};
136
+ //# sourceMappingURL=control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../../src/sharing/control.ts"],"names":[],"mappings":"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"}