@tinycloud/node-sdk 2.4.0-beta.2 → 2.4.0-beta.5
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-BucTrpWH.d.cts → core-BSQqoLAd.d.cts} +5 -1
- package/dist/{core-BucTrpWH.d.ts → core-BSQqoLAd.d.ts} +5 -1
- package/dist/core.cjs +90 -24
- 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 +97 -28
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +90 -24
- 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 +101 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -17337,6 +17337,25 @@ var MemorySessionStorage = class {
|
|
|
17337
17337
|
};
|
|
17338
17338
|
|
|
17339
17339
|
// src/authorization/NodeUserAuthorization.ts
|
|
17340
|
+
var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
|
|
17341
|
+
var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
|
|
17342
|
+
function didPrincipalMatches(actual, expected) {
|
|
17343
|
+
try {
|
|
17344
|
+
return (0, import_sdk_core.principalDidEquals)(actual, expected);
|
|
17345
|
+
} catch {
|
|
17346
|
+
return actual === expected;
|
|
17347
|
+
}
|
|
17348
|
+
}
|
|
17349
|
+
function addRawAbility(rawAbilities, resource, action) {
|
|
17350
|
+
const actions = rawAbilities[resource];
|
|
17351
|
+
if (actions === void 0) {
|
|
17352
|
+
rawAbilities[resource] = [action];
|
|
17353
|
+
return;
|
|
17354
|
+
}
|
|
17355
|
+
if (!actions.includes(action)) {
|
|
17356
|
+
actions.push(action);
|
|
17357
|
+
}
|
|
17358
|
+
}
|
|
17340
17359
|
var NodeUserAuthorization = class {
|
|
17341
17360
|
constructor(config) {
|
|
17342
17361
|
this.extensions = [];
|
|
@@ -17566,20 +17585,18 @@ var NodeUserAuthorization = class {
|
|
|
17566
17585
|
};
|
|
17567
17586
|
}
|
|
17568
17587
|
const rawAbilities = {};
|
|
17588
|
+
const currentDid = (0, import_sdk_core.pkhDid)(address, chainId);
|
|
17569
17589
|
const spaceResources = request.resources.filter((entry) => {
|
|
17570
17590
|
if (entry.service !== import_sdk_core.ENCRYPTION_PERMISSION_SERVICE) {
|
|
17571
17591
|
return true;
|
|
17572
17592
|
}
|
|
17573
|
-
const
|
|
17574
|
-
|
|
17575
|
-
|
|
17576
|
-
|
|
17577
|
-
const
|
|
17578
|
-
|
|
17579
|
-
|
|
17580
|
-
existing.push(action);
|
|
17581
|
-
seen.add(action);
|
|
17582
|
-
}
|
|
17593
|
+
for (const action of entry.actions) {
|
|
17594
|
+
addRawAbility(rawAbilities, entry.path, action);
|
|
17595
|
+
}
|
|
17596
|
+
if (entry.actions.includes(DECRYPT_ACTION)) {
|
|
17597
|
+
const parsed = (0, import_sdk_core.parseNetworkId)(entry.path);
|
|
17598
|
+
if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
|
|
17599
|
+
addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
|
|
17583
17600
|
}
|
|
17584
17601
|
}
|
|
17585
17602
|
return false;
|
|
@@ -18539,11 +18556,11 @@ var NodeSecretsService = class {
|
|
|
18539
18556
|
// src/TinyCloudNode.ts
|
|
18540
18557
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
18541
18558
|
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
18542
|
-
var
|
|
18543
|
-
var
|
|
18559
|
+
var NETWORK_CREATE_ACTION2 = "tinycloud.encryption/network.create";
|
|
18560
|
+
var DECRYPT_ACTION2 = "tinycloud.encryption/decrypt";
|
|
18544
18561
|
var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
|
|
18545
18562
|
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core5.EXPIRY.SESSION_MS;
|
|
18546
|
-
function
|
|
18563
|
+
function didPrincipalMatches2(actual, expected) {
|
|
18547
18564
|
try {
|
|
18548
18565
|
return (0, import_sdk_core5.principalDidEquals)(actual, expected);
|
|
18549
18566
|
} catch {
|
|
@@ -18919,6 +18936,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18919
18936
|
await this.tc.signIn(options);
|
|
18920
18937
|
this.syncResolvedHostFromAuth();
|
|
18921
18938
|
this.initializeServices();
|
|
18939
|
+
await this.ensureRequestedEncryptionNetworks();
|
|
18922
18940
|
if (this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
18923
18941
|
await this.ensureOwnedSpaceHosted(this.ownedSpaceId("secrets"));
|
|
18924
18942
|
}
|
|
@@ -18955,6 +18973,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18955
18973
|
}
|
|
18956
18974
|
}
|
|
18957
18975
|
}
|
|
18976
|
+
requestedEncryptionNetworkIds() {
|
|
18977
|
+
const request = this.capabilityRequest;
|
|
18978
|
+
if (!request) {
|
|
18979
|
+
return [];
|
|
18980
|
+
}
|
|
18981
|
+
const networkIds = /* @__PURE__ */ new Set();
|
|
18982
|
+
for (const resource of request.resources) {
|
|
18983
|
+
if (resource.service === import_sdk_core5.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
|
|
18984
|
+
networkIds.add(resource.path);
|
|
18985
|
+
}
|
|
18986
|
+
}
|
|
18987
|
+
return [...networkIds];
|
|
18988
|
+
}
|
|
18989
|
+
async ensureRequestedEncryptionNetworks() {
|
|
18990
|
+
if (!this.signer || !this.auth) {
|
|
18991
|
+
return;
|
|
18992
|
+
}
|
|
18993
|
+
for (const networkId of this.requestedEncryptionNetworkIds()) {
|
|
18994
|
+
const parsed = (0, import_sdk_core5.parseNetworkId)(networkId);
|
|
18995
|
+
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
18996
|
+
continue;
|
|
18997
|
+
}
|
|
18998
|
+
await this.ensureEncryptionNetwork(networkId);
|
|
18999
|
+
}
|
|
19000
|
+
}
|
|
18958
19001
|
async ensureOwnedSpaceHosted(spaceId) {
|
|
18959
19002
|
if (!this.auth) {
|
|
18960
19003
|
throw new Error("Owned space hosting requires wallet mode");
|
|
@@ -19423,7 +19466,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19423
19466
|
const signed2 = await this.signRawNetworkAuthorization({
|
|
19424
19467
|
targetNode: input.targetNode,
|
|
19425
19468
|
networkId: input.networkId,
|
|
19426
|
-
action:
|
|
19469
|
+
action: DECRYPT_ACTION2,
|
|
19427
19470
|
facts: input.facts
|
|
19428
19471
|
});
|
|
19429
19472
|
return {
|
|
@@ -19440,7 +19483,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19440
19483
|
},
|
|
19441
19484
|
wellKnown: {
|
|
19442
19485
|
fetchWellKnown: async (principal, discoveryKey) => {
|
|
19443
|
-
if (!this._address || !
|
|
19486
|
+
if (!this._address || !didPrincipalMatches2(principal, this.did)) {
|
|
19444
19487
|
return null;
|
|
19445
19488
|
}
|
|
19446
19489
|
if (!this.config.host) {
|
|
@@ -19947,12 +19990,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19947
19990
|
crypto2.sha256,
|
|
19948
19991
|
body
|
|
19949
19992
|
),
|
|
19950
|
-
action:
|
|
19993
|
+
action: NETWORK_CREATE_ACTION2
|
|
19951
19994
|
};
|
|
19952
19995
|
const signed2 = await this.signRawNetworkAuthorization({
|
|
19953
19996
|
targetNode,
|
|
19954
19997
|
networkId,
|
|
19955
|
-
action:
|
|
19998
|
+
action: NETWORK_CREATE_ACTION2,
|
|
19956
19999
|
facts
|
|
19957
20000
|
});
|
|
19958
20001
|
const response = await fetch(`${this.config.host}/encryption/networks`, {
|
|
@@ -19973,12 +20016,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19973
20016
|
const created = await response.json();
|
|
19974
20017
|
return created.descriptor;
|
|
19975
20018
|
}
|
|
19976
|
-
async ensureEncryptionNetwork(
|
|
19977
|
-
const
|
|
20019
|
+
async ensureEncryptionNetwork(nameOrNetworkId = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
20020
|
+
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
20021
|
+
const existing = await this.getEncryptionNetwork(networkId);
|
|
19978
20022
|
if (existing) {
|
|
19979
20023
|
return existing;
|
|
19980
20024
|
}
|
|
19981
|
-
|
|
20025
|
+
const parsed = (0, import_sdk_core5.parseNetworkId)(networkId);
|
|
20026
|
+
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
20027
|
+
throw new Error(
|
|
20028
|
+
`Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
|
|
20029
|
+
);
|
|
20030
|
+
}
|
|
20031
|
+
return this.createEncryptionNetwork(parsed.name);
|
|
19982
20032
|
}
|
|
19983
20033
|
/**
|
|
19984
20034
|
* App-facing secrets API backed by the `secrets` space vault.
|
|
@@ -20126,7 +20176,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20126
20176
|
throw new import_sdk_core5.SessionExpiredError(delegation.expiry);
|
|
20127
20177
|
}
|
|
20128
20178
|
const expectedDids = [session.verificationMethod, this.sessionDid];
|
|
20129
|
-
if (!expectedDids.some((did) =>
|
|
20179
|
+
if (!expectedDids.some((did) => didPrincipalMatches2(delegation.delegateDID, did))) {
|
|
20130
20180
|
throw new Error(
|
|
20131
20181
|
`Runtime delegation targets ${delegation.delegateDID} but this session key is ${session.verificationMethod}.`
|
|
20132
20182
|
);
|
|
@@ -20655,7 +20705,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20655
20705
|
);
|
|
20656
20706
|
}
|
|
20657
20707
|
const target = request.delegationTargets.find(
|
|
20658
|
-
(entry) =>
|
|
20708
|
+
(entry) => didPrincipalMatches2(entry.did, did)
|
|
20659
20709
|
);
|
|
20660
20710
|
if (!target) {
|
|
20661
20711
|
throw new Error(`No manifest delegation target found for DID ${did}`);
|
|
@@ -21105,7 +21155,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21105
21155
|
if (granted.resource !== void 0 || requested.resource !== void 0) {
|
|
21106
21156
|
return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
|
|
21107
21157
|
}
|
|
21108
|
-
return granted.spaceId !== void 0 && requested.spaceId !== void 0 && granted.spaceId
|
|
21158
|
+
return granted.spaceId !== void 0 && requested.spaceId !== void 0 && this.spaceIdsEqual(granted.spaceId, requested.spaceId) && this.pathContains(granted.path, requested.path);
|
|
21159
|
+
}
|
|
21160
|
+
// Space IDs are `tinycloud:pkh:eip155:<chain>:<0xADDR>:<name>`. The embedded
|
|
21161
|
+
// EIP-155 address is case-insensitive, but the CLI canonicalizes it to
|
|
21162
|
+
// lowercase when building a space URI while stored runtime delegations keep
|
|
21163
|
+
// the EIP-55 checksummed form — so a byte-for-byte compare spuriously rejects
|
|
21164
|
+
// an otherwise-valid grant. Lowercase ONLY the `eip155:<chain>:0x<addr>`
|
|
21165
|
+
// segment and leave everything else (crucially the case-sensitive space NAME)
|
|
21166
|
+
// byte-exact. Mirrors the CLI's `normalizeSpaceForCompare` (OPENKEY_SCOPE_MISMATCH fix).
|
|
21167
|
+
spaceIdsEqual(a, b) {
|
|
21168
|
+
return this.normalizeSpaceAddress(a) === this.normalizeSpaceAddress(b);
|
|
21169
|
+
}
|
|
21170
|
+
normalizeSpaceAddress(space) {
|
|
21171
|
+
return space.replace(
|
|
21172
|
+
/(eip155:\d+:)(0x[0-9a-fA-F]{40})/,
|
|
21173
|
+
(_match, prefix, addr) => prefix + addr.toLowerCase()
|
|
21174
|
+
);
|
|
21109
21175
|
}
|
|
21110
21176
|
actionContains(grantedAction, requestedAction) {
|
|
21111
21177
|
if (grantedAction === requestedAction) {
|
|
@@ -21369,7 +21435,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21369
21435
|
const targetHost = delegation.host ?? this.config.host;
|
|
21370
21436
|
if (this.isSessionOnly) {
|
|
21371
21437
|
const myDid = this.did;
|
|
21372
|
-
if (!
|
|
21438
|
+
if (!didPrincipalMatches2(delegation.delegateDID, myDid)) {
|
|
21373
21439
|
throw new Error(
|
|
21374
21440
|
`Delegation targets ${delegation.delegateDID} but this user's DID is ${myDid}. The delegation must target this user's DID.`
|
|
21375
21441
|
);
|