@tinycloud/node-sdk 3.1.0-beta.6 → 3.1.0-beta.8
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 +197 -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 +197 -53
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +249 -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 +248 -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
|
}
|
|
@@ -18738,14 +18742,14 @@ var NodeUserAuthorization = class {
|
|
|
18738
18742
|
* Request signature via event emitter with timeout.
|
|
18739
18743
|
*/
|
|
18740
18744
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18741
|
-
return new Promise((resolve,
|
|
18745
|
+
return new Promise((resolve, reject2) => {
|
|
18742
18746
|
const timeoutId = setTimeout(() => {
|
|
18743
|
-
|
|
18747
|
+
reject2(new Error("Sign request timed out"));
|
|
18744
18748
|
}, timeout);
|
|
18745
18749
|
const respond = async (response) => {
|
|
18746
18750
|
clearTimeout(timeoutId);
|
|
18747
18751
|
if (!response.approved) {
|
|
18748
|
-
|
|
18752
|
+
reject2(
|
|
18749
18753
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18750
18754
|
);
|
|
18751
18755
|
} else {
|
|
@@ -19340,6 +19344,25 @@ function jsonFromVerifier(value) {
|
|
|
19340
19344
|
function verifierRecapEntries(entries) {
|
|
19341
19345
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19342
19346
|
}
|
|
19347
|
+
function exactVerifiedRecap(verified) {
|
|
19348
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19349
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19350
|
+
(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(
|
|
19351
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19352
|
+
)
|
|
19353
|
+
)) {
|
|
19354
|
+
throw new UnsupportedSessionRestoreError(
|
|
19355
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19356
|
+
);
|
|
19357
|
+
}
|
|
19358
|
+
return exactRecap.map((entry) => ({
|
|
19359
|
+
service: entry.service,
|
|
19360
|
+
space: entry.space,
|
|
19361
|
+
path: entry.path,
|
|
19362
|
+
actions: [...entry.actions],
|
|
19363
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19364
|
+
}));
|
|
19365
|
+
}
|
|
19343
19366
|
var ServiceGraphLifetime = class {
|
|
19344
19367
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19345
19368
|
this.invokeFn = invokeFn;
|
|
@@ -21004,23 +21027,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21004
21027
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
21005
21028
|
}
|
|
21006
21029
|
})();
|
|
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
|
-
}));
|
|
21030
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
21024
21031
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
21025
21032
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
21026
21033
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -22881,6 +22888,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22881
22888
|
(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
22889
|
);
|
|
22883
22890
|
}
|
|
22891
|
+
/**
|
|
22892
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22893
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22894
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22895
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22896
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22897
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22898
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22899
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22900
|
+
* which also refuses decrypt-only grants.
|
|
22901
|
+
*/
|
|
22902
|
+
verifySessionGrant(grant) {
|
|
22903
|
+
const bindings = this.wasmBindings;
|
|
22904
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22905
|
+
if (validate5 === void 0) {
|
|
22906
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22907
|
+
}
|
|
22908
|
+
const verified = validate5({
|
|
22909
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22910
|
+
delegationCid: grant.delegationCid,
|
|
22911
|
+
spaceId: grant.spaceId,
|
|
22912
|
+
jwk: this.sessionKeyJwk,
|
|
22913
|
+
address: canonicalizeAddress2(grant.address),
|
|
22914
|
+
chainId: grant.chainId,
|
|
22915
|
+
siwe: grant.siwe,
|
|
22916
|
+
signature: grant.signature
|
|
22917
|
+
});
|
|
22918
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22919
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22920
|
+
}
|
|
22921
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22922
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22923
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22924
|
+
}
|
|
22925
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22926
|
+
}
|
|
22884
22927
|
/**
|
|
22885
22928
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22886
22929
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -23013,7 +23056,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23013
23056
|
delegatedEntries,
|
|
23014
23057
|
spaceId,
|
|
23015
23058
|
session,
|
|
23016
|
-
expiresAt
|
|
23059
|
+
expiresAt,
|
|
23060
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
23017
23061
|
);
|
|
23018
23062
|
this.runtimePermissionGrants.push({
|
|
23019
23063
|
session: {
|
|
@@ -23799,7 +23843,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23799
23843
|
}
|
|
23800
23844
|
return grants;
|
|
23801
23845
|
}
|
|
23802
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23846
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23803
23847
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23804
23848
|
const primary = resources[0];
|
|
23805
23849
|
return {
|
|
@@ -23814,7 +23858,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23814
23858
|
delegateDID: session.verificationMethod,
|
|
23815
23859
|
ownerAddress: session.address,
|
|
23816
23860
|
chainId: session.chainId,
|
|
23817
|
-
host: this.config.host
|
|
23861
|
+
host: this.config.host,
|
|
23862
|
+
siweProof
|
|
23818
23863
|
};
|
|
23819
23864
|
}
|
|
23820
23865
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -24737,6 +24782,29 @@ import {
|
|
|
24737
24782
|
decodeBase64Url,
|
|
24738
24783
|
principalDidEquals as principalDidEquals3
|
|
24739
24784
|
} from "@tinycloud/sdk-core";
|
|
24785
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24786
|
+
"host_mismatch",
|
|
24787
|
+
"expired",
|
|
24788
|
+
"cid_mismatch",
|
|
24789
|
+
"authority_invalid",
|
|
24790
|
+
"proof_missing",
|
|
24791
|
+
"proof_invalid",
|
|
24792
|
+
"owner_mismatch",
|
|
24793
|
+
"audience_mismatch",
|
|
24794
|
+
"resources_mismatch",
|
|
24795
|
+
"unsupported",
|
|
24796
|
+
"activation_rejected"
|
|
24797
|
+
];
|
|
24798
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24799
|
+
constructor(reason, message) {
|
|
24800
|
+
super(message);
|
|
24801
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24802
|
+
this.reason = reason;
|
|
24803
|
+
}
|
|
24804
|
+
};
|
|
24805
|
+
function reject(reason, message) {
|
|
24806
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24807
|
+
}
|
|
24740
24808
|
var SERVICE_BY_SHORT_NAME = {
|
|
24741
24809
|
kv: "tinycloud.kv",
|
|
24742
24810
|
sql: "tinycloud.sql",
|
|
@@ -24883,6 +24951,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24883
24951
|
abilities
|
|
24884
24952
|
));
|
|
24885
24953
|
}
|
|
24954
|
+
return canonicalSignedAuthority({
|
|
24955
|
+
issuer: payload.iss,
|
|
24956
|
+
audience: payload.aud,
|
|
24957
|
+
expiry,
|
|
24958
|
+
proofs: [...payload.prf],
|
|
24959
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24960
|
+
}, permissions);
|
|
24961
|
+
}
|
|
24962
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24886
24963
|
if (permissions.length === 0) {
|
|
24887
24964
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24888
24965
|
}
|
|
@@ -24894,15 +24971,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24894
24971
|
actions: [...permission.actions],
|
|
24895
24972
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24896
24973
|
}));
|
|
24897
|
-
return {
|
|
24898
|
-
|
|
24899
|
-
|
|
24900
|
-
|
|
24901
|
-
|
|
24902
|
-
|
|
24903
|
-
|
|
24904
|
-
|
|
24905
|
-
|
|
24974
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24975
|
+
}
|
|
24976
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24977
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24978
|
+
function comparableSpace(space) {
|
|
24979
|
+
const match = PKH_SPACE.exec(space);
|
|
24980
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24981
|
+
}
|
|
24982
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
24983
|
+
const proof = delegation.siweProof;
|
|
24984
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
24985
|
+
reject(
|
|
24986
|
+
"proof_missing",
|
|
24987
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
24988
|
+
);
|
|
24989
|
+
}
|
|
24990
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
24991
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
24992
|
+
}
|
|
24993
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
24994
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
24995
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
24996
|
+
}
|
|
24997
|
+
let verified;
|
|
24998
|
+
try {
|
|
24999
|
+
verified = node.verifySessionGrant({
|
|
25000
|
+
delegationHeader: { Authorization: authorization },
|
|
25001
|
+
delegationCid: cid,
|
|
25002
|
+
spaceId: delegation.spaceId,
|
|
25003
|
+
address: delegation.ownerAddress,
|
|
25004
|
+
chainId: delegation.chainId,
|
|
25005
|
+
siwe: proof.siwe,
|
|
25006
|
+
signature: proof.signature
|
|
25007
|
+
});
|
|
25008
|
+
} catch (error) {
|
|
25009
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
25010
|
+
}
|
|
25011
|
+
const space = comparableSpace(delegation.spaceId);
|
|
25012
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
25013
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
25014
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
25015
|
+
}
|
|
25016
|
+
const groups = /* @__PURE__ */ new Map();
|
|
25017
|
+
for (const entry of verified.recap) {
|
|
25018
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
25019
|
+
const raw = entry.space === "encryption";
|
|
25020
|
+
if (raw) {
|
|
25021
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
25022
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
25023
|
+
}
|
|
25024
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
25025
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
25026
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
25027
|
+
}
|
|
25028
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
25029
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
25030
|
+
}
|
|
25031
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
25032
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, canonicalizeRecapCaveats2(caveats)]);
|
|
25033
|
+
const group = groups.get(key2) ?? {
|
|
25034
|
+
service,
|
|
25035
|
+
...raw ? {} : { space: entry.space },
|
|
25036
|
+
path: entry.path,
|
|
25037
|
+
actions: [],
|
|
25038
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25039
|
+
};
|
|
25040
|
+
for (const action of entry.actions) {
|
|
25041
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25042
|
+
}
|
|
25043
|
+
groups.set(key2, group);
|
|
25044
|
+
}
|
|
25045
|
+
return canonicalSignedAuthority({
|
|
25046
|
+
issuer: owner,
|
|
25047
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25048
|
+
audience: node.sessionDid,
|
|
25049
|
+
expiry: verified.expiresAt,
|
|
25050
|
+
proofs: []
|
|
25051
|
+
}, [...groups.values()]);
|
|
24906
25052
|
}
|
|
24907
25053
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24908
25054
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24938,49 +25084,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24938
25084
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24939
25085
|
const host = normalizedHost(options.host);
|
|
24940
25086
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24941
|
-
|
|
25087
|
+
reject(
|
|
25088
|
+
"host_mismatch",
|
|
24942
25089
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24943
25090
|
);
|
|
24944
25091
|
}
|
|
24945
25092
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24946
|
-
|
|
25093
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24947
25094
|
}
|
|
24948
25095
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24949
|
-
|
|
25096
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24950
25097
|
}
|
|
24951
25098
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24952
25099
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24953
|
-
|
|
25100
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24954
25101
|
}
|
|
24955
25102
|
const cid = node.computeDelegationCid(authorization);
|
|
24956
25103
|
if (cid !== delegation.cid) {
|
|
24957
|
-
|
|
25104
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25105
|
+
}
|
|
25106
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25107
|
+
let signed2;
|
|
25108
|
+
try {
|
|
25109
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25110
|
+
} catch (error) {
|
|
25111
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25112
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24958
25113
|
}
|
|
24959
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24960
25114
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24961
|
-
|
|
25115
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24962
25116
|
}
|
|
24963
25117
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24964
|
-
|
|
25118
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24965
25119
|
}
|
|
24966
25120
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24967
|
-
|
|
25121
|
+
reject(
|
|
25122
|
+
"audience_mismatch",
|
|
24968
25123
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24969
25124
|
);
|
|
24970
25125
|
}
|
|
24971
25126
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24972
|
-
|
|
25127
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
24973
25128
|
}
|
|
24974
|
-
|
|
24975
|
-
|
|
24976
|
-
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
25129
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25130
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
24977
25131
|
}
|
|
24978
25132
|
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
24979
25133
|
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24980
25134
|
}
|
|
24981
25135
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24982
25136
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24983
|
-
|
|
25137
|
+
reject(
|
|
25138
|
+
"cid_mismatch",
|
|
24984
25139
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24985
25140
|
);
|
|
24986
25141
|
}
|
|
@@ -25010,22 +25165,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
25010
25165
|
})),
|
|
25011
25166
|
expiry: new Date(signed2.expiry),
|
|
25012
25167
|
delegateDID: signed2.audience,
|
|
25013
|
-
host
|
|
25168
|
+
host,
|
|
25169
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
25014
25170
|
};
|
|
25015
|
-
|
|
25016
|
-
|
|
25017
|
-
|
|
25018
|
-
|
|
25171
|
+
try {
|
|
25172
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25173
|
+
await node.useDelegation(installedCandidate);
|
|
25174
|
+
} else {
|
|
25175
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25176
|
+
}
|
|
25177
|
+
} catch (error) {
|
|
25178
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
25019
25179
|
}
|
|
25020
25180
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
25021
25181
|
if (!installed) {
|
|
25022
|
-
|
|
25182
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
25023
25183
|
}
|
|
25024
25184
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
25025
25185
|
canonicalResourcesFromPortableDelegation(installed),
|
|
25026
25186
|
signed2.resources
|
|
25027
25187
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
25028
|
-
|
|
25188
|
+
reject(
|
|
25189
|
+
"activation_rejected",
|
|
25029
25190
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
25030
25191
|
);
|
|
25031
25192
|
}
|
|
@@ -25256,6 +25417,8 @@ export {
|
|
|
25256
25417
|
PrefixedKVService,
|
|
25257
25418
|
PrivateKeySigner,
|
|
25258
25419
|
ProtocolMismatchError,
|
|
25420
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25421
|
+
RuntimeDelegationRejectedError,
|
|
25259
25422
|
SECRET_NAME_RE,
|
|
25260
25423
|
SQLAction,
|
|
25261
25424
|
SQLService3 as SQLService,
|