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