@keyneom/sync-kit 0.1.1 → 0.2.0-rc.1
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 +103 -8
- package/dist/auth/google-web/cache.d.ts +46 -0
- package/dist/auth/google-web/cache.d.ts.map +1 -0
- package/dist/auth/google-web/cache.js +111 -0
- package/dist/auth/google-web/cache.js.map +1 -0
- 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/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/change-detector.d.ts +40 -0
- package/dist/sharing/change-detector.d.ts.map +1 -0
- package/dist/sharing/change-detector.js +96 -0
- package/dist/sharing/change-detector.js.map +1 -0
- package/dist/sharing/checkpoint.d.ts +32 -0
- package/dist/sharing/checkpoint.d.ts.map +1 -0
- package/dist/sharing/checkpoint.js +2 -0
- package/dist/sharing/checkpoint.js.map +1 -0
- package/dist/sharing/controller.d.ts +169 -0
- package/dist/sharing/controller.d.ts.map +1 -0
- package/dist/sharing/controller.js +693 -0
- package/dist/sharing/controller.js.map +1 -0
- package/dist/sharing/index.d.ts +122 -0
- package/dist/sharing/index.d.ts.map +1 -0
- package/dist/sharing/index.js +362 -0
- package/dist/sharing/index.js.map +1 -0
- package/dist/sharing/join.d.ts +56 -0
- package/dist/sharing/join.d.ts.map +1 -0
- package/dist/sharing/join.js +153 -0
- package/dist/sharing/join.js.map +1 -0
- package/dist/sharing/lifecycle.d.ts +20 -0
- package/dist/sharing/lifecycle.d.ts.map +1 -0
- package/dist/sharing/lifecycle.js +55 -0
- package/dist/sharing/lifecycle.js.map +1 -0
- package/dist/sharing/registry-indexeddb.d.ts +21 -0
- package/dist/sharing/registry-indexeddb.d.ts.map +1 -0
- package/dist/sharing/registry-indexeddb.js +60 -0
- package/dist/sharing/registry-indexeddb.js.map +1 -0
- package/dist/sharing/transport.d.ts +75 -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/app-folders.d.ts +19 -0
- package/dist/stores/google-drive/app-folders.d.ts.map +1 -0
- package/dist/stores/google-drive/app-folders.js +38 -0
- package/dist/stores/google-drive/app-folders.js.map +1 -0
- package/dist/stores/google-drive/folder-name.d.ts +16 -0
- package/dist/stores/google-drive/folder-name.d.ts.map +1 -0
- package/dist/stores/google-drive/folder-name.js +37 -0
- package/dist/stores/google-drive/folder-name.js.map +1 -0
- package/dist/stores/google-drive/index.d.ts +149 -1
- package/dist/stores/google-drive/index.d.ts.map +1 -1
- package/dist/stores/google-drive/index.js +399 -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 +57 -0
- package/dist/stores/google-drive/sharing.d.ts.map +1 -0
- package/dist/stores/google-drive/sharing.js +325 -0
- package/dist/stores/google-drive/sharing.js.map +1 -0
- package/package.json +78 -10
package/README.md
CHANGED
|
@@ -7,12 +7,39 @@ The package extracts the behavior already implemented by EasyBC and Family
|
|
|
7
7
|
Chores. It does not own application schemas, merge policy, persistence, UI, or
|
|
8
8
|
lifecycle policy.
|
|
9
9
|
|
|
10
|
+
## Backend-independent by design
|
|
11
|
+
|
|
12
|
+
A primary package objective is to let a static frontend provide encrypted sync
|
|
13
|
+
and multi-user sharing without an application-owned trusted backend. The
|
|
14
|
+
complete interactive flow must be implementable with browser cryptography and
|
|
15
|
+
passkeys, Google Identity Services, and Google Drive:
|
|
16
|
+
|
|
17
|
+
- no server-held client secret or refresh token;
|
|
18
|
+
- no application database, certificate signer, or authorization service;
|
|
19
|
+
- no server required to encrypt, decrypt, invite, accept, reconcile access, or
|
|
20
|
+
publish a signed revision.
|
|
21
|
+
|
|
22
|
+
Google remains the OAuth, identity, and storage provider. Participant keys,
|
|
23
|
+
signed access-control history, and the pinned owner key remain the
|
|
24
|
+
cryptographic authority. An optional backend adapter may add unattended jobs,
|
|
25
|
+
notifications, or operational automation, but package correctness and
|
|
26
|
+
interoperability must never depend on one.
|
|
27
|
+
|
|
28
|
+
Backendless browser deployments operate while the app is open and may need
|
|
29
|
+
user interaction when OAuth access expires or a passkey ceremony is required.
|
|
30
|
+
That limitation must not be hidden by broad Drive scopes or by making a
|
|
31
|
+
backend mandatory.
|
|
32
|
+
|
|
10
33
|
## Status
|
|
11
34
|
|
|
12
|
-
Version `0.1.
|
|
13
|
-
|
|
35
|
+
Version `0.1.1` was published to npm on 2026-06-30. It removes the
|
|
36
|
+
application-specific runtime presets from `0.1.0` and keeps compatibility
|
|
14
37
|
profiles consumer-owned.
|
|
15
38
|
|
|
39
|
+
Version `0.2.0-rc.1` publishes shared encrypted backups, Tier A background
|
|
40
|
+
detection helpers, and the Android sharing port. Live Google validation and
|
|
41
|
+
one external consumer integration remain release gates for a stable `0.2.0`.
|
|
42
|
+
|
|
16
43
|
The tests in this repository cover frozen compatibility vectors, mocked
|
|
17
44
|
browser providers, package orchestration, and installation/imports from the
|
|
18
45
|
packed tarball. They do not install this package into EasyBC, Family Chores, or
|
|
@@ -87,12 +114,30 @@ Available exports:
|
|
|
87
114
|
optional gzip, and canonical JSON/AAD helpers
|
|
88
115
|
- `/snapshot` — serialized snapshot synchronization
|
|
89
116
|
- `/snapshot/lifecycle` — opt-in browser lifecycle binding
|
|
117
|
+
- `/sharing` — browser-independent shared-backup protocol types, validation,
|
|
118
|
+
roles, invitations, signed multi-recipient envelopes, and join-link helpers
|
|
119
|
+
- `/sharing/web-crypto` — P-256 identities, ECDH key grants, signed revisions,
|
|
120
|
+
invitation/key-response proofs, and decryption
|
|
121
|
+
- `/sharing/controller` — headless multi-dataset orchestration, owner pinning,
|
|
122
|
+
serialized writes, exchange processing, roles, revocation, Drive permission
|
|
123
|
+
reconciliation, and optional IndexedDB registry persistence
|
|
124
|
+
- `/sharing/web-passkey` — passkey-encrypted sharing identities with
|
|
125
|
+
non-extractable runtime keys and optional IndexedDB ciphertext storage
|
|
126
|
+
- `/sharing/account-binding` — backendless Google ID-token and WebAuthn
|
|
127
|
+
challenge binding, signature verification, and account provenance
|
|
90
128
|
- `/keys/web-passkey` — WebAuthn PRF keys with exact credential selection,
|
|
91
129
|
unlock coalescing, raw-secret zeroing, and explicit cache clearing
|
|
92
130
|
- `/auth/google-web` — Google Identity Services with memory-only token reuse,
|
|
93
131
|
expiry skew, request coalescing, and explicit invalidation
|
|
94
|
-
- `/
|
|
95
|
-
|
|
132
|
+
- `/auth/google-web/identity` — uncached nonce-bound Google ID tokens for
|
|
133
|
+
account-binding exchanges
|
|
134
|
+
- `/stores/google-drive` — low-level `appDataFolder` objects, a typed snapshot
|
|
135
|
+
wrapper, normal-Drive folder/per-file stores, folder-name helpers, and
|
|
136
|
+
accessible app-folder discovery
|
|
137
|
+
- `/stores/google-drive/sharing` — managed app/exchange folders, conditional
|
|
138
|
+
dataset writes, provenance checks, and per-dataset permissions
|
|
139
|
+
- `/stores/google-drive/picker` — explicit folder Picker and Drive Open-with
|
|
140
|
+
state parsing
|
|
96
141
|
|
|
97
142
|
The root, `/core`, `/crypto`, and `/snapshot` expose no browser adapter.
|
|
98
143
|
Browser globals and script loading are used only after an explicit browser
|
|
@@ -136,12 +181,15 @@ matches the remote value.
|
|
|
136
181
|
The wire protocol is the native compatibility boundary; the browser adapter is
|
|
137
182
|
not.
|
|
138
183
|
|
|
139
|
-
-
|
|
140
|
-
|
|
184
|
+
- **Android:** `com.keyneom:sync-kit-android` (module `android/synckit`) provides
|
|
185
|
+
private v1 snapshot crypto, `SnapshotSyncController`, Drive `appDataFolder`
|
|
186
|
+
storage, and Credential Manager passkey PRF — the same contracts as the npm
|
|
187
|
+
`/crypto`, `/snapshot`, and appData store paths. Published to
|
|
188
|
+
[GitHub Packages](https://github.com/keyneom/sync-kit/packages). See
|
|
189
|
+
[android-library.md](docs/android-library.md).
|
|
190
|
+
- Shared backups (`/sharing`) are TypeScript-only for now.
|
|
141
191
|
- React Native and other JavaScript-native runtimes can inject a
|
|
142
192
|
`CryptoBackend<K>` backed by platform crypto.
|
|
143
|
-
- Kotlin and Swift applications implement the small key, authorization, store,
|
|
144
|
-
and crypto contracts natively while consuming the shared fixtures.
|
|
145
193
|
- Tauri applications can use `/core`, `/crypto`, and the low-level Google Drive
|
|
146
194
|
object store, but should perform OAuth in the system browser through
|
|
147
195
|
Authorization Code + PKCE.
|
|
@@ -149,6 +197,53 @@ not.
|
|
|
149
197
|
See [native consumer guidance](docs/native-consumers.md) and the exact
|
|
150
198
|
[v1 compatibility contract](docs/compatibility-v1.md).
|
|
151
199
|
|
|
200
|
+
## Shared encrypted backups
|
|
201
|
+
|
|
202
|
+
The experimental sharing surface encrypts each revision with a fresh content
|
|
203
|
+
key, wraps that key to every participant's ECDH public key, and accepts writes
|
|
204
|
+
only when an owner/admin/writer signs the complete revision. Viewers receive a
|
|
205
|
+
decryption grant but are not authorized revision signers.
|
|
206
|
+
|
|
207
|
+
Sharing follows the package-wide backend-independent objective above. A static
|
|
208
|
+
frontend can execute the protocol directly against Google Drive; an
|
|
209
|
+
application-owned server is neither a trust root nor a deployment requirement.
|
|
210
|
+
|
|
211
|
+
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.
|
|
215
|
+
|
|
216
|
+
New integrations can use `GoogleDriveFileSnapshotStore`, which defaults to an
|
|
217
|
+
app-owned top-level folder:
|
|
218
|
+
|
|
219
|
+
```text
|
|
220
|
+
Sync Kit - <appId>/
|
|
221
|
+
<consumer filename>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The folder name can be overridden. A selected parent folder is optional rather
|
|
225
|
+
than part of the default flow. Existing v1 consumers continue using
|
|
226
|
+
`GoogleDriveSnapshotStore` and `appDataFolder` until they explicitly migrate.
|
|
227
|
+
|
|
228
|
+
For shared data, the default policy makes the app folder readable to all app
|
|
229
|
+
participants, makes its `exchanges/` child writable, and upgrades selected
|
|
230
|
+
participants to writer on individual dataset files. This exposes filenames,
|
|
231
|
+
metadata, and ciphertext to app participants while cryptographic grants control
|
|
232
|
+
decryption. Applications needing metadata isolation can instead use direct file
|
|
233
|
+
sharing or limited-access subfolders.
|
|
234
|
+
|
|
235
|
+
See the [protocol and threat model](docs/shared-backups.md),
|
|
236
|
+
[authoritative implementation handoff](docs/sharing-implementation-handoff.md),
|
|
237
|
+
[consumer responsibilities](docs/consumer-responsibilities.md), and
|
|
238
|
+
[background notifications](docs/background-notifications.md). The phased gates
|
|
239
|
+
remain in the [sharing execution plan](docs/sharing-execution-plan.md). The crypto and
|
|
240
|
+
per-file transport, Picker, protected identity, account binding, signed
|
|
241
|
+
ancestry/fork policy, key rotation, and controller primitives are implemented.
|
|
242
|
+
The same sharing fixture is consumed by Java, and the packed package completes
|
|
243
|
+
an exchange/decryption smoke test. Live Google OAuth/Picker, Drive
|
|
244
|
+
conditional-write/permission validation, and adoption in an external consumer
|
|
245
|
+
remain release gates.
|
|
246
|
+
|
|
152
247
|
## Compatibility and isolation
|
|
153
248
|
|
|
154
249
|
Each application owns the profile that preserves its filename, AAD, HKDF
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Authorization, AuthorizationProvider } from "../../core/types.js";
|
|
2
|
+
export type CachedAuthorizationRecord = {
|
|
3
|
+
profileId: string;
|
|
4
|
+
accessToken: string;
|
|
5
|
+
expiresAt: number;
|
|
6
|
+
accountHint?: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Opt-in persistence for short-lived Google access tokens used by Tier A
|
|
10
|
+
* background polling. Not enabled by default; memory-only auth remains the
|
|
11
|
+
* default policy.
|
|
12
|
+
*/
|
|
13
|
+
export declare class IndexedDbAuthorizationCache {
|
|
14
|
+
private readonly options;
|
|
15
|
+
constructor(options?: {
|
|
16
|
+
databaseName?: string;
|
|
17
|
+
storeName?: string;
|
|
18
|
+
indexedDB?: IDBFactory;
|
|
19
|
+
});
|
|
20
|
+
load(profileId: string): Promise<CachedAuthorizationRecord | null>;
|
|
21
|
+
save(record: CachedAuthorizationRecord): Promise<void>;
|
|
22
|
+
delete(profileId: string): Promise<void>;
|
|
23
|
+
private transaction;
|
|
24
|
+
private open;
|
|
25
|
+
private storeName;
|
|
26
|
+
}
|
|
27
|
+
export type CachingAuthorizationProviderOptions = {
|
|
28
|
+
profileId: string;
|
|
29
|
+
inner: AuthorizationProvider<Authorization>;
|
|
30
|
+
cache: IndexedDbAuthorizationCache;
|
|
31
|
+
accountHint?: string;
|
|
32
|
+
expirySkewMs?: number;
|
|
33
|
+
now?: () => number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Wraps an authorization provider and mirrors valid access tokens into the
|
|
37
|
+
* opt-in IndexedDB cache for service-worker polling.
|
|
38
|
+
*/
|
|
39
|
+
export declare class CachingAuthorizationProvider implements AuthorizationProvider<Authorization> {
|
|
40
|
+
private readonly options;
|
|
41
|
+
constructor(options: CachingAuthorizationProviderOptions);
|
|
42
|
+
authorize(): Promise<Authorization>;
|
|
43
|
+
authorizeFromCache(): Promise<Authorization | null>;
|
|
44
|
+
clear(): void;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/auth/google-web/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGhF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,qBAAa,2BAA2B;IAEpC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,UAAU,CAAC;KACnB;IAGF,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC;IAelE,IAAI,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtD,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAIhC,WAAW;IAoBzB,OAAO,CAAC,IAAI;IAoCZ,OAAO,CAAC,SAAS;CAGlB;AAED,MAAM,MAAM,mCAAmC,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,qBAAqB,CAAC,aAAa,CAAC,CAAC;IAC5C,KAAK,EAAE,2BAA2B,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,qBAAa,4BACX,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAEnC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,mCAAmC;IAEnE,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;IAmBnC,kBAAkB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAezD,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { SyncKitError } from "../../core/errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Opt-in persistence for short-lived Google access tokens used by Tier A
|
|
4
|
+
* background polling. Not enabled by default; memory-only auth remains the
|
|
5
|
+
* default policy.
|
|
6
|
+
*/
|
|
7
|
+
export class IndexedDbAuthorizationCache {
|
|
8
|
+
options;
|
|
9
|
+
constructor(options = {}) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
async load(profileId) {
|
|
13
|
+
const stored = await this.transaction("readonly", (store) => store.get(profileId));
|
|
14
|
+
if (!stored || typeof stored !== "object")
|
|
15
|
+
return null;
|
|
16
|
+
const record = stored;
|
|
17
|
+
if (typeof record.accessToken !== "string" ||
|
|
18
|
+
typeof record.expiresAt !== "number") {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return structuredClone(record);
|
|
22
|
+
}
|
|
23
|
+
async save(record) {
|
|
24
|
+
await this.transaction("readwrite", (store) => store.put(structuredClone(record)));
|
|
25
|
+
}
|
|
26
|
+
async delete(profileId) {
|
|
27
|
+
await this.transaction("readwrite", (store) => store.delete(profileId));
|
|
28
|
+
}
|
|
29
|
+
async transaction(mode, operation) {
|
|
30
|
+
const database = await this.open();
|
|
31
|
+
return new Promise((resolve, reject) => {
|
|
32
|
+
const transaction = database.transaction(this.storeName(), mode);
|
|
33
|
+
const request = operation(transaction.objectStore(this.storeName()));
|
|
34
|
+
request.onsuccess = () => resolve(request.result);
|
|
35
|
+
request.onerror = () => reject(new SyncKitError("state", "IndexedDB authorization cache failed.", {
|
|
36
|
+
cause: request.error,
|
|
37
|
+
}));
|
|
38
|
+
transaction.oncomplete = () => database.close();
|
|
39
|
+
transaction.onabort = () => database.close();
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
open() {
|
|
43
|
+
const indexedDBImplementation = this.options.indexedDB ??
|
|
44
|
+
(typeof indexedDB === "undefined" ? undefined : indexedDB);
|
|
45
|
+
if (!indexedDBImplementation) {
|
|
46
|
+
return Promise.reject(new SyncKitError("configuration", "IndexedDB is required for authorization cache storage."));
|
|
47
|
+
}
|
|
48
|
+
return new Promise((resolve, reject) => {
|
|
49
|
+
const request = indexedDBImplementation.open(this.options.databaseName ?? "sync-kit-auth-cache", 1);
|
|
50
|
+
request.onupgradeneeded = () => {
|
|
51
|
+
if (!request.result.objectStoreNames.contains(this.storeName())) {
|
|
52
|
+
request.result.createObjectStore(this.storeName(), {
|
|
53
|
+
keyPath: "profileId",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
request.onsuccess = () => resolve(request.result);
|
|
58
|
+
request.onerror = () => reject(new SyncKitError("state", "IndexedDB authorization cache could not be opened.", { cause: request.error }));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
storeName() {
|
|
62
|
+
return this.options.storeName ?? "google-authorization";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Wraps an authorization provider and mirrors valid access tokens into the
|
|
67
|
+
* opt-in IndexedDB cache for service-worker polling.
|
|
68
|
+
*/
|
|
69
|
+
export class CachingAuthorizationProvider {
|
|
70
|
+
options;
|
|
71
|
+
constructor(options) {
|
|
72
|
+
this.options = options;
|
|
73
|
+
}
|
|
74
|
+
async authorize() {
|
|
75
|
+
const authorization = await this.options.inner.authorize();
|
|
76
|
+
const now = this.options.now?.() ?? Date.now();
|
|
77
|
+
const skew = this.options.expirySkewMs ?? 60_000;
|
|
78
|
+
const expiresAt = authorization.expiresAt ?? now + 3_600_000;
|
|
79
|
+
if (expiresAt > now + skew) {
|
|
80
|
+
await this.options.cache.save({
|
|
81
|
+
profileId: this.options.profileId,
|
|
82
|
+
accessToken: authorization.accessToken,
|
|
83
|
+
expiresAt,
|
|
84
|
+
...(this.options.accountHint
|
|
85
|
+
? { accountHint: this.options.accountHint }
|
|
86
|
+
: {}),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return authorization;
|
|
90
|
+
}
|
|
91
|
+
async authorizeFromCache() {
|
|
92
|
+
const record = await this.options.cache.load(this.options.profileId);
|
|
93
|
+
if (!record)
|
|
94
|
+
return null;
|
|
95
|
+
const now = this.options.now?.() ?? Date.now();
|
|
96
|
+
const skew = this.options.expirySkewMs ?? 60_000;
|
|
97
|
+
if (record.expiresAt <= now + skew) {
|
|
98
|
+
await this.options.cache.delete(this.options.profileId);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
accessToken: record.accessToken,
|
|
103
|
+
expiresAt: record.expiresAt,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
clear() {
|
|
107
|
+
this.options.inner.clear();
|
|
108
|
+
void this.options.cache.delete(this.options.profileId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/auth/google-web/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
type GoogleCredentialResponse = {
|
|
2
|
+
credential?: string;
|
|
3
|
+
};
|
|
4
|
+
type PromptMomentNotification = {
|
|
5
|
+
isNotDisplayed(): boolean;
|
|
6
|
+
isSkippedMoment(): boolean;
|
|
7
|
+
getNotDisplayedReason?(): string;
|
|
8
|
+
getSkippedReason?(): string;
|
|
9
|
+
};
|
|
10
|
+
type GoogleIdentityWindow = Window & {
|
|
11
|
+
google?: {
|
|
12
|
+
accounts?: {
|
|
13
|
+
id?: {
|
|
14
|
+
initialize(options: {
|
|
15
|
+
client_id: string;
|
|
16
|
+
nonce: string;
|
|
17
|
+
callback(response: GoogleCredentialResponse): void;
|
|
18
|
+
auto_select?: boolean;
|
|
19
|
+
cancel_on_tap_outside?: boolean;
|
|
20
|
+
use_fedcm_for_prompt?: boolean;
|
|
21
|
+
}): void;
|
|
22
|
+
prompt(callback?: (notification: PromptMomentNotification) => void): void;
|
|
23
|
+
cancel(): void;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
export type GoogleWebIdentityOptions = {
|
|
29
|
+
clientId: string;
|
|
30
|
+
window?: GoogleIdentityWindow;
|
|
31
|
+
document?: Document;
|
|
32
|
+
useFedCm?: boolean;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Requests a Google-signed ID token whose nonce is the sharing-account
|
|
36
|
+
* binding challenge. The token is returned to the caller and is not cached.
|
|
37
|
+
*/
|
|
38
|
+
export declare class GoogleWebIdentityProvider {
|
|
39
|
+
private readonly options;
|
|
40
|
+
private scriptPromise;
|
|
41
|
+
constructor(options: GoogleWebIdentityOptions);
|
|
42
|
+
requestIdToken(nonce: string): Promise<string>;
|
|
43
|
+
cancel(): void;
|
|
44
|
+
private loadScript;
|
|
45
|
+
private browserWindow;
|
|
46
|
+
private browserDocument;
|
|
47
|
+
}
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../src/auth/google-web/identity.ts"],"names":[],"mappings":"AAEA,KAAK,wBAAwB,GAAG;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,cAAc,IAAI,OAAO,CAAC;IAC1B,eAAe,IAAI,OAAO,CAAC;IAC3B,qBAAqB,CAAC,IAAI,MAAM,CAAC;IACjC,gBAAgB,CAAC,IAAI,MAAM,CAAC;CAC7B,CAAC;AAEF,KAAK,oBAAoB,GAAG,MAAM,GAAG;IACnC,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE;YACT,EAAE,CAAC,EAAE;gBACH,UAAU,CAAC,OAAO,EAAE;oBAClB,SAAS,EAAE,MAAM,CAAC;oBAClB,KAAK,EAAE,MAAM,CAAC;oBACd,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;oBACnD,WAAW,CAAC,EAAE,OAAO,CAAC;oBACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;oBAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;iBAChC,GAAG,IAAI,CAAC;gBACT,MAAM,CACJ,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,wBAAwB,KAAK,IAAI,GAC1D,IAAI,CAAC;gBACR,MAAM,IAAI,IAAI,CAAC;aAChB,CAAC;SACH,CAAC;KACH,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,qBAAa,yBAAyB;IAGxB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,aAAa,CAA8B;gBAEtB,OAAO,EAAE,wBAAwB;IAMxD,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiDpD,MAAM,IAAI,IAAI;IAId,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,eAAe;CAYxB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { SyncKitError } from "../../core/errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Requests a Google-signed ID token whose nonce is the sharing-account
|
|
4
|
+
* binding challenge. The token is returned to the caller and is not cached.
|
|
5
|
+
*/
|
|
6
|
+
export class GoogleWebIdentityProvider {
|
|
7
|
+
options;
|
|
8
|
+
scriptPromise = null;
|
|
9
|
+
constructor(options) {
|
|
10
|
+
this.options = options;
|
|
11
|
+
if (!options.clientId.trim()) {
|
|
12
|
+
throw new TypeError("clientId must not be empty.");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async requestIdToken(nonce) {
|
|
16
|
+
if (!nonce.trim())
|
|
17
|
+
throw new TypeError("nonce must not be empty.");
|
|
18
|
+
await this.loadScript();
|
|
19
|
+
const identity = this.browserWindow().google?.accounts?.id;
|
|
20
|
+
if (!identity) {
|
|
21
|
+
throw new SyncKitError("authorization", "Google identity services are unavailable.");
|
|
22
|
+
}
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
let settled = false;
|
|
25
|
+
const fail = (message) => {
|
|
26
|
+
if (settled)
|
|
27
|
+
return;
|
|
28
|
+
settled = true;
|
|
29
|
+
reject(new SyncKitError("authorization", message));
|
|
30
|
+
};
|
|
31
|
+
identity.initialize({
|
|
32
|
+
client_id: this.options.clientId,
|
|
33
|
+
nonce,
|
|
34
|
+
auto_select: false,
|
|
35
|
+
cancel_on_tap_outside: true,
|
|
36
|
+
use_fedcm_for_prompt: this.options.useFedCm ?? true,
|
|
37
|
+
callback: (response) => {
|
|
38
|
+
if (settled)
|
|
39
|
+
return;
|
|
40
|
+
if (!response.credential) {
|
|
41
|
+
fail("Google did not return an identity token.");
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
settled = true;
|
|
45
|
+
resolve(response.credential);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
identity.prompt((notification) => {
|
|
49
|
+
if (notification.isNotDisplayed()) {
|
|
50
|
+
fail(notification.getNotDisplayedReason?.() ??
|
|
51
|
+
"Google sign-in could not be displayed.");
|
|
52
|
+
}
|
|
53
|
+
else if (notification.isSkippedMoment()) {
|
|
54
|
+
fail(notification.getSkippedReason?.() ??
|
|
55
|
+
"Google sign-in was skipped.");
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
cancel() {
|
|
61
|
+
this.browserWindow().google?.accounts?.id?.cancel();
|
|
62
|
+
}
|
|
63
|
+
loadScript() {
|
|
64
|
+
if (this.browserWindow().google?.accounts?.id) {
|
|
65
|
+
return Promise.resolve();
|
|
66
|
+
}
|
|
67
|
+
if (this.scriptPromise)
|
|
68
|
+
return this.scriptPromise;
|
|
69
|
+
this.scriptPromise = new Promise((resolve, reject) => {
|
|
70
|
+
const script = this.browserDocument().createElement("script");
|
|
71
|
+
script.src = "https://accounts.google.com/gsi/client";
|
|
72
|
+
script.async = true;
|
|
73
|
+
script.defer = true;
|
|
74
|
+
script.onload = () => resolve();
|
|
75
|
+
script.onerror = () => {
|
|
76
|
+
this.scriptPromise = null;
|
|
77
|
+
reject(new SyncKitError("authorization", "Google identity services could not be loaded."));
|
|
78
|
+
};
|
|
79
|
+
this.browserDocument().head.append(script);
|
|
80
|
+
});
|
|
81
|
+
return this.scriptPromise;
|
|
82
|
+
}
|
|
83
|
+
browserWindow() {
|
|
84
|
+
const value = this.options.window ??
|
|
85
|
+
(typeof window === "undefined"
|
|
86
|
+
? undefined
|
|
87
|
+
: window);
|
|
88
|
+
if (!value) {
|
|
89
|
+
throw new SyncKitError("configuration", "Google identity requires a browser window.");
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
browserDocument() {
|
|
94
|
+
const value = this.options.document ??
|
|
95
|
+
(typeof document === "undefined" ? undefined : document);
|
|
96
|
+
if (!value) {
|
|
97
|
+
throw new SyncKitError("configuration", "Google identity requires a browser document.");
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../src/auth/google-web/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Authorization, AuthorizationProvider } from "../../core/types.js";
|
|
2
2
|
export declare const GOOGLE_DRIVE_APPDATA_SCOPE = "https://www.googleapis.com/auth/drive.appdata";
|
|
3
|
+
export declare const GOOGLE_DRIVE_FILE_SCOPE = "https://www.googleapis.com/auth/drive.file";
|
|
3
4
|
type TokenResponse = {
|
|
4
5
|
access_token?: string;
|
|
5
6
|
expires_in?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/google-web/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,0BAA0B,kDACU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/google-web/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,0BAA0B,kDACU,CAAC;AAClD,eAAO,MAAM,uBAAuB,+CACU,CAAC;AAE/C,KAAK,aAAa,GAAG;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,WAAW,GAAG;IACjB,kBAAkB,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACzD,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,QAAQ,EAAE;QACR,MAAM,EAAE;YACN,eAAe,CAAC,MAAM,EAAE;gBACtB,SAAS,EAAE,MAAM,CAAC;gBAClB,KAAK,EAAE,MAAM,CAAC;gBACd,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;gBACxC,cAAc,CAAC,CAAC,KAAK,EAAE;oBAAE,IAAI,CAAC,EAAE,MAAM,CAAA;iBAAE,GAAG,IAAI,CAAC;aACjD,GAAG,WAAW,CAAC;SACjB,CAAC;KACH,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG;QAAE,MAAM,CAAC,EAAE,cAAc,CAAA;KAAE,CAAC;IAC9C,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF,qBAAa,8BACX,YAAW,qBAAqB,CAAC,aAAa,CAAC;IAOnC,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,MAAM,CAAuD;IACrE,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,UAAU,CAAK;gBAEM,OAAO,EAAE,6BAA6B;IAE7D,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;IAwBzC,KAAK,IAAI,IAAI;YAMC,YAAY;IAyD1B,OAAO,CAAC,UAAU;IAuBlB,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,QAAQ;CAYjB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SyncKitError } from "../../core/errors.js";
|
|
2
2
|
export const GOOGLE_DRIVE_APPDATA_SCOPE = "https://www.googleapis.com/auth/drive.appdata";
|
|
3
|
+
export const GOOGLE_DRIVE_FILE_SCOPE = "https://www.googleapis.com/auth/drive.file";
|
|
3
4
|
export class GoogleWebAuthorizationProvider {
|
|
4
5
|
options;
|
|
5
6
|
scriptPromise = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/google-web/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,CAAC,MAAM,0BAA0B,GACrC,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/google-web/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type SyncErrorCode = "authorization" | "compatibility" | "configuration" | "crypto" | "decompression" | "key" | "not-found" | "provider" | "serialization" | "state";
|
|
1
|
+
export type SyncErrorCode = "authorization" | "compatibility" | "configuration" | "conflict" | "crypto" | "decompression" | "key" | "not-found" | "provider" | "serialization" | "state";
|
|
2
2
|
export declare class SyncKitError extends Error {
|
|
3
3
|
readonly code: SyncErrorCode;
|
|
4
4
|
readonly status: number | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,eAAe,GACf,eAAe,GACf,QAAQ,GACR,eAAe,GACf,KAAK,GACL,WAAW,GACX,UAAU,GACV,eAAe,GACf,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,eAAe,GACf,eAAe,GACf,UAAU,GACV,QAAQ,GACR,eAAe,GACf,KAAK,GACL,WAAW,GACX,UAAU,GACV,eAAe,GACf,OAAO,CAAC;AAgBZ,qBAAa,YAAa,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;gBAGlC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;CAOnD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAUpE;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,GACd,YAAY,CAId"}
|
package/dist/core/errors.js
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
const SYNC_ERROR_CODES = new Set([
|
|
2
|
+
"authorization",
|
|
3
|
+
"compatibility",
|
|
4
|
+
"configuration",
|
|
5
|
+
"conflict",
|
|
6
|
+
"crypto",
|
|
7
|
+
"decompression",
|
|
8
|
+
"key",
|
|
9
|
+
"not-found",
|
|
10
|
+
"provider",
|
|
11
|
+
"serialization",
|
|
12
|
+
"state",
|
|
13
|
+
]);
|
|
1
14
|
export class SyncKitError extends Error {
|
|
2
15
|
code;
|
|
3
16
|
status;
|
|
@@ -9,7 +22,15 @@ export class SyncKitError extends Error {
|
|
|
9
22
|
}
|
|
10
23
|
}
|
|
11
24
|
export function isSyncKitError(value) {
|
|
12
|
-
|
|
25
|
+
if (value instanceof SyncKitError)
|
|
26
|
+
return true;
|
|
27
|
+
if (typeof value !== "object" || value === null)
|
|
28
|
+
return false;
|
|
29
|
+
const candidate = value;
|
|
30
|
+
return (candidate.name === "SyncKitError" &&
|
|
31
|
+
typeof candidate.message === "string" &&
|
|
32
|
+
typeof candidate.code === "string" &&
|
|
33
|
+
SYNC_ERROR_CODES.has(candidate.code));
|
|
13
34
|
}
|
|
14
35
|
export function asSyncKitError(value, code, message) {
|
|
15
36
|
return isSyncKitError(value)
|
package/dist/core/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAaA,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAgB;IAC9C,eAAe;IACf,eAAe;IACf,eAAe;IACf,UAAU;IACV,QAAQ;IACR,eAAe;IACf,KAAK;IACL,WAAW;IACX,UAAU;IACV,eAAe;IACf,OAAO;CACR,CAAC,CAAC;AAEH,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAgB;IACpB,MAAM,CAAqB;IAEpC,YACE,IAAmB,EACnB,OAAe,EACf,UAA8C,EAAE;QAEhD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,KAAK,YAAY,YAAY;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,SAAS,GAAG,KAA8D,CAAC;IACjF,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,cAAc;QACjC,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;QACrC,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;QAClC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAqB,CAAC,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,KAAc,EACd,IAAmB,EACnB,OAAe;IAEf,OAAO,cAAc,CAAC,KAAK,CAAC;QAC1B,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,IAAI,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
export declare function canonicalJson(value: unknown): string;
|
|
2
2
|
export declare function canonicalAad(value: unknown): Uint8Array;
|
|
3
|
+
/**
|
|
4
|
+
* Compares strings by UTF-16 code units so canonicalization is independent of
|
|
5
|
+
* the host locale and matches Java String.compareTo.
|
|
6
|
+
*/
|
|
7
|
+
export declare function compareUtf16CodeUnits(left: string, right: string): number;
|
|
3
8
|
//# sourceMappingURL=canonical.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAEvD"}
|
|
1
|
+
{"version":3,"file":"canonical.d.ts","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAEvD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzE"}
|
package/dist/crypto/canonical.js
CHANGED
|
@@ -5,6 +5,13 @@ export function canonicalJson(value) {
|
|
|
5
5
|
export function canonicalAad(value) {
|
|
6
6
|
return new TextEncoder().encode(canonicalJson(value));
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* Compares strings by UTF-16 code units so canonicalization is independent of
|
|
10
|
+
* the host locale and matches Java String.compareTo.
|
|
11
|
+
*/
|
|
12
|
+
export function compareUtf16CodeUnits(left, right) {
|
|
13
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
14
|
+
}
|
|
8
15
|
function canonicalValue(value) {
|
|
9
16
|
if (value === null ||
|
|
10
17
|
typeof value === "string" ||
|
|
@@ -22,7 +29,7 @@ function canonicalValue(value) {
|
|
|
22
29
|
if (typeof value === "object") {
|
|
23
30
|
return Object.fromEntries(Object.entries(value)
|
|
24
31
|
.filter(([, child]) => child !== undefined)
|
|
25
|
-
.sort(([left], [right]) => left
|
|
32
|
+
.sort(([left], [right]) => compareUtf16CodeUnits(left, right))
|
|
26
33
|
.map(([key, child]) => [key, canonicalValue(child)]));
|
|
27
34
|
}
|
|
28
35
|
throw new SyncKitError("serialization", `Canonical JSON does not support ${typeof value}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,CACpB,eAAe,EACf,qDAAqD,CACtD,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;aAC1C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"canonical.js","sourceRoot":"","sources":["../../src/crypto/canonical.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY,EAAE,KAAa;IAC/D,OAAO,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACpC,IACE,KAAK,KAAK,IAAI;QACd,OAAO,KAAK,KAAK,QAAQ;QACzB,OAAO,KAAK,KAAK,SAAS,EAC1B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,YAAY,CACpB,eAAe,EACf,qDAAqD,CACtD,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC3D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;aAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;aAC1C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;aAC7D,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CACvD,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,YAAY,CACpB,eAAe,EACf,mCAAmC,OAAO,KAAK,GAAG,CACnD,CAAC;AACJ,CAAC"}
|