@keyneom/sync-kit 0.1.0 → 0.2.0-rc.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 +137 -11
- package/dist/auth/google-web/identity.d.ts +49 -0
- package/dist/auth/google-web/identity.d.ts.map +1 -0
- package/dist/auth/google-web/identity.js +102 -0
- package/dist/auth/google-web/identity.js.map +1 -0
- package/dist/auth/google-web/index.d.ts +1 -0
- package/dist/auth/google-web/index.d.ts.map +1 -1
- package/dist/auth/google-web/index.js +1 -0
- package/dist/auth/google-web/index.js.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +22 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/crypto/canonical.d.ts +5 -0
- package/dist/crypto/canonical.d.ts.map +1 -1
- package/dist/crypto/canonical.js +8 -1
- package/dist/crypto/canonical.js.map +1 -1
- package/dist/crypto/envelope.d.ts.map +1 -1
- package/dist/crypto/envelope.js +1 -0
- package/dist/crypto/envelope.js.map +1 -1
- package/dist/crypto/profiles.d.ts +6 -46
- package/dist/crypto/profiles.d.ts.map +1 -1
- package/dist/crypto/profiles.js +33 -46
- package/dist/crypto/profiles.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/keys/web-passkey/index.d.ts +8 -2
- package/dist/keys/web-passkey/index.d.ts.map +1 -1
- package/dist/keys/web-passkey/index.js +32 -10
- package/dist/keys/web-passkey/index.js.map +1 -1
- package/dist/sharing/account-binding.d.ts +57 -0
- package/dist/sharing/account-binding.d.ts.map +1 -0
- package/dist/sharing/account-binding.js +305 -0
- package/dist/sharing/account-binding.js.map +1 -0
- package/dist/sharing/controller.d.ts +139 -0
- package/dist/sharing/controller.d.ts.map +1 -0
- package/dist/sharing/controller.js +549 -0
- package/dist/sharing/controller.js.map +1 -0
- package/dist/sharing/index.d.ts +119 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +360 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/transport.d.ts +65 -0
- package/dist/sharing/transport.d.ts.map +1 -0
- package/dist/sharing/transport.js +2 -0
- package/dist/sharing/transport.js.map +1 -0
- package/dist/sharing/web-crypto.d.ts +68 -0
- package/dist/sharing/web-crypto.d.ts.map +1 -0
- package/dist/sharing/web-crypto.js +645 -0
- package/dist/sharing/web-crypto.js.map +1 -0
- package/dist/sharing/web-passkey.d.ts +68 -0
- package/dist/sharing/web-passkey.d.ts.map +1 -0
- package/dist/sharing/web-passkey.js +303 -0
- package/dist/sharing/web-passkey.js.map +1 -0
- package/dist/snapshot/controller.d.ts.map +1 -1
- package/dist/snapshot/controller.js +4 -8
- package/dist/snapshot/controller.js.map +1 -1
- package/dist/stores/google-drive/index.d.ts +147 -1
- package/dist/stores/google-drive/index.d.ts.map +1 -1
- package/dist/stores/google-drive/index.js +397 -0
- package/dist/stores/google-drive/index.js.map +1 -1
- package/dist/stores/google-drive/picker.d.ts +89 -0
- package/dist/stores/google-drive/picker.d.ts.map +1 -0
- package/dist/stores/google-drive/picker.js +179 -0
- package/dist/stores/google-drive/picker.js.map +1 -0
- package/dist/stores/google-drive/sharing.d.ts +55 -0
- package/dist/stores/google-drive/sharing.d.ts.map +1 -0
- package/dist/stores/google-drive/sharing.js +295 -0
- package/dist/stores/google-drive/sharing.js.map +1 -0
- package/package.json +67 -12
- package/fixtures/v1/easybc-web-android-gzip.json +0 -41
- package/fixtures/v1/easybc-web-uncompressed.json +0 -35
- package/fixtures/v1/failures.json +0 -42
- package/fixtures/v1/family-chores-web-uncompressed.json +0 -73
- package/fixtures/v1/profiles.json +0 -51
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
export declare const SHARING_KEY_KIND: "sync-kit-public-key";
|
|
2
|
+
export declare const SHARING_INVITATION_KIND: "sync-kit-share-invitation";
|
|
3
|
+
export declare const SHARED_BACKUP_KIND: "sync-kit-shared-backup";
|
|
4
|
+
export declare const SHARING_ENCRYPTION_ALGORITHM: "ECDH-P256";
|
|
5
|
+
export declare const SHARING_SIGNATURE_ALGORITHM: "ECDSA-P256-SHA256-P1363";
|
|
6
|
+
export declare const SHARING_CONTENT_ALGORITHM: "AES-256-GCM+ECDH-P256+HKDF-SHA256";
|
|
7
|
+
export declare const SHARED_BACKUP_MAX_REVISION_ANCESTORS = 256;
|
|
8
|
+
export type SharingRole = "owner" | "admin" | "writer" | "viewer";
|
|
9
|
+
export type SharingPublicKeyV1 = {
|
|
10
|
+
keyId: string;
|
|
11
|
+
encryptionAlgorithm: typeof SHARING_ENCRYPTION_ALGORITHM;
|
|
12
|
+
encryptionPublicKey: string;
|
|
13
|
+
signatureAlgorithm: typeof SHARING_SIGNATURE_ALGORITHM;
|
|
14
|
+
signingPublicKey: string;
|
|
15
|
+
};
|
|
16
|
+
export type SharingPasskeyAssertionV1 = {
|
|
17
|
+
credentialId: string;
|
|
18
|
+
credentialPublicKey: JsonWebKey;
|
|
19
|
+
authenticatorData: string;
|
|
20
|
+
clientDataJSON: string;
|
|
21
|
+
signature: string;
|
|
22
|
+
};
|
|
23
|
+
export type SharingAccountBindingV1 = {
|
|
24
|
+
schemaVersion: 1;
|
|
25
|
+
kind: "sync-kit-sharing-account-binding";
|
|
26
|
+
challenge: string;
|
|
27
|
+
googleIdToken: string;
|
|
28
|
+
passkey: SharingPasskeyAssertionV1;
|
|
29
|
+
};
|
|
30
|
+
export type SharingPublicKeyResponseV1 = SharingPublicKeyV1 & {
|
|
31
|
+
schemaVersion: 1;
|
|
32
|
+
kind: typeof SHARING_KEY_KIND;
|
|
33
|
+
appId: string;
|
|
34
|
+
exchangeId: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
accountBinding?: SharingAccountBindingV1;
|
|
37
|
+
proof: string;
|
|
38
|
+
};
|
|
39
|
+
export type SharingDatasetGrantV1 = {
|
|
40
|
+
datasetId: string;
|
|
41
|
+
role: Exclude<SharingRole, "owner">;
|
|
42
|
+
};
|
|
43
|
+
export type SharingInvitationV1 = {
|
|
44
|
+
schemaVersion: 1;
|
|
45
|
+
kind: typeof SHARING_INVITATION_KIND;
|
|
46
|
+
appId: string;
|
|
47
|
+
appFolderId: string;
|
|
48
|
+
exchangeId: string;
|
|
49
|
+
recipientDrivePermissionId: string;
|
|
50
|
+
requestedGrants: SharingDatasetGrantV1[];
|
|
51
|
+
trustedOwnerKeyId: string;
|
|
52
|
+
createdAt: string;
|
|
53
|
+
expiresAt?: string;
|
|
54
|
+
owner: SharingPublicKeyV1;
|
|
55
|
+
signature: string;
|
|
56
|
+
};
|
|
57
|
+
export type SharingAcceptanceProvenanceV1 = {
|
|
58
|
+
exchangeId: string;
|
|
59
|
+
drivePermissionId: string;
|
|
60
|
+
acceptedAt: string;
|
|
61
|
+
acceptedByKeyId: string;
|
|
62
|
+
googleSubject?: string;
|
|
63
|
+
};
|
|
64
|
+
export type SharedBackupParticipantV1 = SharingPublicKeyV1 & {
|
|
65
|
+
role: SharingRole;
|
|
66
|
+
accepted?: SharingAcceptanceProvenanceV1;
|
|
67
|
+
};
|
|
68
|
+
export type SharedBackupAccessV1 = {
|
|
69
|
+
sequence: number;
|
|
70
|
+
appId?: string;
|
|
71
|
+
backupId?: string;
|
|
72
|
+
previousHash?: string;
|
|
73
|
+
authorKeyId: string;
|
|
74
|
+
participants: SharedBackupParticipantV1[];
|
|
75
|
+
keyRotation?: {
|
|
76
|
+
fromKeyId: string;
|
|
77
|
+
toKeyId: string;
|
|
78
|
+
newKeyProof: string;
|
|
79
|
+
};
|
|
80
|
+
signature: string;
|
|
81
|
+
};
|
|
82
|
+
export type SharedBackupKeyGrantV1 = {
|
|
83
|
+
recipientKeyId: string;
|
|
84
|
+
ephemeralPublicKey: string;
|
|
85
|
+
kdfSalt: string;
|
|
86
|
+
nonce: string;
|
|
87
|
+
wrappedContentKey: string;
|
|
88
|
+
};
|
|
89
|
+
export type SharedBackupEnvelopeV1 = {
|
|
90
|
+
schemaVersion: 1;
|
|
91
|
+
kind: typeof SHARED_BACKUP_KIND;
|
|
92
|
+
algorithm: typeof SHARING_CONTENT_ALGORITHM;
|
|
93
|
+
appId: string;
|
|
94
|
+
backupId: string;
|
|
95
|
+
revisionId: string;
|
|
96
|
+
parentRevisionId?: string;
|
|
97
|
+
revisionAncestors?: string[];
|
|
98
|
+
createdAt: string;
|
|
99
|
+
authorKeyId: string;
|
|
100
|
+
accessControl: SharedBackupAccessV1[];
|
|
101
|
+
keyGrants: SharedBackupKeyGrantV1[];
|
|
102
|
+
payloadNonce: string;
|
|
103
|
+
ciphertext: string;
|
|
104
|
+
signature: string;
|
|
105
|
+
};
|
|
106
|
+
export type SharedBackupCodec<T> = {
|
|
107
|
+
serialize(value: T): unknown;
|
|
108
|
+
parse(value: unknown): T;
|
|
109
|
+
};
|
|
110
|
+
export declare function canReadSharedBackup(role: SharingRole): boolean;
|
|
111
|
+
export declare function canWriteSharedBackup(role: SharingRole): boolean;
|
|
112
|
+
export declare function canAdministerSharedBackup(role: SharingRole): boolean;
|
|
113
|
+
export declare function parseSharingPublicKeyResponseV1(value: unknown): SharingPublicKeyResponseV1;
|
|
114
|
+
export declare function parseSharingInvitationV1(value: unknown): SharingInvitationV1;
|
|
115
|
+
export declare function parseSharedBackupEnvelopeV1(value: unknown): SharedBackupEnvelopeV1;
|
|
116
|
+
export declare function sharedBackupParticipants(envelope: SharedBackupEnvelopeV1): SharedBackupParticipantV1[];
|
|
117
|
+
export declare function sharedBackupParticipant(envelope: SharedBackupEnvelopeV1, keyId: string): SharedBackupParticipantV1 | null;
|
|
118
|
+
export type { SharedBackupStorage, SharedBackupTransport, SharedDatasetFile, SharedDatasetPermission, SharedExchangeFile, SharedKeyResponseFile, VersionedSharedDataset, } from "./transport.js";
|
|
119
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sharing/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,EAAG,qBAA8B,CAAC;AAC/D,eAAO,MAAM,uBAAuB,EAAG,2BAAoC,CAAC;AAC5E,eAAO,MAAM,kBAAkB,EAAG,wBAAiC,CAAC;AACpE,eAAO,MAAM,4BAA4B,EAAG,WAAoB,CAAC;AACjE,eAAO,MAAM,2BAA2B,EACtC,yBAAkC,CAAC;AACrC,eAAO,MAAM,yBAAyB,EACpC,mCAA4C,CAAC;AAC/C,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAElE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,OAAO,4BAA4B,CAAC;IACzD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,OAAO,2BAA2B,CAAC;IACvD,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,UAAU,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,kCAAkC,CAAC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,yBAAyB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,kBAAkB,GAAG;IAC5D,aAAa,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,OAAO,gBAAgB,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,uBAAuB,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,aAAa,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,OAAO,uBAAuB,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,EAAE,MAAM,CAAC;IACnC,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,kBAAkB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG,kBAAkB,GAAG;IAC3D,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,CAAC,EAAE,6BAA6B,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,yBAAyB,EAAE,CAAC;IAC1C,WAAW,CAAC,EAAE;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,EAAE,CAAC,CAAC;IACjB,IAAI,EAAE,OAAO,kBAAkB,CAAC;IAChC,SAAS,EAAE,OAAO,yBAAyB,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,oBAAoB,EAAE,CAAC;IACtC,SAAS,EAAE,sBAAsB,EAAE,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAC7B,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC;CAC1B,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAE9D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAE/D;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAEpE;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,0BAA0B,CAgC5B;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAiE5E;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,GACb,sBAAsB,CA0GxB;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,sBAAsB,GAC/B,yBAAyB,EAAE,CAM7B;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,sBAAsB,EAChC,KAAK,EAAE,MAAM,GACZ,yBAAyB,GAAG,IAAI,CAIlC;AAmND,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { SyncKitError } from "../core/errors.js";
|
|
2
|
+
import { base64UrlToBytes } from "../crypto/base64url.js";
|
|
3
|
+
export const SHARING_KEY_KIND = "sync-kit-public-key";
|
|
4
|
+
export const SHARING_INVITATION_KIND = "sync-kit-share-invitation";
|
|
5
|
+
export const SHARED_BACKUP_KIND = "sync-kit-shared-backup";
|
|
6
|
+
export const SHARING_ENCRYPTION_ALGORITHM = "ECDH-P256";
|
|
7
|
+
export const SHARING_SIGNATURE_ALGORITHM = "ECDSA-P256-SHA256-P1363";
|
|
8
|
+
export const SHARING_CONTENT_ALGORITHM = "AES-256-GCM+ECDH-P256+HKDF-SHA256";
|
|
9
|
+
export const SHARED_BACKUP_MAX_REVISION_ANCESTORS = 256;
|
|
10
|
+
export function canReadSharedBackup(role) {
|
|
11
|
+
return role === "owner" || role === "admin" || role === "writer" || role === "viewer";
|
|
12
|
+
}
|
|
13
|
+
export function canWriteSharedBackup(role) {
|
|
14
|
+
return role === "owner" || role === "admin" || role === "writer";
|
|
15
|
+
}
|
|
16
|
+
export function canAdministerSharedBackup(role) {
|
|
17
|
+
return role === "owner" || role === "admin";
|
|
18
|
+
}
|
|
19
|
+
export function parseSharingPublicKeyResponseV1(value) {
|
|
20
|
+
const parsed = parseObject(value, "public-key response");
|
|
21
|
+
assertExact(parsed.schemaVersion, 1, "schemaVersion");
|
|
22
|
+
assertExact(parsed.kind, SHARING_KEY_KIND, "kind");
|
|
23
|
+
assertNonEmptyStrings(parsed, [
|
|
24
|
+
"appId",
|
|
25
|
+
"exchangeId",
|
|
26
|
+
"createdAt",
|
|
27
|
+
"keyId",
|
|
28
|
+
"encryptionPublicKey",
|
|
29
|
+
"signingPublicKey",
|
|
30
|
+
"proof",
|
|
31
|
+
]);
|
|
32
|
+
assertExact(parsed.encryptionAlgorithm, SHARING_ENCRYPTION_ALGORITHM, "encryptionAlgorithm");
|
|
33
|
+
assertExact(parsed.signatureAlgorithm, SHARING_SIGNATURE_ALGORITHM, "signatureAlgorithm");
|
|
34
|
+
validatePublicKey(parsed.encryptionPublicKey, "encryptionPublicKey");
|
|
35
|
+
validatePublicKey(parsed.signingPublicKey, "signingPublicKey");
|
|
36
|
+
validateBytes(parsed.keyId, 32, "keyId");
|
|
37
|
+
validateBytes(parsed.proof, 64, "proof");
|
|
38
|
+
validateTimestamp(parsed.createdAt, "createdAt");
|
|
39
|
+
if (parsed.accountBinding !== undefined) {
|
|
40
|
+
parseSharingAccountBinding(parsed.accountBinding);
|
|
41
|
+
}
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
export function parseSharingInvitationV1(value) {
|
|
45
|
+
const parsed = parseObject(value, "sharing invitation");
|
|
46
|
+
assertExact(parsed.schemaVersion, 1, "schemaVersion");
|
|
47
|
+
assertExact(parsed.kind, SHARING_INVITATION_KIND, "kind");
|
|
48
|
+
assertNonEmptyStrings(parsed, [
|
|
49
|
+
"appId",
|
|
50
|
+
"appFolderId",
|
|
51
|
+
"exchangeId",
|
|
52
|
+
"recipientDrivePermissionId",
|
|
53
|
+
"trustedOwnerKeyId",
|
|
54
|
+
"createdAt",
|
|
55
|
+
"signature",
|
|
56
|
+
]);
|
|
57
|
+
validateBytes(parsed.trustedOwnerKeyId, 32, "trustedOwnerKeyId");
|
|
58
|
+
if (parsed.expiresAt !== undefined && !nonEmpty(parsed.expiresAt)) {
|
|
59
|
+
throw compatibility("expiresAt must be a non-empty string.");
|
|
60
|
+
}
|
|
61
|
+
if (!Array.isArray(parsed.requestedGrants) ||
|
|
62
|
+
parsed.requestedGrants.length === 0) {
|
|
63
|
+
throw compatibility("requestedGrants must not be empty.");
|
|
64
|
+
}
|
|
65
|
+
const datasetIds = new Set();
|
|
66
|
+
for (const input of parsed.requestedGrants) {
|
|
67
|
+
const grant = parseObject(input, "requested dataset grant");
|
|
68
|
+
assertNonEmptyStrings(grant, ["datasetId", "role"]);
|
|
69
|
+
if (!isRole(grant.role) || grant.role === "owner") {
|
|
70
|
+
throw compatibility("An invitation has an unsupported requested role.");
|
|
71
|
+
}
|
|
72
|
+
const datasetId = grant.datasetId;
|
|
73
|
+
if (datasetIds.has(datasetId)) {
|
|
74
|
+
throw compatibility(`Duplicate requested dataset ${datasetId}.`);
|
|
75
|
+
}
|
|
76
|
+
datasetIds.add(datasetId);
|
|
77
|
+
}
|
|
78
|
+
const owner = parseObject(parsed.owner, "invitation owner");
|
|
79
|
+
assertNonEmptyStrings(owner, [
|
|
80
|
+
"keyId",
|
|
81
|
+
"encryptionPublicKey",
|
|
82
|
+
"signingPublicKey",
|
|
83
|
+
]);
|
|
84
|
+
assertExact(owner.encryptionAlgorithm, SHARING_ENCRYPTION_ALGORITHM, "encryptionAlgorithm");
|
|
85
|
+
assertExact(owner.signatureAlgorithm, SHARING_SIGNATURE_ALGORITHM, "signatureAlgorithm");
|
|
86
|
+
validatePublicKey(owner.encryptionPublicKey, "encryptionPublicKey");
|
|
87
|
+
validatePublicKey(owner.signingPublicKey, "signingPublicKey");
|
|
88
|
+
validateBytes(owner.keyId, 32, "owner keyId");
|
|
89
|
+
validateBytes(parsed.signature, 64, "signature");
|
|
90
|
+
validateTimestamp(parsed.createdAt, "createdAt");
|
|
91
|
+
if (parsed.expiresAt) {
|
|
92
|
+
validateTimestamp(parsed.expiresAt, "expiresAt");
|
|
93
|
+
}
|
|
94
|
+
return parsed;
|
|
95
|
+
}
|
|
96
|
+
export function parseSharedBackupEnvelopeV1(value) {
|
|
97
|
+
const parsed = parseObject(value, "shared-backup envelope");
|
|
98
|
+
assertExact(parsed.schemaVersion, 1, "schemaVersion");
|
|
99
|
+
assertExact(parsed.kind, SHARED_BACKUP_KIND, "kind");
|
|
100
|
+
assertExact(parsed.algorithm, SHARING_CONTENT_ALGORITHM, "algorithm");
|
|
101
|
+
assertNonEmptyStrings(parsed, [
|
|
102
|
+
"appId",
|
|
103
|
+
"backupId",
|
|
104
|
+
"revisionId",
|
|
105
|
+
"createdAt",
|
|
106
|
+
"authorKeyId",
|
|
107
|
+
"payloadNonce",
|
|
108
|
+
"ciphertext",
|
|
109
|
+
"signature",
|
|
110
|
+
]);
|
|
111
|
+
if (parsed.parentRevisionId !== undefined &&
|
|
112
|
+
!nonEmpty(parsed.parentRevisionId)) {
|
|
113
|
+
throw compatibility("parentRevisionId must be a non-empty string.");
|
|
114
|
+
}
|
|
115
|
+
if (parsed.revisionAncestors !== undefined) {
|
|
116
|
+
if (!Array.isArray(parsed.revisionAncestors) ||
|
|
117
|
+
!parsed.revisionAncestors.every(nonEmpty)) {
|
|
118
|
+
throw compatibility("revisionAncestors must contain revision IDs.");
|
|
119
|
+
}
|
|
120
|
+
const ancestors = parsed.revisionAncestors;
|
|
121
|
+
if (ancestors.length > SHARED_BACKUP_MAX_REVISION_ANCESTORS) {
|
|
122
|
+
throw compatibility(`revisionAncestors must contain at most ${SHARED_BACKUP_MAX_REVISION_ANCESTORS} revision IDs.`);
|
|
123
|
+
}
|
|
124
|
+
if (new Set(ancestors).size !== ancestors.length ||
|
|
125
|
+
ancestors.includes(parsed.revisionId)) {
|
|
126
|
+
throw compatibility("revisionAncestors contains a duplicate or cycle.");
|
|
127
|
+
}
|
|
128
|
+
if (parsed.parentRevisionId &&
|
|
129
|
+
ancestors.at(-1) !== parsed.parentRevisionId) {
|
|
130
|
+
throw compatibility("parentRevisionId must be the last revision ancestor.");
|
|
131
|
+
}
|
|
132
|
+
if (!parsed.parentRevisionId && ancestors.length > 0) {
|
|
133
|
+
throw compatibility("A genesis revision cannot have ancestors.");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (!Array.isArray(parsed.accessControl) || parsed.accessControl.length === 0) {
|
|
137
|
+
throw compatibility("accessControl must not be empty.");
|
|
138
|
+
}
|
|
139
|
+
if (!Array.isArray(parsed.keyGrants) || parsed.keyGrants.length === 0) {
|
|
140
|
+
throw compatibility("keyGrants must not be empty.");
|
|
141
|
+
}
|
|
142
|
+
for (const [index, input] of parsed.accessControl.entries()) {
|
|
143
|
+
parseAccessEntry(input, index);
|
|
144
|
+
}
|
|
145
|
+
const accessControl = parsed.accessControl;
|
|
146
|
+
const participants = accessControl.at(-1)?.participants;
|
|
147
|
+
if (!participants)
|
|
148
|
+
throw compatibility("accessControl must not be empty.");
|
|
149
|
+
const participantIds = new Set(participants.map((participant) => participant.keyId));
|
|
150
|
+
if (!participantIds.has(parsed.authorKeyId)) {
|
|
151
|
+
throw compatibility("The revision author is not a participant.");
|
|
152
|
+
}
|
|
153
|
+
const grantIds = new Set();
|
|
154
|
+
for (const input of parsed.keyGrants) {
|
|
155
|
+
const grant = parseObject(input, "key grant");
|
|
156
|
+
assertNonEmptyStrings(grant, [
|
|
157
|
+
"recipientKeyId",
|
|
158
|
+
"ephemeralPublicKey",
|
|
159
|
+
"kdfSalt",
|
|
160
|
+
"nonce",
|
|
161
|
+
"wrappedContentKey",
|
|
162
|
+
]);
|
|
163
|
+
const recipientKeyId = grant.recipientKeyId;
|
|
164
|
+
if (!participantIds.has(recipientKeyId)) {
|
|
165
|
+
throw compatibility("A key grant references a non-participant.");
|
|
166
|
+
}
|
|
167
|
+
if (grantIds.has(recipientKeyId)) {
|
|
168
|
+
throw compatibility(`Duplicate key grant for ${recipientKeyId}.`);
|
|
169
|
+
}
|
|
170
|
+
grantIds.add(recipientKeyId);
|
|
171
|
+
validatePublicKey(grant.ephemeralPublicKey, "ephemeralPublicKey");
|
|
172
|
+
validateBytes(grant.kdfSalt, 32, "kdfSalt");
|
|
173
|
+
validateBytes(grant.nonce, 12, "key-grant nonce");
|
|
174
|
+
base64UrlToBytes(grant.wrappedContentKey);
|
|
175
|
+
}
|
|
176
|
+
if (grantIds.size !== participantIds.size) {
|
|
177
|
+
throw compatibility("Every participant must have exactly one key grant.");
|
|
178
|
+
}
|
|
179
|
+
validateBytes(parsed.payloadNonce, 12, "payload nonce");
|
|
180
|
+
base64UrlToBytes(parsed.ciphertext);
|
|
181
|
+
validateBytes(parsed.signature, 64, "signature");
|
|
182
|
+
validateTimestamp(parsed.createdAt, "createdAt");
|
|
183
|
+
return parsed;
|
|
184
|
+
}
|
|
185
|
+
export function sharedBackupParticipants(envelope) {
|
|
186
|
+
const participants = envelope.accessControl.at(-1)?.participants;
|
|
187
|
+
if (!participants) {
|
|
188
|
+
throw compatibility("accessControl must not be empty.");
|
|
189
|
+
}
|
|
190
|
+
return participants;
|
|
191
|
+
}
|
|
192
|
+
export function sharedBackupParticipant(envelope, keyId) {
|
|
193
|
+
return sharedBackupParticipants(envelope).find((participant) => participant.keyId === keyId) ?? null;
|
|
194
|
+
}
|
|
195
|
+
function parseAccessEntry(input, index) {
|
|
196
|
+
const entry = parseObject(input, "access-control entry");
|
|
197
|
+
if (!Number.isSafeInteger(entry.sequence) || entry.sequence !== index) {
|
|
198
|
+
throw compatibility("Access-control sequence is invalid.");
|
|
199
|
+
}
|
|
200
|
+
assertNonEmptyStrings(entry, ["authorKeyId", "signature"]);
|
|
201
|
+
if (entry.appId !== undefined || entry.backupId !== undefined) {
|
|
202
|
+
assertNonEmptyStrings(entry, ["appId", "backupId"]);
|
|
203
|
+
}
|
|
204
|
+
validateBytes(entry.authorKeyId, 32, "access author keyId");
|
|
205
|
+
validateBytes(entry.signature, 64, "access signature");
|
|
206
|
+
if (index === 0) {
|
|
207
|
+
if (entry.previousHash !== undefined) {
|
|
208
|
+
throw compatibility("The first access-control entry cannot have a previousHash.");
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
if (!nonEmpty(entry.previousHash)) {
|
|
213
|
+
throw compatibility("An access-control entry is missing previousHash.");
|
|
214
|
+
}
|
|
215
|
+
validateBytes(entry.previousHash, 32, "access previousHash");
|
|
216
|
+
}
|
|
217
|
+
if (!Array.isArray(entry.participants) || entry.participants.length === 0) {
|
|
218
|
+
throw compatibility("Access-control participants must not be empty.");
|
|
219
|
+
}
|
|
220
|
+
const participantIds = new Set();
|
|
221
|
+
let ownerCount = 0;
|
|
222
|
+
for (const inputParticipant of entry.participants) {
|
|
223
|
+
const participant = parseObject(inputParticipant, "participant");
|
|
224
|
+
assertNonEmptyStrings(participant, [
|
|
225
|
+
"keyId",
|
|
226
|
+
"encryptionPublicKey",
|
|
227
|
+
"signingPublicKey",
|
|
228
|
+
"role",
|
|
229
|
+
]);
|
|
230
|
+
assertExact(participant.encryptionAlgorithm, SHARING_ENCRYPTION_ALGORITHM, "encryptionAlgorithm");
|
|
231
|
+
assertExact(participant.signatureAlgorithm, SHARING_SIGNATURE_ALGORITHM, "signatureAlgorithm");
|
|
232
|
+
if (!isRole(participant.role)) {
|
|
233
|
+
throw compatibility("A participant has an unsupported role.");
|
|
234
|
+
}
|
|
235
|
+
if (participant.accepted !== undefined) {
|
|
236
|
+
parseAcceptanceProvenance(participant.accepted);
|
|
237
|
+
}
|
|
238
|
+
validatePublicKey(participant.encryptionPublicKey, "encryptionPublicKey");
|
|
239
|
+
validatePublicKey(participant.signingPublicKey, "signingPublicKey");
|
|
240
|
+
const keyId = participant.keyId;
|
|
241
|
+
validateBytes(keyId, 32, "participant keyId");
|
|
242
|
+
if (participantIds.has(keyId)) {
|
|
243
|
+
throw compatibility(`Duplicate participant ${keyId}.`);
|
|
244
|
+
}
|
|
245
|
+
participantIds.add(keyId);
|
|
246
|
+
if (participant.role === "owner")
|
|
247
|
+
ownerCount += 1;
|
|
248
|
+
}
|
|
249
|
+
if (ownerCount !== 1) {
|
|
250
|
+
throw compatibility("An access-control entry must have exactly one owner.");
|
|
251
|
+
}
|
|
252
|
+
if (entry.keyRotation !== undefined) {
|
|
253
|
+
const rotation = parseObject(entry.keyRotation, "key rotation");
|
|
254
|
+
assertNonEmptyStrings(rotation, [
|
|
255
|
+
"fromKeyId",
|
|
256
|
+
"toKeyId",
|
|
257
|
+
"newKeyProof",
|
|
258
|
+
]);
|
|
259
|
+
validateBytes(rotation.fromKeyId, 32, "rotation fromKeyId");
|
|
260
|
+
validateBytes(rotation.toKeyId, 32, "rotation toKeyId");
|
|
261
|
+
validateBytes(rotation.newKeyProof, 64, "rotation proof");
|
|
262
|
+
if (rotation.fromKeyId === rotation.toKeyId) {
|
|
263
|
+
throw compatibility("A key rotation must change the key ID.");
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function parseAcceptanceProvenance(input) {
|
|
268
|
+
const accepted = parseObject(input, "participant acceptance provenance");
|
|
269
|
+
assertNonEmptyStrings(accepted, [
|
|
270
|
+
"exchangeId",
|
|
271
|
+
"drivePermissionId",
|
|
272
|
+
"acceptedAt",
|
|
273
|
+
"acceptedByKeyId",
|
|
274
|
+
]);
|
|
275
|
+
if (accepted.googleSubject !== undefined &&
|
|
276
|
+
!nonEmpty(accepted.googleSubject)) {
|
|
277
|
+
throw compatibility("googleSubject must be a non-empty string.");
|
|
278
|
+
}
|
|
279
|
+
validateBytes(accepted.acceptedByKeyId, 32, "acceptedByKeyId");
|
|
280
|
+
validateTimestamp(accepted.acceptedAt, "acceptedAt");
|
|
281
|
+
}
|
|
282
|
+
function parseSharingAccountBinding(input) {
|
|
283
|
+
const binding = parseObject(input, "sharing account binding");
|
|
284
|
+
assertExact(binding.schemaVersion, 1, "account binding schemaVersion");
|
|
285
|
+
assertExact(binding.kind, "sync-kit-sharing-account-binding", "account binding kind");
|
|
286
|
+
assertNonEmptyStrings(binding, ["challenge", "googleIdToken"]);
|
|
287
|
+
validateBytes(binding.challenge, 32, "account binding challenge");
|
|
288
|
+
const passkey = parseObject(binding.passkey, "passkey assertion");
|
|
289
|
+
assertNonEmptyStrings(passkey, [
|
|
290
|
+
"credentialId",
|
|
291
|
+
"authenticatorData",
|
|
292
|
+
"clientDataJSON",
|
|
293
|
+
"signature",
|
|
294
|
+
]);
|
|
295
|
+
base64UrlToBytes(passkey.credentialId);
|
|
296
|
+
base64UrlToBytes(passkey.authenticatorData);
|
|
297
|
+
base64UrlToBytes(passkey.clientDataJSON);
|
|
298
|
+
base64UrlToBytes(passkey.signature);
|
|
299
|
+
if (!passkey.credentialPublicKey ||
|
|
300
|
+
typeof passkey.credentialPublicKey !== "object" ||
|
|
301
|
+
Array.isArray(passkey.credentialPublicKey)) {
|
|
302
|
+
throw compatibility("credentialPublicKey must be a JWK object.");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function parseObject(value, label) {
|
|
306
|
+
let parsed = value;
|
|
307
|
+
if (typeof value === "string") {
|
|
308
|
+
try {
|
|
309
|
+
parsed = JSON.parse(value);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
throw new SyncKitError("compatibility", `The ${label} is not valid JSON.`, { cause: error });
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
316
|
+
throw compatibility(`The ${label} must be an object.`);
|
|
317
|
+
}
|
|
318
|
+
return parsed;
|
|
319
|
+
}
|
|
320
|
+
function assertNonEmptyStrings(value, fields) {
|
|
321
|
+
for (const field of fields) {
|
|
322
|
+
if (!nonEmpty(value[field])) {
|
|
323
|
+
throw compatibility(`${field} must be a non-empty string.`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function assertExact(value, expected, field) {
|
|
328
|
+
if (value !== expected) {
|
|
329
|
+
throw compatibility(`${field} is not supported.`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
function validatePublicKey(value, field) {
|
|
333
|
+
validateBytes(value, 65, field);
|
|
334
|
+
if (base64UrlToBytes(value)[0] !== 4) {
|
|
335
|
+
throw compatibility(`${field} is not an uncompressed P-256 public key.`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
function validateBytes(value, length, field) {
|
|
339
|
+
if (base64UrlToBytes(value).length !== length) {
|
|
340
|
+
throw compatibility(`${field} has an invalid length.`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
function validateTimestamp(value, field) {
|
|
344
|
+
if (!Number.isFinite(Date.parse(value))) {
|
|
345
|
+
throw compatibility(`${field} is not a valid timestamp.`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function isRole(value) {
|
|
349
|
+
return (value === "owner" ||
|
|
350
|
+
value === "admin" ||
|
|
351
|
+
value === "writer" ||
|
|
352
|
+
value === "viewer");
|
|
353
|
+
}
|
|
354
|
+
function nonEmpty(value) {
|
|
355
|
+
return typeof value === "string" && value.length > 0;
|
|
356
|
+
}
|
|
357
|
+
function compatibility(message) {
|
|
358
|
+
return new SyncKitError("compatibility", message);
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sharing/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SharedBackupEnvelopeV1, SharingInvitationV1, SharingPublicKeyResponseV1, SharingRole } from "./index.js";
|
|
2
|
+
export type SharedBackupStorage = {
|
|
3
|
+
appFolderId: string;
|
|
4
|
+
exchangesFolderId: string;
|
|
5
|
+
};
|
|
6
|
+
export type SharedDatasetFile = {
|
|
7
|
+
datasetId: string;
|
|
8
|
+
fileId: string;
|
|
9
|
+
name: string;
|
|
10
|
+
canEdit?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type VersionedSharedDataset = SharedDatasetFile & {
|
|
13
|
+
envelope: SharedBackupEnvelopeV1;
|
|
14
|
+
version: string;
|
|
15
|
+
};
|
|
16
|
+
export type SharedExchangeFile = {
|
|
17
|
+
fileId: string;
|
|
18
|
+
exchangeId: string;
|
|
19
|
+
kind: "invitation" | "key-response";
|
|
20
|
+
keyId?: string;
|
|
21
|
+
createdTime?: string;
|
|
22
|
+
};
|
|
23
|
+
export type SharedKeyResponseFile = {
|
|
24
|
+
fileId: string;
|
|
25
|
+
response: SharingPublicKeyResponseV1;
|
|
26
|
+
ownerPermissionId: string;
|
|
27
|
+
};
|
|
28
|
+
export type SharedDatasetPermission = {
|
|
29
|
+
permissionId?: string;
|
|
30
|
+
role: "reader" | "writer";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Client-side transport required by the sharing controller. Implementations
|
|
34
|
+
* may use Google Drive or another provider, but cannot depend on a trusted app
|
|
35
|
+
* backend.
|
|
36
|
+
*/
|
|
37
|
+
export interface SharedBackupTransport {
|
|
38
|
+
ensureStorage(): Promise<SharedBackupStorage>;
|
|
39
|
+
listDatasets(): Promise<SharedDatasetFile[]>;
|
|
40
|
+
readDataset(fileId: string): Promise<VersionedSharedDataset>;
|
|
41
|
+
createDataset(datasetId: string, envelope: SharedBackupEnvelopeV1): Promise<VersionedSharedDataset>;
|
|
42
|
+
writeDataset(current: VersionedSharedDataset, envelope: SharedBackupEnvelopeV1): Promise<VersionedSharedDataset>;
|
|
43
|
+
grantExchangeAccess(emailAddress: string, options?: {
|
|
44
|
+
sendNotificationEmail?: boolean;
|
|
45
|
+
emailMessage?: string;
|
|
46
|
+
}): Promise<{
|
|
47
|
+
drivePermissionId: string;
|
|
48
|
+
appFolderId: string;
|
|
49
|
+
}>;
|
|
50
|
+
createInvitation(invitation: SharingInvitationV1): Promise<string>;
|
|
51
|
+
createKeyResponse(response: SharingPublicKeyResponseV1): Promise<string>;
|
|
52
|
+
listExchanges(options?: {
|
|
53
|
+
exchangeId?: string;
|
|
54
|
+
kind?: SharedExchangeFile["kind"];
|
|
55
|
+
}): Promise<SharedExchangeFile[]>;
|
|
56
|
+
readInvitation(fileId: string): Promise<SharingInvitationV1>;
|
|
57
|
+
readKeyResponse(fileId: string, expectedDrivePermissionId: string): Promise<SharedKeyResponseFile>;
|
|
58
|
+
deleteExchange(fileId: string): Promise<void>;
|
|
59
|
+
setDatasetPermission(fileId: string, emailAddress: string, role: Exclude<SharingRole, "owner" | "admin"> | "admin", options?: {
|
|
60
|
+
existingDirectPermissionId?: string;
|
|
61
|
+
hasInheritedReadAccess?: boolean;
|
|
62
|
+
}): Promise<SharedDatasetPermission>;
|
|
63
|
+
removeDatasetPermission(fileId: string, permissionId: string): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/sharing/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/sharing/transport.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type SharedBackupCodec, type SharedBackupEnvelopeV1, type SharingAcceptanceProvenanceV1, type SharingAccountBindingV1, type SharingDatasetGrantV1, type SharingPublicKeyResponseV1, type SharingPublicKeyV1, type SharingInvitationV1, type SharingRole } from "./index.js";
|
|
2
|
+
export type WebCryptoSharingIdentity = {
|
|
3
|
+
publicKey: SharingPublicKeyV1;
|
|
4
|
+
encryptionPrivateKey: CryptoKey;
|
|
5
|
+
signingPrivateKey: CryptoKey;
|
|
6
|
+
};
|
|
7
|
+
export type SharedBackupParticipantInput = {
|
|
8
|
+
publicKey: SharingPublicKeyV1;
|
|
9
|
+
role: SharingRole;
|
|
10
|
+
accepted?: SharingAcceptanceProvenanceV1;
|
|
11
|
+
};
|
|
12
|
+
export type AcceptedSharingGrantV1 = {
|
|
13
|
+
datasetId: string;
|
|
14
|
+
participant: SharedBackupParticipantInput;
|
|
15
|
+
};
|
|
16
|
+
export type WebCryptoSharingOptions = {
|
|
17
|
+
crypto?: Crypto;
|
|
18
|
+
now?: () => Date;
|
|
19
|
+
randomUUID?: () => string;
|
|
20
|
+
};
|
|
21
|
+
export declare function createWebCryptoSharingIdentity(cryptoImplementation?: Crypto): Promise<WebCryptoSharingIdentity>;
|
|
22
|
+
export declare function createSharingPublicKeyResponseV1(identity: WebCryptoSharingIdentity, input: {
|
|
23
|
+
appId: string;
|
|
24
|
+
exchangeId: string;
|
|
25
|
+
createdAt?: string;
|
|
26
|
+
accountBinding?: SharingAccountBindingV1;
|
|
27
|
+
}, options?: WebCryptoSharingOptions): Promise<SharingPublicKeyResponseV1>;
|
|
28
|
+
export declare function createSharingInvitationV1(identity: WebCryptoSharingIdentity, input: {
|
|
29
|
+
appId: string;
|
|
30
|
+
appFolderId: string;
|
|
31
|
+
exchangeId?: string;
|
|
32
|
+
recipientDrivePermissionId: string;
|
|
33
|
+
requestedGrants: SharingDatasetGrantV1[];
|
|
34
|
+
trustedOwnerKeyId?: string;
|
|
35
|
+
createdAt?: string;
|
|
36
|
+
expiresAt?: string;
|
|
37
|
+
}, options?: WebCryptoSharingOptions): Promise<SharingInvitationV1>;
|
|
38
|
+
export declare function acceptSharingPublicKeyResponseV1(invitationInput: unknown, responseInput: unknown, input: {
|
|
39
|
+
acceptedByKeyId: string;
|
|
40
|
+
drivePermissionId: string;
|
|
41
|
+
acceptedAt?: string;
|
|
42
|
+
googleSubject?: string;
|
|
43
|
+
}, options?: WebCryptoSharingOptions): Promise<AcceptedSharingGrantV1[]>;
|
|
44
|
+
export declare function verifySharingInvitationV1(input: unknown, options?: {
|
|
45
|
+
crypto?: Crypto;
|
|
46
|
+
now?: () => Date;
|
|
47
|
+
}): Promise<SharingInvitationV1>;
|
|
48
|
+
export declare function verifySharingPublicKeyResponseV1(input: unknown, cryptoImplementation?: Crypto): Promise<SharingPublicKeyResponseV1>;
|
|
49
|
+
export declare function createSharedBackupEnvelopeV1<T>(value: T, codec: SharedBackupCodec<T>, identity: WebCryptoSharingIdentity, input: {
|
|
50
|
+
appId: string;
|
|
51
|
+
backupId: string;
|
|
52
|
+
participants: SharedBackupParticipantInput[];
|
|
53
|
+
previous?: SharedBackupEnvelopeV1;
|
|
54
|
+
keyRotation?: {
|
|
55
|
+
previousIdentity: WebCryptoSharingIdentity;
|
|
56
|
+
};
|
|
57
|
+
revisionId?: string;
|
|
58
|
+
createdAt?: string;
|
|
59
|
+
}, options?: WebCryptoSharingOptions): Promise<SharedBackupEnvelopeV1>;
|
|
60
|
+
export declare function verifySharedBackupEnvelopeV1(input: unknown, cryptoImplementation?: Crypto, options?: {
|
|
61
|
+
trustedOwnerKeyId?: string;
|
|
62
|
+
}): Promise<SharedBackupEnvelopeV1>;
|
|
63
|
+
export declare function decryptSharedBackupEnvelopeV1<T>(input: unknown, codec: Pick<SharedBackupCodec<T>, "parse">, identity: WebCryptoSharingIdentity, cryptoImplementation?: Crypto, options?: {
|
|
64
|
+
trustedOwnerKeyId?: string;
|
|
65
|
+
}): Promise<T>;
|
|
66
|
+
export declare function sharingKeyFingerprint(keyId: string): string;
|
|
67
|
+
export declare function createSharingPublicKeyV1(encryptionPublicKey: string, signingPublicKey: string, cryptoImplementation: Crypto): Promise<SharingPublicKeyV1>;
|
|
68
|
+
//# sourceMappingURL=web-crypto.d.ts.map
|