@tinycloud/node-sdk 2.2.0-beta.9 → 2.2.0
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-DcJ27GsA.d.cts → core-CNyXnUx9.d.cts} +80 -6
- package/dist/{core-DcJ27GsA.d.ts → core-CNyXnUx9.d.ts} +80 -6
- package/dist/core.cjs +708 -92
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +726 -99
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +802 -114
- 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 +805 -100
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -17028,70 +17028,115 @@ __export(index_exports, {
|
|
|
17028
17028
|
ACCOUNT_REGISTRY_PATH: () => import_sdk_core9.ACCOUNT_REGISTRY_PATH,
|
|
17029
17029
|
ACCOUNT_REGISTRY_SPACE: () => import_sdk_core9.ACCOUNT_REGISTRY_SPACE,
|
|
17030
17030
|
AutoApproveSpaceCreationHandler: () => import_sdk_core8.AutoApproveSpaceCreationHandler,
|
|
17031
|
-
CapabilityKeyRegistry: () =>
|
|
17032
|
-
CapabilityKeyRegistryErrorCodes: () =>
|
|
17031
|
+
CapabilityKeyRegistry: () => import_sdk_core17.CapabilityKeyRegistry,
|
|
17032
|
+
CapabilityKeyRegistryErrorCodes: () => import_sdk_core17.CapabilityKeyRegistryErrorCodes,
|
|
17033
|
+
DECRYPT_ACTION: () => import_sdk_core14.DECRYPT_ACTION,
|
|
17034
|
+
DECRYPT_FACT_TYPE: () => import_sdk_core14.DECRYPT_FACT_TYPE,
|
|
17035
|
+
DECRYPT_RESULT_TYPE: () => import_sdk_core14.DECRYPT_RESULT_TYPE,
|
|
17036
|
+
DEFAULT_ENCRYPTION_ALG: () => import_sdk_core14.DEFAULT_ENCRYPTION_ALG,
|
|
17037
|
+
DEFAULT_KEY_VERSION: () => import_sdk_core14.DEFAULT_KEY_VERSION,
|
|
17033
17038
|
DEFAULT_MANIFEST_SPACE: () => import_sdk_core9.DEFAULT_MANIFEST_SPACE,
|
|
17034
17039
|
DEFAULT_MANIFEST_VERSION: () => import_sdk_core9.DEFAULT_MANIFEST_VERSION,
|
|
17040
|
+
DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core10.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
17035
17041
|
DataVaultService: () => import_sdk_core13.DataVaultService,
|
|
17036
17042
|
DatabaseHandle: () => import_sdk_core11.DatabaseHandle,
|
|
17037
17043
|
DelegatedAccess: () => DelegatedAccess,
|
|
17038
|
-
DelegationErrorCodes: () =>
|
|
17039
|
-
DelegationManager: () =>
|
|
17044
|
+
DelegationErrorCodes: () => import_sdk_core16.DelegationErrorCodes,
|
|
17045
|
+
DelegationManager: () => import_sdk_core16.DelegationManager,
|
|
17040
17046
|
DuckDbAction: () => import_sdk_core12.DuckDbAction,
|
|
17041
17047
|
DuckDbDatabaseHandle: () => import_sdk_core12.DuckDbDatabaseHandle,
|
|
17042
17048
|
DuckDbService: () => import_sdk_core12.DuckDbService,
|
|
17049
|
+
ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_core14.ENCRYPTION_NETWORK_URN_PREFIX,
|
|
17050
|
+
ENCRYPTION_SERVICE: () => import_sdk_core14.ENCRYPTION_SERVICE,
|
|
17051
|
+
ENCRYPTION_SERVICE_SHORT: () => import_sdk_core14.ENCRYPTION_SERVICE_SHORT,
|
|
17052
|
+
ENVELOPE_VERSION: () => import_sdk_core14.ENVELOPE_VERSION,
|
|
17053
|
+
EncryptionService: () => import_sdk_core14.EncryptionService,
|
|
17043
17054
|
FileSessionStorage: () => FileSessionStorage,
|
|
17044
|
-
HooksService: () =>
|
|
17055
|
+
HooksService: () => import_sdk_core15.HooksService,
|
|
17045
17056
|
KVService: () => import_sdk_core10.KVService,
|
|
17046
17057
|
ManifestValidationError: () => import_sdk_core9.ManifestValidationError,
|
|
17047
17058
|
MemorySessionStorage: () => MemorySessionStorage,
|
|
17059
|
+
NETWORK_NAME_PATTERN: () => import_sdk_core14.NETWORK_NAME_PATTERN,
|
|
17060
|
+
NetworkIdError: () => import_sdk_core14.NetworkIdError,
|
|
17048
17061
|
NodeUserAuthorization: () => NodeUserAuthorization,
|
|
17049
17062
|
NodeWasmBindings: () => NodeWasmBindings,
|
|
17050
17063
|
PermissionNotInManifestError: () => import_sdk_core9.PermissionNotInManifestError,
|
|
17051
17064
|
PrefixedKVService: () => import_sdk_core10.PrefixedKVService,
|
|
17052
17065
|
PrivateKeySigner: () => PrivateKeySigner,
|
|
17053
|
-
ProtocolMismatchError: () =>
|
|
17066
|
+
ProtocolMismatchError: () => import_sdk_core19.ProtocolMismatchError,
|
|
17067
|
+
SECRET_NAME_RE: () => import_sdk_core13.SECRET_NAME_RE,
|
|
17054
17068
|
SQLAction: () => import_sdk_core11.SQLAction,
|
|
17055
17069
|
SQLService: () => import_sdk_core11.SQLService,
|
|
17056
17070
|
SecretsService: () => import_sdk_core13.SecretsService,
|
|
17057
|
-
ServiceContext: () =>
|
|
17071
|
+
ServiceContext: () => import_sdk_core20.ServiceContext,
|
|
17058
17072
|
SessionExpiredError: () => import_sdk_core9.SessionExpiredError,
|
|
17059
|
-
SharingService: () =>
|
|
17073
|
+
SharingService: () => import_sdk_core16.SharingService,
|
|
17060
17074
|
SilentNotificationHandler: () => import_sdk_core8.SilentNotificationHandler,
|
|
17061
|
-
Space: () =>
|
|
17062
|
-
SpaceErrorCodes: () =>
|
|
17063
|
-
SpaceService: () =>
|
|
17075
|
+
Space: () => import_sdk_core18.Space,
|
|
17076
|
+
SpaceErrorCodes: () => import_sdk_core18.SpaceErrorCodes,
|
|
17077
|
+
SpaceService: () => import_sdk_core18.SpaceService,
|
|
17064
17078
|
TinyCloud: () => import_sdk_core7.TinyCloud,
|
|
17065
17079
|
TinyCloudNode: () => TinyCloudNode,
|
|
17066
|
-
UnsupportedFeatureError: () =>
|
|
17080
|
+
UnsupportedFeatureError: () => import_sdk_core19.UnsupportedFeatureError,
|
|
17067
17081
|
VAULT_PERMISSION_SERVICE: () => import_sdk_core9.VAULT_PERMISSION_SERVICE,
|
|
17068
17082
|
VaultHeaders: () => import_sdk_core13.VaultHeaders,
|
|
17069
17083
|
VaultPublicSpaceKVActions: () => import_sdk_core13.VaultPublicSpaceKVActions,
|
|
17070
|
-
VersionCheckError: () =>
|
|
17084
|
+
VersionCheckError: () => import_sdk_core19.VersionCheckError,
|
|
17071
17085
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
17072
|
-
|
|
17073
|
-
|
|
17086
|
+
buildCanonicalDecryptRequest: () => import_sdk_core14.buildCanonicalDecryptRequest,
|
|
17087
|
+
buildDecryptAttenuation: () => import_sdk_core14.buildDecryptAttenuation,
|
|
17088
|
+
buildDecryptFacts: () => import_sdk_core14.buildDecryptFacts,
|
|
17089
|
+
buildDecryptInvocation: () => import_sdk_core14.buildDecryptInvocation,
|
|
17090
|
+
buildNetworkId: () => import_sdk_core14.buildNetworkId,
|
|
17091
|
+
buildSpaceUri: () => import_sdk_core18.buildSpaceUri,
|
|
17092
|
+
canonicalHashHex: () => import_sdk_core14.canonicalHashHex,
|
|
17093
|
+
canonicalSignedResponse: () => import_sdk_core14.canonicalSignedResponse,
|
|
17094
|
+
canonicalizeEncryptionJson: () => import_sdk_core14.canonicalizeEncryptionJson,
|
|
17095
|
+
canonicalizeSecretScope: () => import_sdk_core13.canonicalizeSecretScope,
|
|
17096
|
+
checkDecryptInvocationInput: () => import_sdk_core14.checkDecryptInvocationInput,
|
|
17097
|
+
checkNodeInfo: () => import_sdk_core19.checkNodeInfo,
|
|
17074
17098
|
composeManifestRequest: () => import_sdk_core9.composeManifestRequest,
|
|
17075
|
-
createCapabilityKeyRegistry: () =>
|
|
17076
|
-
createSharingService: () =>
|
|
17077
|
-
createSpaceService: () =>
|
|
17099
|
+
createCapabilityKeyRegistry: () => import_sdk_core17.createCapabilityKeyRegistry,
|
|
17100
|
+
createSharingService: () => import_sdk_core16.createSharingService,
|
|
17101
|
+
createSpaceService: () => import_sdk_core18.createSpaceService,
|
|
17078
17102
|
createVaultCrypto: () => import_sdk_core13.createVaultCrypto,
|
|
17079
17103
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
17104
|
+
decryptEnvelopeWithKey: () => import_sdk_core14.decryptEnvelopeWithKey,
|
|
17080
17105
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
17081
17106
|
defaultSpaceCreationHandler: () => import_sdk_core8.defaultSpaceCreationHandler,
|
|
17107
|
+
deriveSignedReceiverKey: () => import_sdk_core14.deriveSignedReceiverKey,
|
|
17082
17108
|
deserializeDelegation: () => deserializeDelegation,
|
|
17109
|
+
discoverNetwork: () => import_sdk_core14.discoverNetwork,
|
|
17110
|
+
encryptToNetwork: () => import_sdk_core14.encryptToNetwork,
|
|
17111
|
+
encryptionBase64Decode: () => import_sdk_core14.encryptionBase64Decode,
|
|
17112
|
+
encryptionBase64Encode: () => import_sdk_core14.encryptionBase64Encode,
|
|
17113
|
+
encryptionError: () => import_sdk_core14.encryptionError,
|
|
17114
|
+
encryptionUtf8Decode: () => import_sdk_core14.encryptionUtf8Decode,
|
|
17115
|
+
encryptionUtf8Encode: () => import_sdk_core14.encryptionUtf8Encode,
|
|
17116
|
+
ensureNetworkUsableForDecrypt: () => import_sdk_core14.ensureNetworkUsableForDecrypt,
|
|
17083
17117
|
expandActionShortNames: () => import_sdk_core9.expandActionShortNames,
|
|
17084
17118
|
expandPermissionEntries: () => import_sdk_core9.expandPermissionEntries,
|
|
17085
17119
|
expandPermissionEntry: () => import_sdk_core9.expandPermissionEntry,
|
|
17120
|
+
generateRandomReceiverKey: () => import_sdk_core14.generateRandomReceiverKey,
|
|
17121
|
+
hexDecode: () => import_sdk_core14.hexDecode,
|
|
17122
|
+
hexEncode: () => import_sdk_core14.hexEncode,
|
|
17086
17123
|
isCapabilitySubset: () => import_sdk_core9.isCapabilitySubset,
|
|
17124
|
+
isNetworkId: () => import_sdk_core14.isNetworkId,
|
|
17087
17125
|
loadManifest: () => import_sdk_core9.loadManifest,
|
|
17088
|
-
makePublicSpaceId: () =>
|
|
17126
|
+
makePublicSpaceId: () => import_sdk_core18.makePublicSpaceId,
|
|
17127
|
+
networkDiscoveryKey: () => import_sdk_core14.networkDiscoveryKey,
|
|
17128
|
+
openWrappedKey: () => import_sdk_core14.openWrappedKey,
|
|
17089
17129
|
parseExpiry: () => import_sdk_core9.parseExpiry,
|
|
17090
|
-
|
|
17130
|
+
parseNetworkId: () => import_sdk_core14.parseNetworkId,
|
|
17131
|
+
parseSpaceUri: () => import_sdk_core18.parseSpaceUri,
|
|
17091
17132
|
resolveManifest: () => import_sdk_core9.resolveManifest,
|
|
17133
|
+
resolveSecretListPrefix: () => import_sdk_core13.resolveSecretListPrefix,
|
|
17134
|
+
resolveSecretPath: () => import_sdk_core13.resolveSecretPath,
|
|
17092
17135
|
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core9.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
17093
17136
|
serializeDelegation: () => serializeDelegation,
|
|
17094
|
-
|
|
17137
|
+
validateEnvelope: () => import_sdk_core14.validateEnvelope,
|
|
17138
|
+
validateManifest: () => import_sdk_core9.validateManifest,
|
|
17139
|
+
verifyDecryptResponse: () => import_sdk_core14.verifyDecryptResponse
|
|
17095
17140
|
});
|
|
17096
17141
|
module.exports = __toCommonJS(index_exports);
|
|
17097
17142
|
|
|
@@ -17101,6 +17146,7 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17101
17146
|
constructor() {
|
|
17102
17147
|
this.invoke = import_node_sdk_wasm.invoke;
|
|
17103
17148
|
this.invokeAny = import_node_sdk_wasm.invokeAny;
|
|
17149
|
+
this.computeCid = import_node_sdk_wasm.computeCid;
|
|
17104
17150
|
this.prepareSession = import_node_sdk_wasm.prepareSession;
|
|
17105
17151
|
this.completeSessionSetup = import_node_sdk_wasm.completeSessionSetup;
|
|
17106
17152
|
this.ensureEip55 = import_node_sdk_wasm.ensureEip55;
|
|
@@ -17328,7 +17374,7 @@ var NodeUserAuthorization = class {
|
|
|
17328
17374
|
]
|
|
17329
17375
|
}
|
|
17330
17376
|
};
|
|
17331
|
-
this.sessionExpirationMs = config.sessionExpirationMs ??
|
|
17377
|
+
this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core.EXPIRY.SESSION_MS;
|
|
17332
17378
|
this.autoCreateSpace = config.autoCreateSpace ?? false;
|
|
17333
17379
|
this.spaceCreationHandler = config.spaceCreationHandler;
|
|
17334
17380
|
this.tinycloudHosts = config.tinycloudHosts;
|
|
@@ -17381,6 +17427,23 @@ var NodeUserAuthorization = class {
|
|
|
17381
17427
|
get tinyCloudSession() {
|
|
17382
17428
|
return this._tinyCloudSession;
|
|
17383
17429
|
}
|
|
17430
|
+
/**
|
|
17431
|
+
* Rehydrate the auth-layer session from previously-persisted delegation
|
|
17432
|
+
* data. Used by {@link TinyCloudNode.restoreSession} so that downstream
|
|
17433
|
+
* surfaces that read from `tinyCloudSession` (notably
|
|
17434
|
+
* `grantRuntimePermissions`, which extracts the SIWE expiry from it) work
|
|
17435
|
+
* without re-running the full sign-in flow.
|
|
17436
|
+
*
|
|
17437
|
+
* Caller must supply the same fields that `signIn` would have written —
|
|
17438
|
+
* `siwe` is the load-bearing one because `extractSiweExpiration` returns
|
|
17439
|
+
* undefined for missing SIWEs and the SDK then treats the session as
|
|
17440
|
+
* expired-at-epoch-zero.
|
|
17441
|
+
*/
|
|
17442
|
+
setRestoredTinyCloudSession(session) {
|
|
17443
|
+
this._tinyCloudSession = session;
|
|
17444
|
+
this._address = session.address;
|
|
17445
|
+
this._chainId = session.chainId;
|
|
17446
|
+
}
|
|
17384
17447
|
async resolveTinyCloudHostsForSignIn(address, chainId) {
|
|
17385
17448
|
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
17386
17449
|
return;
|
|
@@ -17451,21 +17514,64 @@ var NodeUserAuthorization = class {
|
|
|
17451
17514
|
}
|
|
17452
17515
|
return this.wasm.makeSpaceId(address, chainId, space);
|
|
17453
17516
|
}
|
|
17517
|
+
defaultEncryptionNetworkId(address, chainId) {
|
|
17518
|
+
return `urn:tinycloud:encryption:did:pkh:eip155:${chainId}:${address}:default`;
|
|
17519
|
+
}
|
|
17454
17520
|
resolveSignInCapabilities(address, chainId) {
|
|
17455
17521
|
const request = this.getCapabilityRequest();
|
|
17456
17522
|
if (request === void 0) {
|
|
17523
|
+
const defaultNetworkId = this.defaultEncryptionNetworkId(address, chainId);
|
|
17524
|
+
const secretsSpaceId = this.wasm.makeSpaceId(address, chainId, "secrets");
|
|
17457
17525
|
return {
|
|
17458
17526
|
abilities: this.defaultActions,
|
|
17459
|
-
spaceId: this.wasm.makeSpaceId(address, chainId, this.spacePrefix)
|
|
17527
|
+
spaceId: this.wasm.makeSpaceId(address, chainId, this.spacePrefix),
|
|
17528
|
+
spaceAbilities: {
|
|
17529
|
+
[secretsSpaceId]: {
|
|
17530
|
+
kv: {
|
|
17531
|
+
"vault/secrets/": [
|
|
17532
|
+
"tinycloud.kv/get",
|
|
17533
|
+
"tinycloud.kv/put",
|
|
17534
|
+
"tinycloud.kv/del",
|
|
17535
|
+
"tinycloud.kv/list",
|
|
17536
|
+
"tinycloud.kv/metadata"
|
|
17537
|
+
]
|
|
17538
|
+
}
|
|
17539
|
+
}
|
|
17540
|
+
},
|
|
17541
|
+
rawAbilities: {
|
|
17542
|
+
[defaultNetworkId]: [
|
|
17543
|
+
"tinycloud.encryption/decrypt",
|
|
17544
|
+
"tinycloud.encryption/network.create"
|
|
17545
|
+
]
|
|
17546
|
+
}
|
|
17460
17547
|
};
|
|
17461
17548
|
}
|
|
17462
|
-
const
|
|
17549
|
+
const rawAbilities = {};
|
|
17550
|
+
const spaceResources = request.resources.filter((entry) => {
|
|
17551
|
+
if (entry.service !== import_sdk_core.ENCRYPTION_PERMISSION_SERVICE) {
|
|
17552
|
+
return true;
|
|
17553
|
+
}
|
|
17554
|
+
const existing = rawAbilities[entry.path];
|
|
17555
|
+
if (existing === void 0) {
|
|
17556
|
+
rawAbilities[entry.path] = [...entry.actions];
|
|
17557
|
+
} else {
|
|
17558
|
+
const seen = new Set(existing);
|
|
17559
|
+
for (const action of entry.actions) {
|
|
17560
|
+
if (!seen.has(action)) {
|
|
17561
|
+
existing.push(action);
|
|
17562
|
+
seen.add(action);
|
|
17563
|
+
}
|
|
17564
|
+
}
|
|
17565
|
+
}
|
|
17566
|
+
return false;
|
|
17567
|
+
});
|
|
17568
|
+
const primarySpaceName = spaceResources.find((entry) => entry.space !== "account")?.space ?? import_sdk_core.DEFAULT_MANIFEST_SPACE;
|
|
17463
17569
|
const primarySpaceId = this.resolveSpaceName(
|
|
17464
17570
|
primarySpaceName,
|
|
17465
17571
|
address,
|
|
17466
17572
|
chainId
|
|
17467
17573
|
);
|
|
17468
|
-
const bySpace = (0, import_sdk_core.resourceCapabilitiesToSpaceAbilitiesMap)(
|
|
17574
|
+
const bySpace = (0, import_sdk_core.resourceCapabilitiesToSpaceAbilitiesMap)(spaceResources);
|
|
17469
17575
|
const spaceAbilities = {};
|
|
17470
17576
|
for (const [space, abilities] of Object.entries(bySpace)) {
|
|
17471
17577
|
spaceAbilities[this.resolveSpaceName(space, address, chainId)] = abilities;
|
|
@@ -17473,7 +17579,8 @@ var NodeUserAuthorization = class {
|
|
|
17473
17579
|
return {
|
|
17474
17580
|
abilities: spaceAbilities[primarySpaceId] ?? (0, import_sdk_core.resourceCapabilitiesToAbilitiesMap)([]),
|
|
17475
17581
|
spaceId: primarySpaceId,
|
|
17476
|
-
spaceAbilities
|
|
17582
|
+
spaceAbilities,
|
|
17583
|
+
rawAbilities: Object.keys(rawAbilities).length > 0 ? rawAbilities : void 0
|
|
17477
17584
|
};
|
|
17478
17585
|
}
|
|
17479
17586
|
/**
|
|
@@ -17698,6 +17805,7 @@ var NodeUserAuthorization = class {
|
|
|
17698
17805
|
const prepared = this.wasm.prepareSession({
|
|
17699
17806
|
abilities: capabilityPlan.abilities,
|
|
17700
17807
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
17808
|
+
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
17701
17809
|
address,
|
|
17702
17810
|
chainId,
|
|
17703
17811
|
domain: this.domain,
|
|
@@ -17843,6 +17951,7 @@ var NodeUserAuthorization = class {
|
|
|
17843
17951
|
const prepared = this.wasm.prepareSession({
|
|
17844
17952
|
abilities: capabilityPlan.abilities,
|
|
17845
17953
|
...capabilityPlan.spaceAbilities !== void 0 ? { spaceAbilities: capabilityPlan.spaceAbilities } : {},
|
|
17954
|
+
...capabilityPlan.rawAbilities !== void 0 ? { rawAbilities: capabilityPlan.rawAbilities } : {},
|
|
17846
17955
|
address,
|
|
17847
17956
|
chainId,
|
|
17848
17957
|
domain: this.domain,
|
|
@@ -18213,9 +18322,10 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
|
18213
18322
|
}
|
|
18214
18323
|
return entries;
|
|
18215
18324
|
}
|
|
18325
|
+
var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core3.EXPIRY.SESSION_MS;
|
|
18216
18326
|
function resolveExpiryMs(expiry) {
|
|
18217
18327
|
if (expiry === void 0) {
|
|
18218
|
-
return
|
|
18328
|
+
return DEFAULT_DELEGATION_EXPIRY_MS;
|
|
18219
18329
|
}
|
|
18220
18330
|
if (typeof expiry === "number") {
|
|
18221
18331
|
if (!Number.isFinite(expiry) || expiry <= 0) {
|
|
@@ -18243,8 +18353,6 @@ function extractSiweExpiration(siwe) {
|
|
|
18243
18353
|
|
|
18244
18354
|
// src/NodeSecretsService.ts
|
|
18245
18355
|
var import_sdk_core4 = require("@tinycloud/sdk-core");
|
|
18246
|
-
var SECRET_NAME_RE = /^[A-Z][A-Z0-9_]*$/;
|
|
18247
|
-
var SECRET_PREFIX = "secrets/";
|
|
18248
18356
|
var SECRETS_SPACE = "secrets";
|
|
18249
18357
|
function ok() {
|
|
18250
18358
|
return { ok: true, data: void 0 };
|
|
@@ -18261,27 +18369,39 @@ function secretsError(code, message, cause) {
|
|
|
18261
18369
|
};
|
|
18262
18370
|
}
|
|
18263
18371
|
function displayActionUrn(action) {
|
|
18264
|
-
|
|
18372
|
+
switch (action) {
|
|
18373
|
+
case "get":
|
|
18374
|
+
return "tinycloud.kv/get";
|
|
18375
|
+
case "put":
|
|
18376
|
+
return "tinycloud.kv/put";
|
|
18377
|
+
case "del":
|
|
18378
|
+
return "tinycloud.kv/del";
|
|
18379
|
+
case "list":
|
|
18380
|
+
return "tinycloud.kv/list";
|
|
18381
|
+
}
|
|
18265
18382
|
}
|
|
18266
|
-
function
|
|
18267
|
-
return
|
|
18383
|
+
function secretActionName(action) {
|
|
18384
|
+
return action;
|
|
18268
18385
|
}
|
|
18269
|
-
function secretPermissionEntries(name, action) {
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18386
|
+
function secretPermissionEntries(name, options, action, encryptionNetworkId) {
|
|
18387
|
+
const entries = [];
|
|
18388
|
+
const path = action === "list" ? (0, import_sdk_core4.resolveSecretListPrefix)(options) : (0, import_sdk_core4.resolveSecretPath)(name, options).permissionPaths.vault;
|
|
18389
|
+
entries.push({
|
|
18390
|
+
service: "tinycloud.kv",
|
|
18391
|
+
space: SECRETS_SPACE,
|
|
18392
|
+
path,
|
|
18393
|
+
actions: [secretActionName(action)],
|
|
18394
|
+
skipPrefix: true
|
|
18395
|
+
});
|
|
18396
|
+
if (action === "get" && encryptionNetworkId !== void 0) {
|
|
18397
|
+
entries.push({
|
|
18398
|
+
service: "tinycloud.encryption",
|
|
18399
|
+
path: encryptionNetworkId,
|
|
18400
|
+
actions: ["decrypt"],
|
|
18276
18401
|
skipPrefix: true
|
|
18277
|
-
}
|
|
18278
|
-
|
|
18279
|
-
|
|
18280
|
-
function secretResourcePath(base2, name) {
|
|
18281
|
-
return `${base2}/${SECRET_PREFIX}${name}`;
|
|
18282
|
-
}
|
|
18283
|
-
function isSecretsSpace(space) {
|
|
18284
|
-
return space === SECRETS_SPACE || space.endsWith(`:${SECRETS_SPACE}`);
|
|
18402
|
+
});
|
|
18403
|
+
}
|
|
18404
|
+
return entries;
|
|
18285
18405
|
}
|
|
18286
18406
|
var NodeSecretsService = class {
|
|
18287
18407
|
constructor(config) {
|
|
@@ -18309,48 +18429,62 @@ var NodeSecretsService = class {
|
|
|
18309
18429
|
this.shouldRestoreUnlock = false;
|
|
18310
18430
|
this.service.lock();
|
|
18311
18431
|
}
|
|
18312
|
-
get(name) {
|
|
18313
|
-
|
|
18432
|
+
async get(name, options) {
|
|
18433
|
+
const permission = await this.ensurePermission(name, options, "get");
|
|
18434
|
+
if (!permission.ok) return permission;
|
|
18435
|
+
return options === void 0 ? this.service.get(name) : this.service.get(name, options);
|
|
18314
18436
|
}
|
|
18315
|
-
async put(name, value) {
|
|
18316
|
-
const permission = await this.
|
|
18437
|
+
async put(name, value, options) {
|
|
18438
|
+
const permission = await this.ensurePermission(name, options, "put");
|
|
18317
18439
|
if (!permission.ok) return permission;
|
|
18318
|
-
return this.service.put(name, value);
|
|
18440
|
+
return options === void 0 ? this.service.put(name, value) : this.service.put(name, value, options);
|
|
18319
18441
|
}
|
|
18320
|
-
async delete(name) {
|
|
18321
|
-
const permission = await this.
|
|
18442
|
+
async delete(name, options) {
|
|
18443
|
+
const permission = await this.ensurePermission(name, options, "del");
|
|
18322
18444
|
if (!permission.ok) return permission;
|
|
18323
|
-
return this.service.delete(name);
|
|
18445
|
+
return options === void 0 ? this.service.delete(name) : this.service.delete(name, options);
|
|
18324
18446
|
}
|
|
18325
|
-
list() {
|
|
18326
|
-
|
|
18447
|
+
async list(options) {
|
|
18448
|
+
const permission = await this.ensurePermission("", options, "list");
|
|
18449
|
+
if (!permission.ok) return permission;
|
|
18450
|
+
return options === void 0 ? this.service.list() : this.service.list(options);
|
|
18327
18451
|
}
|
|
18328
18452
|
get service() {
|
|
18329
18453
|
return this.config.getService();
|
|
18330
18454
|
}
|
|
18331
|
-
async
|
|
18332
|
-
|
|
18455
|
+
async ensurePermission(name, options, action) {
|
|
18456
|
+
const target = name || "secrets";
|
|
18457
|
+
let permissionEntries;
|
|
18458
|
+
try {
|
|
18459
|
+
permissionEntries = secretPermissionEntries(
|
|
18460
|
+
name,
|
|
18461
|
+
options,
|
|
18462
|
+
action,
|
|
18463
|
+
action === "get" ? this.config.getEncryptionNetworkId?.() : void 0
|
|
18464
|
+
);
|
|
18465
|
+
} catch (error) {
|
|
18333
18466
|
return secretsError(
|
|
18334
18467
|
import_sdk_core4.ErrorCodes.INVALID_INPUT,
|
|
18335
|
-
|
|
18468
|
+
error instanceof Error ? error.message : String(error),
|
|
18469
|
+
error instanceof Error ? error : void 0
|
|
18336
18470
|
);
|
|
18337
18471
|
}
|
|
18338
|
-
if (this.
|
|
18472
|
+
if (this.hasPermission(permissionEntries)) {
|
|
18339
18473
|
return ok();
|
|
18340
18474
|
}
|
|
18341
18475
|
if (!this.config.canEscalate()) {
|
|
18342
18476
|
return secretsError(
|
|
18343
18477
|
import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
|
|
18344
|
-
`Cannot autosign ${displayActionUrn(action)} for ${
|
|
18478
|
+
`Cannot autosign ${displayActionUrn(action)} for ${target}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
18345
18479
|
);
|
|
18346
18480
|
}
|
|
18347
18481
|
try {
|
|
18348
|
-
await this.config.grantPermissions(
|
|
18482
|
+
await this.config.grantPermissions(permissionEntries);
|
|
18349
18483
|
return this.restoreUnlockAfterEscalation();
|
|
18350
18484
|
} catch (error) {
|
|
18351
18485
|
return secretsError(
|
|
18352
18486
|
import_sdk_core4.ErrorCodes.PERMISSION_DENIED,
|
|
18353
|
-
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${
|
|
18487
|
+
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
|
|
18354
18488
|
error instanceof Error ? error : void 0
|
|
18355
18489
|
);
|
|
18356
18490
|
}
|
|
@@ -18361,26 +18495,117 @@ var NodeSecretsService = class {
|
|
|
18361
18495
|
}
|
|
18362
18496
|
return this.service.unlock(this.unlockSigner);
|
|
18363
18497
|
}
|
|
18364
|
-
|
|
18498
|
+
hasPermission(permissionEntries) {
|
|
18499
|
+
if (this.config.hasPermissions?.(permissionEntries)) {
|
|
18500
|
+
return true;
|
|
18501
|
+
}
|
|
18365
18502
|
const manifest = this.config.getManifest();
|
|
18366
18503
|
if (manifest === void 0) {
|
|
18367
18504
|
return false;
|
|
18368
18505
|
}
|
|
18369
18506
|
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
18370
|
-
const
|
|
18371
|
-
return
|
|
18372
|
-
|
|
18373
|
-
|
|
18374
|
-
|
|
18375
|
-
(resource) => resource.service ===
|
|
18376
|
-
)
|
|
18377
|
-
)
|
|
18378
|
-
|
|
18507
|
+
const requestedEntries = (0, import_sdk_core4.expandPermissionEntries)(permissionEntries);
|
|
18508
|
+
return requestedEntries.every(
|
|
18509
|
+
(entry) => manifests.some((candidate) => {
|
|
18510
|
+
const resolved = (0, import_sdk_core4.resolveManifest)(candidate);
|
|
18511
|
+
return resolved.resources.some(
|
|
18512
|
+
(resource) => resource.service === entry.service && resource.space === entry.space && resource.path === entry.path && entry.actions.every((action) => resource.actions.includes(action))
|
|
18513
|
+
);
|
|
18514
|
+
})
|
|
18515
|
+
);
|
|
18379
18516
|
}
|
|
18380
18517
|
};
|
|
18381
18518
|
|
|
18382
18519
|
// src/TinyCloudNode.ts
|
|
18383
18520
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
18521
|
+
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
18522
|
+
var NETWORK_CREATE_ACTION = "tinycloud.encryption/network.create";
|
|
18523
|
+
var DECRYPT_ACTION = "tinycloud.encryption/decrypt";
|
|
18524
|
+
var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
|
|
18525
|
+
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core5.EXPIRY.SESSION_MS;
|
|
18526
|
+
function base64UrlEncode(bytes) {
|
|
18527
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
18528
|
+
let output = "";
|
|
18529
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
18530
|
+
const a = bytes[i];
|
|
18531
|
+
const b = bytes[i + 1];
|
|
18532
|
+
const c = bytes[i + 2];
|
|
18533
|
+
const triplet = a << 16 | (b ?? 0) << 8 | (c ?? 0);
|
|
18534
|
+
output += alphabet[triplet >> 18 & 63];
|
|
18535
|
+
output += alphabet[triplet >> 12 & 63];
|
|
18536
|
+
if (i + 1 < bytes.length) output += alphabet[triplet >> 6 & 63];
|
|
18537
|
+
if (i + 2 < bytes.length) output += alphabet[triplet & 63];
|
|
18538
|
+
}
|
|
18539
|
+
return output;
|
|
18540
|
+
}
|
|
18541
|
+
function base64UrlDecode(value) {
|
|
18542
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
18543
|
+
const bytes = [];
|
|
18544
|
+
let buffer = 0;
|
|
18545
|
+
let bits = 0;
|
|
18546
|
+
for (const char of value) {
|
|
18547
|
+
const index = alphabet.indexOf(char);
|
|
18548
|
+
if (index < 0) {
|
|
18549
|
+
throw new Error("invalid base64url input");
|
|
18550
|
+
}
|
|
18551
|
+
buffer = buffer << 6 | index;
|
|
18552
|
+
bits += 6;
|
|
18553
|
+
if (bits >= 8) {
|
|
18554
|
+
bits -= 8;
|
|
18555
|
+
bytes.push(buffer >> bits & 255);
|
|
18556
|
+
}
|
|
18557
|
+
}
|
|
18558
|
+
return new Uint8Array(bytes);
|
|
18559
|
+
}
|
|
18560
|
+
async function signJwtInputWithJwk(signingInput, jwk) {
|
|
18561
|
+
const bytes = new TextEncoder().encode(signingInput);
|
|
18562
|
+
try {
|
|
18563
|
+
const subtle = globalThis.crypto?.subtle;
|
|
18564
|
+
if (!subtle) {
|
|
18565
|
+
throw new Error("WebCrypto subtle API is unavailable");
|
|
18566
|
+
}
|
|
18567
|
+
const key2 = await subtle.importKey(
|
|
18568
|
+
"jwk",
|
|
18569
|
+
jwk,
|
|
18570
|
+
{ name: "Ed25519" },
|
|
18571
|
+
false,
|
|
18572
|
+
["sign"]
|
|
18573
|
+
);
|
|
18574
|
+
return new Uint8Array(await subtle.sign({ name: "Ed25519" }, key2, bytes));
|
|
18575
|
+
} catch {
|
|
18576
|
+
const nodeCrypto = await import("crypto");
|
|
18577
|
+
const key2 = nodeCrypto.createPrivateKey({ key: jwk, format: "jwk" });
|
|
18578
|
+
return new Uint8Array(nodeCrypto.sign(null, Buffer.from(bytes), key2));
|
|
18579
|
+
}
|
|
18580
|
+
}
|
|
18581
|
+
async function rewriteInvocationAudience(authorization, audience, jwk) {
|
|
18582
|
+
const [headerPart, payloadPart] = authorization.split(".");
|
|
18583
|
+
if (!headerPart || !payloadPart) {
|
|
18584
|
+
throw new Error("invalid invocation authorization");
|
|
18585
|
+
}
|
|
18586
|
+
const header = JSON.parse(new TextDecoder().decode(base64UrlDecode(headerPart)));
|
|
18587
|
+
const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(payloadPart)));
|
|
18588
|
+
payload.aud = audience;
|
|
18589
|
+
const signingInput = `${base64UrlEncode(
|
|
18590
|
+
new TextEncoder().encode(JSON.stringify(header))
|
|
18591
|
+
)}.${base64UrlEncode(new TextEncoder().encode(JSON.stringify(payload)))}`;
|
|
18592
|
+
const signature2 = await signJwtInputWithJwk(signingInput, jwk);
|
|
18593
|
+
return `${signingInput}.${base64UrlEncode(signature2)}`;
|
|
18594
|
+
}
|
|
18595
|
+
function authorizationHeader(headers) {
|
|
18596
|
+
if (Array.isArray(headers)) {
|
|
18597
|
+
const entry = headers.find(([name]) => name.toLowerCase() === "authorization");
|
|
18598
|
+
if (!entry) {
|
|
18599
|
+
throw new Error("network invocation did not include an Authorization header");
|
|
18600
|
+
}
|
|
18601
|
+
return entry[1];
|
|
18602
|
+
}
|
|
18603
|
+
const value = headers.Authorization ?? headers.authorization;
|
|
18604
|
+
if (!value) {
|
|
18605
|
+
throw new Error("network invocation did not include an Authorization header");
|
|
18606
|
+
}
|
|
18607
|
+
return value;
|
|
18608
|
+
}
|
|
18384
18609
|
var _TinyCloudNode = class _TinyCloudNode {
|
|
18385
18610
|
/**
|
|
18386
18611
|
* Create a new TinyCloudNode instance.
|
|
@@ -18425,12 +18650,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18425
18650
|
throw new Error("WASM binding does not support invokeAny");
|
|
18426
18651
|
}
|
|
18427
18652
|
const grant = this.findGrantForOperations(
|
|
18428
|
-
entries.
|
|
18429
|
-
|
|
18430
|
-
|
|
18431
|
-
|
|
18432
|
-
action: entry.action
|
|
18433
|
-
}))
|
|
18653
|
+
entries.flatMap((entry) => {
|
|
18654
|
+
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
18655
|
+
return operation ? [operation] : [];
|
|
18656
|
+
})
|
|
18434
18657
|
);
|
|
18435
18658
|
return this.wasmBindings.invokeAny(grant?.session ?? session, entries, facts);
|
|
18436
18659
|
};
|
|
@@ -18523,7 +18746,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18523
18746
|
sessionStorage: config.sessionStorage ?? new MemorySessionStorage(),
|
|
18524
18747
|
domain: this.siweDomain,
|
|
18525
18748
|
spacePrefix: config.prefix,
|
|
18526
|
-
sessionExpirationMs: config.sessionExpirationMs ??
|
|
18749
|
+
sessionExpirationMs: config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
18527
18750
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18528
18751
|
tinycloudRegistryUrl: config.tinycloudRegistryUrl,
|
|
18529
18752
|
tinycloudFallbackHosts: config.tinycloudFallbackHosts,
|
|
@@ -18658,6 +18881,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18658
18881
|
this._duckdb = void 0;
|
|
18659
18882
|
this._hooks = void 0;
|
|
18660
18883
|
this._vault = void 0;
|
|
18884
|
+
this._encryption = void 0;
|
|
18661
18885
|
this._baseSecrets = void 0;
|
|
18662
18886
|
this._secrets = void 0;
|
|
18663
18887
|
this._spaceService = void 0;
|
|
@@ -18666,6 +18890,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18666
18890
|
await this.tc.signIn(options);
|
|
18667
18891
|
this.syncResolvedHostFromAuth();
|
|
18668
18892
|
this.initializeServices();
|
|
18893
|
+
if (this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
18894
|
+
await this.ensureOwnedSpaceHosted(this.ownedSpaceId("secrets"));
|
|
18895
|
+
}
|
|
18669
18896
|
await this.writeManifestRegistryRecords();
|
|
18670
18897
|
this.notificationHandler.success("Successfully signed in");
|
|
18671
18898
|
}
|
|
@@ -18748,6 +18975,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18748
18975
|
this._duckdb = void 0;
|
|
18749
18976
|
this._hooks = void 0;
|
|
18750
18977
|
this._vault = void 0;
|
|
18978
|
+
this._encryption = void 0;
|
|
18751
18979
|
this._baseSecrets = void 0;
|
|
18752
18980
|
this._secrets = void 0;
|
|
18753
18981
|
this._spaceService = void 0;
|
|
@@ -18789,6 +19017,33 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18789
19017
|
this._vault.initialize(this._serviceContext);
|
|
18790
19018
|
this._serviceContext.registerService("vault", this._vault);
|
|
18791
19019
|
this.initializeV2Services(serviceSession);
|
|
19020
|
+
if (sessionData.siwe && sessionData.address && sessionData.chainId) {
|
|
19021
|
+
const tcSession = {
|
|
19022
|
+
address: sessionData.address,
|
|
19023
|
+
chainId: sessionData.chainId,
|
|
19024
|
+
sessionKey: JSON.stringify(sessionData.jwk),
|
|
19025
|
+
spaceId: sessionData.spaceId,
|
|
19026
|
+
delegationCid: sessionData.delegationCid,
|
|
19027
|
+
delegationHeader: sessionData.delegationHeader,
|
|
19028
|
+
verificationMethod: sessionData.verificationMethod,
|
|
19029
|
+
jwk: sessionData.jwk,
|
|
19030
|
+
siwe: sessionData.siwe,
|
|
19031
|
+
signature: sessionData.signature ?? ""
|
|
19032
|
+
};
|
|
19033
|
+
if (this.auth) {
|
|
19034
|
+
this.auth.setRestoredTinyCloudSession(tcSession);
|
|
19035
|
+
} else {
|
|
19036
|
+
this._restoredTcSession = tcSession;
|
|
19037
|
+
}
|
|
19038
|
+
}
|
|
19039
|
+
}
|
|
19040
|
+
/**
|
|
19041
|
+
* Resolve the currently-active TinyCloudSession, preferring the auth
|
|
19042
|
+
* layer's value (wallet mode) and falling back to the node-level
|
|
19043
|
+
* rehydration set by {@link restoreSession} (session-only mode).
|
|
19044
|
+
*/
|
|
19045
|
+
currentTinyCloudSession() {
|
|
19046
|
+
return this.auth?.tinyCloudSession ?? this._restoredTcSession;
|
|
18792
19047
|
}
|
|
18793
19048
|
/**
|
|
18794
19049
|
* Connect a wallet to upgrade from session-only mode to wallet mode.
|
|
@@ -18833,7 +19088,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18833
19088
|
sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
|
|
18834
19089
|
domain: this.siweDomain,
|
|
18835
19090
|
spacePrefix: prefix,
|
|
18836
|
-
sessionExpirationMs: this.config.sessionExpirationMs ??
|
|
19091
|
+
sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
18837
19092
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18838
19093
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
18839
19094
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
@@ -18877,7 +19132,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18877
19132
|
sessionStorage: options?.sessionStorage ?? this.config.sessionStorage ?? new MemorySessionStorage(),
|
|
18878
19133
|
domain: this.siweDomain,
|
|
18879
19134
|
spacePrefix: prefix,
|
|
18880
|
-
sessionExpirationMs: this.config.sessionExpirationMs ??
|
|
19135
|
+
sessionExpirationMs: this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS,
|
|
18881
19136
|
tinycloudHosts: this.explicitHost ? [this.explicitHost] : void 0,
|
|
18882
19137
|
tinycloudRegistryUrl: this.config.tinycloudRegistryUrl,
|
|
18883
19138
|
tinycloudFallbackHosts: this.config.tinycloudFallbackHosts,
|
|
@@ -18900,7 +19155,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18900
19155
|
* @internal
|
|
18901
19156
|
*/
|
|
18902
19157
|
initializeServices() {
|
|
18903
|
-
const session = this.
|
|
19158
|
+
const session = this.currentTinyCloudSession();
|
|
18904
19159
|
if (!session) {
|
|
18905
19160
|
return;
|
|
18906
19161
|
}
|
|
@@ -18958,6 +19213,163 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18958
19213
|
}
|
|
18959
19214
|
return kvService;
|
|
18960
19215
|
}
|
|
19216
|
+
getDefaultEncryptionNetworkId(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
19217
|
+
return `urn:tinycloud:encryption:${this.did}:${name}`;
|
|
19218
|
+
}
|
|
19219
|
+
requireServiceSession() {
|
|
19220
|
+
const session = this._serviceContext?.session;
|
|
19221
|
+
if (!session) {
|
|
19222
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19223
|
+
}
|
|
19224
|
+
return session;
|
|
19225
|
+
}
|
|
19226
|
+
createEncryptionCrypto() {
|
|
19227
|
+
const wasm = this.wasmBindings;
|
|
19228
|
+
const columnEncrypt = (key2, plaintext) => {
|
|
19229
|
+
const encrypted = wasm.vault_encrypt(key2, plaintext);
|
|
19230
|
+
const out = new Uint8Array(1 + encrypted.length);
|
|
19231
|
+
out[0] = 1;
|
|
19232
|
+
out.set(encrypted, 1);
|
|
19233
|
+
return out;
|
|
19234
|
+
};
|
|
19235
|
+
const columnDecrypt = (key2, blob) => {
|
|
19236
|
+
if (blob[0] !== 1) {
|
|
19237
|
+
return blob;
|
|
19238
|
+
}
|
|
19239
|
+
return wasm.vault_decrypt(key2, blob.slice(1));
|
|
19240
|
+
};
|
|
19241
|
+
return {
|
|
19242
|
+
sha256: (data) => wasm.vault_sha256(data),
|
|
19243
|
+
randomBytes: (length) => wasm.vault_random_bytes(length),
|
|
19244
|
+
x25519FromSeed: (seed) => wasm.vault_x25519_from_seed(seed),
|
|
19245
|
+
x25519Dh: (privateKey, publicKey) => wasm.vault_x25519_dh(privateKey, publicKey),
|
|
19246
|
+
authEncrypt: (key2, plaintext) => wasm.vault_encrypt(key2, plaintext),
|
|
19247
|
+
authDecrypt: (key2, ciphertext) => wasm.vault_decrypt(key2, ciphertext),
|
|
19248
|
+
sealToNetworkKey: (networkPublicKey, symmetricKey) => {
|
|
19249
|
+
const seed = wasm.vault_random_bytes(32);
|
|
19250
|
+
const ephemeral = wasm.vault_x25519_from_seed(seed);
|
|
19251
|
+
const shared = wasm.vault_x25519_dh(
|
|
19252
|
+
ephemeral.privateKey,
|
|
19253
|
+
networkPublicKey
|
|
19254
|
+
);
|
|
19255
|
+
const encrypted = columnEncrypt(shared, symmetricKey);
|
|
19256
|
+
const out = new Uint8Array(ephemeral.publicKey.length + encrypted.length);
|
|
19257
|
+
out.set(ephemeral.publicKey, 0);
|
|
19258
|
+
out.set(encrypted, ephemeral.publicKey.length);
|
|
19259
|
+
return out;
|
|
19260
|
+
},
|
|
19261
|
+
openWithReceiverKey: (receiverPrivateKey, wrappedKey) => {
|
|
19262
|
+
const peerPublic = wrappedKey.slice(0, 32);
|
|
19263
|
+
const ciphertext = wrappedKey.slice(32);
|
|
19264
|
+
const shared = wasm.vault_x25519_dh(receiverPrivateKey, peerPublic);
|
|
19265
|
+
return columnDecrypt(shared, ciphertext);
|
|
19266
|
+
},
|
|
19267
|
+
verifyNodeSignature: (nodeId, message, signature2) => (0, import_sdk_core5.verifyDidKeyEd25519Signature)(nodeId, message, signature2)
|
|
19268
|
+
};
|
|
19269
|
+
}
|
|
19270
|
+
async fetchNodeId() {
|
|
19271
|
+
const response = await fetch(`${this.config.host}/info`);
|
|
19272
|
+
if (!response.ok) {
|
|
19273
|
+
throw new Error(`Failed to fetch node info: HTTP ${response.status}`);
|
|
19274
|
+
}
|
|
19275
|
+
const info = await response.json();
|
|
19276
|
+
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
19277
|
+
throw new Error("Node /info response did not include nodeId");
|
|
19278
|
+
}
|
|
19279
|
+
return info.nodeId;
|
|
19280
|
+
}
|
|
19281
|
+
async signRawNetworkAuthorization(input) {
|
|
19282
|
+
if (!this.wasmBindings.invokeAny) {
|
|
19283
|
+
throw new Error("WASM binding does not support raw-resource invokeAny");
|
|
19284
|
+
}
|
|
19285
|
+
if (!this.wasmBindings.computeCid) {
|
|
19286
|
+
throw new Error("WASM binding does not support invocation CID computation");
|
|
19287
|
+
}
|
|
19288
|
+
const session = this.requireServiceSession();
|
|
19289
|
+
const headers = this.invokeAnyWithRuntimePermissions(
|
|
19290
|
+
session,
|
|
19291
|
+
[
|
|
19292
|
+
{
|
|
19293
|
+
resource: input.networkId,
|
|
19294
|
+
service: "encryption",
|
|
19295
|
+
path: input.networkId,
|
|
19296
|
+
action: input.action
|
|
19297
|
+
}
|
|
19298
|
+
],
|
|
19299
|
+
[input.facts]
|
|
19300
|
+
);
|
|
19301
|
+
const authorization = authorizationHeader(headers);
|
|
19302
|
+
const audienceBound = await rewriteInvocationAudience(
|
|
19303
|
+
authorization,
|
|
19304
|
+
input.targetNode,
|
|
19305
|
+
session.jwk
|
|
19306
|
+
);
|
|
19307
|
+
return {
|
|
19308
|
+
authorization: audienceBound,
|
|
19309
|
+
invocationCid: this.wasmBindings.computeCid(
|
|
19310
|
+
new TextEncoder().encode(audienceBound),
|
|
19311
|
+
0x55n
|
|
19312
|
+
)
|
|
19313
|
+
};
|
|
19314
|
+
}
|
|
19315
|
+
createEncryptionService() {
|
|
19316
|
+
const crypto2 = this.createEncryptionCrypto();
|
|
19317
|
+
const transport = {
|
|
19318
|
+
postDecrypt: async ({ networkId, authorization, canonicalBody }) => {
|
|
19319
|
+
const response = await fetch(
|
|
19320
|
+
`${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
|
|
19321
|
+
{
|
|
19322
|
+
method: "POST",
|
|
19323
|
+
headers: {
|
|
19324
|
+
Authorization: authorization,
|
|
19325
|
+
"Content-Type": "application/json"
|
|
19326
|
+
},
|
|
19327
|
+
body: canonicalBody
|
|
19328
|
+
}
|
|
19329
|
+
);
|
|
19330
|
+
if (!response.ok) {
|
|
19331
|
+
throw new Error(
|
|
19332
|
+
`decrypt failed ${response.status}: ${await response.text()}`
|
|
19333
|
+
);
|
|
19334
|
+
}
|
|
19335
|
+
return await response.json();
|
|
19336
|
+
}
|
|
19337
|
+
};
|
|
19338
|
+
return new import_sdk_core5.EncryptionService({
|
|
19339
|
+
crypto: crypto2,
|
|
19340
|
+
signer: {
|
|
19341
|
+
signDecryptInvocation: async (input) => {
|
|
19342
|
+
const signed2 = await this.signRawNetworkAuthorization({
|
|
19343
|
+
targetNode: input.targetNode,
|
|
19344
|
+
networkId: input.networkId,
|
|
19345
|
+
action: DECRYPT_ACTION,
|
|
19346
|
+
facts: input.facts
|
|
19347
|
+
});
|
|
19348
|
+
return {
|
|
19349
|
+
...signed2,
|
|
19350
|
+
canonicalBody: (0, import_sdk_core5.canonicalizeEncryptionJson)(
|
|
19351
|
+
input.body
|
|
19352
|
+
)
|
|
19353
|
+
};
|
|
19354
|
+
}
|
|
19355
|
+
},
|
|
19356
|
+
transport,
|
|
19357
|
+
node: {
|
|
19358
|
+
fetchByNetworkId: (networkId) => this.getEncryptionNetwork(networkId)
|
|
19359
|
+
}
|
|
19360
|
+
});
|
|
19361
|
+
}
|
|
19362
|
+
getEncryptionService() {
|
|
19363
|
+
if (!this._serviceContext) {
|
|
19364
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19365
|
+
}
|
|
19366
|
+
if (!this._encryption) {
|
|
19367
|
+
this._encryption = this.createEncryptionService();
|
|
19368
|
+
this._encryption.initialize(this._serviceContext);
|
|
19369
|
+
this._serviceContext.registerService("encryption", this._encryption);
|
|
19370
|
+
}
|
|
19371
|
+
return this._encryption;
|
|
19372
|
+
}
|
|
18961
19373
|
createVaultService(spaceId, kv) {
|
|
18962
19374
|
const wasm = this.wasmBindings;
|
|
18963
19375
|
const vaultCrypto = (0, import_sdk_core5.createVaultCrypto)({
|
|
@@ -18973,6 +19385,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18973
19385
|
return new import_sdk_core5.DataVaultService({
|
|
18974
19386
|
spaceId,
|
|
18975
19387
|
crypto: vaultCrypto,
|
|
19388
|
+
encryption: {
|
|
19389
|
+
networkId: this.getDefaultEncryptionNetworkId(),
|
|
19390
|
+
service: this.getEncryptionService(),
|
|
19391
|
+
decryptCapabilityProof: () => ({
|
|
19392
|
+
proofs: [this.requireServiceSession().delegationCid]
|
|
19393
|
+
})
|
|
19394
|
+
},
|
|
18976
19395
|
tc: {
|
|
18977
19396
|
kv,
|
|
18978
19397
|
ensurePublicSpace: async () => {
|
|
@@ -19153,7 +19572,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19153
19572
|
* @internal
|
|
19154
19573
|
*/
|
|
19155
19574
|
getSessionExpiry() {
|
|
19156
|
-
const expirationMs = this.config.sessionExpirationMs ??
|
|
19575
|
+
const expirationMs = this.config.sessionExpirationMs ?? DEFAULT_SESSION_EXPIRATION_MS;
|
|
19157
19576
|
return new Date(Date.now() + expirationMs);
|
|
19158
19577
|
}
|
|
19159
19578
|
/**
|
|
@@ -19210,7 +19629,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19210
19629
|
if (!this.signer) {
|
|
19211
19630
|
return void 0;
|
|
19212
19631
|
}
|
|
19213
|
-
const session = this.
|
|
19632
|
+
const session = this.currentTinyCloudSession();
|
|
19214
19633
|
if (!session) {
|
|
19215
19634
|
return void 0;
|
|
19216
19635
|
}
|
|
@@ -19310,6 +19729,34 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19310
19729
|
}
|
|
19311
19730
|
return this._sql;
|
|
19312
19731
|
}
|
|
19732
|
+
/**
|
|
19733
|
+
* Get an SQL service scoped to a specific space.
|
|
19734
|
+
*
|
|
19735
|
+
* Mirrors {@link SpaceService}'s per-space KV factory: clones the active
|
|
19736
|
+
* service context and overrides its session's spaceId so that subsequent
|
|
19737
|
+
* `sql/<dbName>/<action>` invocations route to that space. Useful when
|
|
19738
|
+
* the caller already holds a delegation covering the target space (e.g.
|
|
19739
|
+
* via {@link grantRuntimePermissions} or {@link useRuntimeDelegation})
|
|
19740
|
+
* but the SDK's per-space SQL surface isn't otherwise exposed.
|
|
19741
|
+
*
|
|
19742
|
+
* Does NOT auto-create the space.
|
|
19743
|
+
*
|
|
19744
|
+
* @param spaceId - Full space URI (`tinycloud:pkh:eip155:<chain>:<addr>:<name>`).
|
|
19745
|
+
*/
|
|
19746
|
+
sqlForSpace(spaceId) {
|
|
19747
|
+
if (!this._serviceContext || !this._serviceContext.session) {
|
|
19748
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
19749
|
+
}
|
|
19750
|
+
const sql = new import_sdk_core5.SQLService({});
|
|
19751
|
+
const spaceScopedContext = new import_sdk_core5.ServiceContext({
|
|
19752
|
+
invoke: this._serviceContext.invoke,
|
|
19753
|
+
fetch: this._serviceContext.fetch,
|
|
19754
|
+
hosts: this._serviceContext.hosts
|
|
19755
|
+
});
|
|
19756
|
+
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
19757
|
+
sql.initialize(spaceScopedContext);
|
|
19758
|
+
return sql;
|
|
19759
|
+
}
|
|
19313
19760
|
/**
|
|
19314
19761
|
* DuckDB database operations on this user's space.
|
|
19315
19762
|
*/
|
|
@@ -19333,6 +19780,79 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19333
19780
|
}
|
|
19334
19781
|
return this._vault;
|
|
19335
19782
|
}
|
|
19783
|
+
/**
|
|
19784
|
+
* Network-scoped encryption/decrypt service.
|
|
19785
|
+
*/
|
|
19786
|
+
get encryption() {
|
|
19787
|
+
return this.getEncryptionService();
|
|
19788
|
+
}
|
|
19789
|
+
async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
|
|
19790
|
+
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
19791
|
+
const response = await fetch(
|
|
19792
|
+
`${this.config.host}/encryption/networks/${encodeURIComponent(networkId)}`
|
|
19793
|
+
);
|
|
19794
|
+
if (response.status === 404) {
|
|
19795
|
+
return null;
|
|
19796
|
+
}
|
|
19797
|
+
if (!response.ok) {
|
|
19798
|
+
throw new Error(
|
|
19799
|
+
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
19800
|
+
);
|
|
19801
|
+
}
|
|
19802
|
+
const body = await response.json();
|
|
19803
|
+
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
19804
|
+
}
|
|
19805
|
+
async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
19806
|
+
const targetNode = await this.fetchNodeId();
|
|
19807
|
+
const principal = this.did;
|
|
19808
|
+
const networkId = this.getDefaultEncryptionNetworkId(name);
|
|
19809
|
+
const body = {
|
|
19810
|
+
name,
|
|
19811
|
+
principal,
|
|
19812
|
+
threshold: { n: 1, t: 1 }
|
|
19813
|
+
};
|
|
19814
|
+
const crypto2 = this.createEncryptionCrypto();
|
|
19815
|
+
const facts = {
|
|
19816
|
+
type: NETWORK_ADMIN_TYPE,
|
|
19817
|
+
targetNode,
|
|
19818
|
+
networkId,
|
|
19819
|
+
bodyHash: (0, import_sdk_core5.canonicalHashHex)(
|
|
19820
|
+
crypto2.sha256,
|
|
19821
|
+
body
|
|
19822
|
+
),
|
|
19823
|
+
action: NETWORK_CREATE_ACTION
|
|
19824
|
+
};
|
|
19825
|
+
const signed2 = await this.signRawNetworkAuthorization({
|
|
19826
|
+
targetNode,
|
|
19827
|
+
networkId,
|
|
19828
|
+
action: NETWORK_CREATE_ACTION,
|
|
19829
|
+
facts
|
|
19830
|
+
});
|
|
19831
|
+
const response = await fetch(`${this.config.host}/encryption/networks`, {
|
|
19832
|
+
method: "POST",
|
|
19833
|
+
headers: {
|
|
19834
|
+
Authorization: signed2.authorization,
|
|
19835
|
+
"Content-Type": "application/json"
|
|
19836
|
+
},
|
|
19837
|
+
body: (0, import_sdk_core5.canonicalizeEncryptionJson)(
|
|
19838
|
+
body
|
|
19839
|
+
)
|
|
19840
|
+
});
|
|
19841
|
+
if (!response.ok) {
|
|
19842
|
+
throw new Error(
|
|
19843
|
+
`Failed to create encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
19844
|
+
);
|
|
19845
|
+
}
|
|
19846
|
+
const created = await response.json();
|
|
19847
|
+
return created.descriptor;
|
|
19848
|
+
}
|
|
19849
|
+
async ensureEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
19850
|
+
const existing = await this.getEncryptionNetwork(name);
|
|
19851
|
+
if (existing) {
|
|
19852
|
+
return existing;
|
|
19853
|
+
}
|
|
19854
|
+
return this.createEncryptionNetwork(name);
|
|
19855
|
+
}
|
|
19336
19856
|
/**
|
|
19337
19857
|
* App-facing secrets API backed by the `secrets` space vault.
|
|
19338
19858
|
*/
|
|
@@ -19344,8 +19864,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19344
19864
|
this._secrets = new NodeSecretsService({
|
|
19345
19865
|
getService: () => this.getBaseSecrets(),
|
|
19346
19866
|
getManifest: () => this.manifest,
|
|
19867
|
+
hasPermissions: (permissions) => this.hasRuntimePermissions(permissions),
|
|
19347
19868
|
grantPermissions: (additional) => this.grantRuntimePermissions(additional),
|
|
19348
19869
|
canEscalate: () => this.signer !== void 0 && this.tc !== void 0,
|
|
19870
|
+
getEncryptionNetworkId: () => this.getDefaultEncryptionNetworkId(),
|
|
19349
19871
|
getUnlockSigner: () => this.signer ?? void 0
|
|
19350
19872
|
});
|
|
19351
19873
|
}
|
|
@@ -19435,7 +19957,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19435
19957
|
* every requested permission.
|
|
19436
19958
|
*/
|
|
19437
19959
|
hasRuntimePermissions(permissions) {
|
|
19438
|
-
const session = this.
|
|
19960
|
+
const session = this.currentTinyCloudSession();
|
|
19439
19961
|
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
19440
19962
|
return false;
|
|
19441
19963
|
}
|
|
@@ -19455,7 +19977,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19455
19977
|
if (permissions === void 0) {
|
|
19456
19978
|
return this.runtimePermissionGrants.map((grant) => grant.delegation);
|
|
19457
19979
|
}
|
|
19458
|
-
const session = this.
|
|
19980
|
+
const session = this.currentTinyCloudSession();
|
|
19459
19981
|
if (!session || !Array.isArray(permissions) || permissions.length === 0) {
|
|
19460
19982
|
return [];
|
|
19461
19983
|
}
|
|
@@ -19469,7 +19991,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19469
19991
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
19470
19992
|
*/
|
|
19471
19993
|
async useRuntimeDelegation(delegation) {
|
|
19472
|
-
const session = this.
|
|
19994
|
+
const session = this.currentTinyCloudSession();
|
|
19473
19995
|
if (!session) {
|
|
19474
19996
|
throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19475
19997
|
}
|
|
@@ -19508,7 +20030,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19508
20030
|
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
19509
20031
|
throw new Error("grantRuntimePermissions requires a non-empty permissions array");
|
|
19510
20032
|
}
|
|
19511
|
-
const session = this.
|
|
20033
|
+
const session = this.currentTinyCloudSession();
|
|
19512
20034
|
if (!session) {
|
|
19513
20035
|
throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19514
20036
|
}
|
|
@@ -19532,13 +20054,22 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19532
20054
|
"grantRuntimePermissions requires wallet mode with a signer or privateKey."
|
|
19533
20055
|
);
|
|
19534
20056
|
}
|
|
20057
|
+
const rawEntries = expanded.filter(
|
|
20058
|
+
(entry) => this.isEncryptionPermissionEntry(entry)
|
|
20059
|
+
);
|
|
20060
|
+
const spaceEntries = expanded.filter(
|
|
20061
|
+
(entry) => !this.isEncryptionPermissionEntry(entry)
|
|
20062
|
+
);
|
|
19535
20063
|
const bySpace = /* @__PURE__ */ new Map();
|
|
19536
|
-
for (const entry of
|
|
20064
|
+
for (const entry of spaceEntries) {
|
|
19537
20065
|
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
19538
20066
|
const current = bySpace.get(spaceId) ?? [];
|
|
19539
20067
|
current.push(entry);
|
|
19540
20068
|
bySpace.set(spaceId, current);
|
|
19541
20069
|
}
|
|
20070
|
+
if (bySpace.size === 0 && rawEntries.length > 0) {
|
|
20071
|
+
bySpace.set(session.spaceId, []);
|
|
20072
|
+
}
|
|
19542
20073
|
const now = /* @__PURE__ */ new Date();
|
|
19543
20074
|
const requestedExpiryMs = resolveExpiryMs(options?.expiry);
|
|
19544
20075
|
let expiresAt = new Date(now.getTime() + requestedExpiryMs);
|
|
@@ -19546,10 +20077,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19546
20077
|
expiresAt = sessionExpiry;
|
|
19547
20078
|
}
|
|
19548
20079
|
const delegations = [];
|
|
20080
|
+
let rawEntriesAttached = false;
|
|
19549
20081
|
for (const [spaceId, entries] of bySpace) {
|
|
20082
|
+
const rawForDelegation = !rawEntriesAttached ? rawEntries : [];
|
|
20083
|
+
if (rawForDelegation.length > 0) {
|
|
20084
|
+
rawEntriesAttached = true;
|
|
20085
|
+
}
|
|
20086
|
+
const delegatedEntries = [...entries, ...rawForDelegation];
|
|
19550
20087
|
const abilities = this.permissionsToAbilities(entries);
|
|
19551
20088
|
const prepared = this.wasmBindings.prepareSession({
|
|
19552
20089
|
abilities,
|
|
20090
|
+
...rawForDelegation.length > 0 ? { rawAbilities: this.permissionsToRawAbilities(rawForDelegation) } : {},
|
|
19553
20091
|
address: this.wasmBindings.ensureEip55(session.address),
|
|
19554
20092
|
chainId: session.chainId,
|
|
19555
20093
|
domain: this.siweDomain,
|
|
@@ -19574,7 +20112,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19574
20112
|
}
|
|
19575
20113
|
const delegation = this.runtimeDelegationFromSession(
|
|
19576
20114
|
delegatedSession,
|
|
19577
|
-
|
|
20115
|
+
delegatedEntries,
|
|
19578
20116
|
spaceId,
|
|
19579
20117
|
session,
|
|
19580
20118
|
expiresAt
|
|
@@ -19588,7 +20126,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19588
20126
|
jwk: session.jwk
|
|
19589
20127
|
},
|
|
19590
20128
|
delegation,
|
|
19591
|
-
operations: this.permissionOperations(
|
|
20129
|
+
operations: this.permissionOperations(delegatedEntries, spaceId),
|
|
19592
20130
|
expiresAt
|
|
19593
20131
|
});
|
|
19594
20132
|
delegations.push(delegation);
|
|
@@ -19736,7 +20274,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19736
20274
|
];
|
|
19737
20275
|
const abilities = { kv: { "": kvActions } };
|
|
19738
20276
|
const now = /* @__PURE__ */ new Date();
|
|
19739
|
-
const expiryMs =
|
|
20277
|
+
const expiryMs = import_sdk_core5.EXPIRY.EPHEMERAL_MS;
|
|
19740
20278
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
19741
20279
|
const prepared = this.wasmBindings.prepareSession({
|
|
19742
20280
|
abilities,
|
|
@@ -19906,7 +20444,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19906
20444
|
* `forceWalletSign` is not set.
|
|
19907
20445
|
*/
|
|
19908
20446
|
async delegateTo(did, permissions, options) {
|
|
19909
|
-
const session = this.
|
|
20447
|
+
const session = this.currentTinyCloudSession();
|
|
19910
20448
|
if (!session) {
|
|
19911
20449
|
throw new import_sdk_core5.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
19912
20450
|
}
|
|
@@ -20020,11 +20558,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20020
20558
|
* the current session; we build one multi-resource abilities map
|
|
20021
20559
|
* and emit one signed UCAN covering them all.
|
|
20022
20560
|
*
|
|
20023
|
-
*
|
|
20024
|
-
*
|
|
20025
|
-
* spaces in a single delegation is not supported by the underlying
|
|
20026
|
-
* Rust create_delegation call and the resulting UCAN would be
|
|
20027
|
-
* under-specified.
|
|
20561
|
+
* Non-encryption entries must share the same target space. Encryption
|
|
20562
|
+
* entries are raw network URNs and do not participate in space grouping.
|
|
20028
20563
|
*
|
|
20029
20564
|
* @internal
|
|
20030
20565
|
*/
|
|
@@ -20036,15 +20571,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20036
20571
|
}
|
|
20037
20572
|
const resolvedSpaces = /* @__PURE__ */ new Set();
|
|
20038
20573
|
for (const entry of entries) {
|
|
20574
|
+
if (this.isEncryptionPermissionEntry(entry)) {
|
|
20575
|
+
continue;
|
|
20576
|
+
}
|
|
20039
20577
|
const spaceId2 = this.resolvePermissionSpace(entry.space, session);
|
|
20040
20578
|
resolvedSpaces.add(spaceId2);
|
|
20041
20579
|
}
|
|
20042
|
-
if (resolvedSpaces.size
|
|
20580
|
+
if (resolvedSpaces.size > 1) {
|
|
20043
20581
|
throw new Error(
|
|
20044
20582
|
`delegateTo: all permission entries must target the same space, got ${resolvedSpaces.size}: ${JSON.stringify([...resolvedSpaces])}`
|
|
20045
20583
|
);
|
|
20046
20584
|
}
|
|
20047
|
-
const spaceId = [...resolvedSpaces][0];
|
|
20585
|
+
const spaceId = resolvedSpaces.size === 1 ? [...resolvedSpaces][0] : session.spaceId;
|
|
20048
20586
|
const abilities = {};
|
|
20049
20587
|
for (const entry of entries) {
|
|
20050
20588
|
const shortService = import_sdk_core5.SERVICE_LONG_TO_SHORT[entry.service];
|
|
@@ -20191,11 +20729,32 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20191
20729
|
}
|
|
20192
20730
|
return abilities;
|
|
20193
20731
|
}
|
|
20732
|
+
isEncryptionPermissionEntry(entry) {
|
|
20733
|
+
return entry.service === import_sdk_core5.ENCRYPTION_PERMISSION_SERVICE && entry.path.startsWith("urn:tinycloud:encryption:");
|
|
20734
|
+
}
|
|
20735
|
+
permissionsToRawAbilities(entries) {
|
|
20736
|
+
const rawAbilities = {};
|
|
20737
|
+
for (const entry of entries) {
|
|
20738
|
+
if (!this.isEncryptionPermissionEntry(entry)) {
|
|
20739
|
+
continue;
|
|
20740
|
+
}
|
|
20741
|
+
const existing = rawAbilities[entry.path] ?? [];
|
|
20742
|
+
const seen = new Set(existing);
|
|
20743
|
+
for (const action of entry.actions) {
|
|
20744
|
+
if (!seen.has(action)) {
|
|
20745
|
+
existing.push(action);
|
|
20746
|
+
seen.add(action);
|
|
20747
|
+
}
|
|
20748
|
+
}
|
|
20749
|
+
rawAbilities[entry.path] = existing;
|
|
20750
|
+
}
|
|
20751
|
+
return rawAbilities;
|
|
20752
|
+
}
|
|
20194
20753
|
permissionOperations(entries, spaceId) {
|
|
20195
20754
|
return entries.flatMap((entry) => {
|
|
20196
20755
|
const service = this.shortServiceName(entry.service);
|
|
20197
20756
|
return entry.actions.map((action) => ({
|
|
20198
|
-
spaceId,
|
|
20757
|
+
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
|
|
20199
20758
|
service,
|
|
20200
20759
|
path: entry.path,
|
|
20201
20760
|
action
|
|
@@ -20218,7 +20777,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20218
20777
|
const spaceId = this.resolvePermissionSpace(entry.space, session);
|
|
20219
20778
|
const service = this.shortServiceName(entry.service);
|
|
20220
20779
|
return entry.actions.map((action) => ({
|
|
20221
|
-
spaceId,
|
|
20780
|
+
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
|
|
20222
20781
|
service,
|
|
20223
20782
|
path: entry.path,
|
|
20224
20783
|
action
|
|
@@ -20275,24 +20834,40 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20275
20834
|
expiresAt: delegation.expiry
|
|
20276
20835
|
};
|
|
20277
20836
|
}
|
|
20837
|
+
installRuntimeGrantFromServiceSession(delegation, session, expiresAt) {
|
|
20838
|
+
const operations = this.operationsFromDelegation(delegation);
|
|
20839
|
+
if (operations.length === 0) {
|
|
20840
|
+
return;
|
|
20841
|
+
}
|
|
20842
|
+
this.runtimePermissionGrants = this.runtimePermissionGrants.filter(
|
|
20843
|
+
(grant) => grant.delegation.cid !== delegation.cid && grant.session.delegationCid !== session.delegationCid
|
|
20844
|
+
);
|
|
20845
|
+
this.runtimePermissionGrants.push({
|
|
20846
|
+
session,
|
|
20847
|
+
delegation,
|
|
20848
|
+
operations,
|
|
20849
|
+
expiresAt
|
|
20850
|
+
});
|
|
20851
|
+
}
|
|
20278
20852
|
delegatedResourcesForEntries(entries, spaceId) {
|
|
20279
20853
|
return entries.map((entry) => ({
|
|
20280
20854
|
service: this.shortServiceName(entry.service),
|
|
20281
|
-
space: spaceId,
|
|
20855
|
+
space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
|
|
20282
20856
|
path: entry.path,
|
|
20283
20857
|
actions: [...entry.actions]
|
|
20284
20858
|
}));
|
|
20285
20859
|
}
|
|
20286
20860
|
operationsFromDelegation(delegation) {
|
|
20287
20861
|
const resources = delegation.resources !== void 0 && delegation.resources.length > 0 ? delegation.resources : this.flatDelegationResources(delegation);
|
|
20288
|
-
return resources.flatMap(
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
service:
|
|
20862
|
+
return resources.flatMap((resource) => {
|
|
20863
|
+
const service = this.invocationServiceName(resource.service);
|
|
20864
|
+
return resource.actions.map((action) => ({
|
|
20865
|
+
...this.isEncryptionNetworkOperation(service, resource.path) ? { resource: resource.path } : { spaceId: resource.space },
|
|
20866
|
+
service,
|
|
20292
20867
|
path: resource.path,
|
|
20293
20868
|
action
|
|
20294
|
-
}))
|
|
20295
|
-
);
|
|
20869
|
+
}));
|
|
20870
|
+
});
|
|
20296
20871
|
}
|
|
20297
20872
|
flatDelegationResources(delegation) {
|
|
20298
20873
|
const byService = /* @__PURE__ */ new Map();
|
|
@@ -20341,7 +20916,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20341
20916
|
);
|
|
20342
20917
|
}
|
|
20343
20918
|
operationCovers(granted, requested) {
|
|
20344
|
-
|
|
20919
|
+
if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
|
|
20920
|
+
return false;
|
|
20921
|
+
}
|
|
20922
|
+
if (granted.resource !== void 0 || requested.resource !== void 0) {
|
|
20923
|
+
return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
|
|
20924
|
+
}
|
|
20925
|
+
return granted.spaceId !== void 0 && requested.spaceId !== void 0 && granted.spaceId === requested.spaceId && this.pathContains(granted.path, requested.path);
|
|
20345
20926
|
}
|
|
20346
20927
|
actionContains(grantedAction, requestedAction) {
|
|
20347
20928
|
if (grantedAction === requestedAction) {
|
|
@@ -20356,6 +20937,37 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20356
20937
|
invocationServiceName(service) {
|
|
20357
20938
|
return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
|
|
20358
20939
|
}
|
|
20940
|
+
isEncryptionNetworkOperation(service, path) {
|
|
20941
|
+
return service === "encryption" && path.startsWith("urn:tinycloud:encryption:");
|
|
20942
|
+
}
|
|
20943
|
+
operationFromInvokeAnyEntry(entry) {
|
|
20944
|
+
const service = this.invocationServiceName(entry.service);
|
|
20945
|
+
if (typeof entry.resource === "string") {
|
|
20946
|
+
return {
|
|
20947
|
+
resource: entry.resource,
|
|
20948
|
+
service,
|
|
20949
|
+
path: entry.path,
|
|
20950
|
+
action: entry.action
|
|
20951
|
+
};
|
|
20952
|
+
}
|
|
20953
|
+
if (this.isEncryptionNetworkOperation(service, entry.path)) {
|
|
20954
|
+
return {
|
|
20955
|
+
resource: entry.path,
|
|
20956
|
+
service,
|
|
20957
|
+
path: entry.path,
|
|
20958
|
+
action: entry.action
|
|
20959
|
+
};
|
|
20960
|
+
}
|
|
20961
|
+
if (typeof entry.spaceId === "string") {
|
|
20962
|
+
return {
|
|
20963
|
+
spaceId: entry.spaceId,
|
|
20964
|
+
service,
|
|
20965
|
+
path: entry.path,
|
|
20966
|
+
action: entry.action
|
|
20967
|
+
};
|
|
20968
|
+
}
|
|
20969
|
+
return void 0;
|
|
20970
|
+
}
|
|
20359
20971
|
pathContains(grantedPath, requestedPath) {
|
|
20360
20972
|
if (grantedPath === "" || grantedPath === "/") {
|
|
20361
20973
|
return true;
|
|
@@ -20594,6 +21206,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20594
21206
|
// Not used in session-only mode
|
|
20595
21207
|
};
|
|
20596
21208
|
this.trackReceivedDelegation(delegation, this.sessionKeyJwk);
|
|
21209
|
+
this.installRuntimeGrantFromServiceSession(
|
|
21210
|
+
delegation,
|
|
21211
|
+
{
|
|
21212
|
+
delegationHeader: session2.delegationHeader,
|
|
21213
|
+
delegationCid: session2.delegationCid,
|
|
21214
|
+
spaceId: session2.spaceId,
|
|
21215
|
+
verificationMethod: session2.verificationMethod,
|
|
21216
|
+
jwk: session2.jwk
|
|
21217
|
+
},
|
|
21218
|
+
delegation.expiry
|
|
21219
|
+
);
|
|
20597
21220
|
return new DelegatedAccess(session2, delegation, targetHost, this.wasmBindings.invoke);
|
|
20598
21221
|
}
|
|
20599
21222
|
const mySession = this.auth?.tinyCloudSession;
|
|
@@ -20605,6 +21228,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20605
21228
|
const kvActions = delegation.actions.filter((a) => a.startsWith("tinycloud.kv/"));
|
|
20606
21229
|
const sqlActions = delegation.actions.filter((a) => a.startsWith("tinycloud.sql/"));
|
|
20607
21230
|
const duckdbActions = delegation.actions.filter((a) => a.startsWith("tinycloud.duckdb/"));
|
|
21231
|
+
const encryptionActions = delegation.actions.filter(
|
|
21232
|
+
(a) => a.startsWith("tinycloud.encryption/")
|
|
21233
|
+
);
|
|
21234
|
+
const rawAbilities = {};
|
|
20608
21235
|
if (kvActions.length > 0) {
|
|
20609
21236
|
abilities.kv = { [delegation.path]: kvActions };
|
|
20610
21237
|
}
|
|
@@ -20614,6 +21241,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20614
21241
|
if (duckdbActions.length > 0) {
|
|
20615
21242
|
abilities.duckdb = { [delegation.path]: duckdbActions };
|
|
20616
21243
|
}
|
|
21244
|
+
if (encryptionActions.length > 0 && delegation.path.startsWith("urn:tinycloud:encryption:")) {
|
|
21245
|
+
rawAbilities[delegation.path] = encryptionActions;
|
|
21246
|
+
}
|
|
20617
21247
|
const now = /* @__PURE__ */ new Date();
|
|
20618
21248
|
const maxExpiry = new Date(now.getTime() + 60 * 60 * 1e3);
|
|
20619
21249
|
const expirationTime = delegation.expiry < maxExpiry ? delegation.expiry : maxExpiry;
|
|
@@ -20626,7 +21256,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20626
21256
|
expirationTime: expirationTime.toISOString(),
|
|
20627
21257
|
spaceId: delegation.spaceId,
|
|
20628
21258
|
jwk,
|
|
20629
|
-
parents: [delegation.cid]
|
|
21259
|
+
parents: [delegation.cid],
|
|
21260
|
+
...Object.keys(rawAbilities).length > 0 ? { rawAbilities } : {}
|
|
20630
21261
|
});
|
|
20631
21262
|
const signature2 = await this.signer.signMessage(prepared.siwe);
|
|
20632
21263
|
const invokerSession = this.wasmBindings.completeSessionSetup({
|
|
@@ -20653,6 +21284,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20653
21284
|
signature: signature2
|
|
20654
21285
|
};
|
|
20655
21286
|
this.trackReceivedDelegation(delegation, jwk);
|
|
21287
|
+
this.installRuntimeGrantFromServiceSession(
|
|
21288
|
+
delegation,
|
|
21289
|
+
{
|
|
21290
|
+
delegationHeader: session.delegationHeader,
|
|
21291
|
+
delegationCid: session.delegationCid,
|
|
21292
|
+
spaceId: session.spaceId,
|
|
21293
|
+
verificationMethod: session.verificationMethod,
|
|
21294
|
+
jwk: session.jwk
|
|
21295
|
+
},
|
|
21296
|
+
expirationTime
|
|
21297
|
+
);
|
|
20656
21298
|
return new DelegatedAccess(session, delegation, targetHost, this.wasmBindings.invoke);
|
|
20657
21299
|
}
|
|
20658
21300
|
/**
|
|
@@ -20917,6 +21559,7 @@ var import_sdk_core16 = require("@tinycloud/sdk-core");
|
|
|
20917
21559
|
var import_sdk_core17 = require("@tinycloud/sdk-core");
|
|
20918
21560
|
var import_sdk_core18 = require("@tinycloud/sdk-core");
|
|
20919
21561
|
var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
21562
|
+
var import_sdk_core20 = require("@tinycloud/sdk-core");
|
|
20920
21563
|
// Annotate the CommonJS export names for ESM import in node:
|
|
20921
21564
|
0 && (module.exports = {
|
|
20922
21565
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -20924,8 +21567,14 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
|
20924
21567
|
AutoApproveSpaceCreationHandler,
|
|
20925
21568
|
CapabilityKeyRegistry,
|
|
20926
21569
|
CapabilityKeyRegistryErrorCodes,
|
|
21570
|
+
DECRYPT_ACTION,
|
|
21571
|
+
DECRYPT_FACT_TYPE,
|
|
21572
|
+
DECRYPT_RESULT_TYPE,
|
|
21573
|
+
DEFAULT_ENCRYPTION_ALG,
|
|
21574
|
+
DEFAULT_KEY_VERSION,
|
|
20927
21575
|
DEFAULT_MANIFEST_SPACE,
|
|
20928
21576
|
DEFAULT_MANIFEST_VERSION,
|
|
21577
|
+
DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
20929
21578
|
DataVaultService,
|
|
20930
21579
|
DatabaseHandle,
|
|
20931
21580
|
DelegatedAccess,
|
|
@@ -20934,17 +21583,25 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
|
20934
21583
|
DuckDbAction,
|
|
20935
21584
|
DuckDbDatabaseHandle,
|
|
20936
21585
|
DuckDbService,
|
|
21586
|
+
ENCRYPTION_NETWORK_URN_PREFIX,
|
|
21587
|
+
ENCRYPTION_SERVICE,
|
|
21588
|
+
ENCRYPTION_SERVICE_SHORT,
|
|
21589
|
+
ENVELOPE_VERSION,
|
|
21590
|
+
EncryptionService,
|
|
20937
21591
|
FileSessionStorage,
|
|
20938
21592
|
HooksService,
|
|
20939
21593
|
KVService,
|
|
20940
21594
|
ManifestValidationError,
|
|
20941
21595
|
MemorySessionStorage,
|
|
21596
|
+
NETWORK_NAME_PATTERN,
|
|
21597
|
+
NetworkIdError,
|
|
20942
21598
|
NodeUserAuthorization,
|
|
20943
21599
|
NodeWasmBindings,
|
|
20944
21600
|
PermissionNotInManifestError,
|
|
20945
21601
|
PrefixedKVService,
|
|
20946
21602
|
PrivateKeySigner,
|
|
20947
21603
|
ProtocolMismatchError,
|
|
21604
|
+
SECRET_NAME_RE,
|
|
20948
21605
|
SQLAction,
|
|
20949
21606
|
SQLService,
|
|
20950
21607
|
SecretsService,
|
|
@@ -20963,7 +21620,17 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
|
20963
21620
|
VaultPublicSpaceKVActions,
|
|
20964
21621
|
VersionCheckError,
|
|
20965
21622
|
WasmKeyProvider,
|
|
21623
|
+
buildCanonicalDecryptRequest,
|
|
21624
|
+
buildDecryptAttenuation,
|
|
21625
|
+
buildDecryptFacts,
|
|
21626
|
+
buildDecryptInvocation,
|
|
21627
|
+
buildNetworkId,
|
|
20966
21628
|
buildSpaceUri,
|
|
21629
|
+
canonicalHashHex,
|
|
21630
|
+
canonicalSignedResponse,
|
|
21631
|
+
canonicalizeEncryptionJson,
|
|
21632
|
+
canonicalizeSecretScope,
|
|
21633
|
+
checkDecryptInvocationInput,
|
|
20967
21634
|
checkNodeInfo,
|
|
20968
21635
|
composeManifestRequest,
|
|
20969
21636
|
createCapabilityKeyRegistry,
|
|
@@ -20971,21 +21638,42 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
|
20971
21638
|
createSpaceService,
|
|
20972
21639
|
createVaultCrypto,
|
|
20973
21640
|
createWasmKeyProvider,
|
|
21641
|
+
decryptEnvelopeWithKey,
|
|
20974
21642
|
defaultSignStrategy,
|
|
20975
21643
|
defaultSpaceCreationHandler,
|
|
21644
|
+
deriveSignedReceiverKey,
|
|
20976
21645
|
deserializeDelegation,
|
|
21646
|
+
discoverNetwork,
|
|
21647
|
+
encryptToNetwork,
|
|
21648
|
+
encryptionBase64Decode,
|
|
21649
|
+
encryptionBase64Encode,
|
|
21650
|
+
encryptionError,
|
|
21651
|
+
encryptionUtf8Decode,
|
|
21652
|
+
encryptionUtf8Encode,
|
|
21653
|
+
ensureNetworkUsableForDecrypt,
|
|
20977
21654
|
expandActionShortNames,
|
|
20978
21655
|
expandPermissionEntries,
|
|
20979
21656
|
expandPermissionEntry,
|
|
21657
|
+
generateRandomReceiverKey,
|
|
21658
|
+
hexDecode,
|
|
21659
|
+
hexEncode,
|
|
20980
21660
|
isCapabilitySubset,
|
|
21661
|
+
isNetworkId,
|
|
20981
21662
|
loadManifest,
|
|
20982
21663
|
makePublicSpaceId,
|
|
21664
|
+
networkDiscoveryKey,
|
|
21665
|
+
openWrappedKey,
|
|
20983
21666
|
parseExpiry,
|
|
21667
|
+
parseNetworkId,
|
|
20984
21668
|
parseSpaceUri,
|
|
20985
21669
|
resolveManifest,
|
|
21670
|
+
resolveSecretListPrefix,
|
|
21671
|
+
resolveSecretPath,
|
|
20986
21672
|
resourceCapabilitiesToSpaceAbilitiesMap,
|
|
20987
21673
|
serializeDelegation,
|
|
20988
|
-
|
|
21674
|
+
validateEnvelope,
|
|
21675
|
+
validateManifest,
|
|
21676
|
+
verifyDecryptResponse
|
|
20989
21677
|
});
|
|
20990
21678
|
/*! Bundled license information:
|
|
20991
21679
|
|