@tinycloud/node-sdk 3.8.0-beta.2 → 3.8.0-beta.20
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/README.md +6 -0
- package/dist/{TinyCloudNode-B6VOBrCb.d.ts → TinyCloudNode-BRyeZas2.d.ts} +47 -6
- package/dist/{TinyCloudNode-CVO41O12.d.cts → TinyCloudNode-NrmztjDd.d.cts} +47 -6
- package/dist/{WasmKeyProvider-5Ee7fcAw.d.cts → WasmKeyProvider-BKCPRC-c.d.cts} +21 -1
- package/dist/{WasmKeyProvider-5Ee7fcAw.d.ts → WasmKeyProvider-BKCPRC-c.d.ts} +21 -1
- package/dist/{authority-DGi1hIMK.d.ts → authority-D6JMJwor.d.ts} +1 -1
- package/dist/{authority-DgVV80bI.d.cts → authority-Z-reu6zL.d.cts} +1 -1
- package/dist/core.cjs +336 -29
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +5 -4
- package/dist/core.d.ts +5 -4
- package/dist/core.js +330 -24
- package/dist/core.js.map +1 -1
- package/dist/credentials-core.d.cts +1 -1
- package/dist/credentials-core.d.ts +1 -1
- package/dist/credentials.d.cts +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/{delegation-0LKZkmP2.d.cts → delegation-Ckc3UETl.d.cts} +1 -1
- package/dist/{delegation-0LKZkmP2.d.ts → delegation-Ckc3UETl.d.ts} +1 -1
- package/dist/encryption-keys.d.cts +2 -2
- package/dist/encryption-keys.d.ts +2 -2
- package/dist/index.cjs +304 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +293 -27
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.cjs +3 -0
- package/dist/replication/authority.cjs.map +1 -1
- package/dist/replication/authority.d.cts +4 -3
- package/dist/replication/authority.d.ts +4 -3
- package/dist/replication/authority.js +3 -0
- package/dist/replication/authority.js.map +1 -1
- package/dist/replication/runtime.cjs +1 -0
- package/dist/replication/runtime.cjs.map +1 -1
- package/dist/replication/runtime.js +1 -0
- package/dist/replication/runtime.js.map +1 -1
- package/dist/share-receive.cjs +775 -0
- package/dist/share-receive.cjs.map +1 -0
- package/dist/share-receive.d.cts +32 -0
- package/dist/share-receive.d.ts +32 -0
- package/dist/share-receive.js +777 -0
- package/dist/share-receive.js.map +1 -0
- package/package.json +11 -4
package/dist/core.cjs
CHANGED
|
@@ -58,6 +58,7 @@ __export(core_exports, {
|
|
|
58
58
|
PermissionNotInManifestError: () => import_sdk_core14.PermissionNotInManifestError,
|
|
59
59
|
PrefixedKVService: () => import_sdk_core15.PrefixedKVService,
|
|
60
60
|
ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
|
|
61
|
+
RuntimeDelegationRejectedError: () => RuntimeDelegationRejectedError,
|
|
61
62
|
SECRET_NAME_RE: () => import_sdk_core18.SECRET_NAME_RE,
|
|
62
63
|
SQLAction: () => import_sdk_core16.SQLAction,
|
|
63
64
|
SQLService: () => import_sdk_core16.SQLService,
|
|
@@ -80,6 +81,7 @@ __export(core_exports, {
|
|
|
80
81
|
VersionCheckError: () => import_sdk_core22.VersionCheckError,
|
|
81
82
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
82
83
|
activateCompactRuntimeDelegation: () => activateCompactRuntimeDelegation,
|
|
84
|
+
activateValidatedRuntimeDelegation: () => activateValidatedRuntimeDelegation,
|
|
83
85
|
addressStorageKey: () => import_sdk_core13.addressStorageKey,
|
|
84
86
|
buildSpaceUri: () => import_sdk_core21.buildSpaceUri,
|
|
85
87
|
canonicalizeAddress: () => import_sdk_core13.canonicalizeAddress,
|
|
@@ -109,6 +111,7 @@ __export(core_exports, {
|
|
|
109
111
|
getNodeReplicationLoaders: () => getNodeReplicationLoaders,
|
|
110
112
|
getTinyCloudDebugLogs: () => import_sdk_core13.getTinyCloudDebugLogs,
|
|
111
113
|
installTinyCloudDebugGlobals: () => import_sdk_core13.installTinyCloudDebugGlobals,
|
|
114
|
+
isAppKeyHostBound: () => isAppKeyHostBound,
|
|
112
115
|
isCapabilitySubset: () => import_sdk_core14.isCapabilitySubset,
|
|
113
116
|
isEvmAddress: () => import_sdk_core13.isEvmAddress,
|
|
114
117
|
loadManifest: () => import_sdk_core14.loadManifest,
|
|
@@ -130,7 +133,8 @@ __export(core_exports, {
|
|
|
130
133
|
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core14.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
131
134
|
serializeDelegation: () => serializeDelegation,
|
|
132
135
|
tinyCloudDebugLogger: () => import_sdk_core13.tinyCloudDebugLogger,
|
|
133
|
-
validateManifest: () => import_sdk_core14.validateManifest
|
|
136
|
+
validateManifest: () => import_sdk_core14.validateManifest,
|
|
137
|
+
wireOpenKeyAuthorize: () => wireOpenKeyAuthorize
|
|
134
138
|
});
|
|
135
139
|
module.exports = __toCommonJS(core_exports);
|
|
136
140
|
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
@@ -345,6 +349,44 @@ var FileSessionStorage = class {
|
|
|
345
349
|
var import_node_crypto = require("crypto");
|
|
346
350
|
var import_siwe = require("siwe");
|
|
347
351
|
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
352
|
+
var import_resource = require("@tinycloud/sdk-services/encryption/resource");
|
|
353
|
+
var import_sdk_services2 = require("@tinycloud/sdk-services");
|
|
354
|
+
|
|
355
|
+
// src/authorization/appKeyHostBinding.ts
|
|
356
|
+
var DOMAIN_LABEL = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
357
|
+
var IPV4 = /^\d+\.\d+\.\d+\.\d+$/;
|
|
358
|
+
var APP_ID = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
359
|
+
function appKeyHostBinding(domain, appId) {
|
|
360
|
+
if (!APP_ID.test(appId)) return false;
|
|
361
|
+
if (domain.endsWith(":")) return false;
|
|
362
|
+
let url;
|
|
363
|
+
try {
|
|
364
|
+
url = new URL(`https://${domain}`);
|
|
365
|
+
} catch {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
if (url.protocol !== "https:" || url.port !== "" || url.username !== "" || url.password !== "") return false;
|
|
369
|
+
if (url.pathname !== "/" || url.search !== "" || url.hash !== "") return false;
|
|
370
|
+
const host = url.hostname;
|
|
371
|
+
if (host.startsWith("[") || host.endsWith(".") || IPV4.test(host)) return false;
|
|
372
|
+
const labels = host.split(".");
|
|
373
|
+
if (labels.length < 2 || labels[labels.length - 1] === "localhost") return false;
|
|
374
|
+
if (!labels.every((label) => DOMAIN_LABEL.test(label))) return false;
|
|
375
|
+
const reversed = labels.reverse().join(".");
|
|
376
|
+
return appId === reversed || appId.startsWith(`${reversed}.`);
|
|
377
|
+
}
|
|
378
|
+
function isAppKeyHostBound(keysAppId, origin) {
|
|
379
|
+
if (typeof origin === "string" && !origin.includes("://")) {
|
|
380
|
+
return appKeyHostBinding(origin, keysAppId);
|
|
381
|
+
}
|
|
382
|
+
let url;
|
|
383
|
+
try {
|
|
384
|
+
url = typeof origin === "string" ? new URL(origin) : origin;
|
|
385
|
+
} catch {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
return appKeyHostBinding(url.host, keysAppId);
|
|
389
|
+
}
|
|
348
390
|
|
|
349
391
|
// src/replication/authority-sign-in.ts
|
|
350
392
|
var import_sdk_core2 = require("@tinycloud/sdk-core");
|
|
@@ -476,6 +518,7 @@ function cloneAbilitiesMap(actions) {
|
|
|
476
518
|
var NodeUserAuthorization = class {
|
|
477
519
|
constructor(config) {
|
|
478
520
|
this.activeSessionKeyId = "default";
|
|
521
|
+
this.preparedSessionCounter = 0;
|
|
479
522
|
/** Incremented by resetSession; a sign-in started earlier publishes nothing. */
|
|
480
523
|
this.sessionGeneration = 0;
|
|
481
524
|
/**
|
|
@@ -832,6 +875,23 @@ var NodeUserAuthorization = class {
|
|
|
832
875
|
);
|
|
833
876
|
return this._capabilityRequest;
|
|
834
877
|
}
|
|
878
|
+
async refreshNamedKeyFeatureForSignIn(address, chainId) {
|
|
879
|
+
const request = this.getCapabilityRequest();
|
|
880
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
881
|
+
const hasNamedKeys = request?.manifests.some((manifest) => manifest.keys?.length && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id));
|
|
882
|
+
if (hasNamedKeys) {
|
|
883
|
+
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
884
|
+
await this.refreshNodeInfo();
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
/** Manifest key paths that this sign-in cannot grant. */
|
|
888
|
+
get unavailableKeyPaths() {
|
|
889
|
+
const request = this.getCapabilityRequest();
|
|
890
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
891
|
+
return (request?.manifests ?? []).flatMap(
|
|
892
|
+
(manifest) => this._nodeFeatures.includes("encryption-named-keys-v1") && appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id) ? [] : (manifest.keys ?? []).map((entry) => "path" in entry ? entry.path : entry.prefix)
|
|
893
|
+
);
|
|
894
|
+
}
|
|
835
895
|
resolveSpaceName(space, address, chainId) {
|
|
836
896
|
if (space.startsWith("tinycloud:")) {
|
|
837
897
|
return space;
|
|
@@ -1023,15 +1083,32 @@ var NodeUserAuthorization = class {
|
|
|
1023
1083
|
}
|
|
1024
1084
|
const rawAbilities = {};
|
|
1025
1085
|
const currentDid = (0, import_sdk_core5.pkhDid)(address, chainId);
|
|
1086
|
+
if (this._nodeFeatures.includes("encryption-named-keys-v1")) {
|
|
1087
|
+
const siweDomain = this.siweConfig?.domain ?? this.domain;
|
|
1088
|
+
for (const manifest of request.manifests) {
|
|
1089
|
+
if (!appKeyHostBinding(siweDomain, manifest.keys_app_id ?? manifest.app_id)) continue;
|
|
1090
|
+
for (const declaration of manifest.keys ?? []) {
|
|
1091
|
+
const path = "path" in declaration ? declaration.path : declaration.prefix;
|
|
1092
|
+
const resource = `urn:tinycloud:encryption:${currentDid}:default/${path}`;
|
|
1093
|
+
for (const ability of declaration.abilities) {
|
|
1094
|
+
addRawAbility(rawAbilities, resource, `tinycloud.encryption/${ability}`);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1026
1099
|
const spaceResources = request.resources.filter((entry) => {
|
|
1027
1100
|
if (entry.service !== import_sdk_core5.ENCRYPTION_PERMISSION_SERVICE) {
|
|
1028
1101
|
return true;
|
|
1029
1102
|
}
|
|
1103
|
+
const parsed = entry.path.includes("/") ? (0, import_resource.parseEncryptionResource)(entry.path) : { ...(0, import_sdk_services2.parseNetworkId)(entry.path), kind: "network" };
|
|
1104
|
+
const sharePrefix = parsed.kind === "prefix" && parsed.network === "default" && parsed.prefix === "share" && entry.actions.length === 1 && entry.actions[0] === DECRYPT_ACTION && didPrincipalMatches(parsed.ownerDid, currentDid);
|
|
1105
|
+
if (parsed.kind !== "network" && !sharePrefix) {
|
|
1106
|
+
throw new import_sdk_core5.ManifestValidationError("named keys go in manifest.keys");
|
|
1107
|
+
}
|
|
1030
1108
|
for (const action of entry.actions) {
|
|
1031
1109
|
addRawAbility(rawAbilities, entry.path, action);
|
|
1032
1110
|
}
|
|
1033
|
-
if (entry.actions.includes(DECRYPT_ACTION)) {
|
|
1034
|
-
const parsed = (0, import_sdk_core5.parseNetworkId)(entry.path);
|
|
1111
|
+
if (entry.actions.includes(DECRYPT_ACTION) && parsed.kind === "network") {
|
|
1035
1112
|
if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
|
|
1036
1113
|
addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
|
|
1037
1114
|
}
|
|
@@ -1068,8 +1145,7 @@ var NodeUserAuthorization = class {
|
|
|
1068
1145
|
/**
|
|
1069
1146
|
* Build SIWE overrides from the top-level nonce and siweConfig.
|
|
1070
1147
|
* - Top-level `nonce` is seeded first so `siweConfig.nonce` wins if both are set.
|
|
1071
|
-
* -
|
|
1072
|
-
* - resources are appended to the default resources
|
|
1148
|
+
* - resources are inserted after WASM preparation, before the final ReCap
|
|
1073
1149
|
* - uri triggers a warning (overwriting delegation target)
|
|
1074
1150
|
* - all other fields override directly
|
|
1075
1151
|
* - per-call nonce overrides siweConfig.nonce when provided
|
|
@@ -1087,9 +1163,6 @@ var NodeUserAuthorization = class {
|
|
|
1087
1163
|
if (statement) {
|
|
1088
1164
|
overrides.statement = this.statement ? `${statement} ${this.statement}` : statement;
|
|
1089
1165
|
}
|
|
1090
|
-
if (resources && resources.length > 0) {
|
|
1091
|
-
overrides.resources = resources;
|
|
1092
|
-
}
|
|
1093
1166
|
if (uri) {
|
|
1094
1167
|
console.warn(
|
|
1095
1168
|
"[tinycloud] siweConfig.uri is overwriting the delegation target URI. This may break delegation chain validation if the URI does not match the session key DID."
|
|
@@ -1101,6 +1174,29 @@ var NodeUserAuthorization = class {
|
|
|
1101
1174
|
}
|
|
1102
1175
|
return overrides;
|
|
1103
1176
|
}
|
|
1177
|
+
prepareSessionWithResources(params) {
|
|
1178
|
+
const resources = this.siweConfig?.resources;
|
|
1179
|
+
if (resources?.some((resource) => typeof resource !== "string" || !/^urn:tinycloud:recipients:[A-Za-z0-9_-]+$/.test(resource))) {
|
|
1180
|
+
throw new Error("SIWE metadata resources must be base64url recipients URIs");
|
|
1181
|
+
}
|
|
1182
|
+
const prepared = this.wasm.prepareSession(params);
|
|
1183
|
+
if (!resources?.length) return prepared;
|
|
1184
|
+
const recapLines = /^- urn:recap:[^\r\n]+$/gim;
|
|
1185
|
+
const recaps = prepared.siwe.match(recapLines);
|
|
1186
|
+
const recap = recaps?.[0];
|
|
1187
|
+
if (recaps?.length !== 1 || !prepared.siwe.endsWith(recap)) {
|
|
1188
|
+
throw new Error("Prepared SIWE must end with exactly one ReCap");
|
|
1189
|
+
}
|
|
1190
|
+
const insertedLines = resources.map((resource) => `- ${resource}`);
|
|
1191
|
+
const siwe = prepared.siwe.slice(0, -recap.length) + insertedLines.join("\n") + "\n" + recap;
|
|
1192
|
+
const expectedFields = (0, import_sdk_core5.extractImmutableSiweFields)(prepared.siwe);
|
|
1193
|
+
expectedFields.nonRecapResources = [expectedFields.nonRecapResources, ...insertedLines].filter(Boolean).join("\n");
|
|
1194
|
+
const actualRecaps = siwe.match(recapLines);
|
|
1195
|
+
if (actualRecaps?.length !== 1 || actualRecaps[0] !== recap || (0, import_sdk_core5.diffImmutableSiweFields)(expectedFields, (0, import_sdk_core5.extractImmutableSiweFields)(siwe)).length) {
|
|
1196
|
+
throw new Error("SIWE metadata insertion changed the prepared message");
|
|
1197
|
+
}
|
|
1198
|
+
return { ...prepared, siwe };
|
|
1199
|
+
}
|
|
1104
1200
|
/**
|
|
1105
1201
|
* Add an extension to the authorization flow.
|
|
1106
1202
|
*/
|
|
@@ -1348,7 +1444,7 @@ var NodeUserAuthorization = class {
|
|
|
1348
1444
|
spaceAbilities[spaceId] = (0, import_sdk_core5.resourceCapabilitiesToAbilitiesMap)(resources);
|
|
1349
1445
|
}
|
|
1350
1446
|
const abilities = spaceAbilities[options.spaceId] ?? (0, import_sdk_core5.resourceCapabilitiesToAbilitiesMap)([]);
|
|
1351
|
-
const prepared = this.
|
|
1447
|
+
const prepared = this.prepareSessionWithResources({
|
|
1352
1448
|
abilities,
|
|
1353
1449
|
spaceAbilities,
|
|
1354
1450
|
...options.rawAbilities !== void 0 ? { rawAbilities: options.rawAbilities } : {},
|
|
@@ -1427,6 +1523,8 @@ var NodeUserAuthorization = class {
|
|
|
1427
1523
|
this._chainId = chainId;
|
|
1428
1524
|
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
1429
1525
|
this.assertSignInCurrent(generation);
|
|
1526
|
+
await this.refreshNamedKeyFeatureForSignIn(address, chainId);
|
|
1527
|
+
this.assertSignInCurrent(generation);
|
|
1430
1528
|
const keyId = `session-${Date.now()}`;
|
|
1431
1529
|
this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
|
|
1432
1530
|
this.activeSessionKeyId = keyId;
|
|
@@ -1439,7 +1537,7 @@ var NodeUserAuthorization = class {
|
|
|
1439
1537
|
const spaceId = capabilityPlan.spaceId;
|
|
1440
1538
|
const now = /* @__PURE__ */ new Date();
|
|
1441
1539
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
1442
|
-
const prepared = this.
|
|
1540
|
+
const prepared = this.prepareSessionWithResources({
|
|
1443
1541
|
abilities: capabilityPlan.abilities,
|
|
1444
1542
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
1445
1543
|
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
@@ -1573,9 +1671,9 @@ var NodeUserAuthorization = class {
|
|
|
1573
1671
|
refuseCaveated(this.getCapabilityRequest()?.manifests);
|
|
1574
1672
|
const address = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
|
|
1575
1673
|
const chainId = await this.signer.getChainId();
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
this.
|
|
1674
|
+
await this.refreshNamedKeyFeatureForSignIn(address, chainId);
|
|
1675
|
+
const keyId = `openkey-session-${Date.now()}-${++this.preparedSessionCounter}`;
|
|
1676
|
+
this.sessionManager.createSessionKey(keyId);
|
|
1579
1677
|
const jwkString = this.sessionManager.jwk(keyId);
|
|
1580
1678
|
if (!jwkString) {
|
|
1581
1679
|
throw new Error("Failed to create session key");
|
|
@@ -1585,7 +1683,7 @@ var NodeUserAuthorization = class {
|
|
|
1585
1683
|
const spaceId = capabilityPlan.spaceId;
|
|
1586
1684
|
const now = /* @__PURE__ */ new Date();
|
|
1587
1685
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
1588
|
-
const prepared = this.
|
|
1686
|
+
const prepared = this.prepareSessionWithResources({
|
|
1589
1687
|
abilities: capabilityPlan.abilities,
|
|
1590
1688
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
1591
1689
|
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
@@ -1656,6 +1754,7 @@ var NodeUserAuthorization = class {
|
|
|
1656
1754
|
await this.sessionStorage.save(address, persistedData);
|
|
1657
1755
|
this._session = clientSession;
|
|
1658
1756
|
this._tinyCloudSession = tinyCloudSession;
|
|
1757
|
+
this.activeSessionKeyId = keyId;
|
|
1659
1758
|
this._address = address;
|
|
1660
1759
|
this._chainId = chainId;
|
|
1661
1760
|
await this.refreshNodeInfo();
|
|
@@ -1702,6 +1801,11 @@ var NodeUserAuthorization = class {
|
|
|
1702
1801
|
* @param options Optional overrides for the OpenKey request.
|
|
1703
1802
|
*/
|
|
1704
1803
|
async signInWithOpenKey(authorizeFn, options) {
|
|
1804
|
+
const pending = await this.prepareOpenKeySignIn(options);
|
|
1805
|
+
return this.completeOpenKeySignIn(pending, authorizeFn(pending.request), options);
|
|
1806
|
+
}
|
|
1807
|
+
/** Finish address, host and SIWE preparation before an approval click. */
|
|
1808
|
+
async prepareOpenKeySignIn(options) {
|
|
1705
1809
|
refuseCaveated(this.getCapabilityRequest()?.manifests);
|
|
1706
1810
|
if (options?.host !== void 0) {
|
|
1707
1811
|
const overrideHost = options.host.trim();
|
|
@@ -1713,7 +1817,7 @@ var NodeUserAuthorization = class {
|
|
|
1713
1817
|
const signingAddress = (0, import_sdk_core5.canonicalizeAddress)(await this.signer.getAddress());
|
|
1714
1818
|
const signingChainId = await this.signer.getChainId();
|
|
1715
1819
|
await this.resolveTinyCloudHostsForSignIn(signingAddress, signingChainId);
|
|
1716
|
-
const { prepared, keyId, jwk } = await this.prepareSessionForSigning();
|
|
1820
|
+
const { prepared, keyId, jwk, address, chainId } = await this.prepareSessionForSigning();
|
|
1717
1821
|
const presentation = this.buildPresentationEnvelope(options?.reason);
|
|
1718
1822
|
const hostHint = this.primaryTinyCloudHost;
|
|
1719
1823
|
const originalRequest = {
|
|
@@ -1725,12 +1829,32 @@ var NodeUserAuthorization = class {
|
|
|
1725
1829
|
keyId: options?.openkeyKeyId,
|
|
1726
1830
|
presentation
|
|
1727
1831
|
};
|
|
1832
|
+
return {
|
|
1833
|
+
request: originalRequest,
|
|
1834
|
+
prepared,
|
|
1835
|
+
keyId,
|
|
1836
|
+
jwk,
|
|
1837
|
+
address,
|
|
1838
|
+
chainId,
|
|
1839
|
+
generation: this.sessionGeneration,
|
|
1840
|
+
createdAt: Date.now()
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
/** Complete a prepared approval. The caller starts authorization before awaiting this method. */
|
|
1844
|
+
async completeOpenKeySignIn(pending, authorization, options) {
|
|
1845
|
+
if (Date.now() - pending.createdAt > 5 * 6e4) {
|
|
1846
|
+
throw new Error("Prepared OpenKey sign-in expired; prepare again");
|
|
1847
|
+
}
|
|
1848
|
+
if (pending.generation !== this.sessionGeneration) {
|
|
1849
|
+
throw new Error("Prepared OpenKey sign-in expired after sign-out");
|
|
1850
|
+
}
|
|
1851
|
+
const { request: originalRequest, prepared, keyId, jwk } = pending;
|
|
1728
1852
|
let result;
|
|
1729
1853
|
let signed;
|
|
1730
1854
|
let signature;
|
|
1731
1855
|
for (let attempt = 0; ; ) {
|
|
1732
1856
|
try {
|
|
1733
|
-
result ?? (result = await
|
|
1857
|
+
result ?? (result = await authorization);
|
|
1734
1858
|
signed = await this.verifyOpenKeyResult(result, prepared);
|
|
1735
1859
|
signature = result.signature;
|
|
1736
1860
|
break;
|
|
@@ -2151,8 +2275,52 @@ var NodeUserAuthorization = class {
|
|
|
2151
2275
|
}
|
|
2152
2276
|
};
|
|
2153
2277
|
|
|
2278
|
+
// src/authorization/openKeyBridge.ts
|
|
2279
|
+
function wireOpenKeyAuthorize(openkey, opts) {
|
|
2280
|
+
return async (input) => {
|
|
2281
|
+
const result = await openkey.authorizeTinyCloud({
|
|
2282
|
+
protocolVersion: 1,
|
|
2283
|
+
siwe: input.siwe,
|
|
2284
|
+
keyId: input.keyId,
|
|
2285
|
+
jwk: input.jwk,
|
|
2286
|
+
host: input.host,
|
|
2287
|
+
// Forward the presentation envelope verbatim — the OpenKey SDK
|
|
2288
|
+
// validates and size-bounds it before use.
|
|
2289
|
+
presentation: input.presentation
|
|
2290
|
+
}, opts);
|
|
2291
|
+
if (result.protocolVersion !== 1) {
|
|
2292
|
+
throw new Error(
|
|
2293
|
+
`wireOpenKeyAuthorize: OpenKey returned unsupported protocolVersion ${result.protocolVersion}`
|
|
2294
|
+
);
|
|
2295
|
+
}
|
|
2296
|
+
if (typeof result.signedMessage !== "string" || !result.signedMessage) {
|
|
2297
|
+
throw new Error(
|
|
2298
|
+
"wireOpenKeyAuthorize: OpenKey returned no signedMessage \u2014 cannot complete a TinyCloud session"
|
|
2299
|
+
);
|
|
2300
|
+
}
|
|
2301
|
+
if (!Array.isArray(result.selectedActionKeys)) {
|
|
2302
|
+
throw new Error(
|
|
2303
|
+
"wireOpenKeyAuthorize: OpenKey returned no selectedActionKeys"
|
|
2304
|
+
);
|
|
2305
|
+
}
|
|
2306
|
+
if (!Array.isArray(result.permissions)) {
|
|
2307
|
+
throw new Error(
|
|
2308
|
+
"wireOpenKeyAuthorize: OpenKey returned no permissions"
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2311
|
+
return {
|
|
2312
|
+
protocolVersion: 1,
|
|
2313
|
+
address: result.address,
|
|
2314
|
+
signature: result.signature,
|
|
2315
|
+
signedMessage: result.signedMessage,
|
|
2316
|
+
selectedActionKeys: result.selectedActionKeys,
|
|
2317
|
+
permissions: result.permissions
|
|
2318
|
+
};
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2154
2322
|
// src/recordingServiceContext.ts
|
|
2155
|
-
var
|
|
2323
|
+
var import_sdk_services3 = require("@tinycloud/sdk-services");
|
|
2156
2324
|
var import_requestLog = require("@tinycloud/sdk-services/telemetry/requestLog");
|
|
2157
2325
|
|
|
2158
2326
|
// src/recordingRegistry.ts
|
|
@@ -2197,9 +2365,9 @@ function replicationEvent(sample, op) {
|
|
|
2197
2365
|
}
|
|
2198
2366
|
function createServiceContext(config) {
|
|
2199
2367
|
const { requestSink, ...base } = config;
|
|
2200
|
-
return requestSink === void 0 ? new
|
|
2368
|
+
return requestSink === void 0 ? new import_sdk_services3.ServiceContext(base) : new RecordingServiceContext(base, requestSink);
|
|
2201
2369
|
}
|
|
2202
|
-
var RecordingServiceContext = class extends
|
|
2370
|
+
var RecordingServiceContext = class extends import_sdk_services3.ServiceContext {
|
|
2203
2371
|
constructor(config, sink) {
|
|
2204
2372
|
const pending = {};
|
|
2205
2373
|
super({
|
|
@@ -2793,8 +2961,9 @@ function deserializeDelegation(data) {
|
|
|
2793
2961
|
// src/TinyCloudNode.ts
|
|
2794
2962
|
var import_siwe2 = require("siwe");
|
|
2795
2963
|
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
2796
|
-
var
|
|
2964
|
+
var import_sdk_services4 = require("@tinycloud/sdk-services");
|
|
2797
2965
|
var import_requestLog2 = require("@tinycloud/sdk-services/telemetry/requestLog");
|
|
2966
|
+
var import_resource2 = require("@tinycloud/sdk-services/encryption/resource");
|
|
2798
2967
|
|
|
2799
2968
|
// src/account/AccountService.ts
|
|
2800
2969
|
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
@@ -3271,6 +3440,7 @@ var ROOT_DELEGATION_ACTIONS = [
|
|
|
3271
3440
|
import_sdk_core11.DUCKDB.ALL
|
|
3272
3441
|
];
|
|
3273
3442
|
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core11.EXPIRY.SESSION_MS;
|
|
3443
|
+
var OWNER_REVOCATION_WINDOW_MS = 10 * 6e4;
|
|
3274
3444
|
function unifiedRootAttenuation(capabilities) {
|
|
3275
3445
|
const attenuation = {};
|
|
3276
3446
|
for (const capability of capabilities) {
|
|
@@ -3768,6 +3938,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3768
3938
|
constructor(config = {}) {
|
|
3769
3939
|
this.signer = null;
|
|
3770
3940
|
this.auth = null;
|
|
3941
|
+
this.consumedOpenKeyPendings = /* @__PURE__ */ new WeakSet();
|
|
3771
3942
|
this.tc = null;
|
|
3772
3943
|
this._chainId = 1;
|
|
3773
3944
|
this.replicaPurgeFailedHandlers = /* @__PURE__ */ new Set();
|
|
@@ -3802,6 +3973,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3802
3973
|
return void 0;
|
|
3803
3974
|
}
|
|
3804
3975
|
};
|
|
3976
|
+
this._keysUnavailable = [];
|
|
3805
3977
|
this._baseVaults = /* @__PURE__ */ new Map();
|
|
3806
3978
|
this._baseSecrets = /* @__PURE__ */ new Map();
|
|
3807
3979
|
this._secrets = /* @__PURE__ */ new Map();
|
|
@@ -4629,6 +4801,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4629
4801
|
this._hooks = void 0;
|
|
4630
4802
|
this._vault = void 0;
|
|
4631
4803
|
this._encryption = void 0;
|
|
4804
|
+
this._namedKeyClient = void 0;
|
|
4805
|
+
this._keysUnavailable = [];
|
|
4632
4806
|
this._baseVaults.clear();
|
|
4633
4807
|
this._baseSecrets.clear();
|
|
4634
4808
|
this._secrets.clear();
|
|
@@ -4705,6 +4879,37 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4705
4879
|
}
|
|
4706
4880
|
await this.signInWith(() => this.auth.signInWithOpenKey(authorizeFn, options));
|
|
4707
4881
|
}
|
|
4882
|
+
/** Prepare the OpenKey request before the approval click. */
|
|
4883
|
+
async prepareOpenKeySignIn() {
|
|
4884
|
+
if (!this.signer || !this.tc || !this.auth) {
|
|
4885
|
+
throw new Error("Cannot prepare OpenKey sign-in in session-only mode. Provide a signer in config.");
|
|
4886
|
+
}
|
|
4887
|
+
await this.signOutInFlight;
|
|
4888
|
+
await this.accountRegistryTail;
|
|
4889
|
+
await this.wasmBindings.ensureInitialized?.();
|
|
4890
|
+
return this.auth.prepareOpenKeySignIn();
|
|
4891
|
+
}
|
|
4892
|
+
/** Start OpenKey authorization synchronously, then complete normal session setup. */
|
|
4893
|
+
signInWithPreparedOpenKey(pending, authorizeFn) {
|
|
4894
|
+
if (!this.signer || !this.tc || !this.auth || this.signOutInFlight) {
|
|
4895
|
+
throw new Error("Prepared OpenKey sign-in is unavailable");
|
|
4896
|
+
}
|
|
4897
|
+
if (this.consumedOpenKeyPendings.has(pending)) {
|
|
4898
|
+
throw new Error("Prepared OpenKey sign-in was already used");
|
|
4899
|
+
}
|
|
4900
|
+
if (Date.now() - pending.createdAt > 5 * 6e4) {
|
|
4901
|
+
throw new Error("Prepared OpenKey sign-in expired; prepare again");
|
|
4902
|
+
}
|
|
4903
|
+
this.consumedOpenKeyPendings.add(pending);
|
|
4904
|
+
const authorization = authorizeFn(pending.request);
|
|
4905
|
+
void authorization.catch(() => void 0);
|
|
4906
|
+
return this.signInWith(() => {
|
|
4907
|
+
if (this._address !== pending.address || this._chainId !== pending.chainId) {
|
|
4908
|
+
throw new Error("OpenKey account changed after sign-in preparation");
|
|
4909
|
+
}
|
|
4910
|
+
return this.auth.completeOpenKeySignIn(pending, authorization);
|
|
4911
|
+
});
|
|
4912
|
+
}
|
|
4708
4913
|
async signInWith(performSignIn) {
|
|
4709
4914
|
refuseCaveated(this.auth?.capabilityRequest?.manifests);
|
|
4710
4915
|
const epoch = this.sessionEpoch;
|
|
@@ -4751,6 +4956,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4751
4956
|
this._hooks = void 0;
|
|
4752
4957
|
this._vault = void 0;
|
|
4753
4958
|
this._encryption = void 0;
|
|
4959
|
+
this._namedKeyClient = void 0;
|
|
4960
|
+
this._keysUnavailable = [];
|
|
4754
4961
|
this._baseVaults.clear();
|
|
4755
4962
|
this._baseSecrets.clear();
|
|
4756
4963
|
this._secrets.clear();
|
|
@@ -4803,6 +5010,26 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4803
5010
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
4804
5011
|
await this.ensureRequestedEncryptionNetworks();
|
|
4805
5012
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
5013
|
+
this._keysUnavailable = this.auth?.unavailableKeyPaths ?? [];
|
|
5014
|
+
if (this._keysUnavailable.length > 0) {
|
|
5015
|
+
this.notificationHandler.warning(`Named keys unavailable: ${this._keysUnavailable.join(", ")}`);
|
|
5016
|
+
}
|
|
5017
|
+
if (this.nodeFeatures.includes("encryption-named-keys-v1")) {
|
|
5018
|
+
for (const manifest of this.auth?.capabilityRequest?.manifests ?? []) {
|
|
5019
|
+
for (const declaration of manifest.keys ?? []) {
|
|
5020
|
+
if ("path" in declaration && declaration.abilities.includes("key.create") && !this._keysUnavailable.includes(declaration.path)) {
|
|
5021
|
+
try {
|
|
5022
|
+
await this.keys.ensureKey(declaration.path);
|
|
5023
|
+
} catch (error) {
|
|
5024
|
+
this._keysUnavailable.push(declaration.path);
|
|
5025
|
+
const code = error && typeof error === "object" && "code" in error && typeof error.code === "string" && /^[A-Z_]+$/.test(error.code) ? error.code : "UNKNOWN";
|
|
5026
|
+
this.notificationHandler.warning(`Named key unavailable: ${declaration.path} (${code})`);
|
|
5027
|
+
}
|
|
5028
|
+
this.assertSessionEpoch(epoch, "Sign-in");
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
}
|
|
5032
|
+
}
|
|
4806
5033
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
4807
5034
|
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(import_sdk_core11.SECRETS_SPACE));
|
|
4808
5035
|
}
|
|
@@ -5379,7 +5606,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5379
5606
|
if (!this.currentSessionCoversAccountRegistry()) {
|
|
5380
5607
|
if (!_TinyCloudNode.accountRegistrySkipLogged) {
|
|
5381
5608
|
_TinyCloudNode.accountRegistrySkipLogged = true;
|
|
5382
|
-
|
|
5609
|
+
import_sdk_services4.tinyCloudDebugLogger.log("registry.skip");
|
|
5383
5610
|
}
|
|
5384
5611
|
return;
|
|
5385
5612
|
}
|
|
@@ -5590,7 +5817,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5590
5817
|
const networkIds = /* @__PURE__ */ new Set();
|
|
5591
5818
|
for (const resource of request.resources) {
|
|
5592
5819
|
if (resource.service === import_sdk_core11.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
|
|
5593
|
-
|
|
5820
|
+
const parsed = resource.path.includes("/") ? (0, import_resource2.parseEncryptionResource)(resource.path) : { ...(0, import_sdk_core11.parseNetworkId)(resource.path), kind: "network" };
|
|
5821
|
+
if (parsed.kind === "network") networkIds.add(resource.path);
|
|
5594
5822
|
}
|
|
5595
5823
|
}
|
|
5596
5824
|
return [...networkIds];
|
|
@@ -6140,6 +6368,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6140
6368
|
this._hooks = stagedGraph.hooks;
|
|
6141
6369
|
this._vault = stagedGraph.vault;
|
|
6142
6370
|
this._encryption = stagedGraph.encryption;
|
|
6371
|
+
this._namedKeyClient = void 0;
|
|
6372
|
+
this._keysUnavailable = [];
|
|
6143
6373
|
this._capabilityRegistry = stagedGraph.capabilityRegistry;
|
|
6144
6374
|
this._keyProvider = stagedGraph.keyProvider;
|
|
6145
6375
|
this._sharingService = stagedGraph.sharingService;
|
|
@@ -6321,6 +6551,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6321
6551
|
invoke: graph.invoke,
|
|
6322
6552
|
invokeAny: graph.invokeAny,
|
|
6323
6553
|
signOwnerRevocation: this.signer ? (cid) => this.signOwnerRevocation(cid) : void 0,
|
|
6554
|
+
sessionInvocationSigner: this.sessionInvocationSignerFor(input.serviceSession),
|
|
6324
6555
|
fetch: graph.fetch
|
|
6325
6556
|
});
|
|
6326
6557
|
const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
|
|
@@ -6536,6 +6767,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6536
6767
|
if (session === void 0) throw new Error("Not signed in. Call signIn() first.");
|
|
6537
6768
|
return signBytesWithJwk(bytes, session.jwk);
|
|
6538
6769
|
}
|
|
6770
|
+
/**
|
|
6771
|
+
* Signs proofless invocations with `session`'s own did:key, for the node's
|
|
6772
|
+
* issued-delegation list and revocation by the delegator. The audience is
|
|
6773
|
+
* this Node's DID; each invocation lives 60 seconds.
|
|
6774
|
+
*/
|
|
6775
|
+
sessionInvocationSignerFor(session) {
|
|
6776
|
+
return {
|
|
6777
|
+
did: () => session.verificationMethod.split("#", 1)[0],
|
|
6778
|
+
sign: async (attenuation) => {
|
|
6779
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
6780
|
+
const invocation = await (0, import_sdk_core11.signCompactUcanAuthorization)({
|
|
6781
|
+
issuerDid: session.verificationMethod.split("#", 1)[0],
|
|
6782
|
+
audienceDid: await this.fetchNodeId(),
|
|
6783
|
+
attenuation,
|
|
6784
|
+
facts: [{}],
|
|
6785
|
+
proofs: [],
|
|
6786
|
+
notBefore: now,
|
|
6787
|
+
expiresAt: now + 60,
|
|
6788
|
+
nonce: `urn:uuid:${crypto.randomUUID()}`,
|
|
6789
|
+
sign: (bytes) => signBytesWithJwk(bytes, session.jwk)
|
|
6790
|
+
});
|
|
6791
|
+
return invocation.authorization;
|
|
6792
|
+
}
|
|
6793
|
+
};
|
|
6794
|
+
}
|
|
6539
6795
|
/** Author a proofless Policy/v3 owner root with the authenticated holder key. */
|
|
6540
6796
|
async createUnifiedOwnerRoot(input) {
|
|
6541
6797
|
const ownerDid = this.credentialHolderDid;
|
|
@@ -7049,7 +7305,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7049
7305
|
);
|
|
7050
7306
|
graph.assertActive();
|
|
7051
7307
|
if (!response.ok) {
|
|
7052
|
-
const permissionHint = response.status === 401 || response.status === 403 ? (0,
|
|
7308
|
+
const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services4.parsePermissionHint)({
|
|
7053
7309
|
service: "tinycloud.encryption",
|
|
7054
7310
|
path: networkId,
|
|
7055
7311
|
actions: ["tinycloud.encryption/decrypt"]
|
|
@@ -7070,7 +7326,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7070
7326
|
graph.assertActive();
|
|
7071
7327
|
const signed = await this.signRawNetworkAuthorization({
|
|
7072
7328
|
targetNode: input.targetNode,
|
|
7073
|
-
networkId: input.networkId
|
|
7329
|
+
networkId: input.body.keyPath === void 0 ? input.networkId : `${input.networkId}/${input.body.keyPath}`,
|
|
7074
7330
|
action: DECRYPT_ACTION2,
|
|
7075
7331
|
facts: input.facts
|
|
7076
7332
|
}, { graph, session });
|
|
@@ -7243,6 +7499,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7243
7499
|
invoke: graph.invoke,
|
|
7244
7500
|
invokeAny: graph.invokeAny,
|
|
7245
7501
|
signOwnerRevocation: this.signer ? (cid) => this.signOwnerRevocation(cid) : void 0,
|
|
7502
|
+
sessionInvocationSigner: this.sessionInvocationSignerFor(serviceSession),
|
|
7246
7503
|
fetch: graph.fetch
|
|
7247
7504
|
});
|
|
7248
7505
|
this._spaceService = new import_sdk_core11.SpaceService({
|
|
@@ -7493,7 +7750,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7493
7750
|
* Sign a wallet (CACAO) revocation of the delegation `cid` for the node's
|
|
7494
7751
|
* `POST /revoke`, and return its Authorization header value. The node
|
|
7495
7752
|
* accepts it when the owner delegated `cid` or owns a space its abilities
|
|
7496
|
-
* target, whichever key issued it. Valid for
|
|
7753
|
+
* target, whichever key issued it. Valid for 10 minutes. Requires the
|
|
7497
7754
|
* owner wallet signer.
|
|
7498
7755
|
*/
|
|
7499
7756
|
async signOwnerRevocation(cid) {
|
|
@@ -7509,7 +7766,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7509
7766
|
chainId: session.chainId,
|
|
7510
7767
|
nonce: (0, import_siwe2.generateNonce)(),
|
|
7511
7768
|
issuedAt: issuedAt.toISOString(),
|
|
7512
|
-
expirationTime: new Date(issuedAt.getTime() +
|
|
7769
|
+
expirationTime: new Date(issuedAt.getTime() + OWNER_REVOCATION_WINDOW_MS).toISOString()
|
|
7513
7770
|
}).prepareMessage();
|
|
7514
7771
|
const signature = await this.signer.signMessage(siwe);
|
|
7515
7772
|
return this.wasmBindings.siweToDelegationHeaders({ siwe, signature }).Authorization;
|
|
@@ -7736,6 +7993,40 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7736
7993
|
get encryption() {
|
|
7737
7994
|
return this.getEncryptionService();
|
|
7738
7995
|
}
|
|
7996
|
+
/** Named keys bound to the current session. */
|
|
7997
|
+
get keys() {
|
|
7998
|
+
return new Proxy({}, {
|
|
7999
|
+
get: (_target, property) => {
|
|
8000
|
+
if (property === "refreshNodeInfo") {
|
|
8001
|
+
return () => {
|
|
8002
|
+
void this._namedKeyClient?.then((client) => client.refreshNodeInfo());
|
|
8003
|
+
};
|
|
8004
|
+
}
|
|
8005
|
+
if (typeof property !== "string" || ![
|
|
8006
|
+
"getPublicKey",
|
|
8007
|
+
"describeKey",
|
|
8008
|
+
"createKey",
|
|
8009
|
+
"blockKey",
|
|
8010
|
+
"unblockKey",
|
|
8011
|
+
"ensureKey",
|
|
8012
|
+
"encrypt",
|
|
8013
|
+
"decrypt",
|
|
8014
|
+
"decryptMany"
|
|
8015
|
+
].includes(property)) return void 0;
|
|
8016
|
+
return (...args) => {
|
|
8017
|
+
this._namedKeyClient ?? (this._namedKeyClient = import("./encryption-keys.cjs").then(({ createNamedKeyClient }) => createNamedKeyClient(this)));
|
|
8018
|
+
return this._namedKeyClient.then((client) => {
|
|
8019
|
+
const method = client[property];
|
|
8020
|
+
return method.apply(client, args);
|
|
8021
|
+
});
|
|
8022
|
+
};
|
|
8023
|
+
}
|
|
8024
|
+
});
|
|
8025
|
+
}
|
|
8026
|
+
/** Manifest key paths unavailable during the latest `signIn()` attempt. */
|
|
8027
|
+
get keysUnavailable() {
|
|
8028
|
+
return this._keysUnavailable;
|
|
8029
|
+
}
|
|
7739
8030
|
async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
|
|
7740
8031
|
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
7741
8032
|
return this.fetchEncryptionNetworkAt(
|
|
@@ -7863,7 +8154,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7863
8154
|
);
|
|
7864
8155
|
if (result.status !== "ok") {
|
|
7865
8156
|
if (result.status === "permission_required") {
|
|
7866
|
-
const hint = (0,
|
|
8157
|
+
const hint = (0, import_sdk_services4.parsePermissionHint)(result.hint);
|
|
7867
8158
|
if (hint === void 0) return { status: "read_failed" };
|
|
7868
8159
|
return {
|
|
7869
8160
|
status: "permission_required",
|
|
@@ -8625,7 +8916,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8625
8916
|
"delegateTo requires a non-empty permissions array"
|
|
8626
8917
|
);
|
|
8627
8918
|
}
|
|
8628
|
-
const expandedEntries =
|
|
8919
|
+
const expandedEntries = (0, import_sdk_core11.expandDelegationPermissionEntries)(permissions);
|
|
8920
|
+
const namedKeyEntries = expandedEntries.filter((entry) => entry.service === import_sdk_core11.ENCRYPTION_PERMISSION_SERVICE && entry.path.includes("/"));
|
|
8921
|
+
if (namedKeyEntries.length > 0) {
|
|
8922
|
+
if (expandedEntries.some((entry) => entry.service === import_sdk_core11.ENCRYPTION_PERMISSION_SERVICE && !entry.path.includes("/"))) {
|
|
8923
|
+
throw new import_sdk_core11.ManifestValidationError("named-key delegation cannot include bare-network permissions");
|
|
8924
|
+
}
|
|
8925
|
+
if (options?.forceWalletSign) {
|
|
8926
|
+
throw new import_sdk_core11.ManifestValidationError("named-key delegation requires a signed session grant");
|
|
8927
|
+
}
|
|
8928
|
+
const granted = this.projectSignedRecapCapabilities(session.siwe);
|
|
8929
|
+
const { subset, missing } = this.signedCapabilitySubset(namedKeyEntries, granted);
|
|
8930
|
+
if (!subset) throw new import_sdk_core11.PermissionNotInManifestError(missing, granted);
|
|
8931
|
+
}
|
|
8629
8932
|
const now = /* @__PURE__ */ new Date();
|
|
8630
8933
|
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
8631
8934
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
@@ -10041,6 +10344,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
10041
10344
|
PermissionNotInManifestError,
|
|
10042
10345
|
PrefixedKVService,
|
|
10043
10346
|
ProtocolMismatchError,
|
|
10347
|
+
RuntimeDelegationRejectedError,
|
|
10044
10348
|
SECRET_NAME_RE,
|
|
10045
10349
|
SQLAction,
|
|
10046
10350
|
SQLService,
|
|
@@ -10063,6 +10367,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
10063
10367
|
VersionCheckError,
|
|
10064
10368
|
WasmKeyProvider,
|
|
10065
10369
|
activateCompactRuntimeDelegation,
|
|
10370
|
+
activateValidatedRuntimeDelegation,
|
|
10066
10371
|
addressStorageKey,
|
|
10067
10372
|
buildSpaceUri,
|
|
10068
10373
|
canonicalizeAddress,
|
|
@@ -10092,6 +10397,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
10092
10397
|
getNodeReplicationLoaders,
|
|
10093
10398
|
getTinyCloudDebugLogs,
|
|
10094
10399
|
installTinyCloudDebugGlobals,
|
|
10400
|
+
isAppKeyHostBound,
|
|
10095
10401
|
isCapabilitySubset,
|
|
10096
10402
|
isEvmAddress,
|
|
10097
10403
|
loadManifest,
|
|
@@ -10113,6 +10419,7 @@ var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
|
10113
10419
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
10114
10420
|
serializeDelegation,
|
|
10115
10421
|
tinyCloudDebugLogger,
|
|
10116
|
-
validateManifest
|
|
10422
|
+
validateManifest,
|
|
10423
|
+
wireOpenKeyAuthorize
|
|
10117
10424
|
});
|
|
10118
10425
|
//# sourceMappingURL=core.cjs.map
|