@tinycloud/node-sdk 3.1.0-beta.7 → 3.1.0-beta.9
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/{core-BWvBTn9l.d.cts → core-CC7uDKZP.d.cts} +72 -6
- package/dist/{core-BWvBTn9l.d.ts → core-CC7uDKZP.d.ts} +72 -6
- package/dist/core.cjs +200 -53
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +201 -53
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +252 -85
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +252 -85
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -4409,19 +4409,19 @@ var init_lib4 = __esm({
|
|
|
4409
4409
|
resolve(value);
|
|
4410
4410
|
});
|
|
4411
4411
|
}
|
|
4412
|
-
return new (P || (P = Promise))(function(resolve,
|
|
4412
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
4413
4413
|
function fulfilled(value) {
|
|
4414
4414
|
try {
|
|
4415
4415
|
step(generator.next(value));
|
|
4416
4416
|
} catch (e) {
|
|
4417
|
-
|
|
4417
|
+
reject2(e);
|
|
4418
4418
|
}
|
|
4419
4419
|
}
|
|
4420
4420
|
function rejected(value) {
|
|
4421
4421
|
try {
|
|
4422
4422
|
step(generator["throw"](value));
|
|
4423
4423
|
} catch (e) {
|
|
4424
|
-
|
|
4424
|
+
reject2(e);
|
|
4425
4425
|
}
|
|
4426
4426
|
}
|
|
4427
4427
|
function step(result) {
|
|
@@ -8045,19 +8045,19 @@ var init_typed_data = __esm({
|
|
|
8045
8045
|
resolve(value);
|
|
8046
8046
|
});
|
|
8047
8047
|
}
|
|
8048
|
-
return new (P || (P = Promise))(function(resolve,
|
|
8048
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
8049
8049
|
function fulfilled(value) {
|
|
8050
8050
|
try {
|
|
8051
8051
|
step(generator.next(value));
|
|
8052
8052
|
} catch (e) {
|
|
8053
|
-
|
|
8053
|
+
reject2(e);
|
|
8054
8054
|
}
|
|
8055
8055
|
}
|
|
8056
8056
|
function rejected(value) {
|
|
8057
8057
|
try {
|
|
8058
8058
|
step(generator["throw"](value));
|
|
8059
8059
|
} catch (e) {
|
|
8060
|
-
|
|
8060
|
+
reject2(e);
|
|
8061
8061
|
}
|
|
8062
8062
|
}
|
|
8063
8063
|
function step(result) {
|
|
@@ -14903,14 +14903,14 @@ var require_scrypt = __commonJS({
|
|
|
14903
14903
|
}
|
|
14904
14904
|
const lib = {
|
|
14905
14905
|
scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
|
|
14906
|
-
return new Promise(function(resolve,
|
|
14906
|
+
return new Promise(function(resolve, reject2) {
|
|
14907
14907
|
let lastProgress = 0;
|
|
14908
14908
|
if (progressCallback) {
|
|
14909
14909
|
progressCallback(0);
|
|
14910
14910
|
}
|
|
14911
14911
|
_scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
|
|
14912
14912
|
if (error) {
|
|
14913
|
-
|
|
14913
|
+
reject2(error);
|
|
14914
14914
|
} else if (key2) {
|
|
14915
14915
|
if (progressCallback && lastProgress !== 1) {
|
|
14916
14916
|
progressCallback(1);
|
|
@@ -15299,19 +15299,19 @@ var init_keystore = __esm({
|
|
|
15299
15299
|
resolve(value);
|
|
15300
15300
|
});
|
|
15301
15301
|
}
|
|
15302
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15302
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15303
15303
|
function fulfilled(value) {
|
|
15304
15304
|
try {
|
|
15305
15305
|
step(generator.next(value));
|
|
15306
15306
|
} catch (e) {
|
|
15307
|
-
|
|
15307
|
+
reject2(e);
|
|
15308
15308
|
}
|
|
15309
15309
|
}
|
|
15310
15310
|
function rejected(value) {
|
|
15311
15311
|
try {
|
|
15312
15312
|
step(generator["throw"](value));
|
|
15313
15313
|
} catch (e) {
|
|
15314
|
-
|
|
15314
|
+
reject2(e);
|
|
15315
15315
|
}
|
|
15316
15316
|
}
|
|
15317
15317
|
function step(result) {
|
|
@@ -15612,19 +15612,19 @@ var init_lib25 = __esm({
|
|
|
15612
15612
|
resolve(value);
|
|
15613
15613
|
});
|
|
15614
15614
|
}
|
|
15615
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15615
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15616
15616
|
function fulfilled(value) {
|
|
15617
15617
|
try {
|
|
15618
15618
|
step(generator.next(value));
|
|
15619
15619
|
} catch (e) {
|
|
15620
|
-
|
|
15620
|
+
reject2(e);
|
|
15621
15621
|
}
|
|
15622
15622
|
}
|
|
15623
15623
|
function rejected(value) {
|
|
15624
15624
|
try {
|
|
15625
15625
|
step(generator["throw"](value));
|
|
15626
15626
|
} catch (e) {
|
|
15627
|
-
|
|
15627
|
+
reject2(e);
|
|
15628
15628
|
}
|
|
15629
15629
|
}
|
|
15630
15630
|
function step(result) {
|
|
@@ -15694,19 +15694,19 @@ var init_lib26 = __esm({
|
|
|
15694
15694
|
resolve(value);
|
|
15695
15695
|
});
|
|
15696
15696
|
}
|
|
15697
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15697
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15698
15698
|
function fulfilled(value) {
|
|
15699
15699
|
try {
|
|
15700
15700
|
step(generator.next(value));
|
|
15701
15701
|
} catch (e) {
|
|
15702
|
-
|
|
15702
|
+
reject2(e);
|
|
15703
15703
|
}
|
|
15704
15704
|
}
|
|
15705
15705
|
function rejected(value) {
|
|
15706
15706
|
try {
|
|
15707
15707
|
step(generator["throw"](value));
|
|
15708
15708
|
} catch (e) {
|
|
15709
|
-
|
|
15709
|
+
reject2(e);
|
|
15710
15710
|
}
|
|
15711
15711
|
}
|
|
15712
15712
|
function step(result) {
|
|
@@ -16016,19 +16016,19 @@ var init_lib27 = __esm({
|
|
|
16016
16016
|
resolve(value);
|
|
16017
16017
|
});
|
|
16018
16018
|
}
|
|
16019
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16019
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16020
16020
|
function fulfilled(value) {
|
|
16021
16021
|
try {
|
|
16022
16022
|
step(generator.next(value));
|
|
16023
16023
|
} catch (e) {
|
|
16024
|
-
|
|
16024
|
+
reject2(e);
|
|
16025
16025
|
}
|
|
16026
16026
|
}
|
|
16027
16027
|
function rejected(value) {
|
|
16028
16028
|
try {
|
|
16029
16029
|
step(generator["throw"](value));
|
|
16030
16030
|
} catch (e) {
|
|
16031
|
-
|
|
16031
|
+
reject2(e);
|
|
16032
16032
|
}
|
|
16033
16033
|
}
|
|
16034
16034
|
function step(result) {
|
|
@@ -16254,19 +16254,19 @@ var init_geturl = __esm({
|
|
|
16254
16254
|
resolve(value);
|
|
16255
16255
|
});
|
|
16256
16256
|
}
|
|
16257
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16257
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16258
16258
|
function fulfilled(value) {
|
|
16259
16259
|
try {
|
|
16260
16260
|
step(generator.next(value));
|
|
16261
16261
|
} catch (e) {
|
|
16262
|
-
|
|
16262
|
+
reject2(e);
|
|
16263
16263
|
}
|
|
16264
16264
|
}
|
|
16265
16265
|
function rejected(value) {
|
|
16266
16266
|
try {
|
|
16267
16267
|
step(generator["throw"](value));
|
|
16268
16268
|
} catch (e) {
|
|
16269
|
-
|
|
16269
|
+
reject2(e);
|
|
16270
16270
|
}
|
|
16271
16271
|
}
|
|
16272
16272
|
function step(result) {
|
|
@@ -16407,14 +16407,14 @@ function _fetchData(connection, body, processFunc) {
|
|
|
16407
16407
|
options.headers = flatHeaders;
|
|
16408
16408
|
const runningTimeout = (function() {
|
|
16409
16409
|
let timer = null;
|
|
16410
|
-
const promise = new Promise(function(resolve,
|
|
16410
|
+
const promise = new Promise(function(resolve, reject2) {
|
|
16411
16411
|
if (timeout) {
|
|
16412
16412
|
timer = setTimeout(() => {
|
|
16413
16413
|
if (timer == null) {
|
|
16414
16414
|
return;
|
|
16415
16415
|
}
|
|
16416
16416
|
timer = null;
|
|
16417
|
-
|
|
16417
|
+
reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
|
|
16418
16418
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
|
16419
16419
|
requestMethod: options.method,
|
|
16420
16420
|
timeout,
|
|
@@ -16577,7 +16577,7 @@ function poll(func, options) {
|
|
|
16577
16577
|
if (options.interval == null) {
|
|
16578
16578
|
options.interval = 250;
|
|
16579
16579
|
}
|
|
16580
|
-
return new Promise(function(resolve,
|
|
16580
|
+
return new Promise(function(resolve, reject2) {
|
|
16581
16581
|
let timer = null;
|
|
16582
16582
|
let done = false;
|
|
16583
16583
|
const cancel = () => {
|
|
@@ -16593,7 +16593,7 @@ function poll(func, options) {
|
|
|
16593
16593
|
if (options.timeout) {
|
|
16594
16594
|
timer = setTimeout(() => {
|
|
16595
16595
|
if (cancel()) {
|
|
16596
|
-
|
|
16596
|
+
reject2(new Error("timeout"));
|
|
16597
16597
|
}
|
|
16598
16598
|
}, options.timeout);
|
|
16599
16599
|
}
|
|
@@ -16613,7 +16613,7 @@ function poll(func, options) {
|
|
|
16613
16613
|
attempt++;
|
|
16614
16614
|
if (attempt > retryLimit) {
|
|
16615
16615
|
if (cancel()) {
|
|
16616
|
-
|
|
16616
|
+
reject2(new Error("retry limit reached"));
|
|
16617
16617
|
}
|
|
16618
16618
|
return;
|
|
16619
16619
|
}
|
|
@@ -16629,7 +16629,7 @@ function poll(func, options) {
|
|
|
16629
16629
|
return null;
|
|
16630
16630
|
}, function(error) {
|
|
16631
16631
|
if (cancel()) {
|
|
16632
|
-
|
|
16632
|
+
reject2(error);
|
|
16633
16633
|
}
|
|
16634
16634
|
});
|
|
16635
16635
|
}
|
|
@@ -16653,19 +16653,19 @@ var init_lib28 = __esm({
|
|
|
16653
16653
|
resolve(value);
|
|
16654
16654
|
});
|
|
16655
16655
|
}
|
|
16656
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16656
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16657
16657
|
function fulfilled(value) {
|
|
16658
16658
|
try {
|
|
16659
16659
|
step(generator.next(value));
|
|
16660
16660
|
} catch (e) {
|
|
16661
|
-
|
|
16661
|
+
reject2(e);
|
|
16662
16662
|
}
|
|
16663
16663
|
}
|
|
16664
16664
|
function rejected(value) {
|
|
16665
16665
|
try {
|
|
16666
16666
|
step(generator["throw"](value));
|
|
16667
16667
|
} catch (e) {
|
|
16668
|
-
|
|
16668
|
+
reject2(e);
|
|
16669
16669
|
}
|
|
16670
16670
|
}
|
|
16671
16671
|
function step(result) {
|
|
@@ -17035,6 +17035,7 @@ import {
|
|
|
17035
17035
|
prepareSession,
|
|
17036
17036
|
completeSessionSetup,
|
|
17037
17037
|
validatePersistedSession,
|
|
17038
|
+
validateSessionGrant,
|
|
17038
17039
|
ensureEip55,
|
|
17039
17040
|
makeSpaceId,
|
|
17040
17041
|
createDelegation,
|
|
@@ -17084,6 +17085,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17084
17085
|
validatePersistedSession(proof) {
|
|
17085
17086
|
return validatePersistedSession(proof);
|
|
17086
17087
|
}
|
|
17088
|
+
validateSessionGrant(proof) {
|
|
17089
|
+
return validateSessionGrant(proof);
|
|
17090
|
+
}
|
|
17087
17091
|
createSessionManager() {
|
|
17088
17092
|
return new TCWSessionManager();
|
|
17089
17093
|
}
|
|
@@ -17197,6 +17201,7 @@ import {
|
|
|
17197
17201
|
recapCaveatsEqual,
|
|
17198
17202
|
expandPermissionEntries as expandPermissionEntriesCore,
|
|
17199
17203
|
isCapabilitySubset,
|
|
17204
|
+
isExplicitOnlyAction,
|
|
17200
17205
|
parseRecapCapabilities,
|
|
17201
17206
|
SERVICE_LONG_TO_SHORT,
|
|
17202
17207
|
SERVICE_SHORT_TO_LONG,
|
|
@@ -18738,14 +18743,14 @@ var NodeUserAuthorization = class {
|
|
|
18738
18743
|
* Request signature via event emitter with timeout.
|
|
18739
18744
|
*/
|
|
18740
18745
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18741
|
-
return new Promise((resolve,
|
|
18746
|
+
return new Promise((resolve, reject2) => {
|
|
18742
18747
|
const timeoutId = setTimeout(() => {
|
|
18743
|
-
|
|
18748
|
+
reject2(new Error("Sign request timed out"));
|
|
18744
18749
|
}, timeout);
|
|
18745
18750
|
const respond = async (response) => {
|
|
18746
18751
|
clearTimeout(timeoutId);
|
|
18747
18752
|
if (!response.approved) {
|
|
18748
|
-
|
|
18753
|
+
reject2(
|
|
18749
18754
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18750
18755
|
);
|
|
18751
18756
|
} else {
|
|
@@ -19340,6 +19345,25 @@ function jsonFromVerifier(value) {
|
|
|
19340
19345
|
function verifierRecapEntries(entries) {
|
|
19341
19346
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19342
19347
|
}
|
|
19348
|
+
function exactVerifiedRecap(verified) {
|
|
19349
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19350
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19351
|
+
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
19352
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19353
|
+
)
|
|
19354
|
+
)) {
|
|
19355
|
+
throw new UnsupportedSessionRestoreError(
|
|
19356
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19357
|
+
);
|
|
19358
|
+
}
|
|
19359
|
+
return exactRecap.map((entry) => ({
|
|
19360
|
+
service: entry.service,
|
|
19361
|
+
space: entry.space,
|
|
19362
|
+
path: entry.path,
|
|
19363
|
+
actions: [...entry.actions],
|
|
19364
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19365
|
+
}));
|
|
19366
|
+
}
|
|
19343
19367
|
var ServiceGraphLifetime = class {
|
|
19344
19368
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19345
19369
|
this.invokeFn = invokeFn;
|
|
@@ -21004,23 +21028,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21004
21028
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
21005
21029
|
}
|
|
21006
21030
|
})();
|
|
21007
|
-
|
|
21008
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
21009
|
-
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
21010
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
21011
|
-
)
|
|
21012
|
-
)) {
|
|
21013
|
-
throw new UnsupportedSessionRestoreError(
|
|
21014
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
21015
|
-
);
|
|
21016
|
-
}
|
|
21017
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
21018
|
-
service: entry.service,
|
|
21019
|
-
space: entry.space,
|
|
21020
|
-
path: entry.path,
|
|
21021
|
-
actions: [...entry.actions],
|
|
21022
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
21023
|
-
}));
|
|
21031
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
21024
21032
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
21025
21033
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
21026
21034
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -22881,6 +22889,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22881
22889
|
(left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0"))
|
|
22882
22890
|
);
|
|
22883
22891
|
}
|
|
22892
|
+
/**
|
|
22893
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22894
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22895
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22896
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22897
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22898
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22899
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22900
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22901
|
+
* which also refuses decrypt-only grants.
|
|
22902
|
+
*/
|
|
22903
|
+
verifySessionGrant(grant) {
|
|
22904
|
+
const bindings = this.wasmBindings;
|
|
22905
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22906
|
+
if (validate5 === void 0) {
|
|
22907
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22908
|
+
}
|
|
22909
|
+
const verified = validate5({
|
|
22910
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22911
|
+
delegationCid: grant.delegationCid,
|
|
22912
|
+
spaceId: grant.spaceId,
|
|
22913
|
+
jwk: this.sessionKeyJwk,
|
|
22914
|
+
address: canonicalizeAddress2(grant.address),
|
|
22915
|
+
chainId: grant.chainId,
|
|
22916
|
+
siwe: grant.siwe,
|
|
22917
|
+
signature: grant.signature
|
|
22918
|
+
});
|
|
22919
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22920
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22921
|
+
}
|
|
22922
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22923
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22924
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22925
|
+
}
|
|
22926
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22927
|
+
}
|
|
22884
22928
|
/**
|
|
22885
22929
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22886
22930
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -23013,7 +23057,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23013
23057
|
delegatedEntries,
|
|
23014
23058
|
spaceId,
|
|
23015
23059
|
session,
|
|
23016
|
-
expiresAt
|
|
23060
|
+
expiresAt,
|
|
23061
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
23017
23062
|
);
|
|
23018
23063
|
this.runtimePermissionGrants.push({
|
|
23019
23064
|
session: {
|
|
@@ -23799,7 +23844,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23799
23844
|
}
|
|
23800
23845
|
return grants;
|
|
23801
23846
|
}
|
|
23802
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23847
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23803
23848
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23804
23849
|
const primary = resources[0];
|
|
23805
23850
|
return {
|
|
@@ -23814,7 +23859,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23814
23859
|
delegateDID: session.verificationMethod,
|
|
23815
23860
|
ownerAddress: session.address,
|
|
23816
23861
|
chainId: session.chainId,
|
|
23817
|
-
host: this.config.host
|
|
23862
|
+
host: this.config.host,
|
|
23863
|
+
siweProof
|
|
23818
23864
|
};
|
|
23819
23865
|
}
|
|
23820
23866
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -24007,6 +24053,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
24007
24053
|
if (grantedAction === requestedAction) {
|
|
24008
24054
|
return true;
|
|
24009
24055
|
}
|
|
24056
|
+
if (isExplicitOnlyAction(requestedAction)) {
|
|
24057
|
+
return false;
|
|
24058
|
+
}
|
|
24010
24059
|
if (grantedAction.endsWith("/*")) {
|
|
24011
24060
|
const prefix = grantedAction.slice(0, -2);
|
|
24012
24061
|
return requestedAction.startsWith(`${prefix}/`);
|
|
@@ -24737,6 +24786,29 @@ import {
|
|
|
24737
24786
|
decodeBase64Url,
|
|
24738
24787
|
principalDidEquals as principalDidEquals3
|
|
24739
24788
|
} from "@tinycloud/sdk-core";
|
|
24789
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24790
|
+
"host_mismatch",
|
|
24791
|
+
"expired",
|
|
24792
|
+
"cid_mismatch",
|
|
24793
|
+
"authority_invalid",
|
|
24794
|
+
"proof_missing",
|
|
24795
|
+
"proof_invalid",
|
|
24796
|
+
"owner_mismatch",
|
|
24797
|
+
"audience_mismatch",
|
|
24798
|
+
"resources_mismatch",
|
|
24799
|
+
"unsupported",
|
|
24800
|
+
"activation_rejected"
|
|
24801
|
+
];
|
|
24802
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24803
|
+
constructor(reason, message) {
|
|
24804
|
+
super(message);
|
|
24805
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24806
|
+
this.reason = reason;
|
|
24807
|
+
}
|
|
24808
|
+
};
|
|
24809
|
+
function reject(reason, message) {
|
|
24810
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24811
|
+
}
|
|
24740
24812
|
var SERVICE_BY_SHORT_NAME = {
|
|
24741
24813
|
kv: "tinycloud.kv",
|
|
24742
24814
|
sql: "tinycloud.sql",
|
|
@@ -24883,6 +24955,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24883
24955
|
abilities
|
|
24884
24956
|
));
|
|
24885
24957
|
}
|
|
24958
|
+
return canonicalSignedAuthority({
|
|
24959
|
+
issuer: payload.iss,
|
|
24960
|
+
audience: payload.aud,
|
|
24961
|
+
expiry,
|
|
24962
|
+
proofs: [...payload.prf],
|
|
24963
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24964
|
+
}, permissions);
|
|
24965
|
+
}
|
|
24966
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24886
24967
|
if (permissions.length === 0) {
|
|
24887
24968
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24888
24969
|
}
|
|
@@ -24894,15 +24975,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24894
24975
|
actions: [...permission.actions],
|
|
24895
24976
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24896
24977
|
}));
|
|
24897
|
-
return {
|
|
24898
|
-
|
|
24899
|
-
|
|
24900
|
-
|
|
24901
|
-
|
|
24902
|
-
|
|
24903
|
-
|
|
24904
|
-
|
|
24905
|
-
|
|
24978
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24979
|
+
}
|
|
24980
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24981
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24982
|
+
function comparableSpace(space) {
|
|
24983
|
+
const match = PKH_SPACE.exec(space);
|
|
24984
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24985
|
+
}
|
|
24986
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
24987
|
+
const proof = delegation.siweProof;
|
|
24988
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
24989
|
+
reject(
|
|
24990
|
+
"proof_missing",
|
|
24991
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
24992
|
+
);
|
|
24993
|
+
}
|
|
24994
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
24995
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
24996
|
+
}
|
|
24997
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
24998
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
24999
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
25000
|
+
}
|
|
25001
|
+
let verified;
|
|
25002
|
+
try {
|
|
25003
|
+
verified = node.verifySessionGrant({
|
|
25004
|
+
delegationHeader: { Authorization: authorization },
|
|
25005
|
+
delegationCid: cid,
|
|
25006
|
+
spaceId: delegation.spaceId,
|
|
25007
|
+
address: delegation.ownerAddress,
|
|
25008
|
+
chainId: delegation.chainId,
|
|
25009
|
+
siwe: proof.siwe,
|
|
25010
|
+
signature: proof.signature
|
|
25011
|
+
});
|
|
25012
|
+
} catch (error) {
|
|
25013
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
25014
|
+
}
|
|
25015
|
+
const space = comparableSpace(delegation.spaceId);
|
|
25016
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
25017
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
25018
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
25019
|
+
}
|
|
25020
|
+
const groups = /* @__PURE__ */ new Map();
|
|
25021
|
+
for (const entry of verified.recap) {
|
|
25022
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
25023
|
+
const raw = entry.space === "encryption";
|
|
25024
|
+
if (raw) {
|
|
25025
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
25026
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
25027
|
+
}
|
|
25028
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
25029
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
25030
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
25031
|
+
}
|
|
25032
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
25033
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
25034
|
+
}
|
|
25035
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
25036
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, canonicalizeRecapCaveats2(caveats)]);
|
|
25037
|
+
const group = groups.get(key2) ?? {
|
|
25038
|
+
service,
|
|
25039
|
+
...raw ? {} : { space: entry.space },
|
|
25040
|
+
path: entry.path,
|
|
25041
|
+
actions: [],
|
|
25042
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25043
|
+
};
|
|
25044
|
+
for (const action of entry.actions) {
|
|
25045
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25046
|
+
}
|
|
25047
|
+
groups.set(key2, group);
|
|
25048
|
+
}
|
|
25049
|
+
return canonicalSignedAuthority({
|
|
25050
|
+
issuer: owner,
|
|
25051
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25052
|
+
audience: node.sessionDid,
|
|
25053
|
+
expiry: verified.expiresAt,
|
|
25054
|
+
proofs: []
|
|
25055
|
+
}, [...groups.values()]);
|
|
24906
25056
|
}
|
|
24907
25057
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24908
25058
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24938,49 +25088,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24938
25088
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24939
25089
|
const host = normalizedHost(options.host);
|
|
24940
25090
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24941
|
-
|
|
25091
|
+
reject(
|
|
25092
|
+
"host_mismatch",
|
|
24942
25093
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24943
25094
|
);
|
|
24944
25095
|
}
|
|
24945
25096
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24946
|
-
|
|
25097
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24947
25098
|
}
|
|
24948
25099
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24949
|
-
|
|
25100
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24950
25101
|
}
|
|
24951
25102
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24952
25103
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24953
|
-
|
|
25104
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24954
25105
|
}
|
|
24955
25106
|
const cid = node.computeDelegationCid(authorization);
|
|
24956
25107
|
if (cid !== delegation.cid) {
|
|
24957
|
-
|
|
25108
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25109
|
+
}
|
|
25110
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25111
|
+
let signed2;
|
|
25112
|
+
try {
|
|
25113
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25114
|
+
} catch (error) {
|
|
25115
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25116
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24958
25117
|
}
|
|
24959
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24960
25118
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24961
|
-
|
|
25119
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24962
25120
|
}
|
|
24963
25121
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24964
|
-
|
|
25122
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24965
25123
|
}
|
|
24966
25124
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24967
|
-
|
|
25125
|
+
reject(
|
|
25126
|
+
"audience_mismatch",
|
|
24968
25127
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24969
25128
|
);
|
|
24970
25129
|
}
|
|
24971
25130
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24972
|
-
|
|
25131
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
24973
25132
|
}
|
|
24974
|
-
|
|
24975
|
-
|
|
24976
|
-
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
25133
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25134
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
24977
25135
|
}
|
|
24978
25136
|
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
24979
25137
|
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24980
25138
|
}
|
|
24981
25139
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24982
25140
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24983
|
-
|
|
25141
|
+
reject(
|
|
25142
|
+
"cid_mismatch",
|
|
24984
25143
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24985
25144
|
);
|
|
24986
25145
|
}
|
|
@@ -25010,22 +25169,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
25010
25169
|
})),
|
|
25011
25170
|
expiry: new Date(signed2.expiry),
|
|
25012
25171
|
delegateDID: signed2.audience,
|
|
25013
|
-
host
|
|
25172
|
+
host,
|
|
25173
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
25014
25174
|
};
|
|
25015
|
-
|
|
25016
|
-
|
|
25017
|
-
|
|
25018
|
-
|
|
25175
|
+
try {
|
|
25176
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25177
|
+
await node.useDelegation(installedCandidate);
|
|
25178
|
+
} else {
|
|
25179
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25180
|
+
}
|
|
25181
|
+
} catch (error) {
|
|
25182
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
25019
25183
|
}
|
|
25020
25184
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
25021
25185
|
if (!installed) {
|
|
25022
|
-
|
|
25186
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
25023
25187
|
}
|
|
25024
25188
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
25025
25189
|
canonicalResourcesFromPortableDelegation(installed),
|
|
25026
25190
|
signed2.resources
|
|
25027
25191
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
25028
|
-
|
|
25192
|
+
reject(
|
|
25193
|
+
"activation_rejected",
|
|
25029
25194
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
25030
25195
|
);
|
|
25031
25196
|
}
|
|
@@ -25256,6 +25421,8 @@ export {
|
|
|
25256
25421
|
PrefixedKVService,
|
|
25257
25422
|
PrivateKeySigner,
|
|
25258
25423
|
ProtocolMismatchError,
|
|
25424
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25425
|
+
RuntimeDelegationRejectedError,
|
|
25259
25426
|
SECRET_NAME_RE,
|
|
25260
25427
|
SQLAction,
|
|
25261
25428
|
SQLService3 as SQLService,
|