@tinycloud/node-sdk 2.6.0-beta.0 → 2.6.0-beta.1
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-ojeY-wet.d.cts → core-Cr-zD1lk.d.cts} +42 -0
- package/dist/{core-ojeY-wet.d.ts → core-Cr-zD1lk.d.ts} +42 -0
- package/dist/core.cjs +125 -10
- 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 +125 -10
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +125 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +125 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -19164,6 +19164,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19164
19164
|
await this.tc.signIn(options);
|
|
19165
19165
|
this.syncResolvedHostFromAuth();
|
|
19166
19166
|
this.initializeServices();
|
|
19167
|
+
const primarySession = this.currentTinyCloudSession();
|
|
19168
|
+
if (primarySession) {
|
|
19169
|
+
this.registerPrimarySessionGrant(primarySession);
|
|
19170
|
+
}
|
|
19167
19171
|
const bootstrapped = await this.bootstrapAccountIfNeeded();
|
|
19168
19172
|
await this.ensureRequestedEncryptionNetworks();
|
|
19169
19173
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
@@ -19407,7 +19411,107 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19407
19411
|
host: this.config.host
|
|
19408
19412
|
},
|
|
19409
19413
|
operations,
|
|
19410
|
-
expiresAt
|
|
19414
|
+
expiresAt,
|
|
19415
|
+
provenance: "bootstrap"
|
|
19416
|
+
});
|
|
19417
|
+
}
|
|
19418
|
+
/**
|
|
19419
|
+
* Map the base session's OWN recap into runtime permission operations.
|
|
19420
|
+
*
|
|
19421
|
+
* Uses the RAW `parseRecapFromSiwe` binding — NOT `parseRecapCapabilities`,
|
|
19422
|
+
* whose `normalizeSpace` collapses `tinycloud:pkh:...:<owner>:<space>` to a
|
|
19423
|
+
* bare short name and would conflate two owners' identically-named spaces.
|
|
19424
|
+
* We must keep the full owner-scoped URI so a synthetic primary grant can
|
|
19425
|
+
* never cover an operation on a different owner's space.
|
|
19426
|
+
*
|
|
19427
|
+
* Mirrors {@link operationsFromDelegation}'s op shape: encryption network
|
|
19428
|
+
* entries (`urn:tinycloud:encryption:` paths) become `resource` ops; every
|
|
19429
|
+
* other entry becomes a `spaceId` op carrying the raw recap `space` URI.
|
|
19430
|
+
* One op per action.
|
|
19431
|
+
*
|
|
19432
|
+
* Returns `[]` for session-only / restored-without-siwe modes and for any
|
|
19433
|
+
* unparseable SIWE — the primary grant is simply not registered in that case.
|
|
19434
|
+
*/
|
|
19435
|
+
recapOperationsFromSession(session) {
|
|
19436
|
+
const siwe = session.siwe;
|
|
19437
|
+
if (!siwe) {
|
|
19438
|
+
return [];
|
|
19439
|
+
}
|
|
19440
|
+
if (this._recapOperationsCache?.siwe === siwe) {
|
|
19441
|
+
return this._recapOperationsCache.operations;
|
|
19442
|
+
}
|
|
19443
|
+
let operations = [];
|
|
19444
|
+
try {
|
|
19445
|
+
const entries = this.wasmBindings.parseRecapFromSiwe(siwe);
|
|
19446
|
+
if (Array.isArray(entries)) {
|
|
19447
|
+
operations = entries.flatMap((entry) => {
|
|
19448
|
+
const service = this.invocationServiceName(entry.service);
|
|
19449
|
+
return entry.actions.map((action) => ({
|
|
19450
|
+
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
|
|
19451
|
+
service,
|
|
19452
|
+
path: entry.path,
|
|
19453
|
+
action
|
|
19454
|
+
}));
|
|
19455
|
+
});
|
|
19456
|
+
}
|
|
19457
|
+
} catch {
|
|
19458
|
+
operations = [];
|
|
19459
|
+
}
|
|
19460
|
+
this._recapOperationsCache = { siwe, operations };
|
|
19461
|
+
return operations;
|
|
19462
|
+
}
|
|
19463
|
+
/**
|
|
19464
|
+
* Register the base (primary) session's own recap as a synthetic runtime
|
|
19465
|
+
* grant tagged `provenance: "primary"` so it always out-ranks other covering
|
|
19466
|
+
* grants in {@link findGrantForOperations}. This closes the selection-design
|
|
19467
|
+
* hazard where a broad — possibly broken — bootstrap/delegated grant could
|
|
19468
|
+
* hijack an operation the primary session itself already authorized (TC-111).
|
|
19469
|
+
*
|
|
19470
|
+
* Two safety exclusions:
|
|
19471
|
+
* - Ops whose space is in `lastActivationSkippedSpaceIds` are dropped: the
|
|
19472
|
+
* node refused to activate those spaces this sign-in even though the recap
|
|
19473
|
+
* claims them. Including them would let the synthetic primary out-rank a
|
|
19474
|
+
* working grant and 401 (the "skipped-activation inverted hijack").
|
|
19475
|
+
* - Encryption `resource` ops are kept as-is (space-independent).
|
|
19476
|
+
*
|
|
19477
|
+
* No-ops when nothing remains after exclusion. Callers (`signIn`,
|
|
19478
|
+
* `restoreSession`) clear `runtimePermissionGrants` first, so no dupes.
|
|
19479
|
+
*/
|
|
19480
|
+
registerPrimarySessionGrant(session) {
|
|
19481
|
+
const skipped = this.auth ? this.auth.lastActivationSkippedSpaceIds ?? [] : [];
|
|
19482
|
+
const operations = this.recapOperationsFromSession(session).filter(
|
|
19483
|
+
(operation) => operation.spaceId === void 0 || !skipped.some((spaceId) => this.spaceIdsEqual(spaceId, operation.spaceId))
|
|
19484
|
+
);
|
|
19485
|
+
if (operations.length === 0) {
|
|
19486
|
+
return;
|
|
19487
|
+
}
|
|
19488
|
+
const expiresAt = extractSiweExpiration(session.siwe) ?? this.getSessionExpiry();
|
|
19489
|
+
const actions = [...new Set(operations.map((operation) => operation.action))];
|
|
19490
|
+
this.runtimePermissionGrants.push({
|
|
19491
|
+
session: {
|
|
19492
|
+
delegationHeader: session.delegationHeader,
|
|
19493
|
+
delegationCid: session.delegationCid,
|
|
19494
|
+
spaceId: session.spaceId,
|
|
19495
|
+
verificationMethod: session.verificationMethod,
|
|
19496
|
+
jwk: session.jwk
|
|
19497
|
+
},
|
|
19498
|
+
delegation: {
|
|
19499
|
+
cid: session.delegationCid,
|
|
19500
|
+
delegationHeader: session.delegationHeader,
|
|
19501
|
+
delegateDID: session.verificationMethod,
|
|
19502
|
+
delegatorDID: this.did,
|
|
19503
|
+
spaceId: session.spaceId,
|
|
19504
|
+
path: "",
|
|
19505
|
+
actions,
|
|
19506
|
+
expiry: expiresAt,
|
|
19507
|
+
allowSubDelegation: true,
|
|
19508
|
+
ownerAddress: session.address,
|
|
19509
|
+
chainId: session.chainId,
|
|
19510
|
+
host: this.config.host
|
|
19511
|
+
},
|
|
19512
|
+
operations,
|
|
19513
|
+
expiresAt,
|
|
19514
|
+
provenance: "primary"
|
|
19411
19515
|
});
|
|
19412
19516
|
}
|
|
19413
19517
|
async writeManifestRegistryRecords() {
|
|
@@ -19743,6 +19847,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19743
19847
|
} else {
|
|
19744
19848
|
this._restoredTcSession = tcSession;
|
|
19745
19849
|
}
|
|
19850
|
+
this.registerPrimarySessionGrant(tcSession);
|
|
19746
19851
|
}
|
|
19747
19852
|
}
|
|
19748
19853
|
/**
|
|
@@ -20781,7 +20886,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20781
20886
|
getRuntimePermissionDelegations(permissions) {
|
|
20782
20887
|
this.pruneExpiredRuntimePermissionGrants();
|
|
20783
20888
|
if (permissions === void 0) {
|
|
20784
|
-
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
20889
|
+
return this.runtimePermissionGrants.filter((grant) => grant.provenance !== "primary").map((grant) => grant.delegation);
|
|
20785
20890
|
}
|
|
20786
20891
|
const session = this.currentTinyCloudSession();
|
|
20787
20892
|
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -20933,7 +21038,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20933
21038
|
},
|
|
20934
21039
|
delegation,
|
|
20935
21040
|
operations: this.permissionOperations(delegatedEntries, spaceId),
|
|
20936
|
-
expiresAt
|
|
21041
|
+
expiresAt,
|
|
21042
|
+
provenance: "runtime"
|
|
20937
21043
|
});
|
|
20938
21044
|
delegations.push(delegation);
|
|
20939
21045
|
}
|
|
@@ -21594,7 +21700,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21594
21700
|
return grants;
|
|
21595
21701
|
}
|
|
21596
21702
|
for (const operation of operations) {
|
|
21597
|
-
const grant = this.findGrantForOperation(operation);
|
|
21703
|
+
const grant = this.findGrantForOperation(operation, { excludePrimary: true });
|
|
21598
21704
|
if (!grant) {
|
|
21599
21705
|
return [];
|
|
21600
21706
|
}
|
|
@@ -21634,7 +21740,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21634
21740
|
},
|
|
21635
21741
|
delegation,
|
|
21636
21742
|
operations,
|
|
21637
|
-
expiresAt: delegation.expiry
|
|
21743
|
+
expiresAt: delegation.expiry,
|
|
21744
|
+
provenance: "delegated"
|
|
21638
21745
|
};
|
|
21639
21746
|
}
|
|
21640
21747
|
installRuntimeGrantFromServiceSession(delegation, session, expiresAt) {
|
|
@@ -21649,7 +21756,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21649
21756
|
session,
|
|
21650
21757
|
delegation,
|
|
21651
21758
|
operations,
|
|
21652
|
-
expiresAt
|
|
21759
|
+
expiresAt,
|
|
21760
|
+
provenance: "delegated"
|
|
21653
21761
|
});
|
|
21654
21762
|
}
|
|
21655
21763
|
delegatedResourcesForEntries(entries, spaceId) {
|
|
@@ -21749,21 +21857,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21749
21857
|
});
|
|
21750
21858
|
return grant?.session ?? fallback;
|
|
21751
21859
|
}
|
|
21752
|
-
findGrantForOperations(operations) {
|
|
21860
|
+
findGrantForOperations(operations, options) {
|
|
21753
21861
|
if (operations.length === 0) {
|
|
21754
21862
|
return void 0;
|
|
21755
21863
|
}
|
|
21756
21864
|
this.pruneExpiredRuntimePermissionGrants();
|
|
21757
|
-
|
|
21865
|
+
const covering = this.runtimePermissionGrants.filter((grant) => {
|
|
21866
|
+
if (options?.excludePrimary && grant.provenance === "primary") {
|
|
21867
|
+
return false;
|
|
21868
|
+
}
|
|
21758
21869
|
return operations.every(
|
|
21759
21870
|
(operation) => grant.operations.some(
|
|
21760
21871
|
(granted) => this.operationCovers(granted, operation)
|
|
21761
21872
|
)
|
|
21762
21873
|
);
|
|
21763
21874
|
});
|
|
21875
|
+
if (covering.length === 0) {
|
|
21876
|
+
return void 0;
|
|
21877
|
+
}
|
|
21878
|
+
return covering.find((grant) => grant.provenance === "primary") ?? covering[0];
|
|
21764
21879
|
}
|
|
21765
|
-
findGrantForOperation(operation) {
|
|
21766
|
-
return this.findGrantForOperations([operation]);
|
|
21880
|
+
findGrantForOperation(operation, options) {
|
|
21881
|
+
return this.findGrantForOperations([operation], options);
|
|
21767
21882
|
}
|
|
21768
21883
|
pruneExpiredRuntimePermissionGrants() {
|
|
21769
21884
|
const now = Date.now();
|