@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.cjs
CHANGED
|
@@ -4404,19 +4404,19 @@ var init_lib4 = __esm({
|
|
|
4404
4404
|
resolve(value);
|
|
4405
4405
|
});
|
|
4406
4406
|
}
|
|
4407
|
-
return new (P || (P = Promise))(function(resolve,
|
|
4407
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
4408
4408
|
function fulfilled(value) {
|
|
4409
4409
|
try {
|
|
4410
4410
|
step(generator.next(value));
|
|
4411
4411
|
} catch (e) {
|
|
4412
|
-
|
|
4412
|
+
reject2(e);
|
|
4413
4413
|
}
|
|
4414
4414
|
}
|
|
4415
4415
|
function rejected(value) {
|
|
4416
4416
|
try {
|
|
4417
4417
|
step(generator["throw"](value));
|
|
4418
4418
|
} catch (e) {
|
|
4419
|
-
|
|
4419
|
+
reject2(e);
|
|
4420
4420
|
}
|
|
4421
4421
|
}
|
|
4422
4422
|
function step(result) {
|
|
@@ -8040,19 +8040,19 @@ var init_typed_data = __esm({
|
|
|
8040
8040
|
resolve(value);
|
|
8041
8041
|
});
|
|
8042
8042
|
}
|
|
8043
|
-
return new (P || (P = Promise))(function(resolve,
|
|
8043
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
8044
8044
|
function fulfilled(value) {
|
|
8045
8045
|
try {
|
|
8046
8046
|
step(generator.next(value));
|
|
8047
8047
|
} catch (e) {
|
|
8048
|
-
|
|
8048
|
+
reject2(e);
|
|
8049
8049
|
}
|
|
8050
8050
|
}
|
|
8051
8051
|
function rejected(value) {
|
|
8052
8052
|
try {
|
|
8053
8053
|
step(generator["throw"](value));
|
|
8054
8054
|
} catch (e) {
|
|
8055
|
-
|
|
8055
|
+
reject2(e);
|
|
8056
8056
|
}
|
|
8057
8057
|
}
|
|
8058
8058
|
function step(result) {
|
|
@@ -14898,14 +14898,14 @@ var require_scrypt = __commonJS({
|
|
|
14898
14898
|
}
|
|
14899
14899
|
const lib = {
|
|
14900
14900
|
scrypt: function(password, salt, N2, r2, p, dkLen, progressCallback) {
|
|
14901
|
-
return new Promise(function(resolve,
|
|
14901
|
+
return new Promise(function(resolve, reject2) {
|
|
14902
14902
|
let lastProgress = 0;
|
|
14903
14903
|
if (progressCallback) {
|
|
14904
14904
|
progressCallback(0);
|
|
14905
14905
|
}
|
|
14906
14906
|
_scrypt(password, salt, N2, r2, p, dkLen, function(error, progress, key2) {
|
|
14907
14907
|
if (error) {
|
|
14908
|
-
|
|
14908
|
+
reject2(error);
|
|
14909
14909
|
} else if (key2) {
|
|
14910
14910
|
if (progressCallback && lastProgress !== 1) {
|
|
14911
14911
|
progressCallback(1);
|
|
@@ -15294,19 +15294,19 @@ var init_keystore = __esm({
|
|
|
15294
15294
|
resolve(value);
|
|
15295
15295
|
});
|
|
15296
15296
|
}
|
|
15297
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15297
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15298
15298
|
function fulfilled(value) {
|
|
15299
15299
|
try {
|
|
15300
15300
|
step(generator.next(value));
|
|
15301
15301
|
} catch (e) {
|
|
15302
|
-
|
|
15302
|
+
reject2(e);
|
|
15303
15303
|
}
|
|
15304
15304
|
}
|
|
15305
15305
|
function rejected(value) {
|
|
15306
15306
|
try {
|
|
15307
15307
|
step(generator["throw"](value));
|
|
15308
15308
|
} catch (e) {
|
|
15309
|
-
|
|
15309
|
+
reject2(e);
|
|
15310
15310
|
}
|
|
15311
15311
|
}
|
|
15312
15312
|
function step(result) {
|
|
@@ -15607,19 +15607,19 @@ var init_lib25 = __esm({
|
|
|
15607
15607
|
resolve(value);
|
|
15608
15608
|
});
|
|
15609
15609
|
}
|
|
15610
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15610
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15611
15611
|
function fulfilled(value) {
|
|
15612
15612
|
try {
|
|
15613
15613
|
step(generator.next(value));
|
|
15614
15614
|
} catch (e) {
|
|
15615
|
-
|
|
15615
|
+
reject2(e);
|
|
15616
15616
|
}
|
|
15617
15617
|
}
|
|
15618
15618
|
function rejected(value) {
|
|
15619
15619
|
try {
|
|
15620
15620
|
step(generator["throw"](value));
|
|
15621
15621
|
} catch (e) {
|
|
15622
|
-
|
|
15622
|
+
reject2(e);
|
|
15623
15623
|
}
|
|
15624
15624
|
}
|
|
15625
15625
|
function step(result) {
|
|
@@ -15689,19 +15689,19 @@ var init_lib26 = __esm({
|
|
|
15689
15689
|
resolve(value);
|
|
15690
15690
|
});
|
|
15691
15691
|
}
|
|
15692
|
-
return new (P || (P = Promise))(function(resolve,
|
|
15692
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
15693
15693
|
function fulfilled(value) {
|
|
15694
15694
|
try {
|
|
15695
15695
|
step(generator.next(value));
|
|
15696
15696
|
} catch (e) {
|
|
15697
|
-
|
|
15697
|
+
reject2(e);
|
|
15698
15698
|
}
|
|
15699
15699
|
}
|
|
15700
15700
|
function rejected(value) {
|
|
15701
15701
|
try {
|
|
15702
15702
|
step(generator["throw"](value));
|
|
15703
15703
|
} catch (e) {
|
|
15704
|
-
|
|
15704
|
+
reject2(e);
|
|
15705
15705
|
}
|
|
15706
15706
|
}
|
|
15707
15707
|
function step(result) {
|
|
@@ -16011,19 +16011,19 @@ var init_lib27 = __esm({
|
|
|
16011
16011
|
resolve(value);
|
|
16012
16012
|
});
|
|
16013
16013
|
}
|
|
16014
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16014
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16015
16015
|
function fulfilled(value) {
|
|
16016
16016
|
try {
|
|
16017
16017
|
step(generator.next(value));
|
|
16018
16018
|
} catch (e) {
|
|
16019
|
-
|
|
16019
|
+
reject2(e);
|
|
16020
16020
|
}
|
|
16021
16021
|
}
|
|
16022
16022
|
function rejected(value) {
|
|
16023
16023
|
try {
|
|
16024
16024
|
step(generator["throw"](value));
|
|
16025
16025
|
} catch (e) {
|
|
16026
|
-
|
|
16026
|
+
reject2(e);
|
|
16027
16027
|
}
|
|
16028
16028
|
}
|
|
16029
16029
|
function step(result) {
|
|
@@ -16249,19 +16249,19 @@ var init_geturl = __esm({
|
|
|
16249
16249
|
resolve(value);
|
|
16250
16250
|
});
|
|
16251
16251
|
}
|
|
16252
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16252
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16253
16253
|
function fulfilled(value) {
|
|
16254
16254
|
try {
|
|
16255
16255
|
step(generator.next(value));
|
|
16256
16256
|
} catch (e) {
|
|
16257
|
-
|
|
16257
|
+
reject2(e);
|
|
16258
16258
|
}
|
|
16259
16259
|
}
|
|
16260
16260
|
function rejected(value) {
|
|
16261
16261
|
try {
|
|
16262
16262
|
step(generator["throw"](value));
|
|
16263
16263
|
} catch (e) {
|
|
16264
|
-
|
|
16264
|
+
reject2(e);
|
|
16265
16265
|
}
|
|
16266
16266
|
}
|
|
16267
16267
|
function step(result) {
|
|
@@ -16402,14 +16402,14 @@ function _fetchData(connection, body, processFunc) {
|
|
|
16402
16402
|
options.headers = flatHeaders;
|
|
16403
16403
|
const runningTimeout = (function() {
|
|
16404
16404
|
let timer = null;
|
|
16405
|
-
const promise = new Promise(function(resolve,
|
|
16405
|
+
const promise = new Promise(function(resolve, reject2) {
|
|
16406
16406
|
if (timeout) {
|
|
16407
16407
|
timer = setTimeout(() => {
|
|
16408
16408
|
if (timer == null) {
|
|
16409
16409
|
return;
|
|
16410
16410
|
}
|
|
16411
16411
|
timer = null;
|
|
16412
|
-
|
|
16412
|
+
reject2(logger28.makeError("timeout", Logger.errors.TIMEOUT, {
|
|
16413
16413
|
requestBody: bodyify(options.body, flatHeaders["content-type"]),
|
|
16414
16414
|
requestMethod: options.method,
|
|
16415
16415
|
timeout,
|
|
@@ -16572,7 +16572,7 @@ function poll(func, options) {
|
|
|
16572
16572
|
if (options.interval == null) {
|
|
16573
16573
|
options.interval = 250;
|
|
16574
16574
|
}
|
|
16575
|
-
return new Promise(function(resolve,
|
|
16575
|
+
return new Promise(function(resolve, reject2) {
|
|
16576
16576
|
let timer = null;
|
|
16577
16577
|
let done = false;
|
|
16578
16578
|
const cancel = () => {
|
|
@@ -16588,7 +16588,7 @@ function poll(func, options) {
|
|
|
16588
16588
|
if (options.timeout) {
|
|
16589
16589
|
timer = setTimeout(() => {
|
|
16590
16590
|
if (cancel()) {
|
|
16591
|
-
|
|
16591
|
+
reject2(new Error("timeout"));
|
|
16592
16592
|
}
|
|
16593
16593
|
}, options.timeout);
|
|
16594
16594
|
}
|
|
@@ -16608,7 +16608,7 @@ function poll(func, options) {
|
|
|
16608
16608
|
attempt++;
|
|
16609
16609
|
if (attempt > retryLimit) {
|
|
16610
16610
|
if (cancel()) {
|
|
16611
|
-
|
|
16611
|
+
reject2(new Error("retry limit reached"));
|
|
16612
16612
|
}
|
|
16613
16613
|
return;
|
|
16614
16614
|
}
|
|
@@ -16624,7 +16624,7 @@ function poll(func, options) {
|
|
|
16624
16624
|
return null;
|
|
16625
16625
|
}, function(error) {
|
|
16626
16626
|
if (cancel()) {
|
|
16627
|
-
|
|
16627
|
+
reject2(error);
|
|
16628
16628
|
}
|
|
16629
16629
|
});
|
|
16630
16630
|
}
|
|
@@ -16648,19 +16648,19 @@ var init_lib28 = __esm({
|
|
|
16648
16648
|
resolve(value);
|
|
16649
16649
|
});
|
|
16650
16650
|
}
|
|
16651
|
-
return new (P || (P = Promise))(function(resolve,
|
|
16651
|
+
return new (P || (P = Promise))(function(resolve, reject2) {
|
|
16652
16652
|
function fulfilled(value) {
|
|
16653
16653
|
try {
|
|
16654
16654
|
step(generator.next(value));
|
|
16655
16655
|
} catch (e) {
|
|
16656
|
-
|
|
16656
|
+
reject2(e);
|
|
16657
16657
|
}
|
|
16658
16658
|
}
|
|
16659
16659
|
function rejected(value) {
|
|
16660
16660
|
try {
|
|
16661
16661
|
step(generator["throw"](value));
|
|
16662
16662
|
} catch (e) {
|
|
16663
|
-
|
|
16663
|
+
reject2(e);
|
|
16664
16664
|
}
|
|
16665
16665
|
}
|
|
16666
16666
|
function step(result) {
|
|
@@ -17072,6 +17072,8 @@ __export(index_exports, {
|
|
|
17072
17072
|
PrefixedKVService: () => import_sdk_core13.PrefixedKVService,
|
|
17073
17073
|
PrivateKeySigner: () => PrivateKeySigner,
|
|
17074
17074
|
ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
|
|
17075
|
+
RUNTIME_DELEGATION_REJECTIONS: () => RUNTIME_DELEGATION_REJECTIONS,
|
|
17076
|
+
RuntimeDelegationRejectedError: () => RuntimeDelegationRejectedError,
|
|
17075
17077
|
SECRET_NAME_RE: () => import_sdk_core16.SECRET_NAME_RE,
|
|
17076
17078
|
SQLAction: () => import_sdk_core14.SQLAction,
|
|
17077
17079
|
SQLService: () => import_sdk_core14.SQLService,
|
|
@@ -17213,6 +17215,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17213
17215
|
validatePersistedSession(proof) {
|
|
17214
17216
|
return (0, import_node_sdk_wasm.validatePersistedSession)(proof);
|
|
17215
17217
|
}
|
|
17218
|
+
validateSessionGrant(proof) {
|
|
17219
|
+
return (0, import_node_sdk_wasm.validateSessionGrant)(proof);
|
|
17220
|
+
}
|
|
17216
17221
|
createSessionManager() {
|
|
17217
17222
|
return new import_node_sdk_wasm.TCWSessionManager();
|
|
17218
17223
|
}
|
|
@@ -18767,14 +18772,14 @@ var NodeUserAuthorization = class {
|
|
|
18767
18772
|
* Request signature via event emitter with timeout.
|
|
18768
18773
|
*/
|
|
18769
18774
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
18770
|
-
return new Promise((resolve,
|
|
18775
|
+
return new Promise((resolve, reject2) => {
|
|
18771
18776
|
const timeoutId = setTimeout(() => {
|
|
18772
|
-
|
|
18777
|
+
reject2(new Error("Sign request timed out"));
|
|
18773
18778
|
}, timeout);
|
|
18774
18779
|
const respond = async (response) => {
|
|
18775
18780
|
clearTimeout(timeoutId);
|
|
18776
18781
|
if (!response.approved) {
|
|
18777
|
-
|
|
18782
|
+
reject2(
|
|
18778
18783
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
18779
18784
|
);
|
|
18780
18785
|
} else {
|
|
@@ -19353,6 +19358,25 @@ function jsonFromVerifier(value) {
|
|
|
19353
19358
|
function verifierRecapEntries(entries) {
|
|
19354
19359
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
19355
19360
|
}
|
|
19361
|
+
function exactVerifiedRecap(verified) {
|
|
19362
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
19363
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
19364
|
+
(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(
|
|
19365
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
19366
|
+
)
|
|
19367
|
+
)) {
|
|
19368
|
+
throw new UnsupportedSessionRestoreError(
|
|
19369
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
19370
|
+
);
|
|
19371
|
+
}
|
|
19372
|
+
return exactRecap.map((entry) => ({
|
|
19373
|
+
service: entry.service,
|
|
19374
|
+
space: entry.space,
|
|
19375
|
+
path: entry.path,
|
|
19376
|
+
actions: [...entry.actions],
|
|
19377
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19378
|
+
}));
|
|
19379
|
+
}
|
|
19356
19380
|
var ServiceGraphLifetime = class {
|
|
19357
19381
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
19358
19382
|
this.invokeFn = invokeFn;
|
|
@@ -21017,23 +21041,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21017
21041
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
21018
21042
|
}
|
|
21019
21043
|
})();
|
|
21020
|
-
|
|
21021
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
21022
|
-
(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(
|
|
21023
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
21024
|
-
)
|
|
21025
|
-
)) {
|
|
21026
|
-
throw new UnsupportedSessionRestoreError(
|
|
21027
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
21028
|
-
);
|
|
21029
|
-
}
|
|
21030
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
21031
|
-
service: entry.service,
|
|
21032
|
-
space: entry.space,
|
|
21033
|
-
path: entry.path,
|
|
21034
|
-
actions: [...entry.actions],
|
|
21035
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
21036
|
-
}));
|
|
21044
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
21037
21045
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
21038
21046
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
21039
21047
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -22894,6 +22902,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22894
22902
|
(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"))
|
|
22895
22903
|
);
|
|
22896
22904
|
}
|
|
22905
|
+
/**
|
|
22906
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
22907
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
22908
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
22909
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
22910
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
22911
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
22912
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
22913
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
22914
|
+
* which also refuses decrypt-only grants.
|
|
22915
|
+
*/
|
|
22916
|
+
verifySessionGrant(grant) {
|
|
22917
|
+
const bindings = this.wasmBindings;
|
|
22918
|
+
const validate5 = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
22919
|
+
if (validate5 === void 0) {
|
|
22920
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
22921
|
+
}
|
|
22922
|
+
const verified = validate5({
|
|
22923
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
22924
|
+
delegationCid: grant.delegationCid,
|
|
22925
|
+
spaceId: grant.spaceId,
|
|
22926
|
+
jwk: this.sessionKeyJwk,
|
|
22927
|
+
address: (0, import_sdk_core7.canonicalizeAddress)(grant.address),
|
|
22928
|
+
chainId: grant.chainId,
|
|
22929
|
+
siwe: grant.siwe,
|
|
22930
|
+
signature: grant.signature
|
|
22931
|
+
});
|
|
22932
|
+
if (typeof verified.expiresAt !== "string") {
|
|
22933
|
+
throw new Error("Session grant has no signed expiry.");
|
|
22934
|
+
}
|
|
22935
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
22936
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
22937
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
22938
|
+
}
|
|
22939
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
22940
|
+
}
|
|
22897
22941
|
/**
|
|
22898
22942
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
22899
22943
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -23026,7 +23070,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23026
23070
|
delegatedEntries,
|
|
23027
23071
|
spaceId,
|
|
23028
23072
|
session,
|
|
23029
|
-
expiresAt
|
|
23073
|
+
expiresAt,
|
|
23074
|
+
{ siwe: prepared.siwe, signature: signature2 }
|
|
23030
23075
|
);
|
|
23031
23076
|
this.runtimePermissionGrants.push({
|
|
23032
23077
|
session: {
|
|
@@ -23812,7 +23857,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23812
23857
|
}
|
|
23813
23858
|
return grants;
|
|
23814
23859
|
}
|
|
23815
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
23860
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
23816
23861
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
23817
23862
|
const primary = resources[0];
|
|
23818
23863
|
return {
|
|
@@ -23827,7 +23872,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
23827
23872
|
delegateDID: session.verificationMethod,
|
|
23828
23873
|
ownerAddress: session.address,
|
|
23829
23874
|
chainId: session.chainId,
|
|
23830
|
-
host: this.config.host
|
|
23875
|
+
host: this.config.host,
|
|
23876
|
+
siweProof
|
|
23831
23877
|
};
|
|
23832
23878
|
}
|
|
23833
23879
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -24697,6 +24743,29 @@ var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
|
24697
24743
|
|
|
24698
24744
|
// src/delegation.ts
|
|
24699
24745
|
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
24746
|
+
var RUNTIME_DELEGATION_REJECTIONS = [
|
|
24747
|
+
"host_mismatch",
|
|
24748
|
+
"expired",
|
|
24749
|
+
"cid_mismatch",
|
|
24750
|
+
"authority_invalid",
|
|
24751
|
+
"proof_missing",
|
|
24752
|
+
"proof_invalid",
|
|
24753
|
+
"owner_mismatch",
|
|
24754
|
+
"audience_mismatch",
|
|
24755
|
+
"resources_mismatch",
|
|
24756
|
+
"unsupported",
|
|
24757
|
+
"activation_rejected"
|
|
24758
|
+
];
|
|
24759
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
24760
|
+
constructor(reason, message) {
|
|
24761
|
+
super(message);
|
|
24762
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
24763
|
+
this.reason = reason;
|
|
24764
|
+
}
|
|
24765
|
+
};
|
|
24766
|
+
function reject(reason, message) {
|
|
24767
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
24768
|
+
}
|
|
24700
24769
|
var SERVICE_BY_SHORT_NAME = {
|
|
24701
24770
|
kv: "tinycloud.kv",
|
|
24702
24771
|
sql: "tinycloud.sql",
|
|
@@ -24843,6 +24912,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24843
24912
|
abilities
|
|
24844
24913
|
));
|
|
24845
24914
|
}
|
|
24915
|
+
return canonicalSignedAuthority({
|
|
24916
|
+
issuer: payload.iss,
|
|
24917
|
+
audience: payload.aud,
|
|
24918
|
+
expiry,
|
|
24919
|
+
proofs: [...payload.prf],
|
|
24920
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
24921
|
+
}, permissions);
|
|
24922
|
+
}
|
|
24923
|
+
function canonicalSignedAuthority(signed2, permissions) {
|
|
24846
24924
|
if (permissions.length === 0) {
|
|
24847
24925
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
24848
24926
|
}
|
|
@@ -24854,15 +24932,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
24854
24932
|
actions: [...permission.actions],
|
|
24855
24933
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
24856
24934
|
}));
|
|
24857
|
-
return {
|
|
24858
|
-
|
|
24859
|
-
|
|
24860
|
-
|
|
24861
|
-
|
|
24862
|
-
|
|
24863
|
-
|
|
24864
|
-
|
|
24865
|
-
|
|
24935
|
+
return { ...signed2, permissions: canonicalPermissions, resources: canonicalResources };
|
|
24936
|
+
}
|
|
24937
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
24938
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
24939
|
+
function comparableSpace(space) {
|
|
24940
|
+
const match = PKH_SPACE.exec(space);
|
|
24941
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
24942
|
+
}
|
|
24943
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
24944
|
+
const proof = delegation.siweProof;
|
|
24945
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
24946
|
+
reject(
|
|
24947
|
+
"proof_missing",
|
|
24948
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
24949
|
+
);
|
|
24950
|
+
}
|
|
24951
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
24952
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
24953
|
+
}
|
|
24954
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
24955
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
24956
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
24957
|
+
}
|
|
24958
|
+
let verified;
|
|
24959
|
+
try {
|
|
24960
|
+
verified = node.verifySessionGrant({
|
|
24961
|
+
delegationHeader: { Authorization: authorization },
|
|
24962
|
+
delegationCid: cid,
|
|
24963
|
+
spaceId: delegation.spaceId,
|
|
24964
|
+
address: delegation.ownerAddress,
|
|
24965
|
+
chainId: delegation.chainId,
|
|
24966
|
+
siwe: proof.siwe,
|
|
24967
|
+
signature: proof.signature
|
|
24968
|
+
});
|
|
24969
|
+
} catch (error) {
|
|
24970
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
24971
|
+
}
|
|
24972
|
+
const space = comparableSpace(delegation.spaceId);
|
|
24973
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
24974
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
24975
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
24976
|
+
}
|
|
24977
|
+
const groups = /* @__PURE__ */ new Map();
|
|
24978
|
+
for (const entry of verified.recap) {
|
|
24979
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
24980
|
+
const raw = entry.space === "encryption";
|
|
24981
|
+
if (raw) {
|
|
24982
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
24983
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
24984
|
+
}
|
|
24985
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
24986
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
24987
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
24988
|
+
}
|
|
24989
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
24990
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
24991
|
+
}
|
|
24992
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
24993
|
+
const key2 = JSON.stringify([service, raw ? "" : entry.space, entry.path, (0, import_sdk_core9.canonicalizeRecapCaveats)(caveats)]);
|
|
24994
|
+
const group = groups.get(key2) ?? {
|
|
24995
|
+
service,
|
|
24996
|
+
...raw ? {} : { space: entry.space },
|
|
24997
|
+
path: entry.path,
|
|
24998
|
+
actions: [],
|
|
24999
|
+
...caveats === void 0 ? {} : { caveats }
|
|
25000
|
+
};
|
|
25001
|
+
for (const action of entry.actions) {
|
|
25002
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
25003
|
+
}
|
|
25004
|
+
groups.set(key2, group);
|
|
25005
|
+
}
|
|
25006
|
+
return canonicalSignedAuthority({
|
|
25007
|
+
issuer: owner,
|
|
25008
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
25009
|
+
audience: node.sessionDid,
|
|
25010
|
+
expiry: verified.expiresAt,
|
|
25011
|
+
proofs: []
|
|
25012
|
+
}, [...groups.values()]);
|
|
24866
25013
|
}
|
|
24867
25014
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
24868
25015
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -24898,49 +25045,58 @@ function resourcesMatch(actual, expected) {
|
|
|
24898
25045
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
24899
25046
|
const host = normalizedHost(options.host);
|
|
24900
25047
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
24901
|
-
|
|
25048
|
+
reject(
|
|
25049
|
+
"host_mismatch",
|
|
24902
25050
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
24903
25051
|
);
|
|
24904
25052
|
}
|
|
24905
25053
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
24906
|
-
|
|
25054
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
24907
25055
|
}
|
|
24908
25056
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
24909
|
-
|
|
25057
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24910
25058
|
}
|
|
24911
25059
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
24912
25060
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
24913
|
-
|
|
25061
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
24914
25062
|
}
|
|
24915
25063
|
const cid = node.computeDelegationCid(authorization);
|
|
24916
25064
|
if (cid !== delegation.cid) {
|
|
24917
|
-
|
|
25065
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
25066
|
+
}
|
|
25067
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
25068
|
+
let signed2;
|
|
25069
|
+
try {
|
|
25070
|
+
signed2 = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
25071
|
+
} catch (error) {
|
|
25072
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
25073
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
24918
25074
|
}
|
|
24919
|
-
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
24920
25075
|
if (signed2.expiry.getTime() <= Date.now()) {
|
|
24921
|
-
|
|
25076
|
+
reject("expired", "Runtime delegation is expired.");
|
|
24922
25077
|
}
|
|
24923
25078
|
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
24924
|
-
|
|
25079
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
24925
25080
|
}
|
|
24926
25081
|
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
24927
|
-
|
|
25082
|
+
reject(
|
|
25083
|
+
"audience_mismatch",
|
|
24928
25084
|
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
24929
25085
|
);
|
|
24930
25086
|
}
|
|
24931
25087
|
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
24932
|
-
|
|
25088
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
24933
25089
|
}
|
|
24934
|
-
|
|
24935
|
-
|
|
24936
|
-
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
25090
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed2.resources)) {
|
|
25091
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
24937
25092
|
}
|
|
24938
25093
|
if (options.authorize !== void 0 && !options.authorize(signed2.permissions)) {
|
|
24939
25094
|
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
24940
25095
|
}
|
|
24941
25096
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24942
25097
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
24943
|
-
|
|
25098
|
+
reject(
|
|
25099
|
+
"cid_mismatch",
|
|
24944
25100
|
"A different authorization is already installed for this runtime delegation CID."
|
|
24945
25101
|
);
|
|
24946
25102
|
}
|
|
@@ -24970,22 +25126,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
24970
25126
|
})),
|
|
24971
25127
|
expiry: new Date(signed2.expiry),
|
|
24972
25128
|
delegateDID: signed2.audience,
|
|
24973
|
-
host
|
|
25129
|
+
host,
|
|
25130
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
24974
25131
|
};
|
|
24975
|
-
|
|
24976
|
-
|
|
24977
|
-
|
|
24978
|
-
|
|
25132
|
+
try {
|
|
25133
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && (0, import_sdk_core9.principalDidEquals)(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
25134
|
+
await node.useDelegation(installedCandidate);
|
|
25135
|
+
} else {
|
|
25136
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
25137
|
+
}
|
|
25138
|
+
} catch (error) {
|
|
25139
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
24979
25140
|
}
|
|
24980
25141
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
24981
25142
|
if (!installed) {
|
|
24982
|
-
|
|
25143
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
24983
25144
|
}
|
|
24984
25145
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
24985
25146
|
canonicalResourcesFromPortableDelegation(installed),
|
|
24986
25147
|
signed2.resources
|
|
24987
25148
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
24988
|
-
|
|
25149
|
+
reject(
|
|
25150
|
+
"activation_rejected",
|
|
24989
25151
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
24990
25152
|
);
|
|
24991
25153
|
}
|
|
@@ -25134,6 +25296,8 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
25134
25296
|
PrefixedKVService,
|
|
25135
25297
|
PrivateKeySigner,
|
|
25136
25298
|
ProtocolMismatchError,
|
|
25299
|
+
RUNTIME_DELEGATION_REJECTIONS,
|
|
25300
|
+
RuntimeDelegationRejectedError,
|
|
25137
25301
|
SECRET_NAME_RE,
|
|
25138
25302
|
SQLAction,
|
|
25139
25303
|
SQLService,
|