@tinycloud/node-sdk 2.7.0-beta.2 → 2.7.0-beta.4
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-BfqzTbfY.d.cts → core-D_KNrE_y.d.cts} +153 -8
- package/dist/{core-BfqzTbfY.d.ts → core-D_KNrE_y.d.ts} +153 -8
- package/dist/core.cjs +1152 -260
- 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 +1083 -181
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +1470 -301
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +1361 -181
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -17025,143 +17025,147 @@ var require_utils2 = __commonJS({
|
|
|
17025
17025
|
// src/index.ts
|
|
17026
17026
|
var index_exports = {};
|
|
17027
17027
|
__export(index_exports, {
|
|
17028
|
-
ACCOUNT_REGISTRY_PATH: () =>
|
|
17029
|
-
ACCOUNT_REGISTRY_SPACE: () =>
|
|
17028
|
+
ACCOUNT_REGISTRY_PATH: () => import_sdk_core12.ACCOUNT_REGISTRY_PATH,
|
|
17029
|
+
ACCOUNT_REGISTRY_SPACE: () => import_sdk_core12.ACCOUNT_REGISTRY_SPACE,
|
|
17030
17030
|
AccountService: () => import_sdk_core3.AccountService,
|
|
17031
|
-
AutoApproveSpaceCreationHandler: () =>
|
|
17032
|
-
CapabilityKeyRegistry: () =>
|
|
17033
|
-
CapabilityKeyRegistryErrorCodes: () =>
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
|
|
17037
|
-
|
|
17038
|
-
|
|
17039
|
-
|
|
17040
|
-
|
|
17041
|
-
|
|
17042
|
-
|
|
17043
|
-
|
|
17031
|
+
AutoApproveSpaceCreationHandler: () => import_sdk_core11.AutoApproveSpaceCreationHandler,
|
|
17032
|
+
CapabilityKeyRegistry: () => import_sdk_core20.CapabilityKeyRegistry,
|
|
17033
|
+
CapabilityKeyRegistryErrorCodes: () => import_sdk_core20.CapabilityKeyRegistryErrorCodes,
|
|
17034
|
+
CaveatedDelegationUnsupportedError: () => import_sdk_core12.CaveatedDelegationUnsupportedError,
|
|
17035
|
+
DECRYPT_ACTION: () => import_sdk_core17.DECRYPT_ACTION,
|
|
17036
|
+
DECRYPT_FACT_TYPE: () => import_sdk_core17.DECRYPT_FACT_TYPE,
|
|
17037
|
+
DECRYPT_RESULT_TYPE: () => import_sdk_core17.DECRYPT_RESULT_TYPE,
|
|
17038
|
+
DEFAULT_ENCRYPTION_ALG: () => import_sdk_core17.DEFAULT_ENCRYPTION_ALG,
|
|
17039
|
+
DEFAULT_KEY_VERSION: () => import_sdk_core17.DEFAULT_KEY_VERSION,
|
|
17040
|
+
DEFAULT_MANIFEST_SPACE: () => import_sdk_core12.DEFAULT_MANIFEST_SPACE,
|
|
17041
|
+
DEFAULT_MANIFEST_VERSION: () => import_sdk_core12.DEFAULT_MANIFEST_VERSION,
|
|
17042
|
+
DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core13.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
17043
|
+
DataVaultService: () => import_sdk_core16.DataVaultService,
|
|
17044
|
+
DatabaseHandle: () => import_sdk_core14.DatabaseHandle,
|
|
17045
|
+
DecryptTransportResponseError: () => import_sdk_core17.DecryptTransportResponseError,
|
|
17044
17046
|
DelegatedAccess: () => DelegatedAccess,
|
|
17045
|
-
DelegationErrorCodes: () =>
|
|
17046
|
-
DelegationManager: () =>
|
|
17047
|
-
DuckDbAction: () =>
|
|
17048
|
-
DuckDbDatabaseHandle: () =>
|
|
17049
|
-
DuckDbService: () =>
|
|
17050
|
-
ENCRYPTION_NETWORK_URN_PREFIX: () =>
|
|
17051
|
-
ENCRYPTION_SERVICE: () =>
|
|
17052
|
-
ENCRYPTION_SERVICE_SHORT: () =>
|
|
17053
|
-
ENVELOPE_VERSION: () =>
|
|
17054
|
-
EncryptionService: () =>
|
|
17047
|
+
DelegationErrorCodes: () => import_sdk_core19.DelegationErrorCodes,
|
|
17048
|
+
DelegationManager: () => import_sdk_core19.DelegationManager,
|
|
17049
|
+
DuckDbAction: () => import_sdk_core15.DuckDbAction,
|
|
17050
|
+
DuckDbDatabaseHandle: () => import_sdk_core15.DuckDbDatabaseHandle,
|
|
17051
|
+
DuckDbService: () => import_sdk_core15.DuckDbService,
|
|
17052
|
+
ENCRYPTION_NETWORK_URN_PREFIX: () => import_sdk_core17.ENCRYPTION_NETWORK_URN_PREFIX,
|
|
17053
|
+
ENCRYPTION_SERVICE: () => import_sdk_core17.ENCRYPTION_SERVICE,
|
|
17054
|
+
ENCRYPTION_SERVICE_SHORT: () => import_sdk_core17.ENCRYPTION_SERVICE_SHORT,
|
|
17055
|
+
ENVELOPE_VERSION: () => import_sdk_core17.ENVELOPE_VERSION,
|
|
17056
|
+
EncryptionService: () => import_sdk_core17.EncryptionService,
|
|
17055
17057
|
FileSessionStorage: () => FileSessionStorage,
|
|
17056
|
-
HooksService: () =>
|
|
17057
|
-
IdentityParseError: () =>
|
|
17058
|
-
KVService: () =>
|
|
17059
|
-
ManifestValidationError: () =>
|
|
17058
|
+
HooksService: () => import_sdk_core18.HooksService,
|
|
17059
|
+
IdentityParseError: () => import_sdk_core11.IdentityParseError,
|
|
17060
|
+
KVService: () => import_sdk_core13.KVService,
|
|
17061
|
+
ManifestValidationError: () => import_sdk_core12.ManifestValidationError,
|
|
17060
17062
|
MemorySessionStorage: () => MemorySessionStorage,
|
|
17061
|
-
NETWORK_NAME_PATTERN: () =>
|
|
17062
|
-
NetworkIdError: () =>
|
|
17063
|
+
NETWORK_NAME_PATTERN: () => import_sdk_core17.NETWORK_NAME_PATTERN,
|
|
17064
|
+
NetworkIdError: () => import_sdk_core17.NetworkIdError,
|
|
17063
17065
|
NodeUserAuthorization: () => NodeUserAuthorization,
|
|
17064
17066
|
NodeWasmBindings: () => NodeWasmBindings,
|
|
17065
|
-
PermissionNotInManifestError: () =>
|
|
17066
|
-
PrefixedKVService: () =>
|
|
17067
|
+
PermissionNotInManifestError: () => import_sdk_core12.PermissionNotInManifestError,
|
|
17068
|
+
PrefixedKVService: () => import_sdk_core13.PrefixedKVService,
|
|
17067
17069
|
PrivateKeySigner: () => PrivateKeySigner,
|
|
17068
|
-
ProtocolMismatchError: () =>
|
|
17069
|
-
SECRET_NAME_RE: () =>
|
|
17070
|
-
SQLAction: () =>
|
|
17071
|
-
SQLService: () =>
|
|
17072
|
-
SecretsService: () =>
|
|
17073
|
-
ServiceContext: () =>
|
|
17074
|
-
SessionExpiredError: () =>
|
|
17075
|
-
SharingService: () =>
|
|
17076
|
-
SilentNotificationHandler: () =>
|
|
17077
|
-
Space: () =>
|
|
17078
|
-
SpaceErrorCodes: () =>
|
|
17079
|
-
SpaceService: () =>
|
|
17080
|
-
TinyCloud: () =>
|
|
17081
|
-
TinyCloudDebugLogger: () =>
|
|
17070
|
+
ProtocolMismatchError: () => import_sdk_core22.ProtocolMismatchError,
|
|
17071
|
+
SECRET_NAME_RE: () => import_sdk_core16.SECRET_NAME_RE,
|
|
17072
|
+
SQLAction: () => import_sdk_core14.SQLAction,
|
|
17073
|
+
SQLService: () => import_sdk_core14.SQLService,
|
|
17074
|
+
SecretsService: () => import_sdk_core16.SecretsService,
|
|
17075
|
+
ServiceContext: () => import_sdk_core23.ServiceContext,
|
|
17076
|
+
SessionExpiredError: () => import_sdk_core12.SessionExpiredError,
|
|
17077
|
+
SharingService: () => import_sdk_core19.SharingService,
|
|
17078
|
+
SilentNotificationHandler: () => import_sdk_core11.SilentNotificationHandler,
|
|
17079
|
+
Space: () => import_sdk_core21.Space,
|
|
17080
|
+
SpaceErrorCodes: () => import_sdk_core21.SpaceErrorCodes,
|
|
17081
|
+
SpaceService: () => import_sdk_core21.SpaceService,
|
|
17082
|
+
TinyCloud: () => import_sdk_core10.TinyCloud,
|
|
17083
|
+
TinyCloudDebugLogger: () => import_sdk_core11.TinyCloudDebugLogger,
|
|
17082
17084
|
TinyCloudNode: () => TinyCloudNode,
|
|
17083
|
-
UnsupportedFeatureError: () =>
|
|
17084
|
-
|
|
17085
|
-
|
|
17086
|
-
|
|
17087
|
-
|
|
17085
|
+
UnsupportedFeatureError: () => import_sdk_core22.UnsupportedFeatureError,
|
|
17086
|
+
UnsupportedSessionRestoreError: () => UnsupportedSessionRestoreError,
|
|
17087
|
+
VAULT_PERMISSION_SERVICE: () => import_sdk_core12.VAULT_PERMISSION_SERVICE,
|
|
17088
|
+
VaultHeaders: () => import_sdk_core16.VaultHeaders,
|
|
17089
|
+
VaultPublicSpaceKVActions: () => import_sdk_core16.VaultPublicSpaceKVActions,
|
|
17090
|
+
VersionCheckError: () => import_sdk_core22.VersionCheckError,
|
|
17088
17091
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
17089
|
-
|
|
17090
|
-
|
|
17091
|
-
|
|
17092
|
-
|
|
17093
|
-
|
|
17094
|
-
|
|
17095
|
-
|
|
17096
|
-
|
|
17097
|
-
|
|
17098
|
-
|
|
17099
|
-
|
|
17100
|
-
|
|
17101
|
-
|
|
17102
|
-
|
|
17103
|
-
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
17107
|
-
|
|
17108
|
-
|
|
17092
|
+
activateValidatedRuntimeDelegation: () => activateValidatedRuntimeDelegation,
|
|
17093
|
+
addressStorageKey: () => import_sdk_core11.addressStorageKey,
|
|
17094
|
+
buildCanonicalDecryptRequest: () => import_sdk_core17.buildCanonicalDecryptRequest,
|
|
17095
|
+
buildDecryptAttenuation: () => import_sdk_core17.buildDecryptAttenuation,
|
|
17096
|
+
buildDecryptFacts: () => import_sdk_core17.buildDecryptFacts,
|
|
17097
|
+
buildDecryptInvocation: () => import_sdk_core17.buildDecryptInvocation,
|
|
17098
|
+
buildNetworkId: () => import_sdk_core17.buildNetworkId,
|
|
17099
|
+
buildSpaceUri: () => import_sdk_core21.buildSpaceUri,
|
|
17100
|
+
canonicalHashHex: () => import_sdk_core17.canonicalHashHex,
|
|
17101
|
+
canonicalSignedResponse: () => import_sdk_core17.canonicalSignedResponse,
|
|
17102
|
+
canonicalizeAddress: () => import_sdk_core11.canonicalizeAddress,
|
|
17103
|
+
canonicalizeDid: () => import_sdk_core11.canonicalizeDid,
|
|
17104
|
+
canonicalizeDidUrl: () => import_sdk_core11.canonicalizeDidUrl,
|
|
17105
|
+
canonicalizeEncryptionJson: () => import_sdk_core17.canonicalizeEncryptionJson,
|
|
17106
|
+
canonicalizeNetworkId: () => import_sdk_core11.canonicalizeNetworkId,
|
|
17107
|
+
canonicalizeSecretScope: () => import_sdk_core16.canonicalizeSecretScope,
|
|
17108
|
+
checkDecryptInvocationInput: () => import_sdk_core17.checkDecryptInvocationInput,
|
|
17109
|
+
checkNodeInfo: () => import_sdk_core22.checkNodeInfo,
|
|
17110
|
+
clearTinyCloudDebugLogs: () => import_sdk_core11.clearTinyCloudDebugLogs,
|
|
17111
|
+
composeManifestRequest: () => import_sdk_core12.composeManifestRequest,
|
|
17112
|
+
createCapabilityKeyRegistry: () => import_sdk_core20.createCapabilityKeyRegistry,
|
|
17109
17113
|
createOpenKeyCallbackSigningStrategy: () => import_sdk_core.createOpenKeyCallbackSigningStrategy,
|
|
17110
|
-
createSharingService: () =>
|
|
17111
|
-
createSpaceService: () =>
|
|
17112
|
-
createVaultCrypto: () =>
|
|
17114
|
+
createSharingService: () => import_sdk_core19.createSharingService,
|
|
17115
|
+
createSpaceService: () => import_sdk_core21.createSpaceService,
|
|
17116
|
+
createVaultCrypto: () => import_sdk_core16.createVaultCrypto,
|
|
17113
17117
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
17114
|
-
decryptEnvelopeWithKey: () =>
|
|
17118
|
+
decryptEnvelopeWithKey: () => import_sdk_core17.decryptEnvelopeWithKey,
|
|
17115
17119
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
17116
|
-
defaultSpaceCreationHandler: () =>
|
|
17117
|
-
deriveSignedReceiverKey: () =>
|
|
17120
|
+
defaultSpaceCreationHandler: () => import_sdk_core11.defaultSpaceCreationHandler,
|
|
17121
|
+
deriveSignedReceiverKey: () => import_sdk_core17.deriveSignedReceiverKey,
|
|
17118
17122
|
deserializeDelegation: () => deserializeDelegation,
|
|
17119
|
-
didCacheKey: () =>
|
|
17120
|
-
didEquals: () =>
|
|
17121
|
-
disableTinyCloudDebug: () =>
|
|
17122
|
-
discoverNetwork: () =>
|
|
17123
|
-
enableTinyCloudDebug: () =>
|
|
17124
|
-
encryptToNetwork: () =>
|
|
17125
|
-
encryptionBase64Decode: () =>
|
|
17126
|
-
encryptionBase64Encode: () =>
|
|
17127
|
-
encryptionError: () =>
|
|
17128
|
-
encryptionUtf8Decode: () =>
|
|
17129
|
-
encryptionUtf8Encode: () =>
|
|
17130
|
-
ensureNetworkUsableForDecrypt: () =>
|
|
17131
|
-
expandActionShortNames: () =>
|
|
17132
|
-
expandPermissionEntries: () =>
|
|
17133
|
-
expandPermissionEntry: () =>
|
|
17134
|
-
generateRandomReceiverKey: () =>
|
|
17135
|
-
getTinyCloudDebugLogs: () =>
|
|
17123
|
+
didCacheKey: () => import_sdk_core11.didCacheKey,
|
|
17124
|
+
didEquals: () => import_sdk_core11.didEquals,
|
|
17125
|
+
disableTinyCloudDebug: () => import_sdk_core11.disableTinyCloudDebug,
|
|
17126
|
+
discoverNetwork: () => import_sdk_core17.discoverNetwork,
|
|
17127
|
+
enableTinyCloudDebug: () => import_sdk_core11.enableTinyCloudDebug,
|
|
17128
|
+
encryptToNetwork: () => import_sdk_core17.encryptToNetwork,
|
|
17129
|
+
encryptionBase64Decode: () => import_sdk_core17.encryptionBase64Decode,
|
|
17130
|
+
encryptionBase64Encode: () => import_sdk_core17.encryptionBase64Encode,
|
|
17131
|
+
encryptionError: () => import_sdk_core17.encryptionError,
|
|
17132
|
+
encryptionUtf8Decode: () => import_sdk_core17.encryptionUtf8Decode,
|
|
17133
|
+
encryptionUtf8Encode: () => import_sdk_core17.encryptionUtf8Encode,
|
|
17134
|
+
ensureNetworkUsableForDecrypt: () => import_sdk_core17.ensureNetworkUsableForDecrypt,
|
|
17135
|
+
expandActionShortNames: () => import_sdk_core12.expandActionShortNames,
|
|
17136
|
+
expandPermissionEntries: () => import_sdk_core12.expandPermissionEntries,
|
|
17137
|
+
expandPermissionEntry: () => import_sdk_core12.expandPermissionEntry,
|
|
17138
|
+
generateRandomReceiverKey: () => import_sdk_core17.generateRandomReceiverKey,
|
|
17139
|
+
getTinyCloudDebugLogs: () => import_sdk_core11.getTinyCloudDebugLogs,
|
|
17136
17140
|
grantAuthRequest: () => grantAuthRequest,
|
|
17137
|
-
hexDecode: () =>
|
|
17138
|
-
hexEncode: () =>
|
|
17139
|
-
installTinyCloudDebugGlobals: () =>
|
|
17140
|
-
isCapabilitySubset: () =>
|
|
17141
|
-
isEvmAddress: () =>
|
|
17142
|
-
isNetworkId: () =>
|
|
17143
|
-
loadManifest: () =>
|
|
17144
|
-
makePkhSpaceId: () =>
|
|
17145
|
-
makePublicSpaceId: () =>
|
|
17146
|
-
networkDiscoveryKey: () =>
|
|
17147
|
-
openWrappedKey: () =>
|
|
17148
|
-
parseCanonicalNetworkId: () =>
|
|
17149
|
-
parseExpiry: () =>
|
|
17150
|
-
parseNetworkId: () =>
|
|
17151
|
-
parsePkhDid: () =>
|
|
17152
|
-
parseSpaceUri: () =>
|
|
17153
|
-
pkhDid: () =>
|
|
17154
|
-
principalDid: () =>
|
|
17155
|
-
principalDidEquals: () =>
|
|
17156
|
-
resolveManifest: () =>
|
|
17157
|
-
resolveSecretListPrefix: () =>
|
|
17158
|
-
resolveSecretPath: () =>
|
|
17159
|
-
resourceCapabilitiesToSpaceAbilitiesMap: () =>
|
|
17141
|
+
hexDecode: () => import_sdk_core17.hexDecode,
|
|
17142
|
+
hexEncode: () => import_sdk_core17.hexEncode,
|
|
17143
|
+
installTinyCloudDebugGlobals: () => import_sdk_core11.installTinyCloudDebugGlobals,
|
|
17144
|
+
isCapabilitySubset: () => import_sdk_core12.isCapabilitySubset,
|
|
17145
|
+
isEvmAddress: () => import_sdk_core11.isEvmAddress,
|
|
17146
|
+
isNetworkId: () => import_sdk_core17.isNetworkId,
|
|
17147
|
+
loadManifest: () => import_sdk_core12.loadManifest,
|
|
17148
|
+
makePkhSpaceId: () => import_sdk_core11.makePkhSpaceId,
|
|
17149
|
+
makePublicSpaceId: () => import_sdk_core21.makePublicSpaceId,
|
|
17150
|
+
networkDiscoveryKey: () => import_sdk_core17.networkDiscoveryKey,
|
|
17151
|
+
openWrappedKey: () => import_sdk_core17.openWrappedKey,
|
|
17152
|
+
parseCanonicalNetworkId: () => import_sdk_core11.parseCanonicalNetworkId,
|
|
17153
|
+
parseExpiry: () => import_sdk_core12.parseExpiry,
|
|
17154
|
+
parseNetworkId: () => import_sdk_core17.parseNetworkId,
|
|
17155
|
+
parsePkhDid: () => import_sdk_core11.parsePkhDid,
|
|
17156
|
+
parseSpaceUri: () => import_sdk_core21.parseSpaceUri,
|
|
17157
|
+
pkhDid: () => import_sdk_core11.pkhDid,
|
|
17158
|
+
principalDid: () => import_sdk_core11.principalDid,
|
|
17159
|
+
principalDidEquals: () => import_sdk_core11.principalDidEquals,
|
|
17160
|
+
resolveManifest: () => import_sdk_core12.resolveManifest,
|
|
17161
|
+
resolveSecretListPrefix: () => import_sdk_core16.resolveSecretListPrefix,
|
|
17162
|
+
resolveSecretPath: () => import_sdk_core16.resolveSecretPath,
|
|
17163
|
+
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core12.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
17160
17164
|
serializeDelegation: () => serializeDelegation,
|
|
17161
|
-
tinyCloudDebugLogger: () =>
|
|
17162
|
-
validateEnvelope: () =>
|
|
17163
|
-
validateManifest: () =>
|
|
17164
|
-
verifyDecryptResponse: () =>
|
|
17165
|
+
tinyCloudDebugLogger: () => import_sdk_core11.tinyCloudDebugLogger,
|
|
17166
|
+
validateEnvelope: () => import_sdk_core17.validateEnvelope,
|
|
17167
|
+
validateManifest: () => import_sdk_core12.validateManifest,
|
|
17168
|
+
verifyDecryptResponse: () => import_sdk_core17.verifyDecryptResponse
|
|
17165
17169
|
});
|
|
17166
17170
|
module.exports = __toCommonJS(index_exports);
|
|
17167
17171
|
|
|
@@ -17178,6 +17182,7 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17178
17182
|
this.makeSpaceId = import_node_sdk_wasm.makeSpaceId;
|
|
17179
17183
|
this.createDelegation = import_node_sdk_wasm.createDelegation;
|
|
17180
17184
|
this.parseRecapFromSiwe = import_node_sdk_wasm.parseRecapFromSiwe;
|
|
17185
|
+
this.parseVerifiedRecapFromSiwe = import_node_sdk_wasm.parseVerifiedRecapFromSiwe;
|
|
17181
17186
|
this.generateHostSIWEMessage = import_node_sdk_wasm.generateHostSIWEMessage;
|
|
17182
17187
|
this.siweToDelegationHeaders = import_node_sdk_wasm.siweToDelegationHeaders;
|
|
17183
17188
|
this.protocolVersion = import_node_sdk_wasm.protocolVersion;
|
|
@@ -17194,6 +17199,9 @@ var _NodeWasmBindings = class _NodeWasmBindings {
|
|
|
17194
17199
|
_NodeWasmBindings.panicHookInitialized = true;
|
|
17195
17200
|
}
|
|
17196
17201
|
}
|
|
17202
|
+
validatePersistedSession(proof) {
|
|
17203
|
+
return (0, import_node_sdk_wasm.validatePersistedSession)(proof);
|
|
17204
|
+
}
|
|
17197
17205
|
createSessionManager() {
|
|
17198
17206
|
return new import_node_sdk_wasm.TCWSessionManager();
|
|
17199
17207
|
}
|
|
@@ -17267,6 +17275,7 @@ var PrivateKeySigner = class {
|
|
|
17267
17275
|
|
|
17268
17276
|
// src/TinyCloudNode.ts
|
|
17269
17277
|
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
17278
|
+
var import_sdk_services = require("@tinycloud/sdk-services");
|
|
17270
17279
|
|
|
17271
17280
|
// src/authorization/NodeUserAuthorization.ts
|
|
17272
17281
|
var import_sdk_core2 = require("@tinycloud/sdk-core");
|
|
@@ -17487,6 +17496,30 @@ var NodeUserAuthorization = class {
|
|
|
17487
17496
|
this.tinycloudHosts = [...hosts];
|
|
17488
17497
|
}
|
|
17489
17498
|
}
|
|
17499
|
+
/** @internal Atomically adopt the state staged by TinyCloudNode.restoreSession. */
|
|
17500
|
+
installRestoredSession(sessionManager, session, hosts) {
|
|
17501
|
+
this.sessionManager = sessionManager;
|
|
17502
|
+
this.tinycloudHosts = hosts && hosts.length > 0 ? [...hosts] : void 0;
|
|
17503
|
+
this._lastActivationSkippedSpaceIds = [];
|
|
17504
|
+
if (!session) {
|
|
17505
|
+
this._session = void 0;
|
|
17506
|
+
this._tinyCloudSession = void 0;
|
|
17507
|
+
this._address = void 0;
|
|
17508
|
+
this._chainId = void 0;
|
|
17509
|
+
return;
|
|
17510
|
+
}
|
|
17511
|
+
this._tinyCloudSession = { ...session };
|
|
17512
|
+
this._address = session.address;
|
|
17513
|
+
this._chainId = session.chainId;
|
|
17514
|
+
this._session = {
|
|
17515
|
+
address: session.address,
|
|
17516
|
+
walletAddress: session.address,
|
|
17517
|
+
chainId: session.chainId,
|
|
17518
|
+
sessionKey: session.sessionKey,
|
|
17519
|
+
siwe: session.siwe,
|
|
17520
|
+
signature: session.signature
|
|
17521
|
+
};
|
|
17522
|
+
}
|
|
17490
17523
|
/**
|
|
17491
17524
|
* Ensure `tinycloudHosts` are resolved before a host-needing call.
|
|
17492
17525
|
*
|
|
@@ -18678,6 +18711,9 @@ var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
|
18678
18711
|
var NETWORK_CREATE_ACTION2 = import_sdk_core7.ENCRYPTION.NETWORK_CREATE;
|
|
18679
18712
|
var DECRYPT_ACTION2 = import_sdk_core7.ENCRYPTION.DECRYPT;
|
|
18680
18713
|
var NETWORK_ADMIN_TYPE = "tinycloud.encryption.network-admin/v1";
|
|
18714
|
+
function isSecretPayload(value) {
|
|
18715
|
+
return typeof value === "object" && value !== null && "value" in value && typeof value.value === "string" && "createdAt" in value && typeof value.createdAt === "string" && "updatedAt" in value && typeof value.updatedAt === "string";
|
|
18716
|
+
}
|
|
18681
18717
|
var ROOT_DELEGATION_ACTIONS = [
|
|
18682
18718
|
import_sdk_core7.KV.PUT,
|
|
18683
18719
|
import_sdk_core7.KV.GET,
|
|
@@ -18732,6 +18768,141 @@ function didPrincipalMatches2(actual, expected) {
|
|
|
18732
18768
|
return actual === expected;
|
|
18733
18769
|
}
|
|
18734
18770
|
}
|
|
18771
|
+
function clonePersistedSessionJwk(jwk) {
|
|
18772
|
+
if (jwk === null || typeof jwk !== "object" || Array.isArray(jwk)) {
|
|
18773
|
+
throw new Error("Persisted session has an invalid private Ed25519 session key.");
|
|
18774
|
+
}
|
|
18775
|
+
try {
|
|
18776
|
+
const serialized = JSON.stringify(jwk);
|
|
18777
|
+
const cloned = serialized === void 0 ? void 0 : JSON.parse(serialized);
|
|
18778
|
+
if (cloned === null || typeof cloned !== "object" || Array.isArray(cloned)) {
|
|
18779
|
+
throw new Error("invalid JWK object");
|
|
18780
|
+
}
|
|
18781
|
+
return cloned;
|
|
18782
|
+
} catch {
|
|
18783
|
+
throw new Error("Persisted session has an invalid private Ed25519 session key.");
|
|
18784
|
+
}
|
|
18785
|
+
}
|
|
18786
|
+
function cloneRecapCaveats(caveats) {
|
|
18787
|
+
if (!caveats) return [];
|
|
18788
|
+
const cloneJson = (value) => {
|
|
18789
|
+
if (value === null || typeof value === "boolean" || typeof value === "string") {
|
|
18790
|
+
return value;
|
|
18791
|
+
}
|
|
18792
|
+
if (typeof value === "number") {
|
|
18793
|
+
if (Number.isFinite(value)) return value;
|
|
18794
|
+
throw new Error("ReCap caveats must contain only JSON values.");
|
|
18795
|
+
}
|
|
18796
|
+
if (Array.isArray(value)) return value.map(cloneJson);
|
|
18797
|
+
if (typeof value === "object") {
|
|
18798
|
+
const prototype = Object.getPrototypeOf(value);
|
|
18799
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
18800
|
+
throw new Error("ReCap caveats must contain only JSON values.");
|
|
18801
|
+
}
|
|
18802
|
+
const copy = /* @__PURE__ */ Object.create(null);
|
|
18803
|
+
for (const [key2, nested] of Object.entries(value)) {
|
|
18804
|
+
copy[key2] = cloneJson(nested);
|
|
18805
|
+
}
|
|
18806
|
+
return copy;
|
|
18807
|
+
}
|
|
18808
|
+
throw new Error("ReCap caveats must contain only JSON values.");
|
|
18809
|
+
};
|
|
18810
|
+
try {
|
|
18811
|
+
return JSON.parse(JSON.stringify(caveats.map(cloneJson)));
|
|
18812
|
+
} catch {
|
|
18813
|
+
throw new Error("Verified persisted session ReCap contains invalid caveats.");
|
|
18814
|
+
}
|
|
18815
|
+
}
|
|
18816
|
+
var ServiceGraphLifetime = class {
|
|
18817
|
+
constructor(invokeFn, invokeAnyFn, fetchFn) {
|
|
18818
|
+
this.invokeFn = invokeFn;
|
|
18819
|
+
this.invokeAnyFn = invokeAnyFn;
|
|
18820
|
+
this.fetchFn = fetchFn;
|
|
18821
|
+
this.abortController = new AbortController();
|
|
18822
|
+
this.contexts = /* @__PURE__ */ new Set();
|
|
18823
|
+
this.retired = false;
|
|
18824
|
+
this.invoke = (session, service, path, action, facts) => {
|
|
18825
|
+
this.assertActive();
|
|
18826
|
+
return this.invokeFn(session, service, path, action, facts);
|
|
18827
|
+
};
|
|
18828
|
+
this.invokeAny = (session, entries, facts) => {
|
|
18829
|
+
this.assertActive();
|
|
18830
|
+
return this.invokeAnyFn(session, entries, facts);
|
|
18831
|
+
};
|
|
18832
|
+
this.fetch = (url, init2) => {
|
|
18833
|
+
this.assertActive();
|
|
18834
|
+
return this.fetchFn(url, {
|
|
18835
|
+
...init2,
|
|
18836
|
+
signal: this.combineSignals(init2?.signal)
|
|
18837
|
+
});
|
|
18838
|
+
};
|
|
18839
|
+
}
|
|
18840
|
+
track(context) {
|
|
18841
|
+
this.assertActive();
|
|
18842
|
+
this.contexts.add(context);
|
|
18843
|
+
return context;
|
|
18844
|
+
}
|
|
18845
|
+
retire() {
|
|
18846
|
+
if (this.retired) return;
|
|
18847
|
+
this.retired = true;
|
|
18848
|
+
this.abortController.abort();
|
|
18849
|
+
try {
|
|
18850
|
+
for (const context of this.contexts) {
|
|
18851
|
+
try {
|
|
18852
|
+
const retire = context.retire;
|
|
18853
|
+
if (retire) retire.call(context);
|
|
18854
|
+
else context.abort();
|
|
18855
|
+
} catch (error) {
|
|
18856
|
+
console.error("Error retiring service graph context:", error);
|
|
18857
|
+
}
|
|
18858
|
+
}
|
|
18859
|
+
} finally {
|
|
18860
|
+
this.contexts.clear();
|
|
18861
|
+
}
|
|
18862
|
+
}
|
|
18863
|
+
assertActive() {
|
|
18864
|
+
if (this.retired) {
|
|
18865
|
+
throw new Error("Service graph has been retired by session replacement.");
|
|
18866
|
+
}
|
|
18867
|
+
}
|
|
18868
|
+
combineSignals(signal) {
|
|
18869
|
+
if (!signal) return this.abortController.signal;
|
|
18870
|
+
const combined = new AbortController();
|
|
18871
|
+
const abort = () => combined.abort();
|
|
18872
|
+
if (signal.aborted || this.abortController.signal.aborted) {
|
|
18873
|
+
abort();
|
|
18874
|
+
} else {
|
|
18875
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
18876
|
+
this.abortController.signal.addEventListener("abort", abort, { once: true });
|
|
18877
|
+
}
|
|
18878
|
+
return combined.signal;
|
|
18879
|
+
}
|
|
18880
|
+
};
|
|
18881
|
+
var UnsupportedSessionRestoreError = class extends Error {
|
|
18882
|
+
constructor(reason = "it cannot replace and enumerate every live session signer") {
|
|
18883
|
+
super(`Persisted session restore is unsupported by this WASM binding because ${reason}.`);
|
|
18884
|
+
this.code = "RESTORE_SESSION_KEY_REPLACEMENT_UNSUPPORTED";
|
|
18885
|
+
this.name = "UnsupportedSessionRestoreError";
|
|
18886
|
+
}
|
|
18887
|
+
};
|
|
18888
|
+
function canonicalRestoredVerificationMethod(canonicalVerificationMethod, persistedVerificationMethod) {
|
|
18889
|
+
if (typeof persistedVerificationMethod !== "string") return void 0;
|
|
18890
|
+
const principal = canonicalVerificationMethod.split("#", 1)[0];
|
|
18891
|
+
return persistedVerificationMethod === principal || persistedVerificationMethod === canonicalVerificationMethod ? canonicalVerificationMethod : void 0;
|
|
18892
|
+
}
|
|
18893
|
+
function persistedExpiry(value) {
|
|
18894
|
+
if (typeof value !== "string") {
|
|
18895
|
+
throw new Error("Persisted session without a SIWE expiration must include expiresAt.");
|
|
18896
|
+
}
|
|
18897
|
+
const expiry = new Date(value);
|
|
18898
|
+
if (!Number.isFinite(expiry.getTime()) || expiry.getTime() <= Date.now()) {
|
|
18899
|
+
throw new Error("Persisted session expiry is invalid or expired.");
|
|
18900
|
+
}
|
|
18901
|
+
return expiry;
|
|
18902
|
+
}
|
|
18903
|
+
function sameInstant(left, right) {
|
|
18904
|
+
return left.getTime() === right.getTime();
|
|
18905
|
+
}
|
|
18735
18906
|
function sharingActionsToAbilities(path, actions) {
|
|
18736
18907
|
var _a;
|
|
18737
18908
|
const abilities = {};
|
|
@@ -18858,6 +19029,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18858
19029
|
this.auth = null;
|
|
18859
19030
|
this.tc = null;
|
|
18860
19031
|
this._chainId = 1;
|
|
19032
|
+
this._baseVaults = /* @__PURE__ */ new Map();
|
|
18861
19033
|
this._baseSecrets = /* @__PURE__ */ new Map();
|
|
18862
19034
|
this._secrets = /* @__PURE__ */ new Map();
|
|
18863
19035
|
this.runtimePermissionGrants = [];
|
|
@@ -18877,26 +19049,55 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18877
19049
|
skipped: false
|
|
18878
19050
|
};
|
|
18879
19051
|
this.invokeWithRuntimePermissions = (session, service, path, action, facts) => {
|
|
18880
|
-
|
|
18881
|
-
|
|
18882
|
-
service,
|
|
19052
|
+
const operation = {
|
|
19053
|
+
spaceId: session.spaceId,
|
|
19054
|
+
service: this.invocationServiceName(service),
|
|
18883
19055
|
path,
|
|
18884
|
-
action
|
|
18885
|
-
|
|
19056
|
+
action
|
|
19057
|
+
};
|
|
19058
|
+
const grant = this.findGrantForOperation(operation);
|
|
19059
|
+
const grantedOperation = grant?.operations.find(
|
|
19060
|
+
(candidate) => this.operationCovers(candidate, operation)
|
|
18886
19061
|
);
|
|
19062
|
+
const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
|
|
19063
|
+
if ((grantedOperation?.caveats?.length ?? 0) > 0) {
|
|
19064
|
+
if (!this.wasmBindings.invokeAny) {
|
|
19065
|
+
throw new Error("WASM binding does not support caveat-preserving invocation");
|
|
19066
|
+
}
|
|
19067
|
+
return this.wasmBindings.invokeAny(invocationSession, [{
|
|
19068
|
+
spaceId: invocationSession.spaceId,
|
|
19069
|
+
service,
|
|
19070
|
+
path,
|
|
19071
|
+
action,
|
|
19072
|
+
caveats: cloneRecapCaveats(grantedOperation.caveats)
|
|
19073
|
+
}], facts);
|
|
19074
|
+
}
|
|
19075
|
+
return this.wasmBindings.invoke(invocationSession, service, path, action, facts);
|
|
18887
19076
|
};
|
|
18888
19077
|
this.invokeAnyWithRuntimePermissions = (session, entries, facts) => {
|
|
18889
19078
|
if (!this.wasmBindings.invokeAny) {
|
|
18890
19079
|
throw new Error("WASM binding does not support invokeAny");
|
|
18891
19080
|
}
|
|
18892
|
-
const
|
|
18893
|
-
|
|
18894
|
-
|
|
18895
|
-
|
|
18896
|
-
|
|
18897
|
-
);
|
|
19081
|
+
const operations = entries.flatMap((entry) => {
|
|
19082
|
+
const operation = this.operationFromInvokeAnyEntry(entry);
|
|
19083
|
+
return operation ? [operation] : [];
|
|
19084
|
+
});
|
|
19085
|
+
const grant = this.findGrantForOperations(operations);
|
|
18898
19086
|
const invocationSession = !grant || grant.provenance === "primary" ? session : grant.session;
|
|
18899
|
-
|
|
19087
|
+
const caveatPreservingEntries = grant ? entries.map((entry) => {
|
|
19088
|
+
const requested = this.operationFromInvokeAnyEntry(entry);
|
|
19089
|
+
const granted = requested && grant.operations.find(
|
|
19090
|
+
(candidate) => this.operationCovers(candidate, requested)
|
|
19091
|
+
);
|
|
19092
|
+
if (!granted?.caveats?.length) {
|
|
19093
|
+
return entry;
|
|
19094
|
+
}
|
|
19095
|
+
if (entry.caveats !== void 0 && !(0, import_sdk_core7.recapCaveatsEqual)(entry.caveats, granted.caveats)) {
|
|
19096
|
+
throw new Error("Invocation caveats do not match signed ReCap authority.");
|
|
19097
|
+
}
|
|
19098
|
+
return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
|
|
19099
|
+
}) : entries;
|
|
19100
|
+
return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
|
|
18900
19101
|
};
|
|
18901
19102
|
this.explicitHost = config.host;
|
|
18902
19103
|
this.config = {
|
|
@@ -18925,16 +19126,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18925
19126
|
throw new Error("Failed to get session key JWK");
|
|
18926
19127
|
}
|
|
18927
19128
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
19129
|
+
this._serviceGraph = this.createServiceGraphLifetime();
|
|
18928
19130
|
this._capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
|
|
18929
19131
|
this._keyProvider = new WasmKeyProvider({
|
|
18930
19132
|
sessionManager: this.sessionManager
|
|
18931
19133
|
});
|
|
18932
19134
|
this.notificationHandler = config.notificationHandler ?? new import_sdk_core7.SilentNotificationHandler();
|
|
19135
|
+
const receiveOnlyGraph = this._serviceGraph;
|
|
18933
19136
|
this._sharingService = new import_sdk_core7.SharingService({
|
|
18934
19137
|
hosts: [this.config.host],
|
|
18935
19138
|
// session: undefined - not needed for receive()
|
|
18936
|
-
invoke:
|
|
18937
|
-
fetch:
|
|
19139
|
+
invoke: receiveOnlyGraph.invoke,
|
|
19140
|
+
fetch: receiveOnlyGraph.fetch,
|
|
19141
|
+
assertActive: () => receiveOnlyGraph.assertActive(),
|
|
18938
19142
|
keyProvider: this._keyProvider,
|
|
18939
19143
|
registry: this._capabilityRegistry,
|
|
18940
19144
|
createDelegationWasm: (params) => this.createDelegationWrapper(params),
|
|
@@ -18946,12 +19150,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
18946
19150
|
createKVService: (config2) => {
|
|
18947
19151
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
18948
19152
|
const kvService = new import_sdk_core7.KVService({ prefix });
|
|
18949
|
-
const kvContext = new import_sdk_core7.ServiceContext({
|
|
19153
|
+
const kvContext = receiveOnlyGraph.track(new import_sdk_core7.ServiceContext({
|
|
18950
19154
|
invoke: config2.invoke,
|
|
18951
19155
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
18952
19156
|
hosts: config2.hosts,
|
|
18953
19157
|
telemetry: this.config.telemetry
|
|
18954
|
-
});
|
|
19158
|
+
}));
|
|
18955
19159
|
kvContext.setSession(config2.session);
|
|
18956
19160
|
kvService.initialize(kvContext);
|
|
18957
19161
|
return kvService;
|
|
@@ -19025,6 +19229,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19025
19229
|
shouldUseBootstrapSignInRequest(config) {
|
|
19026
19230
|
return config.autoBootstrapAccount !== false && config.manifest === void 0 && config.capabilityRequest === void 0 && (config.prefix ?? "default") === "default" && isOpenKeyAutoSignStrategy(config.signStrategy);
|
|
19027
19231
|
}
|
|
19232
|
+
createServiceGraphLifetime() {
|
|
19233
|
+
return new ServiceGraphLifetime(
|
|
19234
|
+
this.invokeWithRuntimePermissions,
|
|
19235
|
+
this.invokeAnyWithRuntimePermissions,
|
|
19236
|
+
// Resolve fetch at request time. This keeps the graph-owned lifetime
|
|
19237
|
+
// signal while preserving the SDK's existing injectable global fetch
|
|
19238
|
+
// behavior (including adapters that install it after construction).
|
|
19239
|
+
(url, init2) => globalThis.fetch(url, init2)
|
|
19240
|
+
);
|
|
19241
|
+
}
|
|
19028
19242
|
syncResolvedHostFromAuth() {
|
|
19029
19243
|
const host = this.auth?.hosts[0];
|
|
19030
19244
|
if (host) {
|
|
@@ -19094,6 +19308,27 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19094
19308
|
get sessionDid() {
|
|
19095
19309
|
return this.sessionManager.getDID(this.sessionKeyId);
|
|
19096
19310
|
}
|
|
19311
|
+
/**
|
|
19312
|
+
* Return the current session's signed ReCap capabilities after the session
|
|
19313
|
+
* has been authenticated or restored. This is intentionally distinct from
|
|
19314
|
+
* installed runtime delegations: it reports base-session authority only.
|
|
19315
|
+
*
|
|
19316
|
+
* Invalid or unparseable signed ReCap material throws so callers fail closed
|
|
19317
|
+
* rather than treating a malformed session as unrestricted authority.
|
|
19318
|
+
*/
|
|
19319
|
+
getVerifiedSessionCapabilities() {
|
|
19320
|
+
const session = this.currentTinyCloudSession();
|
|
19321
|
+
if (!session || !session.siwe) return [];
|
|
19322
|
+
return (0, import_sdk_core7.parseRecapCapabilities)(
|
|
19323
|
+
(siwe) => this.parseRecapWithCaveats(siwe),
|
|
19324
|
+
session.siwe
|
|
19325
|
+
).map((entry) => entry.service === "tinycloud.encryption" ? {
|
|
19326
|
+
service: entry.service,
|
|
19327
|
+
path: entry.path,
|
|
19328
|
+
actions: [...entry.actions],
|
|
19329
|
+
...entry.caveats === void 0 ? {} : { caveats: entry.caveats }
|
|
19330
|
+
} : entry);
|
|
19331
|
+
}
|
|
19097
19332
|
/**
|
|
19098
19333
|
* Get the Ethereum address for this user.
|
|
19099
19334
|
*/
|
|
@@ -19136,6 +19371,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19136
19371
|
getPrimarySpaceId: () => this.spaceId,
|
|
19137
19372
|
getAccountSpaceId: () => this.accountSpaceId,
|
|
19138
19373
|
getSpaces: () => this.spaces,
|
|
19374
|
+
getDelegationManager: () => this.delegationManager,
|
|
19139
19375
|
getAccountDb: () => this.accountSpaceId ? this.sqlForSpace(this.accountSpaceId).db("account") : void 0,
|
|
19140
19376
|
ensureAccountSpaceHosted: async () => {
|
|
19141
19377
|
if (this.accountSpaceId && this.auth) {
|
|
@@ -19182,6 +19418,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19182
19418
|
this._hooks = void 0;
|
|
19183
19419
|
this._vault = void 0;
|
|
19184
19420
|
this._encryption = void 0;
|
|
19421
|
+
this._baseVaults.clear();
|
|
19185
19422
|
this._baseSecrets.clear();
|
|
19186
19423
|
this._secrets.clear();
|
|
19187
19424
|
this._spaceService = void 0;
|
|
@@ -19189,6 +19426,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19189
19426
|
this.runtimePermissionGrants = [];
|
|
19190
19427
|
await this.tc.signIn(options);
|
|
19191
19428
|
this.syncResolvedHostFromAuth();
|
|
19429
|
+
const oldGraph = this._serviceGraph;
|
|
19430
|
+
this._serviceGraph = this.createServiceGraphLifetime();
|
|
19431
|
+
oldGraph.retire();
|
|
19432
|
+
this.tc.retireServices();
|
|
19192
19433
|
const signedInSession = this.currentTinyCloudSession();
|
|
19193
19434
|
if (signedInSession) {
|
|
19194
19435
|
this.sessionKeyId = signedInSession.sessionKey;
|
|
@@ -19473,7 +19714,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19473
19714
|
}
|
|
19474
19715
|
let operations = [];
|
|
19475
19716
|
try {
|
|
19476
|
-
const entries = this.
|
|
19717
|
+
const entries = this.parseRecapWithCaveats(siwe);
|
|
19477
19718
|
if (Array.isArray(entries)) {
|
|
19478
19719
|
operations = entries.flatMap((entry) => {
|
|
19479
19720
|
const service = this.invocationServiceName(entry.service);
|
|
@@ -19481,7 +19722,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19481
19722
|
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
|
|
19482
19723
|
service,
|
|
19483
19724
|
path: entry.path,
|
|
19484
|
-
action
|
|
19725
|
+
action,
|
|
19726
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
19485
19727
|
}));
|
|
19486
19728
|
});
|
|
19487
19729
|
}
|
|
@@ -19834,86 +20076,441 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
19834
20076
|
*/
|
|
19835
20077
|
async restoreSession(sessionData) {
|
|
19836
20078
|
await this.wasmBindings.ensureInitialized?.();
|
|
19837
|
-
|
|
19838
|
-
|
|
19839
|
-
|
|
19840
|
-
|
|
19841
|
-
|
|
19842
|
-
|
|
19843
|
-
this.
|
|
19844
|
-
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19849
|
-
|
|
19850
|
-
|
|
20079
|
+
const restoredJwk = clonePersistedSessionJwk(sessionData.jwk);
|
|
20080
|
+
if (sessionData.chainId !== void 0 && (!Number.isSafeInteger(sessionData.chainId) || sessionData.chainId <= 0)) {
|
|
20081
|
+
throw new Error("Persisted session chain ID must be a positive safe integer.");
|
|
20082
|
+
}
|
|
20083
|
+
const stagedManager = this.wasmBindings.createSessionManager();
|
|
20084
|
+
const stagedReplace = stagedManager.replaceSessionKey;
|
|
20085
|
+
const liveKeys = this.sessionManager.listSessionKeys;
|
|
20086
|
+
const stagedKeys = stagedManager.listSessionKeys;
|
|
20087
|
+
if (typeof stagedReplace !== "function" || typeof liveKeys !== "function" || typeof stagedKeys !== "function") {
|
|
20088
|
+
throw new UnsupportedSessionRestoreError();
|
|
20089
|
+
}
|
|
20090
|
+
let stagedKeyId;
|
|
20091
|
+
let stagedJwk;
|
|
20092
|
+
let canonicalVerificationMethod;
|
|
20093
|
+
try {
|
|
20094
|
+
const keyIds = liveKeys.call(this.sessionManager);
|
|
20095
|
+
if (!Array.isArray(keyIds) || !keyIds.every((keyId) => typeof keyId === "string")) {
|
|
20096
|
+
throw new UnsupportedSessionRestoreError("it cannot reliably enumerate every live session signer");
|
|
20097
|
+
}
|
|
20098
|
+
for (const keyId of keyIds) {
|
|
20099
|
+
if (keyId === this.sessionKeyId) continue;
|
|
20100
|
+
const jwk = this.sessionManager.jwk(keyId);
|
|
20101
|
+
if (!jwk) throw new Error("missing live session key");
|
|
20102
|
+
stagedReplace.call(stagedManager, clonePersistedSessionJwk(JSON.parse(jwk)), keyId);
|
|
20103
|
+
}
|
|
20104
|
+
stagedKeyId = stagedReplace.call(stagedManager, restoredJwk, this.sessionKeyId);
|
|
20105
|
+
const stagedJwkJson = stagedManager.jwk(stagedKeyId);
|
|
20106
|
+
if (!stagedJwkJson) throw new Error("missing restored session key");
|
|
20107
|
+
stagedJwk = clonePersistedSessionJwk(JSON.parse(stagedJwkJson));
|
|
20108
|
+
canonicalVerificationMethod = stagedManager.getDID(stagedKeyId);
|
|
20109
|
+
} catch (error) {
|
|
20110
|
+
if (error instanceof UnsupportedSessionRestoreError) throw error;
|
|
20111
|
+
throw new Error("Persisted session has an invalid private Ed25519 session key.");
|
|
19851
20112
|
}
|
|
19852
|
-
|
|
19853
|
-
|
|
20113
|
+
const restoredVerificationMethod = canonicalRestoredVerificationMethod(
|
|
20114
|
+
canonicalVerificationMethod,
|
|
20115
|
+
sessionData.verificationMethod
|
|
20116
|
+
);
|
|
20117
|
+
if (!restoredVerificationMethod) {
|
|
20118
|
+
throw new Error(
|
|
20119
|
+
"Persisted session verification method does not match its private Ed25519 session key."
|
|
20120
|
+
);
|
|
20121
|
+
}
|
|
20122
|
+
const proofValues = [
|
|
20123
|
+
sessionData.siwe,
|
|
20124
|
+
sessionData.signature,
|
|
20125
|
+
sessionData.address,
|
|
20126
|
+
sessionData.chainId
|
|
20127
|
+
];
|
|
20128
|
+
const hasPersistedProof = proofValues.every((value) => value !== void 0);
|
|
20129
|
+
if (!hasPersistedProof && (proofValues.some((value) => value !== void 0) || sessionData.expiresAt !== void 0)) {
|
|
20130
|
+
throw new Error("Persisted session authority metadata is incomplete.");
|
|
20131
|
+
}
|
|
20132
|
+
const restoredAddress = hasPersistedProof ? (0, import_sdk_core7.canonicalizeAddress)(sessionData.address) : void 0;
|
|
20133
|
+
let stagedSessionExpiry = /* @__PURE__ */ new Date(0);
|
|
20134
|
+
let stagedRecap = [];
|
|
20135
|
+
if (hasPersistedProof) {
|
|
20136
|
+
if (typeof this.wasmBindings.validatePersistedSession !== "function") {
|
|
20137
|
+
throw new UnsupportedSessionRestoreError("it cannot verify persisted SIWE authority");
|
|
20138
|
+
}
|
|
20139
|
+
const verified = this.wasmBindings.validatePersistedSession({
|
|
20140
|
+
delegationHeader: sessionData.delegationHeader,
|
|
20141
|
+
delegationCid: sessionData.delegationCid,
|
|
20142
|
+
spaceId: sessionData.spaceId,
|
|
20143
|
+
jwk: stagedJwk,
|
|
20144
|
+
address: restoredAddress,
|
|
20145
|
+
chainId: sessionData.chainId,
|
|
20146
|
+
siwe: sessionData.siwe,
|
|
20147
|
+
signature: sessionData.signature
|
|
20148
|
+
});
|
|
20149
|
+
const exactRecap = verified.verifiedRecap;
|
|
20150
|
+
if (!Array.isArray(exactRecap) || !exactRecap.every(
|
|
20151
|
+
(entry) => entry !== null && typeof entry === "object" && typeof entry.service === "string" && typeof entry.space === "string" && typeof entry.path === "string" && Array.isArray(entry.actions) && entry.actions.every((action) => typeof action === "string") && Array.isArray(entry.caveats) && entry.caveats.every(
|
|
20152
|
+
(caveat) => caveat !== null && typeof caveat === "object" && !Array.isArray(caveat)
|
|
20153
|
+
)
|
|
20154
|
+
)) {
|
|
20155
|
+
throw new UnsupportedSessionRestoreError(
|
|
20156
|
+
"it cannot reconstruct caveat-preserving persisted ReCap authority"
|
|
20157
|
+
);
|
|
20158
|
+
}
|
|
20159
|
+
stagedRecap = exactRecap.map((entry) => ({
|
|
20160
|
+
service: entry.service,
|
|
20161
|
+
space: entry.space,
|
|
20162
|
+
path: entry.path,
|
|
20163
|
+
actions: [...entry.actions],
|
|
20164
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
20165
|
+
}));
|
|
20166
|
+
const signedExpiry = verified.expiresAt === void 0 ? void 0 : persistedExpiry(verified.expiresAt);
|
|
20167
|
+
const persistedPolicyExpiry = sessionData.expiresAt === void 0 ? void 0 : persistedExpiry(sessionData.expiresAt);
|
|
20168
|
+
if (signedExpiry && persistedPolicyExpiry && !sameInstant(signedExpiry, persistedPolicyExpiry)) {
|
|
20169
|
+
throw new Error("Persisted session expiry does not match its signed SIWE authority.");
|
|
20170
|
+
}
|
|
20171
|
+
stagedSessionExpiry = signedExpiry ?? persistedPolicyExpiry ?? persistedExpiry(void 0);
|
|
19854
20172
|
}
|
|
19855
20173
|
const resolvedHost = await this.resolveRestoredHost(
|
|
19856
20174
|
sessionData.tinycloudHosts,
|
|
19857
20175
|
restoredAddress,
|
|
19858
20176
|
sessionData.chainId
|
|
19859
20177
|
);
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
|
|
19864
|
-
invoke: this.invokeWithRuntimePermissions,
|
|
19865
|
-
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
19866
|
-
fetch: globalThis.fetch.bind(globalThis),
|
|
19867
|
-
hosts: [this.config.host],
|
|
19868
|
-
telemetry: this.config.telemetry
|
|
19869
|
-
});
|
|
19870
|
-
this._kv = new import_sdk_core7.KVService({});
|
|
19871
|
-
this._kv.initialize(this._serviceContext);
|
|
19872
|
-
this._serviceContext.registerService("kv", this._kv);
|
|
19873
|
-
this._sql = new import_sdk_core7.SQLService({});
|
|
19874
|
-
this._sql.initialize(this._serviceContext);
|
|
19875
|
-
this._serviceContext.registerService("sql", this._sql);
|
|
19876
|
-
this._duckdb = new import_sdk_core7.DuckDbService({});
|
|
19877
|
-
this._duckdb.initialize(this._serviceContext);
|
|
19878
|
-
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
19879
|
-
this._hooks = new import_sdk_core7.HooksService({});
|
|
19880
|
-
this._hooks.initialize(this._serviceContext);
|
|
19881
|
-
this._serviceContext.registerService("hooks", this._hooks);
|
|
20178
|
+
const stagedHost = resolvedHost ?? this.config.host;
|
|
20179
|
+
const stagedAddress = restoredAddress;
|
|
20180
|
+
const stagedChainId = sessionData.chainId ?? 1;
|
|
20181
|
+
const stagedNodeDid = stagedAddress ? (0, import_sdk_core7.pkhDid)(stagedAddress, stagedChainId) : canonicalVerificationMethod;
|
|
19882
20182
|
const serviceSession = {
|
|
19883
20183
|
delegationHeader: sessionData.delegationHeader,
|
|
19884
20184
|
delegationCid: sessionData.delegationCid,
|
|
19885
20185
|
spaceId: sessionData.spaceId,
|
|
19886
|
-
verificationMethod:
|
|
19887
|
-
jwk:
|
|
20186
|
+
verificationMethod: restoredVerificationMethod,
|
|
20187
|
+
jwk: stagedJwk
|
|
19888
20188
|
};
|
|
19889
|
-
|
|
19890
|
-
|
|
19891
|
-
|
|
19892
|
-
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
|
|
19897
|
-
|
|
19898
|
-
|
|
19899
|
-
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
|
|
19908
|
-
|
|
19909
|
-
|
|
19910
|
-
|
|
20189
|
+
const stagedTcSession = hasPersistedProof ? {
|
|
20190
|
+
address: restoredAddress,
|
|
20191
|
+
chainId: sessionData.chainId,
|
|
20192
|
+
sessionKey: JSON.stringify(stagedJwk),
|
|
20193
|
+
spaceId: sessionData.spaceId,
|
|
20194
|
+
spaces: sessionData.spaces,
|
|
20195
|
+
delegationCid: sessionData.delegationCid,
|
|
20196
|
+
delegationHeader: sessionData.delegationHeader,
|
|
20197
|
+
verificationMethod: restoredVerificationMethod,
|
|
20198
|
+
jwk: stagedJwk,
|
|
20199
|
+
siwe: sessionData.siwe,
|
|
20200
|
+
signature: sessionData.signature
|
|
20201
|
+
} : void 0;
|
|
20202
|
+
const stagedPrimary = this.stagePrimarySessionState(
|
|
20203
|
+
stagedTcSession,
|
|
20204
|
+
stagedNodeDid,
|
|
20205
|
+
stagedHost,
|
|
20206
|
+
stagedSessionExpiry,
|
|
20207
|
+
stagedRecap
|
|
20208
|
+
);
|
|
20209
|
+
const stagedGraph = this.stageRestoredServiceGraph({
|
|
20210
|
+
host: stagedHost,
|
|
20211
|
+
manager: stagedManager,
|
|
20212
|
+
serviceSession,
|
|
20213
|
+
verificationMethod: canonicalVerificationMethod,
|
|
20214
|
+
nodeDid: stagedNodeDid,
|
|
20215
|
+
address: stagedAddress,
|
|
20216
|
+
chainId: stagedChainId,
|
|
20217
|
+
tinyCloudSession: stagedTcSession,
|
|
20218
|
+
sessionExpiry: stagedSessionExpiry,
|
|
20219
|
+
recap: stagedRecap
|
|
20220
|
+
});
|
|
20221
|
+
const oldGraph = this._serviceGraph;
|
|
20222
|
+
const oldCore = this.tc;
|
|
20223
|
+
this.sessionManager = stagedManager;
|
|
20224
|
+
this.sessionKeyId = stagedKeyId;
|
|
20225
|
+
this.sessionKeyJwk = stagedJwk;
|
|
20226
|
+
if (resolvedHost) this.config.host = resolvedHost;
|
|
20227
|
+
this._address = stagedAddress;
|
|
20228
|
+
this._chainId = stagedChainId;
|
|
20229
|
+
this._serviceContext = stagedGraph.serviceContext;
|
|
20230
|
+
this._kv = stagedGraph.kv;
|
|
20231
|
+
this._sql = stagedGraph.sql;
|
|
20232
|
+
this._duckdb = stagedGraph.duckdb;
|
|
20233
|
+
this._hooks = stagedGraph.hooks;
|
|
20234
|
+
this._vault = stagedGraph.vault;
|
|
20235
|
+
this._encryption = stagedGraph.encryption;
|
|
20236
|
+
this._capabilityRegistry = stagedGraph.capabilityRegistry;
|
|
20237
|
+
this._keyProvider = stagedGraph.keyProvider;
|
|
20238
|
+
this._sharingService = stagedGraph.sharingService;
|
|
20239
|
+
this._delegationManager = stagedGraph.delegationManager;
|
|
20240
|
+
this._spaceService = stagedGraph.spaceService;
|
|
20241
|
+
this._serviceGraph = stagedGraph.graph;
|
|
20242
|
+
this._baseSecrets = /* @__PURE__ */ new Map();
|
|
20243
|
+
this._secrets = /* @__PURE__ */ new Map();
|
|
20244
|
+
this._publicKV = void 0;
|
|
20245
|
+
this._account = void 0;
|
|
20246
|
+
this.tc = stagedGraph.core;
|
|
20247
|
+
this._recapOperationsCache = stagedPrimary.cache;
|
|
20248
|
+
this.runtimePermissionGrants = stagedPrimary.grants;
|
|
20249
|
+
if (this.auth) {
|
|
20250
|
+
this.auth.installRestoredSession(stagedManager, stagedTcSession, [stagedHost]);
|
|
20251
|
+
this._restoredTcSession = void 0;
|
|
20252
|
+
} else {
|
|
20253
|
+
this._restoredTcSession = stagedTcSession;
|
|
20254
|
+
}
|
|
20255
|
+
oldGraph.retire();
|
|
20256
|
+
oldCore?.retireServices?.();
|
|
20257
|
+
}
|
|
20258
|
+
stagePrimarySessionState(session, verificationMethod, host, sessionExpiry, recap) {
|
|
20259
|
+
if (!session?.siwe) return { cache: void 0, grants: [] };
|
|
20260
|
+
let operations = [];
|
|
20261
|
+
operations = recap.flatMap((entry) => {
|
|
20262
|
+
const service = this.invocationServiceName(entry.service);
|
|
20263
|
+
return entry.actions.map((action) => ({
|
|
20264
|
+
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId: entry.space },
|
|
20265
|
+
service,
|
|
20266
|
+
path: entry.path,
|
|
20267
|
+
action,
|
|
20268
|
+
caveats: cloneRecapCaveats(entry.caveats)
|
|
20269
|
+
}));
|
|
20270
|
+
});
|
|
20271
|
+
const cache = { siwe: session.siwe, operations };
|
|
20272
|
+
if (operations.length === 0) return { cache, grants: [] };
|
|
20273
|
+
const expiresAt = sessionExpiry;
|
|
20274
|
+
return {
|
|
20275
|
+
cache,
|
|
20276
|
+
grants: [{
|
|
20277
|
+
session: {
|
|
20278
|
+
delegationHeader: session.delegationHeader,
|
|
20279
|
+
delegationCid: session.delegationCid,
|
|
20280
|
+
spaceId: session.spaceId,
|
|
20281
|
+
verificationMethod: session.verificationMethod,
|
|
20282
|
+
jwk: session.jwk
|
|
20283
|
+
},
|
|
20284
|
+
delegation: {
|
|
20285
|
+
cid: session.delegationCid,
|
|
20286
|
+
delegationHeader: session.delegationHeader,
|
|
20287
|
+
delegateDID: session.verificationMethod,
|
|
20288
|
+
delegatorDID: verificationMethod,
|
|
20289
|
+
spaceId: session.spaceId,
|
|
20290
|
+
path: "",
|
|
20291
|
+
actions: [...new Set(operations.map((operation) => operation.action))],
|
|
20292
|
+
expiry: expiresAt,
|
|
20293
|
+
allowSubDelegation: true,
|
|
20294
|
+
ownerAddress: session.address,
|
|
20295
|
+
chainId: session.chainId,
|
|
20296
|
+
host
|
|
20297
|
+
},
|
|
20298
|
+
operations,
|
|
20299
|
+
expiresAt,
|
|
20300
|
+
provenance: "primary"
|
|
20301
|
+
}]
|
|
20302
|
+
};
|
|
20303
|
+
}
|
|
20304
|
+
stageRestoredServiceGraph(input) {
|
|
20305
|
+
const graph = this.createServiceGraphLifetime();
|
|
20306
|
+
const core = this.auth ? new import_sdk_core7.TinyCloud(this.auth, {
|
|
20307
|
+
invokeAny: graph.invokeAny,
|
|
20308
|
+
telemetry: this.config.telemetry
|
|
20309
|
+
}) : null;
|
|
20310
|
+
if (core) {
|
|
20311
|
+
core.initializeServices(graph.invoke, [input.host], graph.fetch);
|
|
20312
|
+
const coreContext = graph.track(core.serviceContext);
|
|
20313
|
+
coreContext.setSession(input.serviceSession);
|
|
20314
|
+
}
|
|
20315
|
+
const serviceContext = graph.track(new import_sdk_core7.ServiceContext({
|
|
20316
|
+
invoke: graph.invoke,
|
|
20317
|
+
invokeAny: graph.invokeAny,
|
|
20318
|
+
fetch: graph.fetch,
|
|
20319
|
+
hosts: [input.host],
|
|
20320
|
+
telemetry: this.config.telemetry
|
|
20321
|
+
}));
|
|
20322
|
+
const kv = new import_sdk_core7.KVService({});
|
|
20323
|
+
kv.initialize(serviceContext);
|
|
20324
|
+
serviceContext.registerService("kv", kv);
|
|
20325
|
+
const sql = new import_sdk_core7.SQLService({});
|
|
20326
|
+
sql.initialize(serviceContext);
|
|
20327
|
+
serviceContext.registerService("sql", sql);
|
|
20328
|
+
const duckdb = new import_sdk_core7.DuckDbService({});
|
|
20329
|
+
duckdb.initialize(serviceContext);
|
|
20330
|
+
serviceContext.registerService("duckdb", duckdb);
|
|
20331
|
+
const hooks = new import_sdk_core7.HooksService({});
|
|
20332
|
+
hooks.initialize(serviceContext);
|
|
20333
|
+
serviceContext.registerService("hooks", hooks);
|
|
20334
|
+
serviceContext.setSession(input.serviceSession);
|
|
20335
|
+
const encryption = this.createEncryptionService({
|
|
20336
|
+
graph,
|
|
20337
|
+
host: input.host,
|
|
20338
|
+
session: input.serviceSession,
|
|
20339
|
+
did: input.nodeDid,
|
|
20340
|
+
address: input.address,
|
|
20341
|
+
chainId: input.chainId
|
|
20342
|
+
});
|
|
20343
|
+
encryption.initialize(serviceContext);
|
|
20344
|
+
serviceContext.registerService("encryption", encryption);
|
|
20345
|
+
const vault = this.createVaultService(input.serviceSession.spaceId, kv, encryption, {
|
|
20346
|
+
host: input.host,
|
|
20347
|
+
did: input.nodeDid,
|
|
20348
|
+
address: input.address,
|
|
20349
|
+
chainId: input.chainId,
|
|
20350
|
+
serviceGraph: graph
|
|
20351
|
+
});
|
|
20352
|
+
vault.initialize(serviceContext);
|
|
20353
|
+
serviceContext.registerService("vault", vault);
|
|
20354
|
+
const capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
|
|
20355
|
+
if (input.tinyCloudSession) {
|
|
20356
|
+
const session = input.tinyCloudSession;
|
|
20357
|
+
const delegations = input.recap.map((entry) => ({
|
|
20358
|
+
cid: session.delegationCid,
|
|
20359
|
+
delegateDID: session.verificationMethod,
|
|
20360
|
+
spaceId: entry.space,
|
|
20361
|
+
path: entry.path,
|
|
20362
|
+
actions: [...entry.actions],
|
|
20363
|
+
caveats: cloneRecapCaveats(entry.caveats),
|
|
20364
|
+
expiry: input.sessionExpiry,
|
|
20365
|
+
isRevoked: false,
|
|
20366
|
+
allowSubDelegation: true
|
|
20367
|
+
}));
|
|
20368
|
+
if (delegations.length > 0) {
|
|
20369
|
+
capabilityRegistry.registerKey({
|
|
20370
|
+
id: session.sessionKey,
|
|
20371
|
+
did: session.verificationMethod,
|
|
20372
|
+
type: "session",
|
|
20373
|
+
jwk: session.jwk,
|
|
20374
|
+
priority: 0
|
|
20375
|
+
}, delegations);
|
|
20376
|
+
}
|
|
20377
|
+
}
|
|
20378
|
+
const delegationManager = new import_sdk_core7.DelegationManager({
|
|
20379
|
+
hosts: [input.host],
|
|
20380
|
+
session: input.serviceSession,
|
|
20381
|
+
invoke: graph.invoke,
|
|
20382
|
+
invokeAny: graph.invokeAny,
|
|
20383
|
+
fetch: graph.fetch
|
|
20384
|
+
});
|
|
20385
|
+
const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
|
|
20386
|
+
const sharingService = new import_sdk_core7.SharingService({
|
|
20387
|
+
hosts: [input.host],
|
|
20388
|
+
invoke: graph.invoke,
|
|
20389
|
+
fetch: graph.fetch,
|
|
20390
|
+
assertActive: () => graph.assertActive(),
|
|
20391
|
+
keyProvider,
|
|
20392
|
+
registry: capabilityRegistry,
|
|
20393
|
+
createDelegationWasm: (params) => this.createDelegationWrapper(params),
|
|
20394
|
+
computeCid: (data, codec) => {
|
|
20395
|
+
if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
|
|
20396
|
+
return this.wasmBindings.computeCid(data, codec);
|
|
20397
|
+
},
|
|
20398
|
+
createKVService: (config) => {
|
|
20399
|
+
const service = new import_sdk_core7.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
20400
|
+
const context = graph.track(new import_sdk_core7.ServiceContext({
|
|
20401
|
+
invoke: config.invoke,
|
|
20402
|
+
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
20403
|
+
hosts: config.hosts,
|
|
20404
|
+
telemetry: this.config.telemetry
|
|
20405
|
+
}));
|
|
20406
|
+
context.setSession(config.session);
|
|
20407
|
+
service.initialize(context);
|
|
20408
|
+
return service;
|
|
20409
|
+
}
|
|
20410
|
+
});
|
|
20411
|
+
sharingService.updateConfig({
|
|
20412
|
+
session: input.serviceSession,
|
|
20413
|
+
delegationManager,
|
|
20414
|
+
sessionExpiry: input.sessionExpiry,
|
|
20415
|
+
createDelegationWasm: (params) => {
|
|
20416
|
+
graph.assertActive();
|
|
20417
|
+
return this.createDelegationWrapper(params);
|
|
20418
|
+
},
|
|
20419
|
+
onRootDelegationNeeded: this.signer ? async (params) => {
|
|
20420
|
+
graph.assertActive();
|
|
20421
|
+
const delegation = await this.createRootDelegationForSharing(
|
|
20422
|
+
params,
|
|
20423
|
+
() => graph.assertActive()
|
|
19911
20424
|
);
|
|
19912
|
-
|
|
19913
|
-
|
|
20425
|
+
graph.assertActive();
|
|
20426
|
+
return delegation;
|
|
20427
|
+
} : void 0
|
|
20428
|
+
});
|
|
20429
|
+
const spaceService = new import_sdk_core7.SpaceService({
|
|
20430
|
+
hosts: [input.host],
|
|
20431
|
+
session: input.serviceSession,
|
|
20432
|
+
invoke: graph.invoke,
|
|
20433
|
+
fetch: graph.fetch,
|
|
20434
|
+
capabilityRegistry,
|
|
20435
|
+
userDid: input.nodeDid,
|
|
20436
|
+
createKVService: (spaceId) => {
|
|
20437
|
+
graph.assertActive();
|
|
20438
|
+
const scopedKv = new import_sdk_core7.KVService({});
|
|
20439
|
+
const context = graph.track(new import_sdk_core7.ServiceContext({
|
|
20440
|
+
invoke: graph.invoke,
|
|
20441
|
+
invokeAny: graph.invokeAny,
|
|
20442
|
+
fetch: graph.fetch,
|
|
20443
|
+
hosts: [input.host],
|
|
20444
|
+
telemetry: this.config.telemetry
|
|
20445
|
+
}));
|
|
20446
|
+
context.setSession({ ...input.serviceSession, spaceId });
|
|
20447
|
+
scopedKv.initialize(context);
|
|
20448
|
+
return scopedKv;
|
|
20449
|
+
},
|
|
20450
|
+
createVaultService: (spaceId) => {
|
|
20451
|
+
graph.assertActive();
|
|
20452
|
+
const scopedKv = new import_sdk_core7.KVService({});
|
|
20453
|
+
const context = graph.track(new import_sdk_core7.ServiceContext({
|
|
20454
|
+
invoke: graph.invoke,
|
|
20455
|
+
invokeAny: graph.invokeAny,
|
|
20456
|
+
fetch: graph.fetch,
|
|
20457
|
+
hosts: [input.host],
|
|
20458
|
+
telemetry: this.config.telemetry
|
|
20459
|
+
}));
|
|
20460
|
+
context.setSession({ ...input.serviceSession, spaceId });
|
|
20461
|
+
scopedKv.initialize(context);
|
|
20462
|
+
const scopedVault = this.createVaultService(spaceId, scopedKv, encryption, {
|
|
20463
|
+
host: input.host,
|
|
20464
|
+
did: input.nodeDid,
|
|
20465
|
+
address: input.address,
|
|
20466
|
+
chainId: input.chainId,
|
|
20467
|
+
serviceGraph: graph
|
|
20468
|
+
});
|
|
20469
|
+
scopedVault.initialize(context);
|
|
20470
|
+
return scopedVault;
|
|
20471
|
+
},
|
|
20472
|
+
createSecretsService: (spaceId) => {
|
|
20473
|
+
graph.assertActive();
|
|
20474
|
+
return this.secretsForSpace(spaceId);
|
|
20475
|
+
},
|
|
20476
|
+
createDelegation: async (params) => {
|
|
20477
|
+
graph.assertActive();
|
|
20478
|
+
try {
|
|
20479
|
+
const portableDelegation = await this.createDelegation({
|
|
20480
|
+
delegateDID: params.delegateDID,
|
|
20481
|
+
path: params.path,
|
|
20482
|
+
actions: params.actions,
|
|
20483
|
+
disableSubDelegation: params.disableSubDelegation,
|
|
20484
|
+
expiryMs: params.expiry ? params.expiry.getTime() - Date.now() : void 0
|
|
20485
|
+
});
|
|
20486
|
+
return { ok: true, data: {
|
|
20487
|
+
cid: portableDelegation.cid,
|
|
20488
|
+
delegateDID: portableDelegation.delegateDID,
|
|
20489
|
+
delegatorDID: this.did,
|
|
20490
|
+
spaceId: portableDelegation.spaceId,
|
|
20491
|
+
path: portableDelegation.path,
|
|
20492
|
+
actions: portableDelegation.actions,
|
|
20493
|
+
expiry: portableDelegation.expiry,
|
|
20494
|
+
isRevoked: false,
|
|
20495
|
+
allowSubDelegation: !portableDelegation.disableSubDelegation,
|
|
20496
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
20497
|
+
authHeader: portableDelegation.delegationHeader.Authorization
|
|
20498
|
+
} };
|
|
20499
|
+
} catch (error) {
|
|
20500
|
+
return { ok: false, error: {
|
|
20501
|
+
code: "CREATION_FAILED",
|
|
20502
|
+
message: error instanceof Error ? error.message : String(error),
|
|
20503
|
+
service: "delegation"
|
|
20504
|
+
} };
|
|
20505
|
+
}
|
|
20506
|
+
},
|
|
20507
|
+
onSpaceRegistered: async (space) => {
|
|
20508
|
+
graph.assertActive();
|
|
20509
|
+
await this.account.spaces.register(space);
|
|
19914
20510
|
}
|
|
19915
|
-
|
|
19916
|
-
}
|
|
20511
|
+
});
|
|
20512
|
+
spaceService.updateConfig({ sharingService });
|
|
20513
|
+
return { core, graph, serviceContext, kv, sql, duckdb, hooks, vault, encryption, capabilityRegistry, keyProvider, sharingService, delegationManager, spaceService };
|
|
19917
20514
|
}
|
|
19918
20515
|
/**
|
|
19919
20516
|
* Resolve the host a restored session should target.
|
|
@@ -20075,14 +20672,19 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20075
20672
|
if (!session) {
|
|
20076
20673
|
return;
|
|
20077
20674
|
}
|
|
20078
|
-
this.tc.initializeServices(
|
|
20079
|
-
|
|
20080
|
-
|
|
20081
|
-
|
|
20082
|
-
|
|
20675
|
+
this.tc.initializeServices(
|
|
20676
|
+
this._serviceGraph.invoke,
|
|
20677
|
+
[this.config.host],
|
|
20678
|
+
this._serviceGraph.fetch
|
|
20679
|
+
);
|
|
20680
|
+
this._serviceGraph.track(this.tc.serviceContext);
|
|
20681
|
+
this._serviceContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
|
|
20682
|
+
invoke: this._serviceGraph.invoke,
|
|
20683
|
+
invokeAny: this._serviceGraph.invokeAny,
|
|
20684
|
+
fetch: this._serviceGraph.fetch,
|
|
20083
20685
|
hosts: [this.config.host],
|
|
20084
20686
|
telemetry: this.config.telemetry
|
|
20085
|
-
});
|
|
20687
|
+
}));
|
|
20086
20688
|
this._kv = new import_sdk_core7.KVService({});
|
|
20087
20689
|
this._kv.initialize(this._serviceContext);
|
|
20088
20690
|
this._serviceContext.registerService("kv", this._kv);
|
|
@@ -20117,12 +20719,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20117
20719
|
createSpaceScopedKVService(spaceId) {
|
|
20118
20720
|
const kvService = new import_sdk_core7.KVService({});
|
|
20119
20721
|
if (this._serviceContext) {
|
|
20120
|
-
const spaceScopedContext = new import_sdk_core7.ServiceContext({
|
|
20722
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
|
|
20121
20723
|
invoke: this._serviceContext.invoke,
|
|
20122
20724
|
fetch: this._serviceContext.fetch,
|
|
20123
20725
|
hosts: this._serviceContext.hosts,
|
|
20124
20726
|
telemetry: this.config.telemetry
|
|
20125
|
-
});
|
|
20727
|
+
}));
|
|
20126
20728
|
const session = this._serviceContext.session;
|
|
20127
20729
|
if (session) {
|
|
20128
20730
|
spaceScopedContext.setSession({ ...session, spaceId });
|
|
@@ -20155,6 +20757,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20155
20757
|
}
|
|
20156
20758
|
return session;
|
|
20157
20759
|
}
|
|
20760
|
+
/**
|
|
20761
|
+
* Runtime-permission helpers can be used from an authenticated Node session
|
|
20762
|
+
* before its public ServiceContext is initialized. They still need the
|
|
20763
|
+
* current signed session, never an optional or stale authority object.
|
|
20764
|
+
*/
|
|
20765
|
+
requireEncryptionSession() {
|
|
20766
|
+
const session = this._serviceContext?.session ?? this.auth?.tinyCloudSession;
|
|
20767
|
+
if (!session) {
|
|
20768
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
20769
|
+
}
|
|
20770
|
+
return session;
|
|
20771
|
+
}
|
|
20158
20772
|
createEncryptionCrypto() {
|
|
20159
20773
|
const wasm = this.wasmBindings;
|
|
20160
20774
|
const columnEncrypt = (key2, plaintext) => {
|
|
@@ -20210,14 +20824,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20210
20824
|
}
|
|
20211
20825
|
return info.nodeId;
|
|
20212
20826
|
}
|
|
20213
|
-
async signRawNetworkAuthorization(input) {
|
|
20827
|
+
async signRawNetworkAuthorization(input, binding) {
|
|
20828
|
+
binding?.graph.assertActive();
|
|
20214
20829
|
if (!this.wasmBindings.invokeAny) {
|
|
20215
20830
|
throw new Error("WASM binding does not support raw-resource invokeAny");
|
|
20216
20831
|
}
|
|
20217
20832
|
if (!this.wasmBindings.computeCid) {
|
|
20218
20833
|
throw new Error("WASM binding does not support invocation CID computation");
|
|
20219
20834
|
}
|
|
20220
|
-
const session = this.
|
|
20835
|
+
const session = binding?.session ?? this.requireEncryptionSession();
|
|
20221
20836
|
const headers = this.invokeAnyWithRuntimePermissions(
|
|
20222
20837
|
session,
|
|
20223
20838
|
[
|
|
@@ -20236,6 +20851,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20236
20851
|
input.targetNode,
|
|
20237
20852
|
session.jwk
|
|
20238
20853
|
);
|
|
20854
|
+
binding?.graph.assertActive();
|
|
20239
20855
|
return {
|
|
20240
20856
|
authorization: audienceBound,
|
|
20241
20857
|
invocationCid: this.wasmBindings.computeCid(
|
|
@@ -20244,25 +20860,55 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20244
20860
|
)
|
|
20245
20861
|
};
|
|
20246
20862
|
}
|
|
20247
|
-
|
|
20863
|
+
async fetchEncryptionNetworkAt(host, networkId, fetchFn) {
|
|
20864
|
+
const response = await fetchFn(
|
|
20865
|
+
`${host}/encryption/networks/${encodeURIComponent(networkId)}`
|
|
20866
|
+
);
|
|
20867
|
+
if (response.status === 404) return null;
|
|
20868
|
+
if (!response.ok) {
|
|
20869
|
+
throw new Error(
|
|
20870
|
+
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
20871
|
+
);
|
|
20872
|
+
}
|
|
20873
|
+
const body = await response.json();
|
|
20874
|
+
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
20875
|
+
}
|
|
20876
|
+
createEncryptionService(binding) {
|
|
20877
|
+
const graph = binding?.graph ?? this._serviceGraph;
|
|
20878
|
+
const host = binding?.host ?? this.config.host;
|
|
20879
|
+
const session = binding?.session ?? this.requireEncryptionSession();
|
|
20880
|
+
const did = binding?.did ?? this.did;
|
|
20881
|
+
const address = binding?.address ?? this._address;
|
|
20882
|
+
const chainId = binding?.chainId ?? this._chainId;
|
|
20248
20883
|
const crypto2 = this.createEncryptionCrypto();
|
|
20249
20884
|
const transport = {
|
|
20250
|
-
postDecrypt: async ({ networkId, authorization, canonicalBody }) => {
|
|
20251
|
-
|
|
20252
|
-
|
|
20885
|
+
postDecrypt: async ({ networkId, authorization, canonicalBody, signal }) => {
|
|
20886
|
+
graph.assertActive();
|
|
20887
|
+
const response = await graph.fetch(
|
|
20888
|
+
`${host}/encryption/networks/${encodeURIComponent(networkId)}/decrypt`,
|
|
20253
20889
|
{
|
|
20254
20890
|
method: "POST",
|
|
20255
20891
|
headers: {
|
|
20256
20892
|
Authorization: authorization,
|
|
20257
20893
|
"Content-Type": "application/json"
|
|
20258
20894
|
},
|
|
20259
|
-
body: canonicalBody
|
|
20895
|
+
body: canonicalBody,
|
|
20896
|
+
signal
|
|
20260
20897
|
}
|
|
20261
20898
|
);
|
|
20899
|
+
graph.assertActive();
|
|
20262
20900
|
if (!response.ok) {
|
|
20263
|
-
|
|
20264
|
-
|
|
20265
|
-
|
|
20901
|
+
let permissionHint;
|
|
20902
|
+
if (response.status === 401 || response.status === 403) {
|
|
20903
|
+
try {
|
|
20904
|
+
const body = await response.json();
|
|
20905
|
+
const record = typeof body === "object" && body !== null ? body : void 0;
|
|
20906
|
+
const nested = typeof record?.error === "object" && record.error !== null ? record.error : void 0;
|
|
20907
|
+
permissionHint = (0, import_sdk_services.parsePermissionHint)(record?.permissionHint) ?? (0, import_sdk_services.parsePermissionHint)(nested?.permissionHint);
|
|
20908
|
+
} catch {
|
|
20909
|
+
}
|
|
20910
|
+
}
|
|
20911
|
+
throw new import_sdk_core7.DecryptTransportResponseError(response.status, permissionHint);
|
|
20266
20912
|
}
|
|
20267
20913
|
return await response.json();
|
|
20268
20914
|
}
|
|
@@ -20271,12 +20917,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20271
20917
|
crypto: crypto2,
|
|
20272
20918
|
signer: {
|
|
20273
20919
|
signDecryptInvocation: async (input) => {
|
|
20920
|
+
graph.assertActive();
|
|
20274
20921
|
const signed2 = await this.signRawNetworkAuthorization({
|
|
20275
20922
|
targetNode: input.targetNode,
|
|
20276
20923
|
networkId: input.networkId,
|
|
20277
20924
|
action: DECRYPT_ACTION2,
|
|
20278
20925
|
facts: input.facts
|
|
20279
|
-
});
|
|
20926
|
+
}, { graph, session });
|
|
20927
|
+
graph.assertActive();
|
|
20280
20928
|
return {
|
|
20281
20929
|
...signed2,
|
|
20282
20930
|
canonicalBody: (0, import_sdk_core7.canonicalizeEncryptionJson)(
|
|
@@ -20287,25 +20935,35 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20287
20935
|
},
|
|
20288
20936
|
transport,
|
|
20289
20937
|
node: {
|
|
20290
|
-
fetchByNetworkId: (networkId) =>
|
|
20938
|
+
fetchByNetworkId: async (networkId) => {
|
|
20939
|
+
graph.assertActive();
|
|
20940
|
+
const descriptor = await this.fetchEncryptionNetworkAt(host, networkId, graph.fetch);
|
|
20941
|
+
graph.assertActive();
|
|
20942
|
+
return descriptor;
|
|
20943
|
+
}
|
|
20291
20944
|
},
|
|
20292
20945
|
wellKnown: {
|
|
20293
20946
|
fetchWellKnown: async (principal, discoveryKey) => {
|
|
20294
|
-
|
|
20295
|
-
|
|
20296
|
-
}
|
|
20297
|
-
if (!this.config.host) {
|
|
20947
|
+
graph.assertActive();
|
|
20948
|
+
if (!address || !didPrincipalMatches2(principal, did)) {
|
|
20298
20949
|
return null;
|
|
20299
20950
|
}
|
|
20300
|
-
const publicSpaceId = (0, import_sdk_core7.makePublicSpaceId)(
|
|
20301
|
-
const
|
|
20302
|
-
|
|
20951
|
+
const publicSpaceId = (0, import_sdk_core7.makePublicSpaceId)(address, chainId);
|
|
20952
|
+
const encodedKey = discoveryKey.split("/").map(encodeURIComponent).join("/");
|
|
20953
|
+
const response = await graph.fetch(
|
|
20954
|
+
`${host}/public/${encodeURIComponent(publicSpaceId)}/kv/${encodedKey}`,
|
|
20955
|
+
{ method: "GET" }
|
|
20956
|
+
);
|
|
20957
|
+
graph.assertActive();
|
|
20958
|
+
if (!response.ok) {
|
|
20303
20959
|
return null;
|
|
20304
20960
|
}
|
|
20305
|
-
const body =
|
|
20961
|
+
const body = await response.json();
|
|
20962
|
+
graph.assertActive();
|
|
20306
20963
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
20307
20964
|
}
|
|
20308
|
-
}
|
|
20965
|
+
},
|
|
20966
|
+
assertActive: () => graph.assertActive()
|
|
20309
20967
|
});
|
|
20310
20968
|
}
|
|
20311
20969
|
getEncryptionService() {
|
|
@@ -20319,8 +20977,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20319
20977
|
}
|
|
20320
20978
|
return this._encryption;
|
|
20321
20979
|
}
|
|
20322
|
-
createVaultService(spaceId, kv) {
|
|
20980
|
+
createVaultService(spaceId, kv, encryptionService = this.getEncryptionService(), nodeContext) {
|
|
20323
20981
|
const wasm = this.wasmBindings;
|
|
20982
|
+
const serviceGraph = nodeContext?.serviceGraph ?? this._serviceGraph;
|
|
20324
20983
|
const vaultCrypto = (0, import_sdk_core7.createVaultCrypto)({
|
|
20325
20984
|
vault_encrypt: wasm.vault_encrypt,
|
|
20326
20985
|
vault_decrypt: wasm.vault_decrypt,
|
|
@@ -20331,12 +20990,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20331
20990
|
vault_sha256: wasm.vault_sha256
|
|
20332
20991
|
});
|
|
20333
20992
|
const self2 = this;
|
|
20993
|
+
const did = nodeContext?.did ?? this.did;
|
|
20994
|
+
const address = nodeContext?.address ?? this._address;
|
|
20995
|
+
const chainId = nodeContext?.chainId ?? this._chainId;
|
|
20996
|
+
const host = nodeContext?.host ?? this.config.host;
|
|
20997
|
+
const ownerDid = this.ownerDidFromSpaceId(spaceId) ?? did;
|
|
20334
20998
|
return new import_sdk_core7.DataVaultService({
|
|
20335
20999
|
spaceId,
|
|
20336
21000
|
crypto: vaultCrypto,
|
|
20337
21001
|
encryption: {
|
|
20338
|
-
networkId:
|
|
20339
|
-
service:
|
|
21002
|
+
networkId: `urn:tinycloud:encryption:${ownerDid}:${DEFAULT_ENCRYPTION_NETWORK_NAME}`,
|
|
21003
|
+
service: encryptionService,
|
|
20340
21004
|
decryptCapabilityProof: () => ({
|
|
20341
21005
|
proofs: [this.requireServiceSession().delegationCid]
|
|
20342
21006
|
})
|
|
@@ -20345,6 +21009,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20345
21009
|
kv,
|
|
20346
21010
|
ensurePublicSpace: async () => {
|
|
20347
21011
|
try {
|
|
21012
|
+
serviceGraph.assertActive();
|
|
20348
21013
|
await self2.ensurePublicSpace();
|
|
20349
21014
|
return { ok: true, data: void 0 };
|
|
20350
21015
|
} catch (error) {
|
|
@@ -20352,14 +21017,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20352
21017
|
}
|
|
20353
21018
|
},
|
|
20354
21019
|
get publicKV() {
|
|
21020
|
+
serviceGraph.assertActive();
|
|
20355
21021
|
return self2._publicKV ?? self2.tc.publicKV;
|
|
20356
21022
|
},
|
|
20357
|
-
readPublicSpace: (
|
|
21023
|
+
readPublicSpace: (host2, targetSpaceId, key2) => import_sdk_core7.TinyCloud.readPublicSpace(host2, targetSpaceId, key2),
|
|
20358
21024
|
makePublicSpaceId: import_sdk_core7.TinyCloud.makePublicSpaceId,
|
|
20359
|
-
did
|
|
20360
|
-
address:
|
|
20361
|
-
chainId
|
|
20362
|
-
hosts: [
|
|
21025
|
+
did,
|
|
21026
|
+
address: address ?? "",
|
|
21027
|
+
chainId,
|
|
21028
|
+
hosts: [host]
|
|
20363
21029
|
}
|
|
20364
21030
|
});
|
|
20365
21031
|
}
|
|
@@ -20368,6 +21034,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20368
21034
|
* @internal
|
|
20369
21035
|
*/
|
|
20370
21036
|
initializeV2Services(serviceSession) {
|
|
21037
|
+
const graph = this._serviceGraph;
|
|
20371
21038
|
this._capabilityRegistry = new import_sdk_core7.CapabilityKeyRegistry();
|
|
20372
21039
|
const tcSession = this.auth?.tinyCloudSession;
|
|
20373
21040
|
if (tcSession && this._address) {
|
|
@@ -20410,22 +21077,25 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20410
21077
|
}
|
|
20411
21078
|
this._delegationManager = new import_sdk_core7.DelegationManager({
|
|
20412
21079
|
hosts: [this.config.host],
|
|
21080
|
+
accountSpaceId: this.accountSpaceId,
|
|
20413
21081
|
session: serviceSession,
|
|
20414
|
-
invoke:
|
|
20415
|
-
invokeAny:
|
|
20416
|
-
fetch:
|
|
21082
|
+
invoke: graph.invoke,
|
|
21083
|
+
invokeAny: graph.invokeAny,
|
|
21084
|
+
fetch: graph.fetch
|
|
20417
21085
|
});
|
|
20418
21086
|
this._spaceService = new import_sdk_core7.SpaceService({
|
|
20419
21087
|
hosts: [this.config.host],
|
|
20420
21088
|
session: serviceSession,
|
|
20421
|
-
invoke:
|
|
20422
|
-
fetch:
|
|
21089
|
+
invoke: graph.invoke,
|
|
21090
|
+
fetch: graph.fetch,
|
|
20423
21091
|
capabilityRegistry: this._capabilityRegistry,
|
|
20424
21092
|
userDid: this.did,
|
|
20425
21093
|
createKVService: (spaceId) => {
|
|
21094
|
+
graph.assertActive();
|
|
20426
21095
|
return this.createSpaceScopedKVService(spaceId);
|
|
20427
21096
|
},
|
|
20428
21097
|
createVaultService: (spaceId) => {
|
|
21098
|
+
graph.assertActive();
|
|
20429
21099
|
const kvService = this.createSpaceScopedKVService(spaceId);
|
|
20430
21100
|
const vaultService = this.createVaultService(spaceId, kvService);
|
|
20431
21101
|
if (this._serviceContext) {
|
|
@@ -20434,11 +21104,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20434
21104
|
return vaultService;
|
|
20435
21105
|
},
|
|
20436
21106
|
createSecretsService: (spaceId) => {
|
|
21107
|
+
graph.assertActive();
|
|
20437
21108
|
return this.secretsForSpace(spaceId);
|
|
20438
21109
|
},
|
|
20439
21110
|
// Enable space.delegations.create() via SIWE-based delegation
|
|
20440
21111
|
createDelegation: async (params) => {
|
|
20441
21112
|
try {
|
|
21113
|
+
graph.assertActive();
|
|
20442
21114
|
const portableDelegation = await this.createDelegation({
|
|
20443
21115
|
delegateDID: params.delegateDID,
|
|
20444
21116
|
path: params.path,
|
|
@@ -20472,18 +21144,50 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20472
21144
|
}
|
|
20473
21145
|
},
|
|
20474
21146
|
onSpaceRegistered: async (space) => {
|
|
21147
|
+
graph.assertActive();
|
|
20475
21148
|
await this.account.spaces.register(space);
|
|
20476
21149
|
}
|
|
20477
21150
|
});
|
|
20478
|
-
this._sharingService.
|
|
21151
|
+
this._sharingService = new import_sdk_core7.SharingService({
|
|
21152
|
+
hosts: [this.config.host],
|
|
20479
21153
|
session: serviceSession,
|
|
21154
|
+
invoke: graph.invoke,
|
|
21155
|
+
fetch: graph.fetch,
|
|
21156
|
+
assertActive: () => graph.assertActive(),
|
|
21157
|
+
keyProvider: this._keyProvider,
|
|
21158
|
+
registry: this._capabilityRegistry,
|
|
20480
21159
|
delegationManager: this._delegationManager,
|
|
20481
21160
|
sessionExpiry: this.getSessionExpiry(),
|
|
20482
|
-
|
|
20483
|
-
|
|
20484
|
-
|
|
20485
|
-
|
|
20486
|
-
|
|
21161
|
+
createDelegationWasm: (params) => {
|
|
21162
|
+
graph.assertActive();
|
|
21163
|
+
return this.createDelegationWrapper(params);
|
|
21164
|
+
},
|
|
21165
|
+
computeCid: (data, codec) => {
|
|
21166
|
+
if (!this.wasmBindings.computeCid) throw new Error("computeCid is unavailable");
|
|
21167
|
+
return this.wasmBindings.computeCid(data, codec);
|
|
21168
|
+
},
|
|
21169
|
+
createKVService: (config) => {
|
|
21170
|
+
graph.assertActive();
|
|
21171
|
+
const service = new import_sdk_core7.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
21172
|
+
const context = graph.track(new import_sdk_core7.ServiceContext({
|
|
21173
|
+
invoke: config.invoke,
|
|
21174
|
+
fetch: config.fetch ?? graph.fetch,
|
|
21175
|
+
hosts: config.hosts,
|
|
21176
|
+
telemetry: this.config.telemetry
|
|
21177
|
+
}));
|
|
21178
|
+
context.setSession(config.session);
|
|
21179
|
+
service.initialize(context);
|
|
21180
|
+
return service;
|
|
21181
|
+
},
|
|
21182
|
+
onRootDelegationNeeded: this.signer ? async (params) => {
|
|
21183
|
+
graph.assertActive();
|
|
21184
|
+
const delegation = await this.createRootDelegationForSharing(
|
|
21185
|
+
params,
|
|
21186
|
+
() => graph.assertActive()
|
|
21187
|
+
);
|
|
21188
|
+
graph.assertActive();
|
|
21189
|
+
return delegation;
|
|
21190
|
+
} : void 0
|
|
20487
21191
|
});
|
|
20488
21192
|
this._spaceService.updateConfig({
|
|
20489
21193
|
sharingService: this._sharingService
|
|
@@ -20550,7 +21254,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20550
21254
|
* with expiry longer than the current session.
|
|
20551
21255
|
* @internal
|
|
20552
21256
|
*/
|
|
20553
|
-
async createOwnerDelegation(params) {
|
|
21257
|
+
async createOwnerDelegation(params, assertActive) {
|
|
21258
|
+
const assertOwnerGraphActive = assertActive ?? this._serviceGraph.assertActive.bind(this._serviceGraph);
|
|
21259
|
+
assertOwnerGraphActive();
|
|
20554
21260
|
if (!params.delegateDid.startsWith("did:key:") || params.actions.length === 0 || params.path.length === 0) {
|
|
20555
21261
|
throw new Error("Owner delegation requires an external did:key audience and bounded capabilities");
|
|
20556
21262
|
}
|
|
@@ -20575,8 +21281,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20575
21281
|
delegateUri: params.delegateDid
|
|
20576
21282
|
});
|
|
20577
21283
|
const signature2 = await this.signer.signMessage(prepared.siwe);
|
|
21284
|
+
assertOwnerGraphActive();
|
|
20578
21285
|
const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature: signature2 });
|
|
20579
21286
|
const activation = await (0, import_sdk_core7.activateSessionWithHost)(host, delegationSession.delegationHeader);
|
|
21287
|
+
assertOwnerGraphActive();
|
|
20580
21288
|
if (!activation.success) {
|
|
20581
21289
|
throw new Error(`Owner delegation import failed: ${activation.status} ${activation.error ?? ""}`.trim());
|
|
20582
21290
|
}
|
|
@@ -20604,7 +21312,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20604
21312
|
}
|
|
20605
21313
|
};
|
|
20606
21314
|
}
|
|
20607
|
-
async createRootDelegationForSharing(params) {
|
|
21315
|
+
async createRootDelegationForSharing(params, assertActive) {
|
|
20608
21316
|
try {
|
|
20609
21317
|
return (await this.createOwnerDelegation({
|
|
20610
21318
|
delegateDid: params.shareKeyDID,
|
|
@@ -20612,8 +21320,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20612
21320
|
path: params.path,
|
|
20613
21321
|
actions: params.actions,
|
|
20614
21322
|
expiresAt: params.requestedExpiry
|
|
20615
|
-
})).delegation;
|
|
21323
|
+
}, assertActive)).delegation;
|
|
20616
21324
|
} catch {
|
|
21325
|
+
assertActive?.();
|
|
20617
21326
|
return void 0;
|
|
20618
21327
|
}
|
|
20619
21328
|
}
|
|
@@ -20685,13 +21394,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20685
21394
|
throw new Error("Not signed in. Call signIn() first.");
|
|
20686
21395
|
}
|
|
20687
21396
|
const sql = new import_sdk_core7.SQLService({});
|
|
20688
|
-
const spaceScopedContext = new import_sdk_core7.ServiceContext({
|
|
21397
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
|
|
20689
21398
|
invoke: this._serviceContext.invoke,
|
|
20690
21399
|
invokeAny: this._serviceContext.invokeAny,
|
|
20691
21400
|
fetch: this._serviceContext.fetch,
|
|
20692
21401
|
hosts: this._serviceContext.hosts,
|
|
20693
21402
|
telemetry: this.config.telemetry
|
|
20694
|
-
});
|
|
21403
|
+
}));
|
|
20695
21404
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
20696
21405
|
sql.initialize(spaceScopedContext);
|
|
20697
21406
|
return sql;
|
|
@@ -20715,12 +21424,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20715
21424
|
throw new Error("Not signed in. Call signIn() first.");
|
|
20716
21425
|
}
|
|
20717
21426
|
const kv = new import_sdk_core7.KVService({});
|
|
20718
|
-
const spaceScopedContext = new import_sdk_core7.ServiceContext({
|
|
21427
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
|
|
20719
21428
|
invoke: this._serviceContext.invoke,
|
|
20720
21429
|
invokeAny: this._serviceContext.invokeAny,
|
|
20721
21430
|
fetch: this._serviceContext.fetch,
|
|
20722
21431
|
hosts: this._serviceContext.hosts
|
|
20723
|
-
});
|
|
21432
|
+
}));
|
|
20724
21433
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
20725
21434
|
kv.initialize(spaceScopedContext);
|
|
20726
21435
|
return kv;
|
|
@@ -20756,19 +21465,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20756
21465
|
}
|
|
20757
21466
|
async getEncryptionNetwork(nameOrNetworkId = this.getDefaultEncryptionNetworkId()) {
|
|
20758
21467
|
const networkId = nameOrNetworkId.startsWith("urn:tinycloud:encryption:") ? nameOrNetworkId : this.getDefaultEncryptionNetworkId(nameOrNetworkId);
|
|
20759
|
-
|
|
20760
|
-
|
|
21468
|
+
return this.fetchEncryptionNetworkAt(
|
|
21469
|
+
this.config.host,
|
|
21470
|
+
networkId,
|
|
21471
|
+
globalThis.fetch.bind(globalThis)
|
|
20761
21472
|
);
|
|
20762
|
-
if (response.status === 404) {
|
|
20763
|
-
return null;
|
|
20764
|
-
}
|
|
20765
|
-
if (!response.ok) {
|
|
20766
|
-
throw new Error(
|
|
20767
|
-
`Failed to fetch encryption network ${networkId}: HTTP ${response.status} ${await response.text()}`
|
|
20768
|
-
);
|
|
20769
|
-
}
|
|
20770
|
-
const body = await response.json();
|
|
20771
|
-
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
20772
21473
|
}
|
|
20773
21474
|
async createEncryptionNetwork(name = DEFAULT_ENCRYPTION_NETWORK_NAME) {
|
|
20774
21475
|
const targetNode = await this.fetchNodeId();
|
|
@@ -20862,6 +21563,38 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20862
21563
|
}
|
|
20863
21564
|
return secrets;
|
|
20864
21565
|
}
|
|
21566
|
+
/**
|
|
21567
|
+
* Read a secret from an explicit target space without requesting or
|
|
21568
|
+
* auto-signing authority. Active runtime delegations are selected by the
|
|
21569
|
+
* normal KV and encryption invocation paths.
|
|
21570
|
+
*/
|
|
21571
|
+
async readSecret(input) {
|
|
21572
|
+
const resolved = (0, import_sdk_core7.resolveSecretPath)(input.name, { scope: input.scope });
|
|
21573
|
+
const targetSpace = input.space.startsWith("tinycloud:") ? input.space : this.ownedSpaceId(input.space);
|
|
21574
|
+
const result = await this.getBaseVault(targetSpace).readNetworkEncrypted(
|
|
21575
|
+
resolved.vaultKey
|
|
21576
|
+
);
|
|
21577
|
+
if (result.status !== "ok") {
|
|
21578
|
+
if (result.status === "permission_required") {
|
|
21579
|
+
const hint = (0, import_sdk_services.parsePermissionHint)(result.hint);
|
|
21580
|
+
if (hint === void 0) return { status: "read_failed" };
|
|
21581
|
+
return {
|
|
21582
|
+
status: "permission_required",
|
|
21583
|
+
hint: {
|
|
21584
|
+
service: hint.service,
|
|
21585
|
+
...hint.space === void 0 ? {} : { space: hint.space },
|
|
21586
|
+
path: hint.path,
|
|
21587
|
+
actions: [...hint.actions]
|
|
21588
|
+
}
|
|
21589
|
+
};
|
|
21590
|
+
}
|
|
21591
|
+
return { status: result.status };
|
|
21592
|
+
}
|
|
21593
|
+
if (!isSecretPayload(result.entry.value)) {
|
|
21594
|
+
return { status: "invalid_payload" };
|
|
21595
|
+
}
|
|
21596
|
+
return { status: "ok", value: result.entry.value.value };
|
|
21597
|
+
}
|
|
20865
21598
|
getBaseSecrets(spaceId) {
|
|
20866
21599
|
if (!this._spaceService) {
|
|
20867
21600
|
throw new Error("Not signed in. Call signIn() first.");
|
|
@@ -20869,16 +21602,29 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20869
21602
|
const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
|
|
20870
21603
|
let secrets = this._baseSecrets.get(resolvedSpace);
|
|
20871
21604
|
if (!secrets) {
|
|
20872
|
-
|
|
20873
|
-
const vaultService = this.createVaultService(resolvedSpace, kvService);
|
|
20874
|
-
if (this._serviceContext) {
|
|
20875
|
-
vaultService.initialize(this._serviceContext);
|
|
20876
|
-
}
|
|
20877
|
-
secrets = new import_sdk_core7.SecretsService(() => vaultService);
|
|
21605
|
+
secrets = new import_sdk_core7.SecretsService(() => this.getBaseVault(resolvedSpace));
|
|
20878
21606
|
this._baseSecrets.set(resolvedSpace, secrets);
|
|
20879
21607
|
}
|
|
20880
21608
|
return secrets;
|
|
20881
21609
|
}
|
|
21610
|
+
getBaseVault(spaceId) {
|
|
21611
|
+
if (!this._spaceService) {
|
|
21612
|
+
throw new Error("Not signed in. Call signIn() first.");
|
|
21613
|
+
}
|
|
21614
|
+
const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
|
|
21615
|
+
let vault = this._baseVaults.get(resolvedSpace);
|
|
21616
|
+
if (!vault) {
|
|
21617
|
+
vault = this.createVaultService(
|
|
21618
|
+
resolvedSpace,
|
|
21619
|
+
this.createSpaceScopedKVService(resolvedSpace)
|
|
21620
|
+
);
|
|
21621
|
+
if (this._serviceContext) {
|
|
21622
|
+
vault.initialize(this._serviceContext);
|
|
21623
|
+
}
|
|
21624
|
+
this._baseVaults.set(resolvedSpace, vault);
|
|
21625
|
+
}
|
|
21626
|
+
return vault;
|
|
21627
|
+
}
|
|
20882
21628
|
/**
|
|
20883
21629
|
* Hooks write stream subscription API.
|
|
20884
21630
|
*/
|
|
@@ -20983,6 +21729,63 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
20983
21729
|
(grant) => grant.delegation
|
|
20984
21730
|
);
|
|
20985
21731
|
}
|
|
21732
|
+
/**
|
|
21733
|
+
* Return the effective capabilities of installed runtime grants.
|
|
21734
|
+
*
|
|
21735
|
+
* The result is projected from the SDK's activated, expiry-pruned grant
|
|
21736
|
+
* operations rather than from PortableDelegation transport metadata. Base
|
|
21737
|
+
* session authority is intentionally omitted; callers that need the full
|
|
21738
|
+
* live authority must combine this with {@link getVerifiedSessionCapabilities}.
|
|
21739
|
+
*/
|
|
21740
|
+
getEffectiveRuntimePermissionEntries() {
|
|
21741
|
+
const session = this.currentTinyCloudSession();
|
|
21742
|
+
if (!session) return [];
|
|
21743
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
21744
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
21745
|
+
for (const grant of this.runtimePermissionGrants) {
|
|
21746
|
+
if (grant.provenance === "primary") continue;
|
|
21747
|
+
for (const operation of grant.operations) {
|
|
21748
|
+
const service = import_sdk_core7.SERVICE_SHORT_TO_LONG[operation.service];
|
|
21749
|
+
if (service === void 0 || typeof operation.path !== "string" || typeof operation.action !== "string") {
|
|
21750
|
+
continue;
|
|
21751
|
+
}
|
|
21752
|
+
let space;
|
|
21753
|
+
if (service !== "tinycloud.encryption") {
|
|
21754
|
+
if (typeof operation.spaceId !== "string") continue;
|
|
21755
|
+
try {
|
|
21756
|
+
space = this.resolvePermissionSpace(operation.spaceId, session);
|
|
21757
|
+
} catch {
|
|
21758
|
+
continue;
|
|
21759
|
+
}
|
|
21760
|
+
}
|
|
21761
|
+
const caveats = operation.caveats === void 0 || operation.caveats.length === 0 ? void 0 : cloneRecapCaveats(operation.caveats);
|
|
21762
|
+
const identity = JSON.stringify({
|
|
21763
|
+
service,
|
|
21764
|
+
...space === void 0 ? {} : { space },
|
|
21765
|
+
path: operation.path,
|
|
21766
|
+
caveats: (0, import_sdk_core7.canonicalizeRecapCaveats)(caveats)
|
|
21767
|
+
});
|
|
21768
|
+
const existing = grouped.get(identity);
|
|
21769
|
+
if (existing === void 0) {
|
|
21770
|
+
grouped.set(identity, {
|
|
21771
|
+
service,
|
|
21772
|
+
...space === void 0 ? {} : { space },
|
|
21773
|
+
path: operation.path,
|
|
21774
|
+
actions: [operation.action],
|
|
21775
|
+
...caveats === void 0 ? {} : { caveats }
|
|
21776
|
+
});
|
|
21777
|
+
continue;
|
|
21778
|
+
}
|
|
21779
|
+
if (!existing.actions.includes(operation.action)) {
|
|
21780
|
+
existing.actions.push(operation.action);
|
|
21781
|
+
existing.actions.sort();
|
|
21782
|
+
}
|
|
21783
|
+
}
|
|
21784
|
+
}
|
|
21785
|
+
return [...grouped.values()].sort(
|
|
21786
|
+
(left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0"))
|
|
21787
|
+
);
|
|
21788
|
+
}
|
|
20986
21789
|
/**
|
|
20987
21790
|
* Install a portable runtime permission delegation into this SDK instance so
|
|
20988
21791
|
* matching service calls and downstream `delegateTo()` calls can use it.
|
|
@@ -21051,6 +21854,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21051
21854
|
"grantRuntimePermissions requires wallet mode with a signer or privateKey."
|
|
21052
21855
|
);
|
|
21053
21856
|
}
|
|
21857
|
+
this.assertDelegationCaveatsPreservable(expanded);
|
|
21054
21858
|
const rawEntries = expanded.filter(
|
|
21055
21859
|
(entry) => this.isEncryptionPermissionEntry(entry)
|
|
21056
21860
|
);
|
|
@@ -21312,12 +22116,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21312
22116
|
}
|
|
21313
22117
|
if (this._serviceContext) {
|
|
21314
22118
|
const publicKV = new import_sdk_core7.KVService({ prefix: "" });
|
|
21315
|
-
const publicContext = new import_sdk_core7.ServiceContext({
|
|
21316
|
-
invoke: this.
|
|
21317
|
-
fetch: this.
|
|
22119
|
+
const publicContext = this._serviceGraph.track(new import_sdk_core7.ServiceContext({
|
|
22120
|
+
invoke: this._serviceGraph.invoke,
|
|
22121
|
+
fetch: this._serviceGraph.fetch,
|
|
21318
22122
|
hosts: this._serviceContext.hosts,
|
|
21319
22123
|
telemetry: this.config.telemetry
|
|
21320
|
-
});
|
|
22124
|
+
}));
|
|
21321
22125
|
publicContext.setSession({
|
|
21322
22126
|
delegationHeader: delegationSession.delegationHeader,
|
|
21323
22127
|
delegationCid: delegationSession.delegationCid,
|
|
@@ -21384,13 +22188,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21384
22188
|
async getDelegationStatus(cid) {
|
|
21385
22189
|
return this.delegationManager.status(cid);
|
|
21386
22190
|
}
|
|
21387
|
-
/** Compute the canonical CID of a compact delegation authorization. */
|
|
22191
|
+
/** Compute the canonical CID of a compact UCAN or DAG-CBOR delegation authorization. */
|
|
21388
22192
|
computeDelegationCid(authorization) {
|
|
21389
22193
|
if (!authorization || !this.wasmBindings.computeCid) {
|
|
21390
22194
|
throw new Error("Delegation CID computation is unavailable");
|
|
21391
22195
|
}
|
|
22196
|
+
const compact = authorization.replace(/^Bearer /i, "");
|
|
21392
22197
|
return this.wasmBindings.computeCid(
|
|
21393
|
-
new TextEncoder().encode(authorization),
|
|
22198
|
+
compact.includes(".") ? new TextEncoder().encode(compact) : decodeAuthorizationBytes(authorization),
|
|
21394
22199
|
0x55n
|
|
21395
22200
|
);
|
|
21396
22201
|
}
|
|
@@ -21482,6 +22287,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21482
22287
|
"delegateTo with forceWalletSign=true supports at most one PermissionEntry. Multi-entry requests must go through the session-key UCAN path (drop forceWalletSign) or the legacy createDelegation method."
|
|
21483
22288
|
);
|
|
21484
22289
|
}
|
|
22290
|
+
this.assertDelegationCaveatsPreservable(expandedEntries);
|
|
21485
22291
|
const delegation2 = await this.createDelegationLegacyWalletPath(
|
|
21486
22292
|
did,
|
|
21487
22293
|
expandedEntries[0],
|
|
@@ -21490,13 +22296,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21490
22296
|
return { delegation: delegation2, prompted: true };
|
|
21491
22297
|
}
|
|
21492
22298
|
const granted = (0, import_sdk_core7.parseRecapCapabilities)(
|
|
21493
|
-
(siwe) => this.
|
|
22299
|
+
(siwe) => this.parseRecapWithCaveats(siwe),
|
|
21494
22300
|
session.siwe
|
|
21495
22301
|
);
|
|
21496
22302
|
const { subset, missing } = (0, import_sdk_core7.isCapabilitySubset)(expandedEntries, granted);
|
|
21497
22303
|
if (!subset) {
|
|
22304
|
+
const runtimeOperations = this.permissionEntriesToOperations(expandedEntries, session);
|
|
21498
22305
|
const runtimeGrant = this.findGrantForOperations(
|
|
21499
|
-
|
|
22306
|
+
runtimeOperations,
|
|
21500
22307
|
{ excludePrimary: true }
|
|
21501
22308
|
);
|
|
21502
22309
|
if (runtimeGrant) {
|
|
@@ -21509,7 +22316,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21509
22316
|
did,
|
|
21510
22317
|
expandedEntries,
|
|
21511
22318
|
runtimeExpiration,
|
|
21512
|
-
runtimeGrant
|
|
22319
|
+
runtimeGrant,
|
|
22320
|
+
runtimeOperations
|
|
21513
22321
|
);
|
|
21514
22322
|
return { delegation: delegation2, prompted: false };
|
|
21515
22323
|
}
|
|
@@ -21579,6 +22387,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21579
22387
|
"createDelegationViaWasmPath requires a non-empty entries array"
|
|
21580
22388
|
);
|
|
21581
22389
|
}
|
|
22390
|
+
this.assertDelegationCaveatsPreservable(entries);
|
|
21582
22391
|
const resolvedSpaces = /* @__PURE__ */ new Set();
|
|
21583
22392
|
for (const entry of entries) {
|
|
21584
22393
|
if (this.isEncryptionPermissionEntry(entry)) {
|
|
@@ -21659,7 +22468,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21659
22468
|
host: this.config.host
|
|
21660
22469
|
};
|
|
21661
22470
|
}
|
|
21662
|
-
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant) {
|
|
22471
|
+
async createDelegationViaRuntimeGrant(did, entries, expirationTime, grant, requestedOperations) {
|
|
22472
|
+
this.assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant);
|
|
22473
|
+
this.assertDelegationCaveatsPreservable(entries);
|
|
21663
22474
|
const result = this.createDelegationWrapper({
|
|
21664
22475
|
session: grant.session,
|
|
21665
22476
|
delegateDID: did,
|
|
@@ -21713,6 +22524,74 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21713
22524
|
expandPermissionEntries(permissions) {
|
|
21714
22525
|
return (0, import_sdk_core7.expandPermissionEntries)(permissions);
|
|
21715
22526
|
}
|
|
22527
|
+
/**
|
|
22528
|
+
* The current WASM child-delegation APIs accept action-only maps. Refuse any
|
|
22529
|
+
* constrained branch rather than signing a broader action-only child UCAN.
|
|
22530
|
+
*/
|
|
22531
|
+
assertDelegationCaveatsPreservable(entries) {
|
|
22532
|
+
const caveated = entries.filter(
|
|
22533
|
+
(entry) => !(0, import_sdk_core7.recapCaveatsEqual)(entry.caveats, void 0)
|
|
22534
|
+
);
|
|
22535
|
+
if (caveated.length > 0) {
|
|
22536
|
+
throw new import_sdk_core7.CaveatedDelegationUnsupportedError(caveated);
|
|
22537
|
+
}
|
|
22538
|
+
}
|
|
22539
|
+
/**
|
|
22540
|
+
* Runtime grant selection intentionally allows an uncaveated operation to
|
|
22541
|
+
* select a caveated grant so invocation can restore the signed caveat before
|
|
22542
|
+
* crossing the caveat-aware WASM boundary. Child delegation cannot do that:
|
|
22543
|
+
* it only accepts action maps, so reject the selected constrained branch.
|
|
22544
|
+
*/
|
|
22545
|
+
assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant) {
|
|
22546
|
+
let operationIndex = 0;
|
|
22547
|
+
const caveated = [];
|
|
22548
|
+
for (const entry of entries) {
|
|
22549
|
+
for (const action of entry.actions) {
|
|
22550
|
+
const requested = requestedOperations[operationIndex++];
|
|
22551
|
+
if (!requested) continue;
|
|
22552
|
+
const constrained = grant.operations.find(
|
|
22553
|
+
(granted) => this.operationCovers(granted, requested) && !(0, import_sdk_core7.recapCaveatsEqual)(granted.caveats, void 0)
|
|
22554
|
+
);
|
|
22555
|
+
if (constrained) {
|
|
22556
|
+
caveated.push({
|
|
22557
|
+
...entry,
|
|
22558
|
+
actions: [action],
|
|
22559
|
+
caveats: cloneRecapCaveats(constrained.caveats)
|
|
22560
|
+
});
|
|
22561
|
+
}
|
|
22562
|
+
}
|
|
22563
|
+
}
|
|
22564
|
+
if (caveated.length > 0) {
|
|
22565
|
+
throw new import_sdk_core7.CaveatedDelegationUnsupportedError(caveated);
|
|
22566
|
+
}
|
|
22567
|
+
}
|
|
22568
|
+
/** Reject caveated parent branches before action-only child signing. */
|
|
22569
|
+
assertPortableDelegationCaveatsPreservable(delegation) {
|
|
22570
|
+
const entries = [];
|
|
22571
|
+
const add3 = (service, space, path, actions, caveats) => {
|
|
22572
|
+
if ((0, import_sdk_core7.recapCaveatsEqual)(caveats, void 0)) return;
|
|
22573
|
+
entries.push({
|
|
22574
|
+
service: service.startsWith("tinycloud.") ? service : `tinycloud.${service}`,
|
|
22575
|
+
space,
|
|
22576
|
+
path,
|
|
22577
|
+
actions: [...actions],
|
|
22578
|
+
caveats: cloneRecapCaveats(caveats)
|
|
22579
|
+
});
|
|
22580
|
+
};
|
|
22581
|
+
add3(
|
|
22582
|
+
delegation.actions[0]?.split("/", 1)[0] ?? "tinycloud.unknown",
|
|
22583
|
+
delegation.spaceId,
|
|
22584
|
+
delegation.path,
|
|
22585
|
+
delegation.actions,
|
|
22586
|
+
delegation.caveats
|
|
22587
|
+
);
|
|
22588
|
+
for (const resource of delegation.resources ?? []) {
|
|
22589
|
+
add3(resource.service, resource.space, resource.path, resource.actions, resource.caveats);
|
|
22590
|
+
}
|
|
22591
|
+
if (entries.length > 0) {
|
|
22592
|
+
throw new import_sdk_core7.CaveatedDelegationUnsupportedError(entries);
|
|
22593
|
+
}
|
|
22594
|
+
}
|
|
21716
22595
|
shortServiceName(service) {
|
|
21717
22596
|
const short = import_sdk_core7.SERVICE_LONG_TO_SHORT[service];
|
|
21718
22597
|
if (short === void 0) {
|
|
@@ -21767,14 +22646,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21767
22646
|
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
|
|
21768
22647
|
service,
|
|
21769
22648
|
path: entry.path,
|
|
21770
|
-
action
|
|
22649
|
+
action,
|
|
22650
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
21771
22651
|
}));
|
|
21772
22652
|
});
|
|
21773
22653
|
}
|
|
21774
22654
|
sessionCoversPermissionEntries(session, entries) {
|
|
21775
22655
|
try {
|
|
21776
22656
|
const granted = (0, import_sdk_core7.parseRecapCapabilities)(
|
|
21777
|
-
(siwe) => this.
|
|
22657
|
+
(siwe) => this.parseRecapWithCaveats(siwe),
|
|
21778
22658
|
session.siwe
|
|
21779
22659
|
);
|
|
21780
22660
|
return (0, import_sdk_core7.isCapabilitySubset)(entries, granted).subset;
|
|
@@ -21790,7 +22670,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21790
22670
|
...this.isEncryptionNetworkOperation(service, entry.path) ? { resource: entry.path } : { spaceId },
|
|
21791
22671
|
service,
|
|
21792
22672
|
path: entry.path,
|
|
21793
|
-
action
|
|
22673
|
+
action,
|
|
22674
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
21794
22675
|
}));
|
|
21795
22676
|
});
|
|
21796
22677
|
}
|
|
@@ -21866,7 +22747,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21866
22747
|
service: this.shortServiceName(entry.service),
|
|
21867
22748
|
space: this.isEncryptionPermissionEntry(entry) ? "encryption" : spaceId,
|
|
21868
22749
|
path: entry.path,
|
|
21869
|
-
actions: [...entry.actions]
|
|
22750
|
+
actions: [...entry.actions],
|
|
22751
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
21870
22752
|
}));
|
|
21871
22753
|
}
|
|
21872
22754
|
operationsFromDelegation(delegation) {
|
|
@@ -21877,7 +22759,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21877
22759
|
...this.isEncryptionNetworkOperation(service, resource.path) ? { resource: resource.path } : { spaceId: resource.space },
|
|
21878
22760
|
service,
|
|
21879
22761
|
path: resource.path,
|
|
21880
|
-
action
|
|
22762
|
+
action,
|
|
22763
|
+
caveats: cloneRecapCaveats(resource.caveats)
|
|
21881
22764
|
}));
|
|
21882
22765
|
});
|
|
21883
22766
|
}
|
|
@@ -21893,7 +22776,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21893
22776
|
service,
|
|
21894
22777
|
space: delegation.spaceId,
|
|
21895
22778
|
path: delegation.path,
|
|
21896
|
-
actions
|
|
22779
|
+
actions,
|
|
22780
|
+
...delegation.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(delegation.caveats) }
|
|
21897
22781
|
}));
|
|
21898
22782
|
}
|
|
21899
22783
|
/**
|
|
@@ -21994,6 +22878,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
21994
22878
|
if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
|
|
21995
22879
|
return false;
|
|
21996
22880
|
}
|
|
22881
|
+
if (requested.caveats !== void 0 && !(0, import_sdk_core7.recapCaveatsEqual)(granted.caveats, requested.caveats)) {
|
|
22882
|
+
return false;
|
|
22883
|
+
}
|
|
21997
22884
|
if (granted.resource !== void 0 || requested.resource !== void 0) {
|
|
21998
22885
|
return granted.resource !== void 0 && requested.resource !== void 0 && granted.resource === requested.resource && this.pathContains(granted.path, requested.path);
|
|
21999
22886
|
}
|
|
@@ -22028,6 +22915,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22028
22915
|
invocationServiceName(service) {
|
|
22029
22916
|
return service.startsWith("tinycloud.") ? this.shortServiceName(service) : service;
|
|
22030
22917
|
}
|
|
22918
|
+
/** Prefer the v2 caveat-preserving parser while retaining old custom WASM. */
|
|
22919
|
+
parseRecapWithCaveats(siwe) {
|
|
22920
|
+
return this.wasmBindings.parseVerifiedRecapFromSiwe?.(siwe) ?? this.wasmBindings.parseRecapFromSiwe(siwe);
|
|
22921
|
+
}
|
|
22031
22922
|
isEncryptionNetworkOperation(service, path) {
|
|
22032
22923
|
return service === "encryption" && path.startsWith("urn:tinycloud:encryption:");
|
|
22033
22924
|
}
|
|
@@ -22038,7 +22929,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22038
22929
|
resource: entry.resource,
|
|
22039
22930
|
service,
|
|
22040
22931
|
path: entry.path,
|
|
22041
|
-
action: entry.action
|
|
22932
|
+
action: entry.action,
|
|
22933
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
22042
22934
|
};
|
|
22043
22935
|
}
|
|
22044
22936
|
if (this.isEncryptionNetworkOperation(service, entry.path)) {
|
|
@@ -22046,7 +22938,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22046
22938
|
resource: entry.path,
|
|
22047
22939
|
service,
|
|
22048
22940
|
path: entry.path,
|
|
22049
|
-
action: entry.action
|
|
22941
|
+
action: entry.action,
|
|
22942
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
22050
22943
|
};
|
|
22051
22944
|
}
|
|
22052
22945
|
if (typeof entry.spaceId === "string") {
|
|
@@ -22054,7 +22947,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22054
22947
|
spaceId: entry.spaceId,
|
|
22055
22948
|
service,
|
|
22056
22949
|
path: entry.path,
|
|
22057
|
-
action: entry.action
|
|
22950
|
+
action: entry.action,
|
|
22951
|
+
...entry.caveats === void 0 ? {} : { caveats: cloneRecapCaveats(entry.caveats) }
|
|
22058
22952
|
};
|
|
22059
22953
|
}
|
|
22060
22954
|
return void 0;
|
|
@@ -22394,6 +23288,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
22394
23288
|
* @returns A portable delegation for the sub-delegate
|
|
22395
23289
|
*/
|
|
22396
23290
|
async createSubDelegation(parentDelegation, params) {
|
|
23291
|
+
this.assertPortableDelegationCaveatsPreservable(parentDelegation);
|
|
22397
23292
|
if (!this.signer) {
|
|
22398
23293
|
throw new Error("Cannot createSubDelegation() in session-only mode. Requires wallet mode.");
|
|
22399
23294
|
}
|
|
@@ -22492,8 +23387,8 @@ TinyCloudNode.registerNodeDefaults({
|
|
|
22492
23387
|
});
|
|
22493
23388
|
|
|
22494
23389
|
// src/index.ts
|
|
22495
|
-
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
22496
23390
|
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
23391
|
+
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
22497
23392
|
|
|
22498
23393
|
// src/storage/FileSessionStorage.ts
|
|
22499
23394
|
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
@@ -22616,9 +23511,279 @@ var FileSessionStorage = class {
|
|
|
22616
23511
|
};
|
|
22617
23512
|
|
|
22618
23513
|
// src/index.ts
|
|
22619
|
-
var
|
|
23514
|
+
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
22620
23515
|
|
|
22621
23516
|
// src/delegation.ts
|
|
23517
|
+
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
23518
|
+
var SERVICE_BY_SHORT_NAME = {
|
|
23519
|
+
kv: "tinycloud.kv",
|
|
23520
|
+
sql: "tinycloud.sql",
|
|
23521
|
+
duckdb: "tinycloud.duckdb",
|
|
23522
|
+
hooks: "tinycloud.hooks"
|
|
23523
|
+
};
|
|
23524
|
+
function authorizationWithoutBearer(authorization) {
|
|
23525
|
+
return authorization.replace(/^Bearer /i, "");
|
|
23526
|
+
}
|
|
23527
|
+
function normalizedHost(host) {
|
|
23528
|
+
if (typeof host !== "string" || host.length === 0) {
|
|
23529
|
+
throw new Error("Validated runtime delegation requires a non-empty host.");
|
|
23530
|
+
}
|
|
23531
|
+
return host.replace(/\/+$/, "");
|
|
23532
|
+
}
|
|
23533
|
+
function didPrincipalsMatch(left, right) {
|
|
23534
|
+
try {
|
|
23535
|
+
return (0, import_sdk_core9.principalDidEquals)(left, right);
|
|
23536
|
+
} catch {
|
|
23537
|
+
return left === right;
|
|
23538
|
+
}
|
|
23539
|
+
}
|
|
23540
|
+
function compactUcanPayload(authorization) {
|
|
23541
|
+
const compact = authorizationWithoutBearer(authorization);
|
|
23542
|
+
const parts = compact.split(".");
|
|
23543
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
23544
|
+
throw new Error(
|
|
23545
|
+
"Validated runtime delegation requires a compact UCAN authorization so its signed authority can be derived."
|
|
23546
|
+
);
|
|
23547
|
+
}
|
|
23548
|
+
try {
|
|
23549
|
+
const payload = JSON.parse(
|
|
23550
|
+
Buffer.from(parts[1], "base64url").toString("utf8")
|
|
23551
|
+
);
|
|
23552
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
23553
|
+
throw new Error("payload is not an object");
|
|
23554
|
+
}
|
|
23555
|
+
return payload;
|
|
23556
|
+
} catch {
|
|
23557
|
+
throw new Error(
|
|
23558
|
+
"Validated runtime delegation authorization has an invalid compact UCAN payload."
|
|
23559
|
+
);
|
|
23560
|
+
}
|
|
23561
|
+
}
|
|
23562
|
+
function canonicalPermissionEntries(permissions) {
|
|
23563
|
+
return permissions.map((permission) => ({
|
|
23564
|
+
...permission,
|
|
23565
|
+
actions: [...permission.actions].sort()
|
|
23566
|
+
})).sort(
|
|
23567
|
+
(left, right) => left.service.localeCompare(right.service) || (left.space ?? "").localeCompare(right.space ?? "") || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0")) || (0, import_sdk_core9.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core9.canonicalizeRecapCaveats)(right.caveats))
|
|
23568
|
+
);
|
|
23569
|
+
}
|
|
23570
|
+
function signedCaveats(value) {
|
|
23571
|
+
if (!Array.isArray(value) || value.some(
|
|
23572
|
+
(caveat) => caveat === null || typeof caveat !== "object" || Array.isArray(caveat)
|
|
23573
|
+
)) {
|
|
23574
|
+
throw new Error("Validated runtime delegation has malformed signed ReCap caveats.");
|
|
23575
|
+
}
|
|
23576
|
+
const cloned = JSON.parse(JSON.stringify(value));
|
|
23577
|
+
return (0, import_sdk_core9.canonicalizeRecapCaveats)(cloned) === (0, import_sdk_core9.canonicalizeRecapCaveats)(void 0) ? void 0 : cloned;
|
|
23578
|
+
}
|
|
23579
|
+
function groupedSignedEntries(service, space, path, abilities) {
|
|
23580
|
+
const groups = /* @__PURE__ */ new Map();
|
|
23581
|
+
for (const [action, rawCaveats] of Object.entries(abilities)) {
|
|
23582
|
+
const caveats = signedCaveats(rawCaveats);
|
|
23583
|
+
const identity = (0, import_sdk_core9.canonicalizeRecapCaveats)(caveats);
|
|
23584
|
+
const group = groups.get(identity) ?? { actions: [], caveats };
|
|
23585
|
+
group.actions.push(action);
|
|
23586
|
+
groups.set(identity, group);
|
|
23587
|
+
}
|
|
23588
|
+
return [...groups.values()].map((group) => ({
|
|
23589
|
+
service,
|
|
23590
|
+
...space === void 0 ? {} : { space },
|
|
23591
|
+
path,
|
|
23592
|
+
actions: group.actions.sort(),
|
|
23593
|
+
...group.caveats === void 0 ? {} : { caveats: group.caveats }
|
|
23594
|
+
}));
|
|
23595
|
+
}
|
|
23596
|
+
function signedAuthorityFromCompactUcan(authorization) {
|
|
23597
|
+
const payload = compactUcanPayload(authorization);
|
|
23598
|
+
if (typeof payload.aud !== "string" || payload.aud.length === 0) {
|
|
23599
|
+
throw new Error("Validated runtime delegation is missing a signed audience.");
|
|
23600
|
+
}
|
|
23601
|
+
if (typeof payload.exp !== "number" || !Number.isFinite(payload.exp)) {
|
|
23602
|
+
throw new Error("Validated runtime delegation is missing a signed expiry.");
|
|
23603
|
+
}
|
|
23604
|
+
const expiry = new Date(payload.exp * 1e3);
|
|
23605
|
+
if (Number.isNaN(expiry.getTime())) {
|
|
23606
|
+
throw new Error("Validated runtime delegation has an invalid signed expiry.");
|
|
23607
|
+
}
|
|
23608
|
+
if (payload.att === null || typeof payload.att !== "object" || Array.isArray(payload.att)) {
|
|
23609
|
+
throw new Error("Validated runtime delegation is missing a signed attenuation.");
|
|
23610
|
+
}
|
|
23611
|
+
const permissions = [];
|
|
23612
|
+
for (const [resource, abilities] of Object.entries(payload.att)) {
|
|
23613
|
+
if (abilities === null || typeof abilities !== "object" || Array.isArray(abilities)) {
|
|
23614
|
+
throw new Error("Validated runtime delegation has an invalid signed attenuation.");
|
|
23615
|
+
}
|
|
23616
|
+
const abilityEntries = Object.entries(abilities);
|
|
23617
|
+
if (abilityEntries.length === 0) {
|
|
23618
|
+
throw new Error("Validated runtime delegation has an empty signed capability.");
|
|
23619
|
+
}
|
|
23620
|
+
if (resource.startsWith("urn:tinycloud:encryption:")) {
|
|
23621
|
+
permissions.push(...groupedSignedEntries(
|
|
23622
|
+
"tinycloud.encryption",
|
|
23623
|
+
void 0,
|
|
23624
|
+
resource,
|
|
23625
|
+
abilities
|
|
23626
|
+
));
|
|
23627
|
+
continue;
|
|
23628
|
+
}
|
|
23629
|
+
const match = /^(tinycloud:[^/]+)\/(kv|sql|duckdb|hooks)\/(.*)$/.exec(resource);
|
|
23630
|
+
if (!match) {
|
|
23631
|
+
throw new Error(
|
|
23632
|
+
`Validated runtime delegation has an unsupported signed resource '${resource}'.`
|
|
23633
|
+
);
|
|
23634
|
+
}
|
|
23635
|
+
const [, space, shortService, path] = match;
|
|
23636
|
+
const service = SERVICE_BY_SHORT_NAME[shortService];
|
|
23637
|
+
if (service === void 0) {
|
|
23638
|
+
throw new Error(
|
|
23639
|
+
`Validated runtime delegation has an unsupported signed service '${shortService}'.`
|
|
23640
|
+
);
|
|
23641
|
+
}
|
|
23642
|
+
permissions.push(...groupedSignedEntries(
|
|
23643
|
+
service,
|
|
23644
|
+
space,
|
|
23645
|
+
path,
|
|
23646
|
+
abilities
|
|
23647
|
+
));
|
|
23648
|
+
}
|
|
23649
|
+
if (permissions.length === 0) {
|
|
23650
|
+
throw new Error("Validated runtime delegation has no signed capabilities.");
|
|
23651
|
+
}
|
|
23652
|
+
const canonicalPermissions = canonicalPermissionEntries(permissions);
|
|
23653
|
+
const canonicalResources = canonicalPermissions.map((permission) => ({
|
|
23654
|
+
service: permission.service === "tinycloud.encryption" ? "encryption" : permission.service.slice("tinycloud.".length),
|
|
23655
|
+
space: permission.service === "tinycloud.encryption" ? "encryption" : permission.space,
|
|
23656
|
+
path: permission.path,
|
|
23657
|
+
actions: [...permission.actions],
|
|
23658
|
+
...permission.caveats === void 0 ? {} : { caveats: permission.caveats }
|
|
23659
|
+
}));
|
|
23660
|
+
return {
|
|
23661
|
+
audience: payload.aud,
|
|
23662
|
+
expiry,
|
|
23663
|
+
permissions: canonicalPermissions,
|
|
23664
|
+
resources: canonicalResources
|
|
23665
|
+
};
|
|
23666
|
+
}
|
|
23667
|
+
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
23668
|
+
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
23669
|
+
return delegation.resources.map((resource) => ({ ...resource, actions: [...resource.actions].sort() })).sort(
|
|
23670
|
+
(left, right) => left.service.localeCompare(right.service) || left.space.localeCompare(right.space) || left.path.localeCompare(right.path) || left.actions.join("\0").localeCompare(right.actions.join("\0")) || (0, import_sdk_core9.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core9.canonicalizeRecapCaveats)(right.caveats))
|
|
23671
|
+
);
|
|
23672
|
+
}
|
|
23673
|
+
const byService = /* @__PURE__ */ new Map();
|
|
23674
|
+
for (const action of delegation.actions) {
|
|
23675
|
+
const [service] = action.split("/", 1);
|
|
23676
|
+
const shortService = service.replace(/^tinycloud\./, "");
|
|
23677
|
+
const values = byService.get(shortService) ?? [];
|
|
23678
|
+
values.push(action);
|
|
23679
|
+
byService.set(shortService, values);
|
|
23680
|
+
}
|
|
23681
|
+
return [...byService.entries()].map(([service, actions]) => ({
|
|
23682
|
+
service,
|
|
23683
|
+
space: service === "encryption" ? "encryption" : delegation.spaceId,
|
|
23684
|
+
path: delegation.path,
|
|
23685
|
+
actions: [...new Set(actions)].sort(),
|
|
23686
|
+
...delegation.caveats === void 0 ? {} : { caveats: delegation.caveats }
|
|
23687
|
+
})).sort(
|
|
23688
|
+
(left, right) => left.service.localeCompare(right.service) || left.space.localeCompare(right.space) || left.path.localeCompare(right.path)
|
|
23689
|
+
);
|
|
23690
|
+
}
|
|
23691
|
+
function resourcesMatch(actual, expected) {
|
|
23692
|
+
const comparable = (resource) => ({
|
|
23693
|
+
...resource,
|
|
23694
|
+
caveats: (0, import_sdk_core9.canonicalizeRecapCaveats)(resource.caveats)
|
|
23695
|
+
});
|
|
23696
|
+
return JSON.stringify(actual.map(comparable)) === JSON.stringify(expected.map(comparable));
|
|
23697
|
+
}
|
|
23698
|
+
async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
23699
|
+
const host = normalizedHost(options.host);
|
|
23700
|
+
if (delegation.host !== void 0 && normalizedHost(delegation.host) !== host) {
|
|
23701
|
+
throw new Error(
|
|
23702
|
+
`Runtime delegation host '${delegation.host}' does not match expected host '${options.host}'.`
|
|
23703
|
+
);
|
|
23704
|
+
}
|
|
23705
|
+
if (!(delegation.expiry instanceof Date) || Number.isNaN(delegation.expiry.getTime())) {
|
|
23706
|
+
throw new Error("Runtime delegation has an invalid expiry.");
|
|
23707
|
+
}
|
|
23708
|
+
if (delegation.expiry.getTime() <= Date.now()) {
|
|
23709
|
+
throw new Error("Runtime delegation is expired.");
|
|
23710
|
+
}
|
|
23711
|
+
const authorization = delegation.delegationHeader?.Authorization;
|
|
23712
|
+
if (typeof authorization !== "string" || authorization.length === 0) {
|
|
23713
|
+
throw new Error("Runtime delegation is missing authorization bytes.");
|
|
23714
|
+
}
|
|
23715
|
+
const cid = node.computeDelegationCid(authorization);
|
|
23716
|
+
if (cid !== delegation.cid) {
|
|
23717
|
+
throw new Error("Runtime delegation CID does not match authorization bytes.");
|
|
23718
|
+
}
|
|
23719
|
+
const signed2 = signedAuthorityFromCompactUcan(authorization);
|
|
23720
|
+
if (signed2.expiry.getTime() <= Date.now()) {
|
|
23721
|
+
throw new Error("Runtime delegation is expired.");
|
|
23722
|
+
}
|
|
23723
|
+
if (delegation.expiry.getTime() !== signed2.expiry.getTime()) {
|
|
23724
|
+
throw new Error("Runtime delegation expiry does not match signed authority.");
|
|
23725
|
+
}
|
|
23726
|
+
if (!didPrincipalsMatch(signed2.audience, node.sessionDid)) {
|
|
23727
|
+
throw new Error(
|
|
23728
|
+
`Runtime delegation targets ${signed2.audience} but this session is ${node.sessionDid}.`
|
|
23729
|
+
);
|
|
23730
|
+
}
|
|
23731
|
+
if (!didPrincipalsMatch(delegation.delegateDID, signed2.audience)) {
|
|
23732
|
+
throw new Error("Runtime delegation audience does not match signed authority.");
|
|
23733
|
+
}
|
|
23734
|
+
const declaredResources = canonicalResourcesFromPortableDelegation(delegation);
|
|
23735
|
+
if (!resourcesMatch(declaredResources, signed2.resources)) {
|
|
23736
|
+
throw new Error("Runtime delegation resources do not match signed authority.");
|
|
23737
|
+
}
|
|
23738
|
+
const previouslyInstalled = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
23739
|
+
if (previouslyInstalled !== void 0 && previouslyInstalled.delegationHeader.Authorization !== authorization) {
|
|
23740
|
+
throw new Error(
|
|
23741
|
+
"A different authorization is already installed for this runtime delegation CID."
|
|
23742
|
+
);
|
|
23743
|
+
}
|
|
23744
|
+
const primary = signed2.resources[0];
|
|
23745
|
+
const signedSpace = signed2.permissions.find(
|
|
23746
|
+
(permission) => permission.service !== "tinycloud.encryption"
|
|
23747
|
+
)?.space;
|
|
23748
|
+
const installedCandidate = {
|
|
23749
|
+
cid,
|
|
23750
|
+
delegationHeader: { Authorization: authorization },
|
|
23751
|
+
ownerAddress: delegation.ownerAddress,
|
|
23752
|
+
chainId: delegation.chainId,
|
|
23753
|
+
spaceId: signedSpace ?? delegation.spaceId,
|
|
23754
|
+
path: primary.path,
|
|
23755
|
+
actions: [...primary.actions],
|
|
23756
|
+
...primary.caveats === void 0 ? {} : { caveats: primary.caveats },
|
|
23757
|
+
resources: signed2.resources.map((resource) => ({
|
|
23758
|
+
...resource,
|
|
23759
|
+
actions: [...resource.actions]
|
|
23760
|
+
})),
|
|
23761
|
+
expiry: new Date(signed2.expiry),
|
|
23762
|
+
delegateDID: signed2.audience,
|
|
23763
|
+
host
|
|
23764
|
+
};
|
|
23765
|
+
await node.useRuntimeDelegation(installedCandidate);
|
|
23766
|
+
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
23767
|
+
if (!installed) {
|
|
23768
|
+
throw new Error("Runtime delegation activation did not install the validated authority.");
|
|
23769
|
+
}
|
|
23770
|
+
if (installed.delegationHeader.Authorization !== authorization || !didPrincipalsMatch(installed.delegateDID, signed2.audience) || installed.expiry.getTime() !== signed2.expiry.getTime() || !resourcesMatch(
|
|
23771
|
+
canonicalResourcesFromPortableDelegation(installed),
|
|
23772
|
+
signed2.resources
|
|
23773
|
+
) || normalizedHost(installed.host ?? "") !== host) {
|
|
23774
|
+
throw new Error(
|
|
23775
|
+
"Runtime delegation activation installed authority that differs from the validated authority."
|
|
23776
|
+
);
|
|
23777
|
+
}
|
|
23778
|
+
return {
|
|
23779
|
+
cid,
|
|
23780
|
+
delegation: installed,
|
|
23781
|
+
effectivePermissions: signed2.permissions,
|
|
23782
|
+
expiry: new Date(signed2.expiry),
|
|
23783
|
+
audience: signed2.audience,
|
|
23784
|
+
host: normalizedHost(installed.host ?? host)
|
|
23785
|
+
};
|
|
23786
|
+
}
|
|
22622
23787
|
async function grantAuthRequest(authority, request, options) {
|
|
22623
23788
|
if (request.kind !== "tinycloud.auth.request") {
|
|
22624
23789
|
throw new Error(
|
|
@@ -22661,7 +23826,6 @@ function deserializeDelegation(data) {
|
|
|
22661
23826
|
}
|
|
22662
23827
|
|
|
22663
23828
|
// src/index.ts
|
|
22664
|
-
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
22665
23829
|
var import_sdk_core13 = require("@tinycloud/sdk-core");
|
|
22666
23830
|
var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
22667
23831
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
@@ -22672,6 +23836,7 @@ var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
|
22672
23836
|
var import_sdk_core20 = require("@tinycloud/sdk-core");
|
|
22673
23837
|
var import_sdk_core21 = require("@tinycloud/sdk-core");
|
|
22674
23838
|
var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
23839
|
+
var import_sdk_core23 = require("@tinycloud/sdk-core");
|
|
22675
23840
|
// Annotate the CommonJS export names for ESM import in node:
|
|
22676
23841
|
0 && (module.exports = {
|
|
22677
23842
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -22680,6 +23845,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
|
22680
23845
|
AutoApproveSpaceCreationHandler,
|
|
22681
23846
|
CapabilityKeyRegistry,
|
|
22682
23847
|
CapabilityKeyRegistryErrorCodes,
|
|
23848
|
+
CaveatedDelegationUnsupportedError,
|
|
22683
23849
|
DECRYPT_ACTION,
|
|
22684
23850
|
DECRYPT_FACT_TYPE,
|
|
22685
23851
|
DECRYPT_RESULT_TYPE,
|
|
@@ -22690,6 +23856,7 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
|
22690
23856
|
DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
22691
23857
|
DataVaultService,
|
|
22692
23858
|
DatabaseHandle,
|
|
23859
|
+
DecryptTransportResponseError,
|
|
22693
23860
|
DelegatedAccess,
|
|
22694
23861
|
DelegationErrorCodes,
|
|
22695
23862
|
DelegationManager,
|
|
@@ -22730,11 +23897,13 @@ var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
|
22730
23897
|
TinyCloudDebugLogger,
|
|
22731
23898
|
TinyCloudNode,
|
|
22732
23899
|
UnsupportedFeatureError,
|
|
23900
|
+
UnsupportedSessionRestoreError,
|
|
22733
23901
|
VAULT_PERMISSION_SERVICE,
|
|
22734
23902
|
VaultHeaders,
|
|
22735
23903
|
VaultPublicSpaceKVActions,
|
|
22736
23904
|
VersionCheckError,
|
|
22737
23905
|
WasmKeyProvider,
|
|
23906
|
+
activateValidatedRuntimeDelegation,
|
|
22738
23907
|
addressStorageKey,
|
|
22739
23908
|
buildCanonicalDecryptRequest,
|
|
22740
23909
|
buildDecryptAttenuation,
|