@tinycloud/node-sdk 3.6.2-beta.0 → 3.7.0-beta.2
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/dist/{TinyCloudNode--OyL6lZh.d.ts → TinyCloudNode-CclYdOh4.d.ts} +15 -6
- package/dist/{TinyCloudNode-BMi72EIk.d.cts → TinyCloudNode-u_PobKS1.d.cts} +15 -6
- package/dist/{authority-U0m7P2TE.d.cts → authority-CI3qRIcu.d.cts} +1 -1
- package/dist/{authority-DSG538B7.d.ts → authority-OZr9meoT.d.ts} +1 -1
- package/dist/core.cjs +63 -30
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +67 -31
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +63 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +67 -31
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +2 -2
- package/dist/replication/authority.d.ts +2 -2
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -21713,17 +21713,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21713
21713
|
throw new Error("WASM binding does not support invokeAny");
|
|
21714
21714
|
}
|
|
21715
21715
|
const routedEntries = entries;
|
|
21716
|
-
const
|
|
21717
|
-
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
21718
|
-
return operation ? [operation] : [];
|
|
21719
|
-
});
|
|
21720
|
-
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
21721
|
-
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
21722
|
-
if (authorityCid !== void 0 && !explicitGrant) {
|
|
21723
|
-
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
21724
|
-
}
|
|
21725
|
-
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
21726
|
-
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
21716
|
+
const { session: invocationSession, grant } = this.selectInvokeAnySession(session, entries);
|
|
21727
21717
|
const caveatPreservingEntries = routedEntries.map(({ revokeAuthorityCid: _cid, ...entry }) => {
|
|
21728
21718
|
const requested = this.operationFromInvokeAnyEntry(entry);
|
|
21729
21719
|
const granted = grant && requested && grant.operations.find(
|
|
@@ -21961,6 +21951,27 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21961
21951
|
get siweDomain() {
|
|
21962
21952
|
return this.config.domain ?? "app.tinycloud.xyz";
|
|
21963
21953
|
}
|
|
21954
|
+
/**
|
|
21955
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
21956
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
21957
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
21958
|
+
* invocation must use this session's key.
|
|
21959
|
+
*/
|
|
21960
|
+
selectInvokeAnySession(session, entries) {
|
|
21961
|
+
const routedEntries = entries;
|
|
21962
|
+
const operations = routedEntries.flatMap((entry) => {
|
|
21963
|
+
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
21964
|
+
return operation ? [operation] : [];
|
|
21965
|
+
});
|
|
21966
|
+
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
21967
|
+
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
21968
|
+
if (authorityCid !== void 0 && !explicitGrant) {
|
|
21969
|
+
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
21970
|
+
}
|
|
21971
|
+
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
21972
|
+
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
21973
|
+
return { session: invocationSession, grant };
|
|
21974
|
+
}
|
|
21964
21975
|
/**
|
|
21965
21976
|
* SharingService for receive-only access (no session required), bound to the
|
|
21966
21977
|
* current service graph. This lets session-only users receive sharing links
|
|
@@ -24380,7 +24391,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24380
24391
|
async bindInvocationAudience(authorization, audience) {
|
|
24381
24392
|
const session = this.currentTinyCloudSession() ?? this._activeServiceSession;
|
|
24382
24393
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
24383
|
-
|
|
24394
|
+
const payload = JSON.parse(
|
|
24395
|
+
new TextDecoder().decode(base64UrlDecode(authorization.split(".")[1] ?? ""))
|
|
24396
|
+
);
|
|
24397
|
+
const did = (value) => String(value).split("#", 1)[0];
|
|
24398
|
+
const signer = [session, ...this.runtimePermissionGrants.map((grant) => grant.session)].find((candidate) => did(candidate.verificationMethod) === did(payload.iss));
|
|
24399
|
+
if (!signer) throw new Error("invocation issuer does not match a held session");
|
|
24400
|
+
return rewriteInvocationAudience(authorization, audience, signer.jwk);
|
|
24384
24401
|
}
|
|
24385
24402
|
/**
|
|
24386
24403
|
* Connect a wallet to upgrade from session-only mode to wallet mode.
|
|
@@ -24715,23 +24732,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24715
24732
|
throw new Error("WASM binding does not support invocation CID computation");
|
|
24716
24733
|
}
|
|
24717
24734
|
const session = binding?.session ?? this.requireEncryptionSession();
|
|
24735
|
+
const entries = [
|
|
24736
|
+
{
|
|
24737
|
+
resource: input.networkId,
|
|
24738
|
+
service: "encryption",
|
|
24739
|
+
path: input.networkId,
|
|
24740
|
+
action: input.action
|
|
24741
|
+
}
|
|
24742
|
+
];
|
|
24718
24743
|
const headers = this.invokeAnyWithRuntimePermissions(
|
|
24719
24744
|
session,
|
|
24720
|
-
|
|
24721
|
-
{
|
|
24722
|
-
resource: input.networkId,
|
|
24723
|
-
service: "encryption",
|
|
24724
|
-
path: input.networkId,
|
|
24725
|
-
action: input.action
|
|
24726
|
-
}
|
|
24727
|
-
],
|
|
24745
|
+
entries,
|
|
24728
24746
|
[input.facts]
|
|
24729
24747
|
);
|
|
24748
|
+
const signingSession = this.selectInvokeAnySession(session, entries).session;
|
|
24730
24749
|
const authorization = authorizationHeader(headers);
|
|
24731
24750
|
const audienceBound = await rewriteInvocationAudience(
|
|
24732
24751
|
authorization,
|
|
24733
24752
|
input.targetNode,
|
|
24734
|
-
|
|
24753
|
+
signingSession.jwk
|
|
24735
24754
|
);
|
|
24736
24755
|
binding?.graph.assertActive();
|
|
24737
24756
|
return {
|
|
@@ -24784,7 +24803,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24784
24803
|
path: networkId,
|
|
24785
24804
|
actions: ["tinycloud.encryption/decrypt"]
|
|
24786
24805
|
}) : void 0;
|
|
24787
|
-
throw new import_sdk_core10.DecryptTransportResponseError(
|
|
24806
|
+
throw new import_sdk_core10.DecryptTransportResponseError(
|
|
24807
|
+
response.status,
|
|
24808
|
+
permissionHint,
|
|
24809
|
+
response.status === 404 && networkId === this.getDefaultEncryptionNetworkId() && await response.text().catch(() => "") === "network not found" ? `Network not found: ${networkId}. Sign in again with a current SDK to create the account's encryption network.` : void 0
|
|
24810
|
+
);
|
|
24788
24811
|
}
|
|
24789
24812
|
return await response.json();
|
|
24790
24813
|
}
|
|
@@ -25249,8 +25272,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25249
25272
|
fetch: globalThis.fetch.bind(globalThis)
|
|
25250
25273
|
});
|
|
25251
25274
|
}
|
|
25252
|
-
/**
|
|
25275
|
+
/**
|
|
25276
|
+
* Authorize one short-lived v3 delivery. `shareUrl` is the short `/s/<id>#v=4&k=…&c=…` link: the node fetches the
|
|
25277
|
+
* sealed body by id and opens it with the link's key, so the body of the request carries the link and nothing else
|
|
25278
|
+
* of the share. `envelope` is the signed v3 envelope the sender holds; it checks the node's admission here and is
|
|
25279
|
+
* not sent.
|
|
25280
|
+
*/
|
|
25253
25281
|
async authorizeShareDeliveryV3(input) {
|
|
25282
|
+
const envelopeRef = await (0, import_sdk_core10.shortDeliveryLinkBodyCid)(input.shareUrl, input.trustedOrigins);
|
|
25254
25283
|
const session = this.currentTinyCloudSession();
|
|
25255
25284
|
const serviceSession = this._serviceContext?.session;
|
|
25256
25285
|
if (!session || !serviceSession) throw new Error("Share delivery requires an authenticated session");
|
|
@@ -25260,15 +25289,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25260
25289
|
}
|
|
25261
25290
|
const jtiDigest = new Uint8Array(await crypto.subtle.digest("SHA-256", idempotencyBytes));
|
|
25262
25291
|
const body = {
|
|
25263
|
-
envelope: input.envelope,
|
|
25264
|
-
sealedEnvelope: input.sealedEnvelope,
|
|
25265
|
-
envelopeKey: input.envelopeKey,
|
|
25266
|
-
shareCid: input.shareCid,
|
|
25267
25292
|
recipientEmail: input.recipientEmail,
|
|
25268
25293
|
shareUrl: input.shareUrl,
|
|
25269
25294
|
documentName: input.documentName,
|
|
25270
25295
|
jti: base64UrlEncode(jtiDigest.slice(0, 16)),
|
|
25271
|
-
|
|
25296
|
+
// Re-normalised through Date, so the sent value is always `YYYY-MM-DDTHH:mm:ss.SSSZ` (UTC, three digits).
|
|
25297
|
+
expiresAt: new Date(input.expiresAt).toISOString()
|
|
25272
25298
|
};
|
|
25273
25299
|
const requestBodyDigest = base64UrlEncode(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode((0, import_sdk_core10.canonicalizeEncryptionJson)(body)))));
|
|
25274
25300
|
const request = { ...body, requestBodyDigest };
|
|
@@ -25278,9 +25304,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
25278
25304
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
25279
25305
|
body: (0, import_sdk_core10.canonicalizeEncryptionJson)(request)
|
|
25280
25306
|
});
|
|
25281
|
-
if (
|
|
25282
|
-
|
|
25307
|
+
if (response.status === 400 || response.status === 422) throw new import_sdk_core10.ShareDeliveryRefusedError();
|
|
25308
|
+
if (!response.ok) {
|
|
25309
|
+
const reply = await response.text().catch(() => response.statusText);
|
|
25310
|
+
const body2 = (await (0, import_sdk_core10.withoutShareLink)(reply, input.shareUrl)).trim().slice(0, 512);
|
|
25311
|
+
throw Object.assign(new Error(`V3 share delivery authorization failed: HTTP ${response.status}${body2 ? ` - ${body2}` : ""}`), { status: response.status });
|
|
25312
|
+
}
|
|
25313
|
+
const verified = await (0, import_sdk_core10.verifyShareDeliveryAuthorizationV3Bytes)(new Uint8Array(await response.arrayBuffer()), {
|
|
25283
25314
|
request,
|
|
25315
|
+
envelope: input.envelope,
|
|
25316
|
+
envelopeRef,
|
|
25284
25317
|
senderKeyDid: this.credentialHolderDid,
|
|
25285
25318
|
deliveryAudience: input.deliveryAudience
|
|
25286
25319
|
});
|