@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
|
@@ -1435,6 +1435,13 @@ declare class TinyCloudNode {
|
|
|
1435
1435
|
/** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
|
|
1436
1436
|
private get siweDomain();
|
|
1437
1437
|
private readonly invokeWithRuntimePermissions;
|
|
1438
|
+
/**
|
|
1439
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
1440
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
1441
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
1442
|
+
* invocation must use this session's key.
|
|
1443
|
+
*/
|
|
1444
|
+
private selectInvokeAnySession;
|
|
1438
1445
|
private readonly invokeAnyWithRuntimePermissions;
|
|
1439
1446
|
/**
|
|
1440
1447
|
* Create a new TinyCloudNode instance.
|
|
@@ -2040,14 +2047,14 @@ declare class TinyCloudNode {
|
|
|
2040
2047
|
signOwnerRevocation(cid: string): Promise<string>;
|
|
2041
2048
|
/** Register a signed policy and sibling roots with this Node's Policy/v3 runtime. */
|
|
2042
2049
|
registerPolicy(params: Omit<RegisterPolicyV3Input, "nodeOrigin" | "fetch">): Promise<RegisterPolicyV3Receipt>;
|
|
2043
|
-
/**
|
|
2050
|
+
/**
|
|
2051
|
+
* Authorize one short-lived v3 delivery. `shareUrl` is the short `/s/<id>#v=4&k=…&c=…` link: the node fetches the
|
|
2052
|
+
* sealed body by id and opens it with the link's key, so the body of the request carries the link and nothing else
|
|
2053
|
+
* of the share. `envelope` is the signed v3 envelope the sender holds; it checks the node's admission here and is
|
|
2054
|
+
* not sent.
|
|
2055
|
+
*/
|
|
2044
2056
|
authorizeShareDeliveryV3(input: {
|
|
2045
2057
|
readonly envelope: Record<string, CanonicalJson | undefined>;
|
|
2046
|
-
/** Canonical sealed recipient envelope: version || nonce || ciphertext+tag. */
|
|
2047
|
-
readonly sealedEnvelope: string;
|
|
2048
|
-
/** Base64url 32-byte envelope key; it must also be the URL fragment key. */
|
|
2049
|
-
readonly envelopeKey: string;
|
|
2050
|
-
readonly shareCid: string;
|
|
2051
2058
|
readonly resourcePath: string;
|
|
2052
2059
|
readonly recipientEmail: string;
|
|
2053
2060
|
readonly shareUrl: string;
|
|
@@ -2056,6 +2063,8 @@ declare class TinyCloudNode {
|
|
|
2056
2063
|
readonly deliveryAudience: string;
|
|
2057
2064
|
/** Stable caller retry identity. It is hashed into the protocol's 16-byte JTI. */
|
|
2058
2065
|
readonly idempotencyKey: string;
|
|
2066
|
+
/** The origins `shareUrl` may be on: the node's `return_origin`. Default: `https://share.tinycloud.xyz`. */
|
|
2067
|
+
readonly trustedOrigins?: readonly string[];
|
|
2059
2068
|
}): Promise<ShareDeliveryAuthorizationV3Receipt>;
|
|
2060
2069
|
private createRootDelegationForSharing;
|
|
2061
2070
|
/**
|
|
@@ -1435,6 +1435,13 @@ declare class TinyCloudNode {
|
|
|
1435
1435
|
/** SIWE domain — uses config override or defaults to app.tinycloud.xyz */
|
|
1436
1436
|
private get siweDomain();
|
|
1437
1437
|
private readonly invokeWithRuntimePermissions;
|
|
1438
|
+
/**
|
|
1439
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
1440
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
1441
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
1442
|
+
* invocation must use this session's key.
|
|
1443
|
+
*/
|
|
1444
|
+
private selectInvokeAnySession;
|
|
1438
1445
|
private readonly invokeAnyWithRuntimePermissions;
|
|
1439
1446
|
/**
|
|
1440
1447
|
* Create a new TinyCloudNode instance.
|
|
@@ -2040,14 +2047,14 @@ declare class TinyCloudNode {
|
|
|
2040
2047
|
signOwnerRevocation(cid: string): Promise<string>;
|
|
2041
2048
|
/** Register a signed policy and sibling roots with this Node's Policy/v3 runtime. */
|
|
2042
2049
|
registerPolicy(params: Omit<RegisterPolicyV3Input, "nodeOrigin" | "fetch">): Promise<RegisterPolicyV3Receipt>;
|
|
2043
|
-
/**
|
|
2050
|
+
/**
|
|
2051
|
+
* Authorize one short-lived v3 delivery. `shareUrl` is the short `/s/<id>#v=4&k=…&c=…` link: the node fetches the
|
|
2052
|
+
* sealed body by id and opens it with the link's key, so the body of the request carries the link and nothing else
|
|
2053
|
+
* of the share. `envelope` is the signed v3 envelope the sender holds; it checks the node's admission here and is
|
|
2054
|
+
* not sent.
|
|
2055
|
+
*/
|
|
2044
2056
|
authorizeShareDeliveryV3(input: {
|
|
2045
2057
|
readonly envelope: Record<string, CanonicalJson | undefined>;
|
|
2046
|
-
/** Canonical sealed recipient envelope: version || nonce || ciphertext+tag. */
|
|
2047
|
-
readonly sealedEnvelope: string;
|
|
2048
|
-
/** Base64url 32-byte envelope key; it must also be the URL fragment key. */
|
|
2049
|
-
readonly envelopeKey: string;
|
|
2050
|
-
readonly shareCid: string;
|
|
2051
2058
|
readonly resourcePath: string;
|
|
2052
2059
|
readonly recipientEmail: string;
|
|
2053
2060
|
readonly shareUrl: string;
|
|
@@ -2056,6 +2063,8 @@ declare class TinyCloudNode {
|
|
|
2056
2063
|
readonly deliveryAudience: string;
|
|
2057
2064
|
/** Stable caller retry identity. It is hashed into the protocol's 16-byte JTI. */
|
|
2058
2065
|
readonly idempotencyKey: string;
|
|
2066
|
+
/** The origins `shareUrl` may be on: the node's `return_origin`. Default: `https://share.tinycloud.xyz`. */
|
|
2067
|
+
readonly trustedOrigins?: readonly string[];
|
|
2059
2068
|
}): Promise<ShareDeliveryAuthorizationV3Receipt>;
|
|
2060
2069
|
private createRootDelegationForSharing;
|
|
2061
2070
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-u_PobKS1.cjs';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-CclYdOh4.js';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
package/dist/core.cjs
CHANGED
|
@@ -3886,17 +3886,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3886
3886
|
throw new Error("WASM binding does not support invokeAny");
|
|
3887
3887
|
}
|
|
3888
3888
|
const routedEntries = entries;
|
|
3889
|
-
const
|
|
3890
|
-
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
3891
|
-
return operation ? [operation] : [];
|
|
3892
|
-
});
|
|
3893
|
-
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
3894
|
-
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
3895
|
-
if (authorityCid !== void 0 && !explicitGrant) {
|
|
3896
|
-
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
3897
|
-
}
|
|
3898
|
-
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
3899
|
-
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
3889
|
+
const { session: invocationSession, grant } = this.selectInvokeAnySession(session, entries);
|
|
3900
3890
|
const caveatPreservingEntries = routedEntries.map(({ revokeAuthorityCid: _cid, ...entry }) => {
|
|
3901
3891
|
const requested = this.operationFromInvokeAnyEntry(entry);
|
|
3902
3892
|
const granted = grant && requested && grant.operations.find(
|
|
@@ -4134,6 +4124,27 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4134
4124
|
get siweDomain() {
|
|
4135
4125
|
return this.config.domain ?? "app.tinycloud.xyz";
|
|
4136
4126
|
}
|
|
4127
|
+
/**
|
|
4128
|
+
* The session (key, issuer, proof) that signs an invokeAny call for `entries`:
|
|
4129
|
+
* the explicit revocation authority, else the covering non-primary runtime
|
|
4130
|
+
* grant, else the caller's session. Everything that re-signs the resulting
|
|
4131
|
+
* invocation must use this session's key.
|
|
4132
|
+
*/
|
|
4133
|
+
selectInvokeAnySession(session, entries) {
|
|
4134
|
+
const routedEntries = entries;
|
|
4135
|
+
const operations = routedEntries.flatMap((entry) => {
|
|
4136
|
+
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
4137
|
+
return operation ? [operation] : [];
|
|
4138
|
+
});
|
|
4139
|
+
const authorityCid = routedEntries.length === 1 ? routedEntries[0]?.revokeAuthorityCid : void 0;
|
|
4140
|
+
const explicitGrant = authorityCid === void 0 ? void 0 : this.runtimePermissionGrants.find((grant2) => grant2.delegation.cid === authorityCid);
|
|
4141
|
+
if (authorityCid !== void 0 && !explicitGrant) {
|
|
4142
|
+
throw new Error(`Explicit revocation authority ${authorityCid} is not installed.`);
|
|
4143
|
+
}
|
|
4144
|
+
const grant = explicitGrant ?? this.findGrantForOperations(operations);
|
|
4145
|
+
const invocationSession = explicitGrant ? explicitGrant.session : !grant || grant.provenance === "primary" ? session : grant.session;
|
|
4146
|
+
return { session: invocationSession, grant };
|
|
4147
|
+
}
|
|
4137
4148
|
/**
|
|
4138
4149
|
* SharingService for receive-only access (no session required), bound to the
|
|
4139
4150
|
* current service graph. This lets session-only users receive sharing links
|
|
@@ -6553,7 +6564,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6553
6564
|
async bindInvocationAudience(authorization, audience) {
|
|
6554
6565
|
const session = this.currentTinyCloudSession() ?? this._activeServiceSession;
|
|
6555
6566
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
6556
|
-
|
|
6567
|
+
const payload = JSON.parse(
|
|
6568
|
+
new TextDecoder().decode(base64UrlDecode(authorization.split(".")[1] ?? ""))
|
|
6569
|
+
);
|
|
6570
|
+
const did = (value) => String(value).split("#", 1)[0];
|
|
6571
|
+
const signer = [session, ...this.runtimePermissionGrants.map((grant) => grant.session)].find((candidate) => did(candidate.verificationMethod) === did(payload.iss));
|
|
6572
|
+
if (!signer) throw new Error("invocation issuer does not match a held session");
|
|
6573
|
+
return rewriteInvocationAudience(authorization, audience, signer.jwk);
|
|
6557
6574
|
}
|
|
6558
6575
|
/**
|
|
6559
6576
|
* Connect a wallet to upgrade from session-only mode to wallet mode.
|
|
@@ -6888,23 +6905,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6888
6905
|
throw new Error("WASM binding does not support invocation CID computation");
|
|
6889
6906
|
}
|
|
6890
6907
|
const session = binding?.session ?? this.requireEncryptionSession();
|
|
6908
|
+
const entries = [
|
|
6909
|
+
{
|
|
6910
|
+
resource: input.networkId,
|
|
6911
|
+
service: "encryption",
|
|
6912
|
+
path: input.networkId,
|
|
6913
|
+
action: input.action
|
|
6914
|
+
}
|
|
6915
|
+
];
|
|
6891
6916
|
const headers = this.invokeAnyWithRuntimePermissions(
|
|
6892
6917
|
session,
|
|
6893
|
-
|
|
6894
|
-
{
|
|
6895
|
-
resource: input.networkId,
|
|
6896
|
-
service: "encryption",
|
|
6897
|
-
path: input.networkId,
|
|
6898
|
-
action: input.action
|
|
6899
|
-
}
|
|
6900
|
-
],
|
|
6918
|
+
entries,
|
|
6901
6919
|
[input.facts]
|
|
6902
6920
|
);
|
|
6921
|
+
const signingSession = this.selectInvokeAnySession(session, entries).session;
|
|
6903
6922
|
const authorization = authorizationHeader(headers);
|
|
6904
6923
|
const audienceBound = await rewriteInvocationAudience(
|
|
6905
6924
|
authorization,
|
|
6906
6925
|
input.targetNode,
|
|
6907
|
-
|
|
6926
|
+
signingSession.jwk
|
|
6908
6927
|
);
|
|
6909
6928
|
binding?.graph.assertActive();
|
|
6910
6929
|
return {
|
|
@@ -6957,7 +6976,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6957
6976
|
path: networkId,
|
|
6958
6977
|
actions: ["tinycloud.encryption/decrypt"]
|
|
6959
6978
|
}) : void 0;
|
|
6960
|
-
throw new import_sdk_core11.DecryptTransportResponseError(
|
|
6979
|
+
throw new import_sdk_core11.DecryptTransportResponseError(
|
|
6980
|
+
response.status,
|
|
6981
|
+
permissionHint,
|
|
6982
|
+
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
|
|
6983
|
+
);
|
|
6961
6984
|
}
|
|
6962
6985
|
return await response.json();
|
|
6963
6986
|
}
|
|
@@ -7422,8 +7445,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7422
7445
|
fetch: globalThis.fetch.bind(globalThis)
|
|
7423
7446
|
});
|
|
7424
7447
|
}
|
|
7425
|
-
/**
|
|
7448
|
+
/**
|
|
7449
|
+
* Authorize one short-lived v3 delivery. `shareUrl` is the short `/s/<id>#v=4&k=…&c=…` link: the node fetches the
|
|
7450
|
+
* sealed body by id and opens it with the link's key, so the body of the request carries the link and nothing else
|
|
7451
|
+
* of the share. `envelope` is the signed v3 envelope the sender holds; it checks the node's admission here and is
|
|
7452
|
+
* not sent.
|
|
7453
|
+
*/
|
|
7426
7454
|
async authorizeShareDeliveryV3(input) {
|
|
7455
|
+
const envelopeRef = await (0, import_sdk_core11.shortDeliveryLinkBodyCid)(input.shareUrl, input.trustedOrigins);
|
|
7427
7456
|
const session = this.currentTinyCloudSession();
|
|
7428
7457
|
const serviceSession = this._serviceContext?.session;
|
|
7429
7458
|
if (!session || !serviceSession) throw new Error("Share delivery requires an authenticated session");
|
|
@@ -7433,15 +7462,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7433
7462
|
}
|
|
7434
7463
|
const jtiDigest = new Uint8Array(await crypto.subtle.digest("SHA-256", idempotencyBytes));
|
|
7435
7464
|
const body = {
|
|
7436
|
-
envelope: input.envelope,
|
|
7437
|
-
sealedEnvelope: input.sealedEnvelope,
|
|
7438
|
-
envelopeKey: input.envelopeKey,
|
|
7439
|
-
shareCid: input.shareCid,
|
|
7440
7465
|
recipientEmail: input.recipientEmail,
|
|
7441
7466
|
shareUrl: input.shareUrl,
|
|
7442
7467
|
documentName: input.documentName,
|
|
7443
7468
|
jti: base64UrlEncode(jtiDigest.slice(0, 16)),
|
|
7444
|
-
|
|
7469
|
+
// Re-normalised through Date, so the sent value is always `YYYY-MM-DDTHH:mm:ss.SSSZ` (UTC, three digits).
|
|
7470
|
+
expiresAt: new Date(input.expiresAt).toISOString()
|
|
7445
7471
|
};
|
|
7446
7472
|
const requestBodyDigest = base64UrlEncode(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode((0, import_sdk_core11.canonicalizeEncryptionJson)(body)))));
|
|
7447
7473
|
const request = { ...body, requestBodyDigest };
|
|
@@ -7451,9 +7477,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7451
7477
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
7452
7478
|
body: (0, import_sdk_core11.canonicalizeEncryptionJson)(request)
|
|
7453
7479
|
});
|
|
7454
|
-
if (
|
|
7455
|
-
|
|
7480
|
+
if (response.status === 400 || response.status === 422) throw new import_sdk_core11.ShareDeliveryRefusedError();
|
|
7481
|
+
if (!response.ok) {
|
|
7482
|
+
const reply = await response.text().catch(() => response.statusText);
|
|
7483
|
+
const body2 = (await (0, import_sdk_core11.withoutShareLink)(reply, input.shareUrl)).trim().slice(0, 512);
|
|
7484
|
+
throw Object.assign(new Error(`V3 share delivery authorization failed: HTTP ${response.status}${body2 ? ` - ${body2}` : ""}`), { status: response.status });
|
|
7485
|
+
}
|
|
7486
|
+
const verified = await (0, import_sdk_core11.verifyShareDeliveryAuthorizationV3Bytes)(new Uint8Array(await response.arrayBuffer()), {
|
|
7456
7487
|
request,
|
|
7488
|
+
envelope: input.envelope,
|
|
7489
|
+
envelopeRef,
|
|
7457
7490
|
senderKeyDid: this.credentialHolderDid,
|
|
7458
7491
|
deliveryAudience: input.deliveryAudience
|
|
7459
7492
|
});
|