@tinycloud/node-sdk 3.1.0-beta.1 → 3.1.0-beta.10
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-Bm76PnOz.d.cts → core-CC7uDKZP.d.cts} +77 -6
- package/dist/{core-Bm76PnOz.d.ts → core-CC7uDKZP.d.ts} +77 -6
- package/dist/core.cjs +308 -111
- 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 +314 -112
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +366 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +372 -145
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/core.js
CHANGED
|
@@ -262,6 +262,10 @@ var defaultSignStrategy = { type: "auto-sign" };
|
|
|
262
262
|
// src/authorization/NodeUserAuthorization.ts
|
|
263
263
|
var DECRYPT_ACTION = ENCRYPTION.DECRYPT;
|
|
264
264
|
var NETWORK_CREATE_ACTION = ENCRYPTION.NETWORK_CREATE;
|
|
265
|
+
function describeHostFailure(result) {
|
|
266
|
+
const text = result.error?.trim();
|
|
267
|
+
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
268
|
+
}
|
|
265
269
|
function canonicalizeOpenKeyManifestJson(value) {
|
|
266
270
|
const json = JSON.stringify(value);
|
|
267
271
|
if (json === void 0) {
|
|
@@ -790,10 +794,12 @@ var NodeUserAuthorization = class {
|
|
|
790
794
|
return;
|
|
791
795
|
}
|
|
792
796
|
try {
|
|
793
|
-
const created =
|
|
794
|
-
if (!created) {
|
|
795
|
-
const err =
|
|
796
|
-
|
|
797
|
+
const created = await this.hostSpace();
|
|
798
|
+
if (!created.success) {
|
|
799
|
+
const err = Object.assign(
|
|
800
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
801
|
+
{ cause: created }
|
|
802
|
+
);
|
|
797
803
|
throw err;
|
|
798
804
|
}
|
|
799
805
|
} catch (error) {
|
|
@@ -809,8 +815,9 @@ var NodeUserAuthorization = class {
|
|
|
809
815
|
this._tinyCloudSession.delegationHeader
|
|
810
816
|
);
|
|
811
817
|
if (!retryResult.success) {
|
|
812
|
-
const err =
|
|
813
|
-
`Failed to activate session after creating space: ${retryResult
|
|
818
|
+
const err = Object.assign(
|
|
819
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
820
|
+
{ cause: retryResult }
|
|
814
821
|
);
|
|
815
822
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
816
823
|
throw err;
|
|
@@ -827,10 +834,12 @@ var NodeUserAuthorization = class {
|
|
|
827
834
|
return;
|
|
828
835
|
}
|
|
829
836
|
try {
|
|
830
|
-
const created =
|
|
831
|
-
if (!created) {
|
|
832
|
-
const err =
|
|
833
|
-
|
|
837
|
+
const created = await this.hostSpace();
|
|
838
|
+
if (!created.success) {
|
|
839
|
+
const err = Object.assign(
|
|
840
|
+
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
841
|
+
{ cause: created }
|
|
842
|
+
);
|
|
834
843
|
throw err;
|
|
835
844
|
}
|
|
836
845
|
} catch (error) {
|
|
@@ -846,8 +855,9 @@ var NodeUserAuthorization = class {
|
|
|
846
855
|
this._tinyCloudSession.delegationHeader
|
|
847
856
|
);
|
|
848
857
|
if (!retryResult.success) {
|
|
849
|
-
const err =
|
|
850
|
-
`Failed to activate session after creating space: ${retryResult
|
|
858
|
+
const err = Object.assign(
|
|
859
|
+
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
860
|
+
{ cause: retryResult }
|
|
851
861
|
);
|
|
852
862
|
handler.onSpaceCreationFailed?.(creationContext, err);
|
|
853
863
|
throw err;
|
|
@@ -855,7 +865,10 @@ var NodeUserAuthorization = class {
|
|
|
855
865
|
handler.onSpaceCreated?.(creationContext);
|
|
856
866
|
return;
|
|
857
867
|
}
|
|
858
|
-
throw
|
|
868
|
+
throw Object.assign(
|
|
869
|
+
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
870
|
+
{ cause: result }
|
|
871
|
+
);
|
|
859
872
|
}
|
|
860
873
|
recordActivationSkippedSpaces(result, primarySpaceId) {
|
|
861
874
|
if (result.success) {
|
|
@@ -1645,14 +1658,14 @@ var NodeUserAuthorization = class {
|
|
|
1645
1658
|
* Request signature via event emitter with timeout.
|
|
1646
1659
|
*/
|
|
1647
1660
|
requestSignatureViaEmitter(request, emitter, timeout) {
|
|
1648
|
-
return new Promise((resolve,
|
|
1661
|
+
return new Promise((resolve, reject2) => {
|
|
1649
1662
|
const timeoutId = setTimeout(() => {
|
|
1650
|
-
|
|
1663
|
+
reject2(new Error("Sign request timed out"));
|
|
1651
1664
|
}, timeout);
|
|
1652
1665
|
const respond = async (response) => {
|
|
1653
1666
|
clearTimeout(timeoutId);
|
|
1654
1667
|
if (!response.approved) {
|
|
1655
|
-
|
|
1668
|
+
reject2(
|
|
1656
1669
|
new Error(response.reason ?? "Sign request rejected via emitter")
|
|
1657
1670
|
);
|
|
1658
1671
|
} else {
|
|
@@ -1670,6 +1683,7 @@ import {
|
|
|
1670
1683
|
TinyCloud,
|
|
1671
1684
|
activateSessionWithHost as activateSessionWithHost2,
|
|
1672
1685
|
authorizationVerdictOf,
|
|
1686
|
+
httpResponseError,
|
|
1673
1687
|
KVService as KVService2,
|
|
1674
1688
|
SQLService as SQLService2,
|
|
1675
1689
|
DuckDbService as DuckDbService2,
|
|
@@ -1703,6 +1717,7 @@ import {
|
|
|
1703
1717
|
recapCaveatsEqual,
|
|
1704
1718
|
expandPermissionEntries as expandPermissionEntriesCore,
|
|
1705
1719
|
isCapabilitySubset,
|
|
1720
|
+
isExplicitOnlyAction,
|
|
1706
1721
|
parseRecapCapabilities,
|
|
1707
1722
|
SERVICE_LONG_TO_SHORT,
|
|
1708
1723
|
SERVICE_SHORT_TO_LONG,
|
|
@@ -1725,7 +1740,10 @@ import {
|
|
|
1725
1740
|
CREDENTIAL_INVITATION_REQUEST_DOMAIN,
|
|
1726
1741
|
validateShareDeliveryAuthorizationV3Bytes,
|
|
1727
1742
|
verifyEip191MessageSignature,
|
|
1728
|
-
signCompactUcanRootAuthorization
|
|
1743
|
+
signCompactUcanRootAuthorization,
|
|
1744
|
+
isStorageFullError,
|
|
1745
|
+
STORAGE_FULL_MESSAGE,
|
|
1746
|
+
STORAGE_WRITE_TOO_LARGE_MESSAGE
|
|
1729
1747
|
} from "@tinycloud/sdk-core";
|
|
1730
1748
|
import {
|
|
1731
1749
|
parsePermissionHint
|
|
@@ -2313,6 +2331,25 @@ function jsonFromVerifier(value) {
|
|
|
2313
2331
|
function verifierRecapEntries(entries) {
|
|
2314
2332
|
return entries.map((entry) => Array.isArray(entry.caveats) ? { ...entry, caveats: entry.caveats.map((caveat) => jsonFromVerifier(caveat)) } : entry);
|
|
2315
2333
|
}
|
|
2334
|
+
function exactVerifiedRecap(verified) {
|
|
2335
|
+
const exactRecap = Array.isArray(verified.verifiedRecap) ? verifierRecapEntries(verified.verifiedRecap) : verified.verifiedRecap;
|
|
2336
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
2337
|
+
(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(
|
|
2338
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
2339
|
+
)
|
|
2340
|
+
)) {
|
|
2341
|
+
throw new UnsupportedSessionRestoreError(
|
|
2342
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
2343
|
+
);
|
|
2344
|
+
}
|
|
2345
|
+
return exactRecap.map((entry) => ({
|
|
2346
|
+
service: entry.service,
|
|
2347
|
+
space: entry.space,
|
|
2348
|
+
path: entry.path,
|
|
2349
|
+
actions: [...entry.actions],
|
|
2350
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
2351
|
+
}));
|
|
2352
|
+
}
|
|
2316
2353
|
var ServiceGraphLifetime = class {
|
|
2317
2354
|
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
2318
2355
|
this.invokeFn = invokeFn;
|
|
@@ -2408,7 +2445,7 @@ function persistedExpiry(value) {
|
|
|
2408
2445
|
function sameInstant(left, right) {
|
|
2409
2446
|
return left.getTime() === right.getTime();
|
|
2410
2447
|
}
|
|
2411
|
-
function
|
|
2448
|
+
function describeHostFailure2(result) {
|
|
2412
2449
|
const text = result.error?.trim();
|
|
2413
2450
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
2414
2451
|
}
|
|
@@ -3215,7 +3252,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3215
3252
|
marker
|
|
3216
3253
|
);
|
|
3217
3254
|
if (!written.ok) {
|
|
3218
|
-
throw
|
|
3255
|
+
throw Object.assign(
|
|
3256
|
+
new Error(`Failed to write bootstrap completion marker: ${written.error.message}`),
|
|
3257
|
+
{ cause: written.error }
|
|
3258
|
+
);
|
|
3219
3259
|
}
|
|
3220
3260
|
}
|
|
3221
3261
|
isAcceptedBootstrapCompletionMarker(value) {
|
|
@@ -3261,17 +3301,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3261
3301
|
rawAbilities
|
|
3262
3302
|
});
|
|
3263
3303
|
} catch (err) {
|
|
3264
|
-
throw
|
|
3265
|
-
|
|
3304
|
+
throw Object.assign(
|
|
3305
|
+
new Error(
|
|
3306
|
+
`Account bootstrap aborted: signature rejected for space "${step.space}". Cause: ${err instanceof Error ? err.message : String(err)}`
|
|
3307
|
+
),
|
|
3308
|
+
{ cause: err }
|
|
3266
3309
|
);
|
|
3267
3310
|
}
|
|
3268
3311
|
sessions.set(step.space, session);
|
|
3269
3312
|
}
|
|
3270
3313
|
for (const step of steps) {
|
|
3271
3314
|
if (step.kind !== "host") continue;
|
|
3272
|
-
const hosted = await auth.
|
|
3273
|
-
if (!hosted) {
|
|
3274
|
-
throw
|
|
3315
|
+
const hosted = await auth.hostOwnedSpaceResult(step.spaceId, "bootstrap-host");
|
|
3316
|
+
if (!hosted.success) {
|
|
3317
|
+
throw Object.assign(
|
|
3318
|
+
new Error(`Failed to host bootstrap space ${step.spaceId}: ${describeHostFailure2(hosted)}`),
|
|
3319
|
+
{ cause: hosted }
|
|
3320
|
+
);
|
|
3275
3321
|
}
|
|
3276
3322
|
}
|
|
3277
3323
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -3283,8 +3329,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3283
3329
|
}
|
|
3284
3330
|
const activated = await activateSessionWithHost2(host, session.delegationHeader);
|
|
3285
3331
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
3286
|
-
throw
|
|
3287
|
-
|
|
3332
|
+
throw Object.assign(
|
|
3333
|
+
new Error(
|
|
3334
|
+
`Failed to activate bootstrap session for ${step.spaceId}: ${activated.success ? "space was skipped" : describeHostFailure2(activated)}`
|
|
3335
|
+
),
|
|
3336
|
+
{ cause: activated }
|
|
3288
3337
|
);
|
|
3289
3338
|
}
|
|
3290
3339
|
this.registerBootstrapRuntimeGrant(
|
|
@@ -3297,7 +3346,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3297
3346
|
if (step.kind === "account-index-schema") {
|
|
3298
3347
|
const ensured = await this.account.index.ensure();
|
|
3299
3348
|
if (!ensured.ok) {
|
|
3300
|
-
throw new Error(`Failed to create account index schema: ${ensured.error.message}`);
|
|
3349
|
+
throw Object.assign(new Error(`Failed to create account index schema: ${ensured.error.message}`), { cause: ensured.error });
|
|
3301
3350
|
}
|
|
3302
3351
|
}
|
|
3303
3352
|
if (step.kind === "seed-spaces") {
|
|
@@ -3312,8 +3361,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3312
3361
|
}))
|
|
3313
3362
|
);
|
|
3314
3363
|
if (!registered.ok) {
|
|
3315
|
-
throw
|
|
3316
|
-
`Failed to seed account spaces: ${registered.error.message}`
|
|
3364
|
+
throw Object.assign(
|
|
3365
|
+
new Error(`Failed to seed account spaces: ${registered.error.message}`),
|
|
3366
|
+
{ cause: registered.error }
|
|
3317
3367
|
);
|
|
3318
3368
|
}
|
|
3319
3369
|
const batchError = registered.data.recoveredFromBatchError;
|
|
@@ -3334,7 +3384,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3334
3384
|
{ assumeUnregistered: true }
|
|
3335
3385
|
);
|
|
3336
3386
|
if (!registered.ok) {
|
|
3337
|
-
throw new Error(`Failed to seed bootstrap applications: ${registered.error.message}`);
|
|
3387
|
+
throw Object.assign(new Error(`Failed to seed bootstrap applications: ${registered.error.message}`), { cause: registered.error });
|
|
3338
3388
|
}
|
|
3339
3389
|
}
|
|
3340
3390
|
if (step.kind === "encryption-network-create") {
|
|
@@ -3352,8 +3402,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3352
3402
|
]
|
|
3353
3403
|
});
|
|
3354
3404
|
if (!migrated.ok) {
|
|
3355
|
-
throw
|
|
3356
|
-
`Failed to create secret_records schema: ${migrated.error.message}`
|
|
3405
|
+
throw Object.assign(
|
|
3406
|
+
new Error(`Failed to create secret_records schema: ${migrated.error.message}`),
|
|
3407
|
+
{ cause: migrated.error }
|
|
3357
3408
|
);
|
|
3358
3409
|
}
|
|
3359
3410
|
}
|
|
@@ -3620,6 +3671,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3620
3671
|
);
|
|
3621
3672
|
return;
|
|
3622
3673
|
}
|
|
3674
|
+
if (isStorageFullError(error) || isStorageFullError(error?.cause) || message.includes(STORAGE_FULL_MESSAGE) || message.includes(STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
|
|
3675
|
+
console.warn("TinyCloud account registry sync stopped: storage is full", error);
|
|
3676
|
+
return;
|
|
3677
|
+
}
|
|
3623
3678
|
lastError = error;
|
|
3624
3679
|
if (attempt < delays.length - 1) {
|
|
3625
3680
|
await new Promise((resolve) => setTimeout(resolve, delays[attempt]));
|
|
@@ -3694,14 +3749,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3694
3749
|
}
|
|
3695
3750
|
if (!activation.success && activation.status !== 404) {
|
|
3696
3751
|
throw Object.assign(
|
|
3697
|
-
new Error(`Failed to check owned space ${spaceId}: ${
|
|
3752
|
+
new Error(`Failed to check owned space ${spaceId}: ${describeHostFailure2(activation)}`),
|
|
3698
3753
|
{ cause: activation }
|
|
3699
3754
|
);
|
|
3700
3755
|
}
|
|
3701
3756
|
const created = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
3702
3757
|
if (!created.success) {
|
|
3703
3758
|
throw Object.assign(
|
|
3704
|
-
new Error(`Failed to create owned space ${spaceId}: ${
|
|
3759
|
+
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
3705
3760
|
{ cause: created }
|
|
3706
3761
|
);
|
|
3707
3762
|
}
|
|
@@ -3710,7 +3765,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3710
3765
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
3711
3766
|
throw Object.assign(
|
|
3712
3767
|
new Error(
|
|
3713
|
-
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" :
|
|
3768
|
+
`Failed to activate session after creating owned space ${spaceId}: ${retry.success ? "space was skipped" : describeHostFailure2(retry)}`
|
|
3714
3769
|
),
|
|
3715
3770
|
{ cause: retry }
|
|
3716
3771
|
);
|
|
@@ -3747,19 +3802,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3747
3802
|
if (!host) {
|
|
3748
3803
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
3749
3804
|
}
|
|
3750
|
-
const hosted = await this.auth.
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3805
|
+
const hosted = await this.auth.hostOwnedSpaceResult(spaceId);
|
|
3806
|
+
if (!hosted.success) {
|
|
3807
|
+
throw Object.assign(
|
|
3808
|
+
new Error(`Failed to host owned space ${spaceId}: ${describeHostFailure2(hosted)}`),
|
|
3809
|
+
{ cause: hosted }
|
|
3810
|
+
);
|
|
3755
3811
|
}
|
|
3756
3812
|
const activation = await activateSessionWithHost2(
|
|
3757
3813
|
host,
|
|
3758
3814
|
session.delegationHeader
|
|
3759
3815
|
);
|
|
3760
3816
|
if (!activation.success || activation.skipped?.includes(spaceId)) {
|
|
3761
|
-
throw
|
|
3762
|
-
|
|
3817
|
+
throw Object.assign(
|
|
3818
|
+
new Error(
|
|
3819
|
+
`Failed to activate session for owned space ${spaceId}: ${activation.success ? "space was skipped" : describeHostFailure2(activation)}`
|
|
3820
|
+
),
|
|
3821
|
+
{ cause: activation }
|
|
3763
3822
|
);
|
|
3764
3823
|
}
|
|
3765
3824
|
try {
|
|
@@ -3955,23 +4014,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3955
4014
|
throw new InvalidRestoredSessionError(error instanceof Error ? error.message : String(error));
|
|
3956
4015
|
}
|
|
3957
4016
|
})();
|
|
3958
|
-
|
|
3959
|
-
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
3960
|
-
(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(
|
|
3961
|
-
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
3962
|
-
)
|
|
3963
|
-
)) {
|
|
3964
|
-
throw new UnsupportedSessionRestoreError(
|
|
3965
|
-
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
3966
|
-
);
|
|
3967
|
-
}
|
|
3968
|
-
stagedRecap = exactRecap.map((entry) => ({
|
|
3969
|
-
service: entry.service,
|
|
3970
|
-
space: entry.space,
|
|
3971
|
-
path: entry.path,
|
|
3972
|
-
actions: [...entry.actions],
|
|
3973
|
-
caveats: cloneRecapCaveats(entry.caveats)
|
|
3974
|
-
}));
|
|
4017
|
+
stagedRecap = exactVerifiedRecap(verified);
|
|
3975
4018
|
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
3976
4019
|
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
3977
4020
|
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
@@ -4775,7 +4818,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4775
4818
|
if (cached) return cached;
|
|
4776
4819
|
const response = await fetch(`${this.config.host}/info`);
|
|
4777
4820
|
if (!response.ok) {
|
|
4778
|
-
throw
|
|
4821
|
+
throw await httpResponseError(response, "Failed to fetch node info");
|
|
4779
4822
|
}
|
|
4780
4823
|
const info = await response.json();
|
|
4781
4824
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -4825,9 +4868,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4825
4868
|
);
|
|
4826
4869
|
if (response.status === 404) return null;
|
|
4827
4870
|
if (!response.ok) {
|
|
4828
|
-
throw
|
|
4829
|
-
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
4830
|
-
);
|
|
4871
|
+
throw await httpResponseError(response, `Failed to fetch encryption network ${networkId}`);
|
|
4831
4872
|
}
|
|
4832
4873
|
const body = await response.json();
|
|
4833
4874
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -5328,7 +5369,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5328
5369
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
5329
5370
|
body: canonicalizeEncryptionJson(request)
|
|
5330
5371
|
});
|
|
5331
|
-
if (!response.ok) throw
|
|
5372
|
+
if (!response.ok) throw await httpResponseError(response, "V3 share delivery authorization failed");
|
|
5332
5373
|
const verified = validateShareDeliveryAuthorizationV3Bytes(new Uint8Array(await response.arrayBuffer()), {
|
|
5333
5374
|
request,
|
|
5334
5375
|
senderKeyDid: this.credentialHolderDid,
|
|
@@ -5550,9 +5591,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5550
5591
|
);
|
|
5551
5592
|
}
|
|
5552
5593
|
if (!response.ok) {
|
|
5553
|
-
throw
|
|
5554
|
-
`Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
5555
|
-
);
|
|
5594
|
+
throw await httpResponseError(response, `Failed to create encryption network ${networkId}`);
|
|
5556
5595
|
}
|
|
5557
5596
|
const created = await response.json();
|
|
5558
5597
|
return created.descriptor;
|
|
@@ -5836,6 +5875,42 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5836
5875
|
(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"))
|
|
5837
5876
|
);
|
|
5838
5877
|
}
|
|
5878
|
+
/**
|
|
5879
|
+
* Verify a wallet-signed session grant (a CACAO built from a SIWE and its
|
|
5880
|
+
* EIP-191 signature) issued to this instance's live session key. The
|
|
5881
|
+
* verifier rebuilds the CACAO from `siwe` and `signature`, so the grant is
|
|
5882
|
+
* accepted only when its authorization bytes and CID are exactly that CACAO,
|
|
5883
|
+
* its signer is `address`, its audience is this session key, it is valid
|
|
5884
|
+
* now, and its ReCap covers `spaceId` or names only raw encryption networks
|
|
5885
|
+
* (a decrypt-only grant has no space). Returns the signed ReCap and expiry.
|
|
5886
|
+
* Bindings without `validateSessionGrant` fall back to the session verifier,
|
|
5887
|
+
* which also refuses decrypt-only grants.
|
|
5888
|
+
*/
|
|
5889
|
+
verifySessionGrant(grant) {
|
|
5890
|
+
const bindings = this.wasmBindings;
|
|
5891
|
+
const validate = typeof bindings.validateSessionGrant === "function" ? bindings.validateSessionGrant.bind(bindings) : bindings.validatePersistedSession?.bind(bindings);
|
|
5892
|
+
if (validate === void 0) {
|
|
5893
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
5894
|
+
}
|
|
5895
|
+
const verified = validate({
|
|
5896
|
+
delegationHeader: { Authorization: grant.delegationHeader.Authorization },
|
|
5897
|
+
delegationCid: grant.delegationCid,
|
|
5898
|
+
spaceId: grant.spaceId,
|
|
5899
|
+
jwk: this.sessionKeyJwk,
|
|
5900
|
+
address: canonicalizeAddress2(grant.address),
|
|
5901
|
+
chainId: grant.chainId,
|
|
5902
|
+
siwe: grant.siwe,
|
|
5903
|
+
signature: grant.signature
|
|
5904
|
+
});
|
|
5905
|
+
if (typeof verified.expiresAt !== "string") {
|
|
5906
|
+
throw new Error("Session grant has no signed expiry.");
|
|
5907
|
+
}
|
|
5908
|
+
const expiresAt = new Date(verified.expiresAt);
|
|
5909
|
+
if (!Number.isFinite(expiresAt.getTime())) {
|
|
5910
|
+
throw new Error("Session grant has an invalid signed expiry.");
|
|
5911
|
+
}
|
|
5912
|
+
return { recap: exactVerifiedRecap(verified), expiresAt };
|
|
5913
|
+
}
|
|
5839
5914
|
/**
|
|
5840
5915
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
5841
5916
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -5860,8 +5935,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5860
5935
|
delegation.delegationHeader
|
|
5861
5936
|
);
|
|
5862
5937
|
if (!activateResult.success) {
|
|
5863
|
-
throw
|
|
5864
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
5938
|
+
throw Object.assign(
|
|
5939
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
5940
|
+
{ cause: activateResult }
|
|
5865
5941
|
);
|
|
5866
5942
|
}
|
|
5867
5943
|
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
@@ -5957,8 +6033,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5957
6033
|
delegatedSession.delegationHeader
|
|
5958
6034
|
);
|
|
5959
6035
|
if (!activateResult.success) {
|
|
5960
|
-
throw
|
|
5961
|
-
`Failed to activate runtime permission delegation: ${activateResult
|
|
6036
|
+
throw Object.assign(
|
|
6037
|
+
new Error(`Failed to activate runtime permission delegation: ${describeHostFailure2(activateResult)}`),
|
|
6038
|
+
{ cause: activateResult }
|
|
5962
6039
|
);
|
|
5963
6040
|
}
|
|
5964
6041
|
const delegation = this.runtimeDelegationFromSession(
|
|
@@ -5966,7 +6043,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5966
6043
|
delegatedEntries,
|
|
5967
6044
|
spaceId,
|
|
5968
6045
|
session,
|
|
5969
|
-
expiresAt
|
|
6046
|
+
expiresAt,
|
|
6047
|
+
{ siwe: prepared.siwe, signature }
|
|
5970
6048
|
);
|
|
5971
6049
|
this.runtimePermissionGrants.push({
|
|
5972
6050
|
session: {
|
|
@@ -6143,7 +6221,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6143
6221
|
delegationSession.delegationHeader
|
|
6144
6222
|
);
|
|
6145
6223
|
if (!activateResult.success) {
|
|
6146
|
-
throw
|
|
6224
|
+
throw Object.assign(
|
|
6225
|
+
new Error(`Failed to activate public space delegation: ${describeHostFailure2(activateResult)}`),
|
|
6226
|
+
{ cause: activateResult }
|
|
6227
|
+
);
|
|
6147
6228
|
}
|
|
6148
6229
|
if (this._capabilityRegistry && this.session) {
|
|
6149
6230
|
const sessionKey = {
|
|
@@ -6496,8 +6577,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6496
6577
|
delegationHeader
|
|
6497
6578
|
);
|
|
6498
6579
|
if (!activateResult.success) {
|
|
6499
|
-
throw
|
|
6500
|
-
`Failed to activate delegation with host: ${activateResult
|
|
6580
|
+
throw Object.assign(
|
|
6581
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
6582
|
+
{ cause: activateResult }
|
|
6501
6583
|
);
|
|
6502
6584
|
}
|
|
6503
6585
|
return {
|
|
@@ -6533,8 +6615,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6533
6615
|
delegationHeader
|
|
6534
6616
|
);
|
|
6535
6617
|
if (!activateResult.success) {
|
|
6536
|
-
throw
|
|
6537
|
-
`Failed to activate delegation with host: ${activateResult
|
|
6618
|
+
throw Object.assign(
|
|
6619
|
+
new Error(`Failed to activate delegation with host: ${describeHostFailure2(activateResult)}`),
|
|
6620
|
+
{ cause: activateResult }
|
|
6538
6621
|
);
|
|
6539
6622
|
}
|
|
6540
6623
|
return {
|
|
@@ -6747,7 +6830,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6747
6830
|
}
|
|
6748
6831
|
return grants;
|
|
6749
6832
|
}
|
|
6750
|
-
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt) {
|
|
6833
|
+
runtimeDelegationFromSession(delegatedSession, entries, spaceId, session, expiresAt, siweProof) {
|
|
6751
6834
|
const resources = this.delegatedResourcesForEntries(entries, spaceId);
|
|
6752
6835
|
const primary = resources[0];
|
|
6753
6836
|
return {
|
|
@@ -6762,7 +6845,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6762
6845
|
delegateDID: session.verificationMethod,
|
|
6763
6846
|
ownerAddress: session.address,
|
|
6764
6847
|
chainId: session.chainId,
|
|
6765
|
-
host: this.config.host
|
|
6848
|
+
host: this.config.host,
|
|
6849
|
+
siweProof
|
|
6766
6850
|
};
|
|
6767
6851
|
}
|
|
6768
6852
|
runtimeGrantFromDelegation(delegation, session) {
|
|
@@ -6955,6 +7039,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6955
7039
|
if (grantedAction === requestedAction) {
|
|
6956
7040
|
return true;
|
|
6957
7041
|
}
|
|
7042
|
+
if (isExplicitOnlyAction(requestedAction)) {
|
|
7043
|
+
return false;
|
|
7044
|
+
}
|
|
6958
7045
|
if (grantedAction.endsWith("/*")) {
|
|
6959
7046
|
const prefix = grantedAction.slice(0, -2);
|
|
6960
7047
|
return requestedAction.startsWith(`${prefix}/`);
|
|
@@ -7141,7 +7228,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7141
7228
|
delegationSession.delegationHeader
|
|
7142
7229
|
);
|
|
7143
7230
|
if (!activateResult.success) {
|
|
7144
|
-
throw
|
|
7231
|
+
throw Object.assign(
|
|
7232
|
+
new Error(`Failed to activate delegation: ${describeHostFailure2(activateResult)}`),
|
|
7233
|
+
{ cause: activateResult }
|
|
7234
|
+
);
|
|
7145
7235
|
}
|
|
7146
7236
|
const result = {
|
|
7147
7237
|
cid: delegationSession.delegationCid,
|
|
@@ -7291,7 +7381,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7291
7381
|
invokerSession.delegationHeader
|
|
7292
7382
|
);
|
|
7293
7383
|
if (!activateResult.success) {
|
|
7294
|
-
throw
|
|
7384
|
+
throw Object.assign(
|
|
7385
|
+
new Error(`Failed to activate delegated session: ${describeHostFailure2(activateResult)}`),
|
|
7386
|
+
{ cause: activateResult }
|
|
7387
|
+
);
|
|
7295
7388
|
}
|
|
7296
7389
|
const session = {
|
|
7297
7390
|
address: mySession.address,
|
|
@@ -7408,7 +7501,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7408
7501
|
subDelegationSession.delegationHeader
|
|
7409
7502
|
);
|
|
7410
7503
|
if (!activateResult.success) {
|
|
7411
|
-
throw
|
|
7504
|
+
throw Object.assign(
|
|
7505
|
+
new Error(`Failed to activate sub-delegation: ${describeHostFailure2(activateResult)}`),
|
|
7506
|
+
{ cause: activateResult }
|
|
7507
|
+
);
|
|
7412
7508
|
}
|
|
7413
7509
|
return {
|
|
7414
7510
|
cid: subDelegationSession.delegationCid,
|
|
@@ -7473,6 +7569,16 @@ import {
|
|
|
7473
7569
|
decodeBase64Url,
|
|
7474
7570
|
principalDidEquals as principalDidEquals3
|
|
7475
7571
|
} from "@tinycloud/sdk-core";
|
|
7572
|
+
var RuntimeDelegationRejectedError = class extends Error {
|
|
7573
|
+
constructor(reason, message) {
|
|
7574
|
+
super(message);
|
|
7575
|
+
this.name = "RuntimeDelegationRejectedError";
|
|
7576
|
+
this.reason = reason;
|
|
7577
|
+
}
|
|
7578
|
+
};
|
|
7579
|
+
function reject(reason, message) {
|
|
7580
|
+
throw new RuntimeDelegationRejectedError(reason, message);
|
|
7581
|
+
}
|
|
7476
7582
|
var SERVICE_BY_SHORT_NAME = {
|
|
7477
7583
|
kv: "tinycloud.kv",
|
|
7478
7584
|
sql: "tinycloud.sql",
|
|
@@ -7619,6 +7725,15 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
7619
7725
|
abilities
|
|
7620
7726
|
));
|
|
7621
7727
|
}
|
|
7728
|
+
return canonicalSignedAuthority({
|
|
7729
|
+
issuer: payload.iss,
|
|
7730
|
+
audience: payload.aud,
|
|
7731
|
+
expiry,
|
|
7732
|
+
proofs: [...payload.prf],
|
|
7733
|
+
...remainingRedelegationDepth === void 0 ? {} : { remainingRedelegationDepth }
|
|
7734
|
+
}, permissions);
|
|
7735
|
+
}
|
|
7736
|
+
function canonicalSignedAuthority(signed, permissions) {
|
|
7622
7737
|
if (permissions.length === 0) {
|
|
7623
7738
|
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
7624
7739
|
}
|
|
@@ -7630,15 +7745,84 @@ function signedAuthorityFromCompactUcan(authorization) {
|
|
|
7630
7745
|
actions: [...permission.actions],
|
|
7631
7746
|
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
7632
7747
|
}));
|
|
7633
|
-
return {
|
|
7634
|
-
|
|
7635
|
-
|
|
7636
|
-
|
|
7637
|
-
|
|
7638
|
-
|
|
7639
|
-
|
|
7640
|
-
|
|
7641
|
-
|
|
7748
|
+
return { ...signed, permissions: canonicalPermissions, resources: canonicalResources };
|
|
7749
|
+
}
|
|
7750
|
+
var RAW_ENCRYPTION_PREFIX = "urn:tinycloud:encryption:";
|
|
7751
|
+
var PKH_SPACE = /^tinycloud:pkh:eip155:(\d+):(0x[0-9a-fA-F]{40}):(.+)$/;
|
|
7752
|
+
function comparableSpace(space) {
|
|
7753
|
+
const match = PKH_SPACE.exec(space);
|
|
7754
|
+
return match ? `tinycloud:pkh:eip155:${match[1]}:${match[2].toLowerCase()}:${match[3]}` : space;
|
|
7755
|
+
}
|
|
7756
|
+
function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
7757
|
+
const proof = delegation.siweProof;
|
|
7758
|
+
if (proof === void 0 || proof === null || typeof proof !== "object" || typeof proof.siwe !== "string" || typeof proof.signature !== "string") {
|
|
7759
|
+
reject(
|
|
7760
|
+
"proof_missing",
|
|
7761
|
+
"Runtime delegation is a wallet-signed session grant stored without its signed SIWE proof, so its authority cannot be verified."
|
|
7762
|
+
);
|
|
7763
|
+
}
|
|
7764
|
+
if (typeof node.verifySessionGrant !== "function") {
|
|
7765
|
+
reject("unsupported", "This runtime cannot verify wallet-signed session grants.");
|
|
7766
|
+
}
|
|
7767
|
+
const owner = `did:pkh:eip155:${delegation.chainId}:${delegation.ownerAddress}`;
|
|
7768
|
+
if (typeof node.did !== "string" || !didPrincipalsMatch(owner, node.did)) {
|
|
7769
|
+
reject("owner_mismatch", "Runtime delegation is not signed by this session's owner.");
|
|
7770
|
+
}
|
|
7771
|
+
let verified;
|
|
7772
|
+
try {
|
|
7773
|
+
verified = node.verifySessionGrant({
|
|
7774
|
+
delegationHeader: { Authorization: authorization },
|
|
7775
|
+
delegationCid: cid,
|
|
7776
|
+
spaceId: delegation.spaceId,
|
|
7777
|
+
address: delegation.ownerAddress,
|
|
7778
|
+
chainId: delegation.chainId,
|
|
7779
|
+
siwe: proof.siwe,
|
|
7780
|
+
signature: proof.signature
|
|
7781
|
+
});
|
|
7782
|
+
} catch (error) {
|
|
7783
|
+
reject("proof_invalid", error instanceof Error ? error.message : String(error));
|
|
7784
|
+
}
|
|
7785
|
+
const space = comparableSpace(delegation.spaceId);
|
|
7786
|
+
const spaceOwner = PKH_SPACE.exec(delegation.spaceId);
|
|
7787
|
+
if (!spaceOwner || !didPrincipalsMatch(`did:pkh:eip155:${spaceOwner[1]}:${spaceOwner[2]}`, owner)) {
|
|
7788
|
+
reject("authority_invalid", "Runtime delegation space is not owned by its signer.");
|
|
7789
|
+
}
|
|
7790
|
+
const groups = /* @__PURE__ */ new Map();
|
|
7791
|
+
for (const entry of verified.recap) {
|
|
7792
|
+
const service = entry.service.startsWith("tinycloud.") ? entry.service : `tinycloud.${entry.service}`;
|
|
7793
|
+
const raw = entry.space === "encryption";
|
|
7794
|
+
if (raw) {
|
|
7795
|
+
if (service !== "tinycloud.encryption" || !entry.path.startsWith(RAW_ENCRYPTION_PREFIX)) {
|
|
7796
|
+
reject("authority_invalid", "Runtime delegation has an unsupported signed raw resource.");
|
|
7797
|
+
}
|
|
7798
|
+
const networkOwner = entry.path.slice(RAW_ENCRYPTION_PREFIX.length, entry.path.lastIndexOf(":"));
|
|
7799
|
+
if (!didPrincipalsMatch(networkOwner, owner)) {
|
|
7800
|
+
reject("authority_invalid", "Runtime delegation names an encryption network its signer does not own.");
|
|
7801
|
+
}
|
|
7802
|
+
} else if (service === "tinycloud.encryption" || comparableSpace(entry.space) !== space) {
|
|
7803
|
+
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
7804
|
+
}
|
|
7805
|
+
const caveats = signedCaveats(entry.caveats ?? []);
|
|
7806
|
+
const key = JSON.stringify([service, raw ? "" : entry.space, entry.path, canonicalizeRecapCaveats2(caveats)]);
|
|
7807
|
+
const group = groups.get(key) ?? {
|
|
7808
|
+
service,
|
|
7809
|
+
...raw ? {} : { space: entry.space },
|
|
7810
|
+
path: entry.path,
|
|
7811
|
+
actions: [],
|
|
7812
|
+
...caveats === void 0 ? {} : { caveats }
|
|
7813
|
+
};
|
|
7814
|
+
for (const action of entry.actions) {
|
|
7815
|
+
if (!group.actions.includes(action)) group.actions.push(action);
|
|
7816
|
+
}
|
|
7817
|
+
groups.set(key, group);
|
|
7818
|
+
}
|
|
7819
|
+
return canonicalSignedAuthority({
|
|
7820
|
+
issuer: owner,
|
|
7821
|
+
// The verifier bound the SIWE audience to this runtime's own session key.
|
|
7822
|
+
audience: node.sessionDid,
|
|
7823
|
+
expiry: verified.expiresAt,
|
|
7824
|
+
proofs: []
|
|
7825
|
+
}, [...groups.values()]);
|
|
7642
7826
|
}
|
|
7643
7827
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
7644
7828
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
@@ -7674,46 +7858,58 @@ function resourcesMatch(actual, expected) {
|
|
|
7674
7858
|
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
7675
7859
|
const host = normalizedHost(options.host);
|
|
7676
7860
|
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
7677
|
-
|
|
7861
|
+
reject(
|
|
7862
|
+
"host_mismatch",
|
|
7678
7863
|
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
7679
7864
|
);
|
|
7680
7865
|
}
|
|
7681
7866
|
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
7682
|
-
|
|
7867
|
+
reject("authority_invalid", "Runtime delegation has an invalid expiry.");
|
|
7683
7868
|
}
|
|
7684
7869
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
7685
|
-
|
|
7870
|
+
reject("expired", "Runtime delegation is expired.");
|
|
7686
7871
|
}
|
|
7687
7872
|
const authorization = delegation.delegationHeader?.Authorization;
|
|
7688
7873
|
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
7689
|
-
|
|
7874
|
+
reject("authority_invalid", "Runtime delegation is missing authorization bytes.");
|
|
7690
7875
|
}
|
|
7691
7876
|
const cid = node.computeDelegationCid(authorization);
|
|
7692
7877
|
if (cid !== delegation.cid) {
|
|
7693
|
-
|
|
7878
|
+
reject("cid_mismatch", "Runtime delegation CID does not match authorization bytes.");
|
|
7879
|
+
}
|
|
7880
|
+
const compact = authorizationWithoutBearer(authorization).split(".").length === 3;
|
|
7881
|
+
let signed;
|
|
7882
|
+
try {
|
|
7883
|
+
signed = compact ? signedAuthorityFromCompactUcan(authorization) : signedAuthorityFromSessionGrant(node, delegation, authorization, cid);
|
|
7884
|
+
} catch (error) {
|
|
7885
|
+
if (error instanceof RuntimeDelegationRejectedError) throw error;
|
|
7886
|
+
reject("authority_invalid", error instanceof Error ? error.message : String(error));
|
|
7694
7887
|
}
|
|
7695
|
-
const signed = signedAuthorityFromCompactUcan(authorization);
|
|
7696
7888
|
if (signed.expiry.getTime() <= Date.now()) {
|
|
7697
|
-
|
|
7889
|
+
reject("expired", "Runtime delegation is expired.");
|
|
7698
7890
|
}
|
|
7699
7891
|
if (delegation.expiry.getTime() !== signed.expiry.getTime()) {
|
|
7700
|
-
|
|
7892
|
+
reject("authority_invalid", "Runtime delegation expiry does not match signed authority.");
|
|
7701
7893
|
}
|
|
7702
7894
|
if (!didPrincipalsMatch(signed.audience, node.sessionDid)) {
|
|
7703
|
-
|
|
7895
|
+
reject(
|
|
7896
|
+
"audience_mismatch",
|
|
7704
7897
|
`Runtime delegation targets ${signed.audience} but this session is ${node.sessionDid}.`
|
|
7705
7898
|
);
|
|
7706
7899
|
}
|
|
7707
7900
|
if (!didPrincipalsMatch(delegation.delegateDID, signed.audience)) {
|
|
7708
|
-
|
|
7901
|
+
reject("audience_mismatch", "Runtime delegation audience does not match signed authority.");
|
|
7902
|
+
}
|
|
7903
|
+
if (compact && !resourcesMatch(canonicalResourcesFromPortableDelegation(delegation), signed.resources)) {
|
|
7904
|
+
reject("resources_mismatch", "Runtime delegation resources do not match signed authority.");
|
|
7709
7905
|
}
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
7906
|
+
if (options.authorize !== void 0 && !options.authorize(signed.permissions)) {
|
|
7907
|
+
throw new Error("Runtime delegation is not authorized for this runtime.");
|
|
7713
7908
|
}
|
|
7714
7909
|
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
7715
7910
|
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
7716
|
-
|
|
7911
|
+
reject(
|
|
7912
|
+
"cid_mismatch",
|
|
7717
7913
|
"A different authorization is already installed for this runtime delegation CID."
|
|
7718
7914
|
);
|
|
7719
7915
|
}
|
|
@@ -7743,22 +7939,28 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
7743
7939
|
})),
|
|
7744
7940
|
expiry: new Date(signed.expiry),
|
|
7745
7941
|
delegateDID: signed.audience,
|
|
7746
|
-
host
|
|
7942
|
+
host,
|
|
7943
|
+
...compact ? {} : { siweProof: delegation.siweProof }
|
|
7747
7944
|
};
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7945
|
+
try {
|
|
7946
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && principalDidEquals3(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
7947
|
+
await node.useDelegation(installedCandidate);
|
|
7948
|
+
} else {
|
|
7949
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
7950
|
+
}
|
|
7951
|
+
} catch (error) {
|
|
7952
|
+
reject("activation_rejected", error instanceof Error ? error.message : String(error));
|
|
7752
7953
|
}
|
|
7753
7954
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
7754
7955
|
if (!installed) {
|
|
7755
|
-
|
|
7956
|
+
reject("activation_rejected", "Runtime delegation activation did not install the validated authority.");
|
|
7756
7957
|
}
|
|
7757
7958
|
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed.audience) || installed.expiry.getTime() !== signed.expiry.getTime() || !resourcesMatch(
|
|
7758
7959
|
canonicalResourcesFromPortableDelegation(installed),
|
|
7759
7960
|
signed.resources
|
|
7760
7961
|
) || normalizedHost(installed.host ?? "") !== host) {
|
|
7761
|
-
|
|
7962
|
+
reject(
|
|
7963
|
+
"activation_rejected",
|
|
7762
7964
|
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
7763
7965
|
);
|
|
7764
7966
|
}
|