@tinycloud/node-sdk 3.2.0-beta.2 → 3.2.0-beta.3
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-DjLtgeVT.d.cts → WasmKeyProvider-DjfRu9aL.d.cts} +162 -2
- package/dist/{core-DjLtgeVT.d.ts → WasmKeyProvider-DjfRu9aL.d.ts} +162 -2
- package/dist/authority-mTQEgN56.d.cts +97 -0
- package/dist/authority-mTQEgN56.d.ts +97 -0
- package/dist/core.cjs +1049 -443
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +13 -3
- package/dist/core.d.ts +13 -3
- package/dist/core.js +725 -115
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +2348 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -4
- package/dist/index.d.ts +34 -4
- package/dist/index.js +1996 -128
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.cjs +278 -0
- package/dist/replication/authority.cjs.map +1 -0
- package/dist/replication/authority.d.cts +3 -0
- package/dist/replication/authority.d.ts +3 -0
- package/dist/replication/authority.js +257 -0
- package/dist/replication/authority.js.map +1 -0
- package/dist/replication/runtime.cjs +224 -0
- package/dist/replication/runtime.cjs.map +1 -0
- package/dist/replication/runtime.d.cts +3 -0
- package/dist/replication/runtime.d.ts +3 -0
- package/dist/replication/runtime.js +189 -0
- package/dist/replication/runtime.js.map +1 -0
- package/dist/runtime-DyYwHW8j.d.cts +64 -0
- package/dist/runtime-DyYwHW8j.d.ts +64 -0
- package/package.json +25 -3
package/dist/core.cjs
CHANGED
|
@@ -30,109 +30,124 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/core.ts
|
|
31
31
|
var core_exports = {};
|
|
32
32
|
__export(core_exports, {
|
|
33
|
-
ACCOUNT_REGISTRY_PATH: () =>
|
|
34
|
-
ACCOUNT_REGISTRY_SPACE: () =>
|
|
35
|
-
AccountService: () =>
|
|
36
|
-
AutoApproveSpaceCreationHandler: () =>
|
|
37
|
-
CapabilityKeyRegistry: () =>
|
|
38
|
-
CapabilityKeyRegistryErrorCodes: () =>
|
|
39
|
-
CaveatedDelegationUnsupportedError: () =>
|
|
40
|
-
DEFAULT_MANIFEST_SPACE: () =>
|
|
41
|
-
DEFAULT_MANIFEST_VERSION: () =>
|
|
42
|
-
DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () =>
|
|
43
|
-
DataVaultService: () =>
|
|
44
|
-
DatabaseHandle: () =>
|
|
33
|
+
ACCOUNT_REGISTRY_PATH: () => import_sdk_core13.ACCOUNT_REGISTRY_PATH,
|
|
34
|
+
ACCOUNT_REGISTRY_SPACE: () => import_sdk_core13.ACCOUNT_REGISTRY_SPACE,
|
|
35
|
+
AccountService: () => import_sdk_core6.AccountService,
|
|
36
|
+
AutoApproveSpaceCreationHandler: () => import_sdk_core12.AutoApproveSpaceCreationHandler,
|
|
37
|
+
CapabilityKeyRegistry: () => import_sdk_core19.CapabilityKeyRegistry,
|
|
38
|
+
CapabilityKeyRegistryErrorCodes: () => import_sdk_core19.CapabilityKeyRegistryErrorCodes,
|
|
39
|
+
CaveatedDelegationUnsupportedError: () => import_sdk_core13.CaveatedDelegationUnsupportedError,
|
|
40
|
+
DEFAULT_MANIFEST_SPACE: () => import_sdk_core13.DEFAULT_MANIFEST_SPACE,
|
|
41
|
+
DEFAULT_MANIFEST_VERSION: () => import_sdk_core13.DEFAULT_MANIFEST_VERSION,
|
|
42
|
+
DEFAULT_SIGNED_READ_URL_EXPIRY_MS: () => import_sdk_core14.DEFAULT_SIGNED_READ_URL_EXPIRY_MS,
|
|
43
|
+
DataVaultService: () => import_sdk_core17.DataVaultService,
|
|
44
|
+
DatabaseHandle: () => import_sdk_core15.DatabaseHandle,
|
|
45
45
|
DelegatedAccess: () => DelegatedAccess,
|
|
46
|
-
DelegationErrorCodes: () =>
|
|
47
|
-
DelegationManager: () =>
|
|
48
|
-
DuckDbAction: () =>
|
|
49
|
-
DuckDbDatabaseHandle: () =>
|
|
50
|
-
DuckDbService: () =>
|
|
46
|
+
DelegationErrorCodes: () => import_sdk_core18.DelegationErrorCodes,
|
|
47
|
+
DelegationManager: () => import_sdk_core18.DelegationManager,
|
|
48
|
+
DuckDbAction: () => import_sdk_core16.DuckDbAction,
|
|
49
|
+
DuckDbDatabaseHandle: () => import_sdk_core16.DuckDbDatabaseHandle,
|
|
50
|
+
DuckDbService: () => import_sdk_core16.DuckDbService,
|
|
51
51
|
FileSessionStorage: () => FileSessionStorage,
|
|
52
|
-
IdentityParseError: () =>
|
|
52
|
+
IdentityParseError: () => import_sdk_core12.IdentityParseError,
|
|
53
53
|
InvalidRestoredSessionError: () => InvalidRestoredSessionError,
|
|
54
|
-
KVService: () =>
|
|
55
|
-
ManifestValidationError: () =>
|
|
54
|
+
KVService: () => import_sdk_core14.KVService,
|
|
55
|
+
ManifestValidationError: () => import_sdk_core13.ManifestValidationError,
|
|
56
56
|
MemorySessionStorage: () => MemorySessionStorage,
|
|
57
57
|
NodeUserAuthorization: () => NodeUserAuthorization,
|
|
58
|
-
PermissionNotInManifestError: () =>
|
|
59
|
-
PrefixedKVService: () =>
|
|
60
|
-
ProtocolMismatchError: () =>
|
|
61
|
-
SECRET_NAME_RE: () =>
|
|
62
|
-
SQLAction: () =>
|
|
63
|
-
SQLService: () =>
|
|
64
|
-
SecretsService: () =>
|
|
65
|
-
ServiceContext: () =>
|
|
66
|
-
SessionExpiredError: () =>
|
|
67
|
-
SharingService: () =>
|
|
68
|
-
SilentNotificationHandler: () =>
|
|
69
|
-
Space: () =>
|
|
70
|
-
SpaceErrorCodes: () =>
|
|
71
|
-
SpaceService: () =>
|
|
72
|
-
TinyCloud: () =>
|
|
73
|
-
TinyCloudDebugLogger: () =>
|
|
58
|
+
PermissionNotInManifestError: () => import_sdk_core13.PermissionNotInManifestError,
|
|
59
|
+
PrefixedKVService: () => import_sdk_core14.PrefixedKVService,
|
|
60
|
+
ProtocolMismatchError: () => import_sdk_core21.ProtocolMismatchError,
|
|
61
|
+
SECRET_NAME_RE: () => import_sdk_core17.SECRET_NAME_RE,
|
|
62
|
+
SQLAction: () => import_sdk_core15.SQLAction,
|
|
63
|
+
SQLService: () => import_sdk_core15.SQLService,
|
|
64
|
+
SecretsService: () => import_sdk_core17.SecretsService,
|
|
65
|
+
ServiceContext: () => import_sdk_core22.ServiceContext,
|
|
66
|
+
SessionExpiredError: () => import_sdk_core13.SessionExpiredError,
|
|
67
|
+
SharingService: () => import_sdk_core18.SharingService,
|
|
68
|
+
SilentNotificationHandler: () => import_sdk_core12.SilentNotificationHandler,
|
|
69
|
+
Space: () => import_sdk_core20.Space,
|
|
70
|
+
SpaceErrorCodes: () => import_sdk_core20.SpaceErrorCodes,
|
|
71
|
+
SpaceService: () => import_sdk_core20.SpaceService,
|
|
72
|
+
TinyCloud: () => import_sdk_core11.TinyCloud,
|
|
73
|
+
TinyCloudDebugLogger: () => import_sdk_core12.TinyCloudDebugLogger,
|
|
74
74
|
TinyCloudNode: () => TinyCloudNode,
|
|
75
|
-
UnsupportedFeatureError: () =>
|
|
75
|
+
UnsupportedFeatureError: () => import_sdk_core21.UnsupportedFeatureError,
|
|
76
76
|
UnsupportedSessionRestoreError: () => UnsupportedSessionRestoreError,
|
|
77
|
-
VAULT_PERMISSION_SERVICE: () =>
|
|
78
|
-
VaultHeaders: () =>
|
|
79
|
-
VaultPublicSpaceKVActions: () =>
|
|
80
|
-
VersionCheckError: () =>
|
|
77
|
+
VAULT_PERMISSION_SERVICE: () => import_sdk_core13.VAULT_PERMISSION_SERVICE,
|
|
78
|
+
VaultHeaders: () => import_sdk_core17.VaultHeaders,
|
|
79
|
+
VaultPublicSpaceKVActions: () => import_sdk_core17.VaultPublicSpaceKVActions,
|
|
80
|
+
VersionCheckError: () => import_sdk_core21.VersionCheckError,
|
|
81
81
|
WasmKeyProvider: () => WasmKeyProvider,
|
|
82
82
|
activateCompactRuntimeDelegation: () => activateCompactRuntimeDelegation,
|
|
83
|
-
addressStorageKey: () =>
|
|
84
|
-
buildSpaceUri: () =>
|
|
85
|
-
canonicalizeAddress: () =>
|
|
86
|
-
canonicalizeDid: () =>
|
|
87
|
-
canonicalizeDidUrl: () =>
|
|
88
|
-
canonicalizeNetworkId: () =>
|
|
89
|
-
canonicalizeSecretScope: () =>
|
|
90
|
-
checkNodeInfo: () =>
|
|
91
|
-
clearTinyCloudDebugLogs: () =>
|
|
92
|
-
composeManifestRequest: () =>
|
|
93
|
-
createCapabilityKeyRegistry: () =>
|
|
94
|
-
createOpenKeyCallbackSigningStrategy: () =>
|
|
95
|
-
createSharingService: () =>
|
|
96
|
-
createSpaceService: () =>
|
|
97
|
-
createVaultCrypto: () =>
|
|
83
|
+
addressStorageKey: () => import_sdk_core12.addressStorageKey,
|
|
84
|
+
buildSpaceUri: () => import_sdk_core20.buildSpaceUri,
|
|
85
|
+
canonicalizeAddress: () => import_sdk_core12.canonicalizeAddress,
|
|
86
|
+
canonicalizeDid: () => import_sdk_core12.canonicalizeDid,
|
|
87
|
+
canonicalizeDidUrl: () => import_sdk_core12.canonicalizeDidUrl,
|
|
88
|
+
canonicalizeNetworkId: () => import_sdk_core12.canonicalizeNetworkId,
|
|
89
|
+
canonicalizeSecretScope: () => import_sdk_core17.canonicalizeSecretScope,
|
|
90
|
+
checkNodeInfo: () => import_sdk_core21.checkNodeInfo,
|
|
91
|
+
clearTinyCloudDebugLogs: () => import_sdk_core12.clearTinyCloudDebugLogs,
|
|
92
|
+
composeManifestRequest: () => import_sdk_core13.composeManifestRequest,
|
|
93
|
+
createCapabilityKeyRegistry: () => import_sdk_core19.createCapabilityKeyRegistry,
|
|
94
|
+
createOpenKeyCallbackSigningStrategy: () => import_sdk_core3.createOpenKeyCallbackSigningStrategy,
|
|
95
|
+
createSharingService: () => import_sdk_core18.createSharingService,
|
|
96
|
+
createSpaceService: () => import_sdk_core20.createSpaceService,
|
|
97
|
+
createVaultCrypto: () => import_sdk_core17.createVaultCrypto,
|
|
98
98
|
createWasmKeyProvider: () => createWasmKeyProvider,
|
|
99
99
|
defaultSignStrategy: () => defaultSignStrategy,
|
|
100
|
-
defaultSpaceCreationHandler: () =>
|
|
100
|
+
defaultSpaceCreationHandler: () => import_sdk_core12.defaultSpaceCreationHandler,
|
|
101
101
|
deserializeDelegation: () => deserializeDelegation,
|
|
102
|
-
didCacheKey: () =>
|
|
103
|
-
didEquals: () =>
|
|
104
|
-
disableTinyCloudDebug: () =>
|
|
105
|
-
enableTinyCloudDebug: () =>
|
|
106
|
-
expandActionShortNames: () =>
|
|
107
|
-
expandPermissionEntries: () =>
|
|
108
|
-
expandPermissionEntry: () =>
|
|
109
|
-
getTinyCloudDebugLogs: () =>
|
|
110
|
-
installTinyCloudDebugGlobals: () =>
|
|
111
|
-
isCapabilitySubset: () =>
|
|
112
|
-
isEvmAddress: () =>
|
|
113
|
-
loadManifest: () =>
|
|
114
|
-
makePkhSpaceId: () =>
|
|
115
|
-
makePublicSpaceId: () =>
|
|
116
|
-
parseCanonicalNetworkId: () =>
|
|
117
|
-
parseExpiry: () =>
|
|
118
|
-
parsePkhDid: () =>
|
|
119
|
-
parseSecretCatalogKey: () =>
|
|
120
|
-
parseSpaceUri: () =>
|
|
121
|
-
pkhDid: () =>
|
|
122
|
-
principalDid: () =>
|
|
123
|
-
principalDidEquals: () =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
102
|
+
didCacheKey: () => import_sdk_core12.didCacheKey,
|
|
103
|
+
didEquals: () => import_sdk_core12.didEquals,
|
|
104
|
+
disableTinyCloudDebug: () => import_sdk_core12.disableTinyCloudDebug,
|
|
105
|
+
enableTinyCloudDebug: () => import_sdk_core12.enableTinyCloudDebug,
|
|
106
|
+
expandActionShortNames: () => import_sdk_core13.expandActionShortNames,
|
|
107
|
+
expandPermissionEntries: () => import_sdk_core13.expandPermissionEntries,
|
|
108
|
+
expandPermissionEntry: () => import_sdk_core13.expandPermissionEntry,
|
|
109
|
+
getTinyCloudDebugLogs: () => import_sdk_core12.getTinyCloudDebugLogs,
|
|
110
|
+
installTinyCloudDebugGlobals: () => import_sdk_core12.installTinyCloudDebugGlobals,
|
|
111
|
+
isCapabilitySubset: () => import_sdk_core13.isCapabilitySubset,
|
|
112
|
+
isEvmAddress: () => import_sdk_core12.isEvmAddress,
|
|
113
|
+
loadManifest: () => import_sdk_core13.loadManifest,
|
|
114
|
+
makePkhSpaceId: () => import_sdk_core12.makePkhSpaceId,
|
|
115
|
+
makePublicSpaceId: () => import_sdk_core20.makePublicSpaceId,
|
|
116
|
+
parseCanonicalNetworkId: () => import_sdk_core12.parseCanonicalNetworkId,
|
|
117
|
+
parseExpiry: () => import_sdk_core13.parseExpiry,
|
|
118
|
+
parsePkhDid: () => import_sdk_core12.parsePkhDid,
|
|
119
|
+
parseSecretCatalogKey: () => import_sdk_core17.parseSecretCatalogKey,
|
|
120
|
+
parseSpaceUri: () => import_sdk_core20.parseSpaceUri,
|
|
121
|
+
pkhDid: () => import_sdk_core12.pkhDid,
|
|
122
|
+
principalDid: () => import_sdk_core12.principalDid,
|
|
123
|
+
principalDidEquals: () => import_sdk_core12.principalDidEquals,
|
|
124
|
+
registerReplicationLoaders: () => registerReplicationLoaders,
|
|
125
|
+
resolveManifest: () => import_sdk_core13.resolveManifest,
|
|
126
|
+
resolveSecretListPrefix: () => import_sdk_core17.resolveSecretListPrefix,
|
|
127
|
+
resolveSecretPath: () => import_sdk_core17.resolveSecretPath,
|
|
128
|
+
resourceCapabilitiesToSpaceAbilitiesMap: () => import_sdk_core13.resourceCapabilitiesToSpaceAbilitiesMap,
|
|
128
129
|
serializeDelegation: () => serializeDelegation,
|
|
129
|
-
tinyCloudDebugLogger: () =>
|
|
130
|
-
validateManifest: () =>
|
|
130
|
+
tinyCloudDebugLogger: () => import_sdk_core12.tinyCloudDebugLogger,
|
|
131
|
+
validateManifest: () => import_sdk_core13.validateManifest
|
|
131
132
|
});
|
|
132
133
|
module.exports = __toCommonJS(core_exports);
|
|
133
|
-
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
134
134
|
var import_sdk_core11 = require("@tinycloud/sdk-core");
|
|
135
135
|
|
|
136
|
+
// src/replication/module-registry.ts
|
|
137
|
+
var nodeLoaders;
|
|
138
|
+
function registerReplicationLoaders(loaders) {
|
|
139
|
+
nodeLoaders = loaders;
|
|
140
|
+
}
|
|
141
|
+
function getNodeReplicationLoaders() {
|
|
142
|
+
if (nodeLoaders === void 0) {
|
|
143
|
+
throw new Error("Replication requires registering replication controller loaders.");
|
|
144
|
+
}
|
|
145
|
+
return nodeLoaders;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/core.ts
|
|
149
|
+
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
150
|
+
|
|
136
151
|
// src/storage/MemorySessionStorage.ts
|
|
137
152
|
var MemorySessionStorage = class {
|
|
138
153
|
constructor() {
|
|
@@ -327,15 +342,51 @@ var FileSessionStorage = class {
|
|
|
327
342
|
// src/authorization/NodeUserAuthorization.ts
|
|
328
343
|
var import_node_crypto = require("crypto");
|
|
329
344
|
var import_siwe = require("siwe");
|
|
330
|
-
var
|
|
345
|
+
var import_sdk_core4 = require("@tinycloud/sdk-core");
|
|
331
346
|
|
|
332
|
-
// src/
|
|
347
|
+
// src/replication/authority-sign-in.ts
|
|
333
348
|
var import_sdk_core2 = require("@tinycloud/sdk-core");
|
|
349
|
+
var import_sdk_services = require("@tinycloud/sdk-services");
|
|
350
|
+
var KV_GET = import_sdk_core2.KV.GET;
|
|
351
|
+
var KV_SYNC = import_sdk_core2.KV.SYNC;
|
|
352
|
+
var KV_SERVICE = "tinycloud.kv";
|
|
353
|
+
function hasUnrestrictedGetCoverage(entries, spaceId, prefix) {
|
|
354
|
+
const requiredPaths = (0, import_sdk_core2.grantPathsForSelector)(prefix);
|
|
355
|
+
return (0, import_sdk_core2.isCapabilitySubset)(
|
|
356
|
+
requiredPaths.map((path) => ({ service: KV_SERVICE, space: spaceId, path, actions: [KV_GET] })),
|
|
357
|
+
[...entries]
|
|
358
|
+
).subset;
|
|
359
|
+
}
|
|
360
|
+
function augmentSignInEntriesWithReplication(input) {
|
|
361
|
+
const out = [];
|
|
362
|
+
const replication = input.replication;
|
|
363
|
+
if (replication === void 0) return out;
|
|
364
|
+
for (const prefix of replication.prefixes) {
|
|
365
|
+
if ((0, import_sdk_services.requiresSecretsOptIn)(input.primarySpaceId, prefix) && replication.allowSecrets !== true) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (!hasUnrestrictedGetCoverage(input.entries, input.primarySpaceId, prefix)) {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
for (const path of (0, import_sdk_core2.grantPathsForSelector)(prefix)) {
|
|
372
|
+
out.push({
|
|
373
|
+
service: KV_SERVICE,
|
|
374
|
+
space: input.primarySpaceId,
|
|
375
|
+
path,
|
|
376
|
+
actions: [KV_GET, KV_SYNC]
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return out;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/authorization/strategies.ts
|
|
384
|
+
var import_sdk_core3 = require("@tinycloud/sdk-core");
|
|
334
385
|
var defaultSignStrategy = { type: "auto-sign" };
|
|
335
386
|
|
|
336
387
|
// src/authorization/NodeUserAuthorization.ts
|
|
337
|
-
var DECRYPT_ACTION =
|
|
338
|
-
var NETWORK_CREATE_ACTION =
|
|
388
|
+
var DECRYPT_ACTION = import_sdk_core4.ENCRYPTION.DECRYPT;
|
|
389
|
+
var NETWORK_CREATE_ACTION = import_sdk_core4.ENCRYPTION.NETWORK_CREATE;
|
|
339
390
|
function describeHostFailure(result) {
|
|
340
391
|
const text = result.error?.trim();
|
|
341
392
|
return text ? `${result.status} - ${text}` : `${result.status}`;
|
|
@@ -363,7 +414,7 @@ function canonicalOpenKeyManifestSha256Hex(value) {
|
|
|
363
414
|
}
|
|
364
415
|
function didPrincipalMatches(actual, expected) {
|
|
365
416
|
try {
|
|
366
|
-
return (0,
|
|
417
|
+
return (0, import_sdk_core4.principalDidEquals)(actual, expected);
|
|
367
418
|
} catch {
|
|
368
419
|
return actual === expected;
|
|
369
420
|
}
|
|
@@ -404,30 +455,30 @@ var NodeUserAuthorization = class {
|
|
|
404
455
|
this.spacePrefix = config.spacePrefix ?? "default";
|
|
405
456
|
this.defaultActions = config.defaultActions ?? {
|
|
406
457
|
kv: {
|
|
407
|
-
"": [
|
|
458
|
+
"": [import_sdk_core4.KV.PUT, import_sdk_core4.KV.GET, import_sdk_core4.KV.DEL, import_sdk_core4.KV.LIST, import_sdk_core4.KV.METADATA]
|
|
408
459
|
},
|
|
409
460
|
sql: {
|
|
410
|
-
"": [
|
|
461
|
+
"": [import_sdk_core4.SQL.READ, import_sdk_core4.SQL.WRITE, import_sdk_core4.SQL.SCHEMA, import_sdk_core4.SQL.ADMIN, import_sdk_core4.SQL.EXPORT]
|
|
411
462
|
},
|
|
412
463
|
duckdb: {
|
|
413
464
|
"": [
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
465
|
+
import_sdk_core4.DUCKDB.READ,
|
|
466
|
+
import_sdk_core4.DUCKDB.WRITE,
|
|
467
|
+
import_sdk_core4.DUCKDB.ADMIN,
|
|
468
|
+
import_sdk_core4.DUCKDB.DESCRIBE,
|
|
469
|
+
import_sdk_core4.DUCKDB.EXPORT,
|
|
470
|
+
import_sdk_core4.DUCKDB.IMPORT,
|
|
471
|
+
import_sdk_core4.DUCKDB.EXECUTE
|
|
421
472
|
]
|
|
422
473
|
},
|
|
423
474
|
capabilities: {
|
|
424
|
-
"": [
|
|
475
|
+
"": [import_sdk_core4.CAPABILITIES.READ]
|
|
425
476
|
},
|
|
426
477
|
hooks: {
|
|
427
|
-
"": [
|
|
478
|
+
"": [import_sdk_core4.HOOKS.SUBSCRIBE, import_sdk_core4.HOOKS.REGISTER, import_sdk_core4.HOOKS.LIST, import_sdk_core4.HOOKS.UNREGISTER]
|
|
428
479
|
}
|
|
429
480
|
};
|
|
430
|
-
this.sessionExpirationMs = config.sessionExpirationMs ??
|
|
481
|
+
this.sessionExpirationMs = config.sessionExpirationMs ?? import_sdk_core4.EXPIRY.SESSION_MS;
|
|
431
482
|
this.autoCreateSpace = config.autoCreateSpace ?? false;
|
|
432
483
|
this.spaceCreationHandler = config.spaceCreationHandler;
|
|
433
484
|
this.tinycloudHosts = config.tinycloudHosts;
|
|
@@ -442,6 +493,7 @@ var NodeUserAuthorization = class {
|
|
|
442
493
|
this.nonce = config.nonce;
|
|
443
494
|
this.siweConfig = config.siweConfig;
|
|
444
495
|
this.includeAccountRegistryPermissions = config.includeAccountRegistryPermissions ?? true;
|
|
496
|
+
this.replication = config.replication?.enabled === true ? config.replication : void 0;
|
|
445
497
|
this._manifest = config.manifest;
|
|
446
498
|
this._capabilityRequest = config.capabilityRequest;
|
|
447
499
|
this.sessionManager = config.sessionManager ?? this.wasm.createSessionManager();
|
|
@@ -506,7 +558,7 @@ var NodeUserAuthorization = class {
|
|
|
506
558
|
* {@link ensureTinyCloudHosts}.
|
|
507
559
|
*/
|
|
508
560
|
setRestoredTinyCloudSession(session, hosts) {
|
|
509
|
-
const address = (0,
|
|
561
|
+
const address = (0, import_sdk_core4.canonicalizeAddress)(session.address);
|
|
510
562
|
this._tinyCloudSession = { ...session, address };
|
|
511
563
|
this._address = address;
|
|
512
564
|
this._chainId = session.chainId;
|
|
@@ -567,8 +619,8 @@ var NodeUserAuthorization = class {
|
|
|
567
619
|
if (this.tinycloudHosts && this.tinycloudHosts.length > 0) {
|
|
568
620
|
return;
|
|
569
621
|
}
|
|
570
|
-
const subject = (0,
|
|
571
|
-
const resolved = await (0,
|
|
622
|
+
const subject = (0, import_sdk_core4.pkhDid)(address, chainId);
|
|
623
|
+
const resolved = await (0, import_sdk_core4.resolveTinyCloudHosts)(subject, {
|
|
572
624
|
registryUrl: this.tinycloudRegistryUrl,
|
|
573
625
|
fallbackHosts: this.tinycloudFallbackHosts,
|
|
574
626
|
autoDiscoverLocalNode: this.autoDiscoverLocalNode,
|
|
@@ -636,7 +688,7 @@ var NodeUserAuthorization = class {
|
|
|
636
688
|
if (this._manifest === void 0) {
|
|
637
689
|
return void 0;
|
|
638
690
|
}
|
|
639
|
-
this._capabilityRequest = (0,
|
|
691
|
+
this._capabilityRequest = (0, import_sdk_core4.composeManifestRequest)(
|
|
640
692
|
Array.isArray(this._manifest) ? this._manifest : [this._manifest],
|
|
641
693
|
{
|
|
642
694
|
includeAccountRegistryPermissions: this.includeAccountRegistryPermissions
|
|
@@ -648,50 +700,173 @@ var NodeUserAuthorization = class {
|
|
|
648
700
|
if (space.startsWith("tinycloud:")) {
|
|
649
701
|
return space;
|
|
650
702
|
}
|
|
651
|
-
return (0,
|
|
703
|
+
return (0, import_sdk_core4.makePkhSpaceId)(address, chainId, space);
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* The plain-session primary abilities: `defaultActions` (the shared table)
|
|
707
|
+
* unless the primary space IS the account space, where account-registry
|
|
708
|
+
* permissions merge into a private clone so the shared table is never
|
|
709
|
+
* mutated. Shared between `resolveSignInCapabilities` and
|
|
710
|
+
* `signInPermissionInputs` so sign-in and `replicationSignInEntries`
|
|
711
|
+
* can't disagree (§4.6).
|
|
712
|
+
*/
|
|
713
|
+
primaryActionsForSignIn() {
|
|
714
|
+
const primaryActions = this.includeAccountRegistryPermissions && this.spacePrefix === import_sdk_core4.ACCOUNT_REGISTRY_SPACE ? cloneAbilitiesMap(this.defaultActions) : this.defaultActions;
|
|
715
|
+
if (this.includeAccountRegistryPermissions && this.spacePrefix === import_sdk_core4.ACCOUNT_REGISTRY_SPACE) {
|
|
716
|
+
const accountAbilities = (0, import_sdk_core4.resourceCapabilitiesToAbilitiesMap)(
|
|
717
|
+
import_sdk_core4.ACCOUNT_MANIFEST_PERMISSIONS
|
|
718
|
+
);
|
|
719
|
+
for (const [service, paths] of Object.entries(accountAbilities)) {
|
|
720
|
+
const existingPaths = primaryActions[service] ?? (primaryActions[service] = {});
|
|
721
|
+
for (const [path, actions] of Object.entries(paths)) {
|
|
722
|
+
const existingActions = existingPaths[path] ?? (existingPaths[path] = []);
|
|
723
|
+
for (const action of actions) {
|
|
724
|
+
if (!existingActions.includes(action)) existingActions.push(action);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return primaryActions;
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* The abilities a `spacePrefix: "secrets"` plain session actually requests
|
|
733
|
+
* for its primary space: the vault-secrets subtree only — the
|
|
734
|
+
* `defaultActions` root `get` is REPLACED, not merged (sign-in installs
|
|
735
|
+
* this map under the primary space id). Shared between
|
|
736
|
+
* `resolveSignInCapabilities` and `signInPermissionInputs` so the
|
|
737
|
+
* replication augmentation measures coverage against the effective
|
|
738
|
+
* pre-replication request, never the uninstalled `primaryActions` (§4.1).
|
|
739
|
+
*/
|
|
740
|
+
secretsPrimaryAbilities() {
|
|
741
|
+
return {
|
|
742
|
+
kv: {
|
|
743
|
+
"vault/secrets/": [
|
|
744
|
+
import_sdk_core4.KV.GET,
|
|
745
|
+
import_sdk_core4.KV.PUT,
|
|
746
|
+
import_sdk_core4.KV.DEL,
|
|
747
|
+
import_sdk_core4.KV.LIST,
|
|
748
|
+
import_sdk_core4.KV.METADATA
|
|
749
|
+
]
|
|
750
|
+
}
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* The effective sign-in request as `PermissionEntry`s plus the resolved
|
|
755
|
+
* primary space id — the inputs to the replication augmentation (§4.1).
|
|
756
|
+
* `resolveSignInCapabilities` merges the augmented entries into its
|
|
757
|
+
* abilities; `replicationSignInEntries()` returns them verbatim, so the
|
|
758
|
+
* entries the SIWE recap carries and the restore check sees are the same.
|
|
759
|
+
*/
|
|
760
|
+
signInPermissionInputs(address, chainId) {
|
|
761
|
+
const request = this.getCapabilityRequest();
|
|
762
|
+
if (request === void 0) {
|
|
763
|
+
const primarySpaceId2 = (0, import_sdk_core4.makePkhSpaceId)(address, chainId, this.spacePrefix);
|
|
764
|
+
const effectivePrimary = this.spacePrefix === "secrets" ? this.secretsPrimaryAbilities() : this.primaryActionsForSignIn();
|
|
765
|
+
const kvPaths = effectivePrimary["kv"] ?? {};
|
|
766
|
+
return {
|
|
767
|
+
primarySpaceId: primarySpaceId2,
|
|
768
|
+
entries: Object.entries(kvPaths).map(([path, actions]) => ({
|
|
769
|
+
service: "tinycloud.kv",
|
|
770
|
+
space: primarySpaceId2,
|
|
771
|
+
path,
|
|
772
|
+
actions: [...actions]
|
|
773
|
+
}))
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
const spaceResources = request.resources.filter(
|
|
777
|
+
(entry) => entry.service !== import_sdk_core4.ENCRYPTION_PERMISSION_SERVICE
|
|
778
|
+
);
|
|
779
|
+
const primarySpaceName = spaceResources.find((entry) => entry.space !== "account")?.space ?? import_sdk_core4.DEFAULT_MANIFEST_SPACE;
|
|
780
|
+
const primarySpaceId = this.resolveSpaceName(
|
|
781
|
+
primarySpaceName,
|
|
782
|
+
address,
|
|
783
|
+
chainId
|
|
784
|
+
);
|
|
785
|
+
return {
|
|
786
|
+
primarySpaceId,
|
|
787
|
+
entries: spaceResources.map((entry) => ({
|
|
788
|
+
service: entry.service,
|
|
789
|
+
space: this.resolveSpaceName(entry.space, address, chainId),
|
|
790
|
+
path: entry.path,
|
|
791
|
+
actions: [...entry.actions]
|
|
792
|
+
}))
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Merge replication augmentation entries into a space's abilities map
|
|
797
|
+
* without mutating shared tables (`defaultActions` may back the base map):
|
|
798
|
+
* the primary entry in `spaceAbilities` is replaced with a copy whose `kv`
|
|
799
|
+
* paths gain `get`/`sync`. Returns the merged map for `abilities`.
|
|
800
|
+
*/
|
|
801
|
+
mergeReplicationEntries(spaceAbilities, primarySpaceId, abilities, entries) {
|
|
802
|
+
var _a;
|
|
803
|
+
if (entries.length === 0) {
|
|
804
|
+
return abilities;
|
|
805
|
+
}
|
|
806
|
+
const base = spaceAbilities[primarySpaceId] ?? abilities;
|
|
807
|
+
const kv = {};
|
|
808
|
+
for (const [path, actions] of Object.entries(base["kv"] ?? {})) {
|
|
809
|
+
kv[path] = [...actions];
|
|
810
|
+
}
|
|
811
|
+
for (const entry of entries) {
|
|
812
|
+
const list = kv[_a = entry.path] ?? (kv[_a] = []);
|
|
813
|
+
for (const action of entry.actions) {
|
|
814
|
+
if (!list.includes(action)) list.push(action);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
const merged = { ...base, kv };
|
|
818
|
+
spaceAbilities[primarySpaceId] = merged;
|
|
819
|
+
return merged;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* The replication entries this authorization's sign-in request carries
|
|
823
|
+
* for the signed-in or restored address (TC-858 §4.1/§4.6): the output of
|
|
824
|
+
* the same augmentation `resolveSignInCapabilities` runs — one
|
|
825
|
+
* `{tinycloud.kv, primarySpace, prefix, [get, sync]}` per configured
|
|
826
|
+
* prefix that already has an unrestricted covering `get` and passes the
|
|
827
|
+
* secrets opt-in gate. Empty when replication is off or no address is
|
|
828
|
+
* known. Pure.
|
|
829
|
+
*/
|
|
830
|
+
replicationSignInEntries() {
|
|
831
|
+
if (this.replication === void 0) return [];
|
|
832
|
+
const address = this._address ?? this._tinyCloudSession?.address;
|
|
833
|
+
const chainId = this._chainId ?? this._tinyCloudSession?.chainId;
|
|
834
|
+
if (address === void 0 || chainId === void 0) return [];
|
|
835
|
+
const { entries, primarySpaceId } = this.signInPermissionInputs(address, chainId);
|
|
836
|
+
return augmentSignInEntriesWithReplication({
|
|
837
|
+
entries,
|
|
838
|
+
primarySpaceId,
|
|
839
|
+
replication: this.replication
|
|
840
|
+
});
|
|
652
841
|
}
|
|
653
842
|
defaultEncryptionNetworkId(address, chainId) {
|
|
654
|
-
return `urn:tinycloud:encryption:${(0,
|
|
843
|
+
return `urn:tinycloud:encryption:${(0, import_sdk_core4.pkhDid)(address, chainId)}:default`;
|
|
655
844
|
}
|
|
656
845
|
resolveSignInCapabilities(address, chainId) {
|
|
657
846
|
const request = this.getCapabilityRequest();
|
|
658
847
|
if (request === void 0) {
|
|
659
848
|
const defaultNetworkId = this.defaultEncryptionNetworkId(address, chainId);
|
|
660
|
-
const primarySpaceId2 = (0,
|
|
661
|
-
const secretsSpaceId = (0,
|
|
662
|
-
const primaryActions = this.
|
|
849
|
+
const primarySpaceId2 = (0, import_sdk_core4.makePkhSpaceId)(address, chainId, this.spacePrefix);
|
|
850
|
+
const secretsSpaceId = (0, import_sdk_core4.makePkhSpaceId)(address, chainId, "secrets");
|
|
851
|
+
const primaryActions = this.primaryActionsForSignIn();
|
|
663
852
|
const spaceAbilities2 = {
|
|
664
853
|
[primarySpaceId2]: primaryActions,
|
|
665
|
-
[secretsSpaceId]:
|
|
666
|
-
kv: {
|
|
667
|
-
"vault/secrets/": [
|
|
668
|
-
import_sdk_core3.KV.GET,
|
|
669
|
-
import_sdk_core3.KV.PUT,
|
|
670
|
-
import_sdk_core3.KV.DEL,
|
|
671
|
-
import_sdk_core3.KV.LIST,
|
|
672
|
-
import_sdk_core3.KV.METADATA
|
|
673
|
-
]
|
|
674
|
-
}
|
|
675
|
-
}
|
|
854
|
+
[secretsSpaceId]: this.secretsPrimaryAbilities()
|
|
676
855
|
};
|
|
677
|
-
if (this.includeAccountRegistryPermissions && this.spacePrefix !==
|
|
678
|
-
spaceAbilities2[(0,
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
}
|
|
856
|
+
if (this.includeAccountRegistryPermissions && this.spacePrefix !== import_sdk_core4.ACCOUNT_REGISTRY_SPACE) {
|
|
857
|
+
spaceAbilities2[(0, import_sdk_core4.makePkhSpaceId)(address, chainId, import_sdk_core4.ACCOUNT_REGISTRY_SPACE)] = (0, import_sdk_core4.resourceCapabilitiesToAbilitiesMap)(import_sdk_core4.ACCOUNT_MANIFEST_PERMISSIONS);
|
|
858
|
+
}
|
|
859
|
+
const mergedPrimary = this.mergeReplicationEntries(
|
|
860
|
+
spaceAbilities2,
|
|
861
|
+
primarySpaceId2,
|
|
862
|
+
primaryActions,
|
|
863
|
+
augmentSignInEntriesWithReplication({
|
|
864
|
+
...this.signInPermissionInputs(address, chainId),
|
|
865
|
+
replication: this.replication
|
|
866
|
+
})
|
|
867
|
+
);
|
|
693
868
|
return {
|
|
694
|
-
abilities:
|
|
869
|
+
abilities: mergedPrimary,
|
|
695
870
|
spaceId: primarySpaceId2,
|
|
696
871
|
spaceAbilities: spaceAbilities2,
|
|
697
872
|
rawAbilities: {
|
|
@@ -700,35 +875,44 @@ var NodeUserAuthorization = class {
|
|
|
700
875
|
};
|
|
701
876
|
}
|
|
702
877
|
const rawAbilities = {};
|
|
703
|
-
const currentDid = (0,
|
|
878
|
+
const currentDid = (0, import_sdk_core4.pkhDid)(address, chainId);
|
|
704
879
|
const spaceResources = request.resources.filter((entry) => {
|
|
705
|
-
if (entry.service !==
|
|
880
|
+
if (entry.service !== import_sdk_core4.ENCRYPTION_PERMISSION_SERVICE) {
|
|
706
881
|
return true;
|
|
707
882
|
}
|
|
708
883
|
for (const action of entry.actions) {
|
|
709
884
|
addRawAbility(rawAbilities, entry.path, action);
|
|
710
885
|
}
|
|
711
886
|
if (entry.actions.includes(DECRYPT_ACTION)) {
|
|
712
|
-
const parsed = (0,
|
|
887
|
+
const parsed = (0, import_sdk_core4.parseNetworkId)(entry.path);
|
|
713
888
|
if (didPrincipalMatches(parsed.ownerDid, currentDid)) {
|
|
714
889
|
addRawAbility(rawAbilities, entry.path, NETWORK_CREATE_ACTION);
|
|
715
890
|
}
|
|
716
891
|
}
|
|
717
892
|
return false;
|
|
718
893
|
});
|
|
719
|
-
const primarySpaceName = spaceResources.find((entry) => entry.space !== "account")?.space ??
|
|
894
|
+
const primarySpaceName = spaceResources.find((entry) => entry.space !== "account")?.space ?? import_sdk_core4.DEFAULT_MANIFEST_SPACE;
|
|
720
895
|
const primarySpaceId = this.resolveSpaceName(
|
|
721
896
|
primarySpaceName,
|
|
722
897
|
address,
|
|
723
898
|
chainId
|
|
724
899
|
);
|
|
725
|
-
const bySpace = (0,
|
|
900
|
+
const bySpace = (0, import_sdk_core4.resourceCapabilitiesToSpaceAbilitiesMap)(spaceResources);
|
|
726
901
|
const spaceAbilities = {};
|
|
727
902
|
for (const [space, abilities] of Object.entries(bySpace)) {
|
|
728
903
|
spaceAbilities[this.resolveSpaceName(space, address, chainId)] = abilities;
|
|
729
904
|
}
|
|
905
|
+
const mergedPrimaryAbilities = this.mergeReplicationEntries(
|
|
906
|
+
spaceAbilities,
|
|
907
|
+
primarySpaceId,
|
|
908
|
+
spaceAbilities[primarySpaceId] ?? (0, import_sdk_core4.resourceCapabilitiesToAbilitiesMap)([]),
|
|
909
|
+
augmentSignInEntriesWithReplication({
|
|
910
|
+
...this.signInPermissionInputs(address, chainId),
|
|
911
|
+
replication: this.replication
|
|
912
|
+
})
|
|
913
|
+
);
|
|
730
914
|
return {
|
|
731
|
-
abilities:
|
|
915
|
+
abilities: mergedPrimaryAbilities,
|
|
732
916
|
spaceId: primarySpaceId,
|
|
733
917
|
spaceAbilities,
|
|
734
918
|
rawAbilities: Object.keys(rawAbilities).length > 0 ? rawAbilities : void 0
|
|
@@ -786,14 +970,14 @@ var NodeUserAuthorization = class {
|
|
|
786
970
|
* Create the space on the TinyCloud server (host delegation).
|
|
787
971
|
* This registers the user as the owner of the space.
|
|
788
972
|
*/
|
|
789
|
-
async hostSpace(targetSpaceId, purpose) {
|
|
973
|
+
async hostSpace(targetSpaceId, purpose, signal) {
|
|
790
974
|
if (!this._tinyCloudSession || !this._address || !this._chainId) {
|
|
791
975
|
throw new Error("Must be signed in to host space");
|
|
792
976
|
}
|
|
793
977
|
await this.ensureTinyCloudHosts();
|
|
794
978
|
const host = this.primaryTinyCloudHost;
|
|
795
979
|
const spaceId = targetSpaceId ?? this._tinyCloudSession.spaceId;
|
|
796
|
-
const peerId = await (0,
|
|
980
|
+
const peerId = await (0, import_sdk_core4.fetchPeerId)(host, spaceId, signal);
|
|
797
981
|
const siwe = this.wasm.generateHostSIWEMessage({
|
|
798
982
|
address: this._address,
|
|
799
983
|
chainId: this._chainId,
|
|
@@ -802,9 +986,28 @@ var NodeUserAuthorization = class {
|
|
|
802
986
|
spaceId,
|
|
803
987
|
peerId
|
|
804
988
|
});
|
|
805
|
-
|
|
989
|
+
if (signal?.aborted) throw signal.reason;
|
|
990
|
+
const signing = this.signMessage(siwe, purpose);
|
|
991
|
+
let signature;
|
|
992
|
+
if (!signal) {
|
|
993
|
+
signature = await signing;
|
|
994
|
+
} else {
|
|
995
|
+
let rejectOnAbort;
|
|
996
|
+
const aborted = new Promise((_resolve, reject2) => {
|
|
997
|
+
rejectOnAbort = reject2;
|
|
998
|
+
});
|
|
999
|
+
const onAbort = () => rejectOnAbort(signal.reason);
|
|
1000
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1001
|
+
if (signal.aborted) onAbort();
|
|
1002
|
+
try {
|
|
1003
|
+
signature = await Promise.race([signing, aborted]);
|
|
1004
|
+
} finally {
|
|
1005
|
+
signal.removeEventListener("abort", onAbort);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
if (signal?.aborted) throw signal.reason;
|
|
806
1009
|
const headers = this.wasm.siweToDelegationHeaders({ siwe, signature });
|
|
807
|
-
return (0,
|
|
1010
|
+
return (0, import_sdk_core4.submitHostDelegation)(host, headers, signal);
|
|
808
1011
|
}
|
|
809
1012
|
/**
|
|
810
1013
|
* Create a specific space on the server via host delegation.
|
|
@@ -825,8 +1028,8 @@ var NodeUserAuthorization = class {
|
|
|
825
1028
|
* keeps its HTTP status (e.g. a typed 401/403) instead of collapsing to
|
|
826
1029
|
* `false`.
|
|
827
1030
|
*/
|
|
828
|
-
async hostOwnedSpaceResult(spaceId, purpose) {
|
|
829
|
-
return this.hostSpace(spaceId, purpose);
|
|
1031
|
+
async hostOwnedSpaceResult(spaceId, purpose, signal) {
|
|
1032
|
+
return this.hostSpace(spaceId, purpose, signal);
|
|
830
1033
|
}
|
|
831
1034
|
/**
|
|
832
1035
|
* Ensure the user's space exists on the TinyCloud server.
|
|
@@ -843,12 +1046,12 @@ var NodeUserAuthorization = class {
|
|
|
843
1046
|
await this.ensureTinyCloudHosts();
|
|
844
1047
|
const host = this.primaryTinyCloudHost;
|
|
845
1048
|
const primarySpaceId = this._tinyCloudSession.spaceId;
|
|
846
|
-
const result = await (0,
|
|
1049
|
+
const result = await (0, import_sdk_core4.activateSessionWithHost)(
|
|
847
1050
|
host,
|
|
848
1051
|
this._tinyCloudSession.delegationHeader
|
|
849
1052
|
);
|
|
850
1053
|
this.recordActivationSkippedSpaces(result, primarySpaceId);
|
|
851
|
-
const handler = this.spaceCreationHandler ?? (this.autoCreateSpace ? new
|
|
1054
|
+
const handler = this.spaceCreationHandler ?? (this.autoCreateSpace ? new import_sdk_core4.AutoApproveSpaceCreationHandler() : void 0);
|
|
852
1055
|
const creationContext = {
|
|
853
1056
|
spaceId: primarySpaceId,
|
|
854
1057
|
address: this._address,
|
|
@@ -884,7 +1087,7 @@ var NodeUserAuthorization = class {
|
|
|
884
1087
|
throw error;
|
|
885
1088
|
}
|
|
886
1089
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
887
|
-
const retryResult = await (0,
|
|
1090
|
+
const retryResult = await (0, import_sdk_core4.activateSessionWithHost)(
|
|
888
1091
|
host,
|
|
889
1092
|
this._tinyCloudSession.delegationHeader
|
|
890
1093
|
);
|
|
@@ -924,7 +1127,7 @@ var NodeUserAuthorization = class {
|
|
|
924
1127
|
throw error;
|
|
925
1128
|
}
|
|
926
1129
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
927
|
-
const retryResult = await (0,
|
|
1130
|
+
const retryResult = await (0, import_sdk_core4.activateSessionWithHost)(
|
|
928
1131
|
host,
|
|
929
1132
|
this._tinyCloudSession.delegationHeader
|
|
930
1133
|
);
|
|
@@ -966,7 +1169,7 @@ var NodeUserAuthorization = class {
|
|
|
966
1169
|
const jwk = JSON.parse(jwkString);
|
|
967
1170
|
const now = /* @__PURE__ */ new Date();
|
|
968
1171
|
const expirationTime = new Date(now.getTime() + this.sessionExpirationMs);
|
|
969
|
-
const abilities = (0,
|
|
1172
|
+
const abilities = (0, import_sdk_core4.resourceCapabilitiesToAbilitiesMap)(
|
|
970
1173
|
options.capabilityRequest.resources
|
|
971
1174
|
);
|
|
972
1175
|
const prepared = this.wasm.prepareSession({
|
|
@@ -1017,7 +1220,7 @@ var NodeUserAuthorization = class {
|
|
|
1017
1220
|
* @param options - Optional per-call SIWE overrides for this sign-in only
|
|
1018
1221
|
*/
|
|
1019
1222
|
async signIn(options) {
|
|
1020
|
-
this._address = (0,
|
|
1223
|
+
this._address = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1021
1224
|
this._chainId = await this.signer.getChainId();
|
|
1022
1225
|
const address = this._address;
|
|
1023
1226
|
const chainId = this._chainId;
|
|
@@ -1066,7 +1269,7 @@ var NodeUserAuthorization = class {
|
|
|
1066
1269
|
siwe: prepared.siwe,
|
|
1067
1270
|
signature
|
|
1068
1271
|
};
|
|
1069
|
-
const spacesMetadata = this.enablePublicSpace ? { public: (0,
|
|
1272
|
+
const spacesMetadata = this.enablePublicSpace ? { public: (0, import_sdk_core4.makePkhSpaceId)(address, chainId, "public") } : void 0;
|
|
1070
1273
|
const tinyCloudSession = {
|
|
1071
1274
|
address,
|
|
1072
1275
|
chainId,
|
|
@@ -1104,7 +1307,7 @@ var NodeUserAuthorization = class {
|
|
|
1104
1307
|
this._address = address;
|
|
1105
1308
|
this._chainId = chainId;
|
|
1106
1309
|
const infoHost = this.primaryTinyCloudHost;
|
|
1107
|
-
const nodeInfo = await (0,
|
|
1310
|
+
const nodeInfo = await (0, import_sdk_core4.checkNodeInfo)(
|
|
1108
1311
|
infoHost,
|
|
1109
1312
|
this.wasm.protocolVersion()
|
|
1110
1313
|
);
|
|
@@ -1144,7 +1347,7 @@ var NodeUserAuthorization = class {
|
|
|
1144
1347
|
*/
|
|
1145
1348
|
async signMessage(message, purpose) {
|
|
1146
1349
|
if (!this._address) {
|
|
1147
|
-
this._address = (0,
|
|
1350
|
+
this._address = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1148
1351
|
}
|
|
1149
1352
|
if (!this._chainId) {
|
|
1150
1353
|
this._chainId = await this.signer.getChainId();
|
|
@@ -1172,7 +1375,7 @@ var NodeUserAuthorization = class {
|
|
|
1172
1375
|
* ```
|
|
1173
1376
|
*/
|
|
1174
1377
|
async prepareSessionForSigning() {
|
|
1175
|
-
const address = (0,
|
|
1378
|
+
const address = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1176
1379
|
const chainId = await this.signer.getChainId();
|
|
1177
1380
|
const keyId = `session-${Date.now()}`;
|
|
1178
1381
|
this.sessionManager.renameSessionKeyId(this.activeSessionKeyId, keyId);
|
|
@@ -1223,7 +1426,7 @@ var NodeUserAuthorization = class {
|
|
|
1223
1426
|
...prepared,
|
|
1224
1427
|
signature
|
|
1225
1428
|
});
|
|
1226
|
-
const address = (0,
|
|
1429
|
+
const address = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1227
1430
|
const chainId = await this.signer.getChainId();
|
|
1228
1431
|
await this.resolveTinyCloudHostsForSignIn(address, chainId);
|
|
1229
1432
|
const clientSession = {
|
|
@@ -1234,7 +1437,7 @@ var NodeUserAuthorization = class {
|
|
|
1234
1437
|
siwe: prepared.siwe,
|
|
1235
1438
|
signature
|
|
1236
1439
|
};
|
|
1237
|
-
const spacesMetadata = this.enablePublicSpace ? { public: (0,
|
|
1440
|
+
const spacesMetadata = this.enablePublicSpace ? { public: (0, import_sdk_core4.makePkhSpaceId)(address, chainId, "public") } : void 0;
|
|
1238
1441
|
const tinyCloudSession = {
|
|
1239
1442
|
address,
|
|
1240
1443
|
chainId,
|
|
@@ -1276,7 +1479,7 @@ var NodeUserAuthorization = class {
|
|
|
1276
1479
|
this._address = address;
|
|
1277
1480
|
this._chainId = chainId;
|
|
1278
1481
|
const infoHost = this.primaryTinyCloudHost;
|
|
1279
|
-
const nodeInfo = await (0,
|
|
1482
|
+
const nodeInfo = await (0, import_sdk_core4.checkNodeInfo)(
|
|
1280
1483
|
infoHost,
|
|
1281
1484
|
this.wasm.protocolVersion()
|
|
1282
1485
|
);
|
|
@@ -1332,7 +1535,7 @@ var NodeUserAuthorization = class {
|
|
|
1332
1535
|
}
|
|
1333
1536
|
this.tinycloudHosts = [overrideHost];
|
|
1334
1537
|
}
|
|
1335
|
-
const signingAddress = (0,
|
|
1538
|
+
const signingAddress = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1336
1539
|
const signingChainId = await this.signer.getChainId();
|
|
1337
1540
|
await this.resolveTinyCloudHostsForSignIn(signingAddress, signingChainId);
|
|
1338
1541
|
const { prepared, keyId, jwk } = await this.prepareSessionForSigning();
|
|
@@ -1437,8 +1640,8 @@ var NodeUserAuthorization = class {
|
|
|
1437
1640
|
"signInWithOpenKeyResult requires prepared.siwe (the SDK-generated SIWE the sign-in was proposed with)"
|
|
1438
1641
|
);
|
|
1439
1642
|
}
|
|
1440
|
-
const expectedAddress = (0,
|
|
1441
|
-
if ((0,
|
|
1643
|
+
const expectedAddress = (0, import_sdk_core4.canonicalizeAddress)(await this.signer.getAddress());
|
|
1644
|
+
if ((0, import_sdk_core4.canonicalizeAddress)(result.address) !== expectedAddress) {
|
|
1442
1645
|
throw new Error(
|
|
1443
1646
|
`OpenKey returned signature from ${result.address} but expected ${expectedAddress}`
|
|
1444
1647
|
);
|
|
@@ -1463,15 +1666,15 @@ var NodeUserAuthorization = class {
|
|
|
1463
1666
|
`OpenKey signature verification failed${type ? `: ${type}` : ""}${details}`
|
|
1464
1667
|
);
|
|
1465
1668
|
}
|
|
1466
|
-
if ((0,
|
|
1669
|
+
if ((0, import_sdk_core4.canonicalizeAddress)(parsedSignedSiwe.address) !== expectedAddress) {
|
|
1467
1670
|
throw new Error(
|
|
1468
1671
|
`OpenKey signedMessage.address (${parsedSignedSiwe.address}) does not match local signer address (${expectedAddress})`
|
|
1469
1672
|
);
|
|
1470
1673
|
}
|
|
1471
1674
|
const originalHasRecap = /(?:^|\n)-\s+urn:recap:/i.test(prepared.siwe);
|
|
1472
|
-
const originalFields = (0,
|
|
1473
|
-
const signedFields = (0,
|
|
1474
|
-
const changedFields = (0,
|
|
1675
|
+
const originalFields = (0, import_sdk_core4.extractImmutableSiweFields)(prepared.siwe);
|
|
1676
|
+
const signedFields = (0, import_sdk_core4.extractImmutableSiweFields)(result.signedMessage);
|
|
1677
|
+
const changedFields = (0, import_sdk_core4.diffImmutableSiweFields)(originalFields, signedFields, {
|
|
1475
1678
|
originalHasRecap
|
|
1476
1679
|
});
|
|
1477
1680
|
if (changedFields.length > 0) {
|
|
@@ -1482,20 +1685,20 @@ var NodeUserAuthorization = class {
|
|
|
1482
1685
|
let originalCaps;
|
|
1483
1686
|
let signedCaps;
|
|
1484
1687
|
try {
|
|
1485
|
-
originalCaps = (0,
|
|
1688
|
+
originalCaps = (0, import_sdk_core4.extractRecapAttenuations)(prepared.siwe);
|
|
1486
1689
|
} catch (err) {
|
|
1487
1690
|
throw new Error(
|
|
1488
1691
|
`Failed to decode prepared SIWE recap: ${err.message}`
|
|
1489
1692
|
);
|
|
1490
1693
|
}
|
|
1491
1694
|
try {
|
|
1492
|
-
signedCaps = (0,
|
|
1695
|
+
signedCaps = (0, import_sdk_core4.extractRecapAttenuations)(result.signedMessage);
|
|
1493
1696
|
} catch (err) {
|
|
1494
1697
|
throw new Error(
|
|
1495
1698
|
`Failed to decode OpenKey signedMessage recap: ${err.message}`
|
|
1496
1699
|
);
|
|
1497
1700
|
}
|
|
1498
|
-
const unauthorized = (0,
|
|
1701
|
+
const unauthorized = (0, import_sdk_core4.unauthorizedRecapCapabilities)(signedCaps, originalCaps);
|
|
1499
1702
|
if (unauthorized.length > 0) {
|
|
1500
1703
|
const previewLimit = 5;
|
|
1501
1704
|
const preview = unauthorized.slice(0, previewLimit).map((u) => `${u.resource}::${u.action}`).join(", ");
|
|
@@ -1512,7 +1715,7 @@ var NodeUserAuthorization = class {
|
|
|
1512
1715
|
const grantedPairs = /* @__PURE__ */ new Set();
|
|
1513
1716
|
const grantedFourPartIndex = /* @__PURE__ */ new Map();
|
|
1514
1717
|
for (const [resource, actions] of Object.entries(signedCaps)) {
|
|
1515
|
-
const { space, path } = (0,
|
|
1718
|
+
const { space, path } = (0, import_sdk_core4.parseCanonicalRecapResource)(resource);
|
|
1516
1719
|
for (const action of Object.keys(actions)) {
|
|
1517
1720
|
grantedPairs.add(`${resource}\0${action}`);
|
|
1518
1721
|
const slashIdx = action.indexOf("/");
|
|
@@ -1753,7 +1956,7 @@ var NodeUserAuthorization = class {
|
|
|
1753
1956
|
};
|
|
1754
1957
|
|
|
1755
1958
|
// src/delegation.ts
|
|
1756
|
-
var
|
|
1959
|
+
var import_sdk_core5 = require("@tinycloud/sdk-core");
|
|
1757
1960
|
var RuntimeDelegationRejectedError = class extends Error {
|
|
1758
1961
|
constructor(reason, message) {
|
|
1759
1962
|
super(message);
|
|
@@ -1793,7 +1996,7 @@ function normalizedHost(host) {
|
|
|
1793
1996
|
}
|
|
1794
1997
|
function didPrincipalsMatch(left, right) {
|
|
1795
1998
|
try {
|
|
1796
|
-
return (0,
|
|
1999
|
+
return (0, import_sdk_core5.principalDidEquals)(left, right);
|
|
1797
2000
|
} catch {
|
|
1798
2001
|
return left === right;
|
|
1799
2002
|
}
|
|
@@ -1808,7 +2011,7 @@ function compactUcanPayload(authorization) {
|
|
|
1808
2011
|
}
|
|
1809
2012
|
try {
|
|
1810
2013
|
const payload = JSON.parse(
|
|
1811
|
-
new TextDecoder("utf-8", { fatal: true }).decode((0,
|
|
2014
|
+
new TextDecoder("utf-8", { fatal: true }).decode((0, import_sdk_core5.decodeBase64Url)(parts[1]))
|
|
1812
2015
|
);
|
|
1813
2016
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
1814
2017
|
throw new Error("payload is not an object");
|
|
@@ -1836,7 +2039,7 @@ function canonicalPermissionEntries(permissions) {
|
|
|
1836
2039
|
...permission,
|
|
1837
2040
|
actions: [...permission.actions].sort()
|
|
1838
2041
|
})).sort(
|
|
1839
|
-
(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,
|
|
2042
|
+
(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_core5.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core5.canonicalizeRecapCaveats)(right.caveats))
|
|
1840
2043
|
);
|
|
1841
2044
|
}
|
|
1842
2045
|
function signedCaveats(value) {
|
|
@@ -1846,13 +2049,13 @@ function signedCaveats(value) {
|
|
|
1846
2049
|
throw new Error("Validated runtime delegation has malformed signed ReCap caveats.");
|
|
1847
2050
|
}
|
|
1848
2051
|
const cloned = JSON.parse(JSON.stringify(value));
|
|
1849
|
-
return (0,
|
|
2052
|
+
return (0, import_sdk_core5.canonicalizeRecapCaveats)(cloned) === (0, import_sdk_core5.canonicalizeRecapCaveats)(void 0) ? void 0 : cloned;
|
|
1850
2053
|
}
|
|
1851
2054
|
function groupedSignedEntries(service, space, path, abilities) {
|
|
1852
2055
|
const groups = /* @__PURE__ */ new Map();
|
|
1853
2056
|
for (const [action, rawCaveats] of Object.entries(abilities)) {
|
|
1854
2057
|
const caveats = signedCaveats(rawCaveats);
|
|
1855
|
-
const identity = (0,
|
|
2058
|
+
const identity = (0, import_sdk_core5.canonicalizeRecapCaveats)(caveats);
|
|
1856
2059
|
const group = groups.get(identity) ?? { actions: [], caveats };
|
|
1857
2060
|
group.actions.push(action);
|
|
1858
2061
|
groups.set(identity, group);
|
|
@@ -2011,7 +2214,7 @@ function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
|
2011
2214
|
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
2012
2215
|
}
|
|
2013
2216
|
const caveats = signedCaveats(entry.caveats ?? []);
|
|
2014
|
-
const key = JSON.stringify([service, raw ? "" : entry.space, entry.path, (0,
|
|
2217
|
+
const key = JSON.stringify([service, raw ? "" : entry.space, entry.path, (0, import_sdk_core5.canonicalizeRecapCaveats)(caveats)]);
|
|
2015
2218
|
const group = groups.get(key) ?? {
|
|
2016
2219
|
service,
|
|
2017
2220
|
...raw ? {} : { space: entry.space },
|
|
@@ -2035,7 +2238,7 @@ function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
|
2035
2238
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
2036
2239
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
2037
2240
|
return delegation.resources.map((resource) => ({ ...resource, actions: [...resource.actions].sort() })).sort(
|
|
2038
|
-
(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,
|
|
2241
|
+
(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_core5.canonicalizeRecapCaveats)(left.caveats).localeCompare((0, import_sdk_core5.canonicalizeRecapCaveats)(right.caveats))
|
|
2039
2242
|
);
|
|
2040
2243
|
}
|
|
2041
2244
|
const byService = /* @__PURE__ */ new Map();
|
|
@@ -2059,7 +2262,7 @@ function canonicalResourcesFromPortableDelegation(delegation) {
|
|
|
2059
2262
|
function resourcesMatch(actual, expected) {
|
|
2060
2263
|
const comparable = (resource) => ({
|
|
2061
2264
|
...resource,
|
|
2062
|
-
caveats: (0,
|
|
2265
|
+
caveats: (0, import_sdk_core5.canonicalizeRecapCaveats)(resource.caveats)
|
|
2063
2266
|
});
|
|
2064
2267
|
return JSON.stringify(actual.map(comparable)) === JSON.stringify(expected.map(comparable));
|
|
2065
2268
|
}
|
|
@@ -2151,7 +2354,7 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
2151
2354
|
...compact ? {} : { siweProof: delegation.siweProof }
|
|
2152
2355
|
};
|
|
2153
2356
|
try {
|
|
2154
|
-
if (node.isSessionOnly === true && typeof node.did === "string" && (0,
|
|
2357
|
+
if (node.isSessionOnly === true && typeof node.did === "string" && (0, import_sdk_core5.principalDidEquals)(node.did, node.sessionDid) && typeof node.useDelegation === "function") {
|
|
2155
2358
|
await node.useDelegation(installedCandidate);
|
|
2156
2359
|
} else {
|
|
2157
2360
|
await node.useRuntimeDelegation(installedCandidate);
|
|
@@ -2233,21 +2436,52 @@ function deserializeDelegation(data) {
|
|
|
2233
2436
|
};
|
|
2234
2437
|
}
|
|
2235
2438
|
|
|
2439
|
+
// src/replication/config.ts
|
|
2440
|
+
var import_sdk_services2 = require("@tinycloud/sdk-services");
|
|
2441
|
+
function assertValidReplicationConfig(replication) {
|
|
2442
|
+
if (replication === void 0 || replication.enabled !== true) return;
|
|
2443
|
+
if (replication.storage === void 0 || replication.storage === null) {
|
|
2444
|
+
throw new TypeError("replication.enabled requires replication.storage");
|
|
2445
|
+
}
|
|
2446
|
+
if (!Array.isArray(replication.prefixes) || replication.prefixes.length === 0) {
|
|
2447
|
+
throw new TypeError("replication.prefixes must be a non-empty array");
|
|
2448
|
+
}
|
|
2449
|
+
for (const prefix of replication.prefixes) {
|
|
2450
|
+
if (typeof prefix !== "string" || prefix === "") {
|
|
2451
|
+
throw new TypeError("replication.prefixes must not contain an empty prefix");
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
for (const [index, prefix] of replication.prefixes.entries()) {
|
|
2455
|
+
for (const other of replication.prefixes.slice(index + 1)) {
|
|
2456
|
+
if ((0, import_sdk_services2.kvPrefixCovers)(prefix, other) || (0, import_sdk_services2.kvPrefixCovers)(other, prefix)) {
|
|
2457
|
+
throw new TypeError(
|
|
2458
|
+
`replication.prefixes must not overlap: ${JSON.stringify(prefix)} and ${JSON.stringify(other)}`
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
if (prefix.split("/", 1)[0] === "vault" && replication.allowSecrets !== true) {
|
|
2463
|
+
throw new TypeError(
|
|
2464
|
+
`replication prefix ${JSON.stringify(prefix)} overlaps the vault namespace; pass allowSecrets to opt in`
|
|
2465
|
+
);
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2236
2470
|
// src/TinyCloudNode.ts
|
|
2237
|
-
var
|
|
2238
|
-
var
|
|
2471
|
+
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
2472
|
+
var import_sdk_services3 = require("@tinycloud/sdk-services");
|
|
2239
2473
|
|
|
2240
2474
|
// src/account/AccountService.ts
|
|
2241
|
-
var
|
|
2475
|
+
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
2242
2476
|
|
|
2243
2477
|
// src/DelegatedAccess.ts
|
|
2244
|
-
var
|
|
2478
|
+
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
2245
2479
|
var DelegatedAccess = class {
|
|
2246
2480
|
constructor(session, delegation, host, invoke, invokeAny, telemetry) {
|
|
2247
2481
|
this.session = session;
|
|
2248
2482
|
this._delegation = delegation;
|
|
2249
2483
|
this.host = host;
|
|
2250
|
-
this._serviceContext = new
|
|
2484
|
+
this._serviceContext = new import_sdk_core7.ServiceContext({
|
|
2251
2485
|
invoke,
|
|
2252
2486
|
invokeAny,
|
|
2253
2487
|
fetch: globalThis.fetch.bind(globalThis),
|
|
@@ -2255,16 +2489,16 @@ var DelegatedAccess = class {
|
|
|
2255
2489
|
telemetry
|
|
2256
2490
|
});
|
|
2257
2491
|
const prefix = this._delegation.path.replace(/\/$/, "");
|
|
2258
|
-
this._kv = new
|
|
2492
|
+
this._kv = new import_sdk_core7.KVService({ prefix });
|
|
2259
2493
|
this._kv.initialize(this._serviceContext);
|
|
2260
2494
|
this._serviceContext.registerService("kv", this._kv);
|
|
2261
|
-
this._sql = new
|
|
2495
|
+
this._sql = new import_sdk_core7.SQLService({});
|
|
2262
2496
|
this._sql.initialize(this._serviceContext);
|
|
2263
2497
|
this._serviceContext.registerService("sql", this._sql);
|
|
2264
|
-
this._duckdb = new
|
|
2498
|
+
this._duckdb = new import_sdk_core7.DuckDbService({});
|
|
2265
2499
|
this._duckdb.initialize(this._serviceContext);
|
|
2266
2500
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
2267
|
-
this._hooks = new
|
|
2501
|
+
this._hooks = new import_sdk_core7.HooksService({});
|
|
2268
2502
|
this._hooks.initialize(this._serviceContext);
|
|
2269
2503
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
2270
2504
|
const serviceSession = {
|
|
@@ -2414,7 +2648,7 @@ function createWasmKeyProvider(sessionManager) {
|
|
|
2414
2648
|
}
|
|
2415
2649
|
|
|
2416
2650
|
// src/delegateToHelpers.ts
|
|
2417
|
-
var
|
|
2651
|
+
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
2418
2652
|
function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
2419
2653
|
const byService = /* @__PURE__ */ new Map();
|
|
2420
2654
|
for (const a of actions) {
|
|
@@ -2445,7 +2679,7 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
|
2445
2679
|
}
|
|
2446
2680
|
return entries;
|
|
2447
2681
|
}
|
|
2448
|
-
var DEFAULT_DELEGATION_EXPIRY_MS =
|
|
2682
|
+
var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core8.EXPIRY.SESSION_MS;
|
|
2449
2683
|
function resolveExpiryMs(expiry) {
|
|
2450
2684
|
if (expiry === void 0) {
|
|
2451
2685
|
return DEFAULT_DELEGATION_EXPIRY_MS;
|
|
@@ -2458,10 +2692,10 @@ function resolveExpiryMs(expiry) {
|
|
|
2458
2692
|
}
|
|
2459
2693
|
return expiry;
|
|
2460
2694
|
}
|
|
2461
|
-
return (0,
|
|
2695
|
+
return (0, import_sdk_core8.parseExpiry)(expiry);
|
|
2462
2696
|
}
|
|
2463
2697
|
function extractSiweExpiration(siwe) {
|
|
2464
|
-
const parsed = new
|
|
2698
|
+
const parsed = new import_sdk_core8.SiweMessage(siwe);
|
|
2465
2699
|
if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
|
|
2466
2700
|
return void 0;
|
|
2467
2701
|
}
|
|
@@ -2475,7 +2709,7 @@ function extractSiweExpiration(siwe) {
|
|
|
2475
2709
|
}
|
|
2476
2710
|
|
|
2477
2711
|
// src/NodeSecretsService.ts
|
|
2478
|
-
var
|
|
2712
|
+
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
2479
2713
|
var SECRETS_SPACE = "secrets";
|
|
2480
2714
|
function ok() {
|
|
2481
2715
|
return { ok: true, data: void 0 };
|
|
@@ -2508,7 +2742,7 @@ function secretActionName(action) {
|
|
|
2508
2742
|
}
|
|
2509
2743
|
function secretPermissionEntries(name, options, action, space, encryptionNetworkId) {
|
|
2510
2744
|
const entries = [];
|
|
2511
|
-
const path = action === "list" ? (0,
|
|
2745
|
+
const path = action === "list" ? (0, import_sdk_core9.resolveSecretListPrefix)(options) : (0, import_sdk_core9.resolveSecretPath)(name, options).permissionPaths.vault;
|
|
2512
2746
|
entries.push({
|
|
2513
2747
|
service: "tinycloud.kv",
|
|
2514
2748
|
space,
|
|
@@ -2605,7 +2839,7 @@ var NodeSecretsService = class {
|
|
|
2605
2839
|
);
|
|
2606
2840
|
} catch (error) {
|
|
2607
2841
|
return secretsError(
|
|
2608
|
-
|
|
2842
|
+
import_sdk_core9.ErrorCodes.INVALID_INPUT,
|
|
2609
2843
|
error instanceof Error ? error.message : String(error),
|
|
2610
2844
|
error instanceof Error ? error : void 0
|
|
2611
2845
|
);
|
|
@@ -2615,7 +2849,7 @@ var NodeSecretsService = class {
|
|
|
2615
2849
|
}
|
|
2616
2850
|
if (!this.config.canEscalate()) {
|
|
2617
2851
|
return secretsError(
|
|
2618
|
-
|
|
2852
|
+
import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
|
|
2619
2853
|
`Cannot autosign ${displayActionUrn(action)} for ${target}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
2620
2854
|
);
|
|
2621
2855
|
}
|
|
@@ -2624,7 +2858,7 @@ var NodeSecretsService = class {
|
|
|
2624
2858
|
return this.restoreUnlockAfterEscalation();
|
|
2625
2859
|
} catch (error) {
|
|
2626
2860
|
return secretsError(
|
|
2627
|
-
|
|
2861
|
+
import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
|
|
2628
2862
|
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
|
|
2629
2863
|
error instanceof Error ? error : void 0
|
|
2630
2864
|
);
|
|
@@ -2645,10 +2879,10 @@ var NodeSecretsService = class {
|
|
|
2645
2879
|
return false;
|
|
2646
2880
|
}
|
|
2647
2881
|
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
2648
|
-
const requestedEntries = (0,
|
|
2882
|
+
const requestedEntries = (0, import_sdk_core9.expandPermissionEntries)(permissionEntries);
|
|
2649
2883
|
return requestedEntries.every(
|
|
2650
2884
|
(entry) => manifests.some((candidate) => {
|
|
2651
|
-
const resolved = (0,
|
|
2885
|
+
const resolved = (0, import_sdk_core9.resolveManifest)(candidate);
|
|
2652
2886
|
return resolved.resources.some(
|
|
2653
2887
|
(resource) => resource.service === entry.service && spaceMatches(
|
|
2654
2888
|
resource.space,
|
|
@@ -2664,8 +2898,8 @@ var NodeSecretsService = class {
|
|
|
2664
2898
|
// src/TinyCloudNode.ts
|
|
2665
2899
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
2666
2900
|
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
2667
|
-
var NETWORK_CREATE_ACTION2 =
|
|
2668
|
-
var DECRYPT_ACTION2 =
|
|
2901
|
+
var NETWORK_CREATE_ACTION2 = import_sdk_core10.ENCRYPTION.NETWORK_CREATE;
|
|
2902
|
+
var DECRYPT_ACTION2 = import_sdk_core10.ENCRYPTION.DECRYPT;
|
|
2669
2903
|
var BOOTSTRAP_COMPLETION_MARKER_KEY = "system/bootstrap/complete";
|
|
2670
2904
|
var BOOTSTRAP_COMPLETION_MARKER_VERSION = 1;
|
|
2671
2905
|
var ACCEPTED_MARKER_VERSIONS = [BOOTSTRAP_COMPLETION_MARKER_VERSION];
|
|
@@ -2674,24 +2908,24 @@ function isSecretPayload(value) {
|
|
|
2674
2908
|
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";
|
|
2675
2909
|
}
|
|
2676
2910
|
var ROOT_DELEGATION_ACTIONS = [
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2911
|
+
import_sdk_core10.KV.PUT,
|
|
2912
|
+
import_sdk_core10.KV.GET,
|
|
2913
|
+
import_sdk_core10.KV.DEL,
|
|
2914
|
+
import_sdk_core10.KV.LIST,
|
|
2915
|
+
import_sdk_core10.KV.METADATA,
|
|
2916
|
+
import_sdk_core10.SQL.READ,
|
|
2917
|
+
import_sdk_core10.SQL.WRITE,
|
|
2918
|
+
import_sdk_core10.SQL.ADMIN,
|
|
2919
|
+
import_sdk_core10.SQL.ALL,
|
|
2920
|
+
import_sdk_core10.DUCKDB.READ,
|
|
2921
|
+
import_sdk_core10.DUCKDB.WRITE,
|
|
2922
|
+
import_sdk_core10.DUCKDB.ADMIN,
|
|
2923
|
+
import_sdk_core10.DUCKDB.DESCRIBE,
|
|
2924
|
+
import_sdk_core10.DUCKDB.EXPORT,
|
|
2925
|
+
import_sdk_core10.DUCKDB.IMPORT,
|
|
2926
|
+
import_sdk_core10.DUCKDB.ALL
|
|
2693
2927
|
];
|
|
2694
|
-
var DEFAULT_SESSION_EXPIRATION_MS =
|
|
2928
|
+
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core10.EXPIRY.SESSION_MS;
|
|
2695
2929
|
function unifiedRootAttenuation(capabilities) {
|
|
2696
2930
|
const attenuation = {};
|
|
2697
2931
|
for (const capability of capabilities) {
|
|
@@ -2737,7 +2971,7 @@ function isInteractiveSigner(config) {
|
|
|
2737
2971
|
}
|
|
2738
2972
|
function didPrincipalMatches2(actual, expected) {
|
|
2739
2973
|
try {
|
|
2740
|
-
return (0,
|
|
2974
|
+
return (0, import_sdk_core10.principalDidEquals)(actual, expected);
|
|
2741
2975
|
} catch {
|
|
2742
2976
|
return actual === expected;
|
|
2743
2977
|
}
|
|
@@ -2948,7 +3182,7 @@ function ownerDelegationPermissions(params) {
|
|
|
2948
3182
|
}
|
|
2949
3183
|
const slash = action.indexOf("/");
|
|
2950
3184
|
const service = slash === -1 ? "" : action.slice(0, slash);
|
|
2951
|
-
if (
|
|
3185
|
+
if (import_sdk_core10.SERVICE_LONG_TO_SHORT[service] === void 0) {
|
|
2952
3186
|
throw new Error("Owner delegation capabilities are unsupported");
|
|
2953
3187
|
}
|
|
2954
3188
|
const actions = byService.get(service) ?? [];
|
|
@@ -2964,7 +3198,7 @@ function ownerDelegationPermissions(params) {
|
|
|
2964
3198
|
}
|
|
2965
3199
|
const resources = /* @__PURE__ */ new Set();
|
|
2966
3200
|
for (const permission of permissions) {
|
|
2967
|
-
if (typeof permission.service !== "string" ||
|
|
3201
|
+
if (typeof permission.service !== "string" || import_sdk_core10.SERVICE_LONG_TO_SHORT[permission.service] === void 0 || typeof permission.path !== "string" || permission.path.length === 0 || permission.path.trim() !== permission.path || /[\u0000-\u001f\u007f\\*]/.test(permission.path) || !Array.isArray(permission.actions) || permission.actions.length === 0 || permission.actions.length > 32) {
|
|
2968
3202
|
throw new Error("Owner delegation requires bounded capabilities");
|
|
2969
3203
|
}
|
|
2970
3204
|
const resourceKey = `${permission.service}\0${permission.path}`;
|
|
@@ -2979,9 +3213,9 @@ function ownerDelegationPermissions(params) {
|
|
|
2979
3213
|
}
|
|
2980
3214
|
actions.add(action);
|
|
2981
3215
|
}
|
|
2982
|
-
if (permission.service ===
|
|
3216
|
+
if (permission.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE) {
|
|
2983
3217
|
try {
|
|
2984
|
-
(0,
|
|
3218
|
+
(0, import_sdk_core10.parseNetworkId)(permission.path);
|
|
2985
3219
|
} catch {
|
|
2986
3220
|
throw new Error("Owner delegation encryption permission requires a canonical network URN");
|
|
2987
3221
|
}
|
|
@@ -2993,11 +3227,11 @@ function ownerPermissionsToAbilities(permissions) {
|
|
|
2993
3227
|
const abilities = {};
|
|
2994
3228
|
const rawAbilities = {};
|
|
2995
3229
|
for (const permission of permissions) {
|
|
2996
|
-
if (permission.service ===
|
|
3230
|
+
if (permission.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE) {
|
|
2997
3231
|
rawAbilities[permission.path] = [...permission.actions];
|
|
2998
3232
|
continue;
|
|
2999
3233
|
}
|
|
3000
|
-
const shortService =
|
|
3234
|
+
const shortService = import_sdk_core10.SERVICE_LONG_TO_SHORT[permission.service];
|
|
3001
3235
|
abilities[shortService] ?? (abilities[shortService] = {});
|
|
3002
3236
|
abilities[shortService][permission.path] = [...permission.actions];
|
|
3003
3237
|
}
|
|
@@ -3129,6 +3363,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3129
3363
|
this.confirmedHostedSpaceIds = /* @__PURE__ */ new Set();
|
|
3130
3364
|
/** Serializes account-registry writes for the active node instance. */
|
|
3131
3365
|
this.accountRegistryTail = Promise.resolve();
|
|
3366
|
+
/** Bounds best-effort registry work on the sign-in critical path. */
|
|
3367
|
+
this.accountRegistryDeadlineMs = 4e3;
|
|
3132
3368
|
/**
|
|
3133
3369
|
* True when the last signIn() detected an interactive signer and skipped
|
|
3134
3370
|
* client-side bootstrap. Apps can read this to know whether bootstrap was
|
|
@@ -3200,18 +3436,53 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3200
3436
|
if (!granted?.caveats?.length) {
|
|
3201
3437
|
return entry;
|
|
3202
3438
|
}
|
|
3203
|
-
if (entry.caveats !== void 0 && !(0,
|
|
3439
|
+
if (entry.caveats !== void 0 && !(0, import_sdk_core10.recapCaveatsEqual)(entry.caveats, granted.caveats)) {
|
|
3204
3440
|
throw new Error("Invocation caveats do not match signed ReCap authority.");
|
|
3205
3441
|
}
|
|
3206
3442
|
return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
|
|
3207
3443
|
});
|
|
3208
3444
|
return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
|
|
3209
3445
|
};
|
|
3446
|
+
assertValidReplicationConfig(config.replication);
|
|
3210
3447
|
this.explicitHost = config.host;
|
|
3211
3448
|
this.config = {
|
|
3212
3449
|
...config,
|
|
3213
3450
|
host: config.host ?? DEFAULT_HOST
|
|
3214
3451
|
};
|
|
3452
|
+
if (this.config.replication?.enabled) {
|
|
3453
|
+
const runtime = getNodeReplicationLoaders().runtime().then(({ ReplicationRuntime }) => {
|
|
3454
|
+
const instance = new ReplicationRuntime(this.config.replication);
|
|
3455
|
+
this.replicationRuntimeInstance = instance;
|
|
3456
|
+
return instance;
|
|
3457
|
+
});
|
|
3458
|
+
this.replicationRuntime = runtime;
|
|
3459
|
+
this.replicationControl = {
|
|
3460
|
+
status: async () => {
|
|
3461
|
+
const status = await runtime.then((ready) => ready.control.status());
|
|
3462
|
+
const scopeError = this.replicationScopeError;
|
|
3463
|
+
if (!scopeError) return status;
|
|
3464
|
+
return this.config.replication.prefixes.map((prefix) => ({
|
|
3465
|
+
prefix,
|
|
3466
|
+
state: "unavailable",
|
|
3467
|
+
lastError: {
|
|
3468
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3469
|
+
code: "SESSION_SCOPE_MISMATCH",
|
|
3470
|
+
message: scopeError
|
|
3471
|
+
},
|
|
3472
|
+
pending: { inFlight: 0, committed: 0, ambiguous: 0 },
|
|
3473
|
+
pinned: [],
|
|
3474
|
+
lagMs: null
|
|
3475
|
+
}));
|
|
3476
|
+
},
|
|
3477
|
+
sync: async (input) => (await runtime).control.sync(input),
|
|
3478
|
+
purge: (input) => {
|
|
3479
|
+
const instance = this.replicationRuntimeInstance;
|
|
3480
|
+
return instance ? instance.control.purge(input) : runtime.then((ready) => ready.control.purge(input));
|
|
3481
|
+
},
|
|
3482
|
+
clearPending: async () => (await runtime).control.clearPending(),
|
|
3483
|
+
close: async () => (await runtime).control.close()
|
|
3484
|
+
};
|
|
3485
|
+
}
|
|
3215
3486
|
if (config.wasmBindings) {
|
|
3216
3487
|
this.wasmBindings = config.wasmBindings;
|
|
3217
3488
|
} else if (_TinyCloudNode.nodeDefaults) {
|
|
@@ -3235,13 +3506,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3235
3506
|
}
|
|
3236
3507
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
3237
3508
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
3238
|
-
this._capabilityRegistry = new
|
|
3509
|
+
this._capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
3239
3510
|
this._keyProvider = new WasmKeyProvider({
|
|
3240
3511
|
sessionManager: this.sessionManager
|
|
3241
3512
|
});
|
|
3242
|
-
this.notificationHandler = config.notificationHandler ?? new
|
|
3513
|
+
this.notificationHandler = config.notificationHandler ?? new import_sdk_core10.SilentNotificationHandler();
|
|
3243
3514
|
const receiveOnlyGraph = this._serviceGraph;
|
|
3244
|
-
this._sharingService = new
|
|
3515
|
+
this._sharingService = new import_sdk_core10.SharingService({
|
|
3245
3516
|
hosts: [this.config.host],
|
|
3246
3517
|
// session: undefined - not needed for receive()
|
|
3247
3518
|
invoke: receiveOnlyGraph.invoke,
|
|
@@ -3257,8 +3528,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3257
3528
|
// delegationManager: undefined - not needed for receive()
|
|
3258
3529
|
createKVService: (config2) => {
|
|
3259
3530
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
3260
|
-
const kvService = new
|
|
3261
|
-
const kvContext = receiveOnlyGraph.track(new
|
|
3531
|
+
const kvService = new import_sdk_core10.KVService({ prefix });
|
|
3532
|
+
const kvContext = receiveOnlyGraph.track(new import_sdk_core10.ServiceContext({
|
|
3262
3533
|
invoke: config2.invoke,
|
|
3263
3534
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
3264
3535
|
hosts: config2.hosts,
|
|
@@ -3331,10 +3602,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3331
3602
|
nonce: config.nonce,
|
|
3332
3603
|
siweConfig: config.siweConfig,
|
|
3333
3604
|
manifest: useBootstrapSignInRequest ? void 0 : config.manifest,
|
|
3334
|
-
capabilityRequest: useBootstrapSignInRequest ? config.includeAccountRegistryPermissions === false ?
|
|
3335
|
-
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : config.includeAccountRegistryPermissions
|
|
3605
|
+
capabilityRequest: useBootstrapSignInRequest ? config.includeAccountRegistryPermissions === false ? import_sdk_core10.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default : config.capabilityRequest,
|
|
3606
|
+
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : config.includeAccountRegistryPermissions,
|
|
3607
|
+
// Sign-in needs only the entry inputs (prefixes + secrets opt-in);
|
|
3608
|
+
// storage and scheduling never leave TinyCloudNode.
|
|
3609
|
+
replication: config.replication?.enabled === true ? {
|
|
3610
|
+
enabled: true,
|
|
3611
|
+
prefixes: config.replication.prefixes,
|
|
3612
|
+
allowSecrets: config.replication.allowSecrets === true
|
|
3613
|
+
} : void 0
|
|
3336
3614
|
});
|
|
3337
|
-
this.tc = new
|
|
3615
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
3338
3616
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
3339
3617
|
telemetry: config.telemetry
|
|
3340
3618
|
});
|
|
@@ -3414,7 +3692,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3414
3692
|
/** Publish the active owner Node as a session-signed registry record. */
|
|
3415
3693
|
async publishActiveNodeLocation(registryUrl, fetchFn = globalThis.fetch.bind(globalThis)) {
|
|
3416
3694
|
const node = await this.activeNodeIdentity();
|
|
3417
|
-
return (0,
|
|
3695
|
+
return (0, import_sdk_core10.publishLocationRecord)({
|
|
3418
3696
|
registryUrl,
|
|
3419
3697
|
subject: this.credentialHolderDid,
|
|
3420
3698
|
nodeOrigin: node.origin,
|
|
@@ -3431,7 +3709,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3431
3709
|
*/
|
|
3432
3710
|
get did() {
|
|
3433
3711
|
if (this._address) {
|
|
3434
|
-
return (0,
|
|
3712
|
+
return (0, import_sdk_core10.pkhDid)(this._address, this._chainId);
|
|
3435
3713
|
}
|
|
3436
3714
|
return this.sessionManager.getDID(this.sessionKeyId);
|
|
3437
3715
|
}
|
|
@@ -3468,7 +3746,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3468
3746
|
/** Normalize signed capabilities without collapsing nested encryption into raw authority. */
|
|
3469
3747
|
projectSignedRecapCapabilities(siwe) {
|
|
3470
3748
|
const projected = this.parseRecapWithCaveats(siwe).map((entry) => {
|
|
3471
|
-
const normalized = (0,
|
|
3749
|
+
const normalized = (0, import_sdk_core10.parseRecapCapabilities)(() => [entry], siwe)[0];
|
|
3472
3750
|
if (normalized.service !== "tinycloud.encryption") return normalized;
|
|
3473
3751
|
if (!this.isEncryptionNetworkOperation("encryption", entry.path, entry.space)) {
|
|
3474
3752
|
return { ...normalized, space: entry.space };
|
|
@@ -3513,14 +3791,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3513
3791
|
if (!this._address) {
|
|
3514
3792
|
return void 0;
|
|
3515
3793
|
}
|
|
3516
|
-
return this.wasmBindings.makeSpaceId(this._address, this._chainId,
|
|
3794
|
+
return this.wasmBindings.makeSpaceId(this._address, this._chainId, import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
3517
3795
|
}
|
|
3518
3796
|
/**
|
|
3519
3797
|
* Account-level application and delegation helpers.
|
|
3520
3798
|
*/
|
|
3521
3799
|
get account() {
|
|
3522
3800
|
if (!this._account) {
|
|
3523
|
-
this._account = new
|
|
3801
|
+
this._account = new import_sdk_core6.AccountService({
|
|
3524
3802
|
getDid: () => this.did,
|
|
3525
3803
|
getHost: () => this.hosts[0] ?? this.config.host,
|
|
3526
3804
|
getPrimarySpaceId: () => this.spaceId,
|
|
@@ -3566,7 +3844,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3566
3844
|
}
|
|
3567
3845
|
await this.accountRegistryTail;
|
|
3568
3846
|
await this.wasmBindings.ensureInitialized?.();
|
|
3569
|
-
this._address = (0,
|
|
3847
|
+
this._address = (0, import_sdk_core10.canonicalizeAddress)(await this.signer.getAddress());
|
|
3570
3848
|
this._chainId = await this.signer.getChainId();
|
|
3571
3849
|
this._kv = void 0;
|
|
3572
3850
|
this._sql = void 0;
|
|
@@ -3583,6 +3861,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3583
3861
|
this.confirmedHostedSpaceIds.clear();
|
|
3584
3862
|
await this.tc.signIn(options);
|
|
3585
3863
|
this.syncResolvedHostFromAuth();
|
|
3864
|
+
this.replicationDelegateSession = void 0;
|
|
3865
|
+
this.replicationScopeError = void 0;
|
|
3866
|
+
if (this.replicationRuntime) await (await this.replicationRuntime).unbind();
|
|
3586
3867
|
const oldGraph = this._serviceGraph;
|
|
3587
3868
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
3588
3869
|
oldGraph.retire();
|
|
@@ -3592,7 +3873,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3592
3873
|
this.sessionKeyId = signedInSession.sessionKey;
|
|
3593
3874
|
this.sessionKeyJwk = signedInSession.jwk;
|
|
3594
3875
|
}
|
|
3595
|
-
this.initializeServices();
|
|
3876
|
+
await this.initializeServices();
|
|
3596
3877
|
const primarySession = this.currentTinyCloudSession();
|
|
3597
3878
|
if (primarySession) {
|
|
3598
3879
|
this.registerPrimarySessionGrant(primarySession);
|
|
@@ -3600,10 +3881,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3600
3881
|
const bootstrapped = await this.bootstrapAccountIfNeeded();
|
|
3601
3882
|
await this.ensureRequestedEncryptionNetworks();
|
|
3602
3883
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
3603
|
-
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(
|
|
3884
|
+
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(import_sdk_core10.SECRETS_SPACE));
|
|
3604
3885
|
}
|
|
3605
3886
|
if (!bootstrapped) {
|
|
3606
3887
|
this.scheduleAccountRegistrySync();
|
|
3888
|
+
await this.accountRegistryTail;
|
|
3607
3889
|
}
|
|
3608
3890
|
this.notificationHandler.success("Successfully signed in");
|
|
3609
3891
|
}
|
|
@@ -3631,7 +3913,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3631
3913
|
this._bootstrapStatus = { skipped: true, reason: "interactive-signer" };
|
|
3632
3914
|
return false;
|
|
3633
3915
|
}
|
|
3634
|
-
const steps = (0,
|
|
3916
|
+
const steps = (0, import_sdk_core10.bootstrapSteps)(this._address, this._chainId);
|
|
3635
3917
|
try {
|
|
3636
3918
|
const decision = await this.resolveBootstrapDecision(steps);
|
|
3637
3919
|
if (decision.action === "skip") {
|
|
@@ -3669,7 +3951,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3669
3951
|
if (!auth) {
|
|
3670
3952
|
throw new Error("Account bootstrap requires an active wallet session");
|
|
3671
3953
|
}
|
|
3672
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
3954
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
3673
3955
|
const skipped = auth.lastActivationSkippedSpaceIds;
|
|
3674
3956
|
if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
|
|
3675
3957
|
if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
|
|
@@ -3692,7 +3974,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3692
3974
|
}
|
|
3693
3975
|
return { action: "run", mode: "repair" };
|
|
3694
3976
|
}
|
|
3695
|
-
if (marker.error.code ===
|
|
3977
|
+
if (marker.error.code === import_sdk_core10.ErrorCodes.KV_NOT_FOUND && this.markerReadIsUnhostedSpace(marker.error.meta)) {
|
|
3696
3978
|
return { action: "run", mode: "fresh" };
|
|
3697
3979
|
}
|
|
3698
3980
|
} catch (err) {
|
|
@@ -3706,7 +3988,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3706
3988
|
return { action: "run", mode: "repair" };
|
|
3707
3989
|
}
|
|
3708
3990
|
async readBootstrapCompletionMarker() {
|
|
3709
|
-
return this.kvForSpace(this.ownedSpaceId(
|
|
3991
|
+
return this.kvForSpace(this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE)).get(
|
|
3710
3992
|
BOOTSTRAP_COMPLETION_MARKER_KEY
|
|
3711
3993
|
);
|
|
3712
3994
|
}
|
|
@@ -3715,7 +3997,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3715
3997
|
throw new Error("Bootstrap completion marker requires an active wallet session");
|
|
3716
3998
|
}
|
|
3717
3999
|
const canonicalStepIds = new Set(
|
|
3718
|
-
(0,
|
|
4000
|
+
(0, import_sdk_core10.bootstrapSteps)(this._address, this._chainId).map((step) => step.id)
|
|
3719
4001
|
);
|
|
3720
4002
|
const providedStepIds = new Set(steps.map((step) => step.id));
|
|
3721
4003
|
if (canonicalStepIds.size !== providedStepIds.size || [...canonicalStepIds].some((stepId) => !providedStepIds.has(stepId))) {
|
|
@@ -3726,7 +4008,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3726
4008
|
stepIds: [...canonicalStepIds],
|
|
3727
4009
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3728
4010
|
};
|
|
3729
|
-
const written = await this.kvForSpace(this.ownedSpaceId(
|
|
4011
|
+
const written = await this.kvForSpace(this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE)).put(
|
|
3730
4012
|
BOOTSTRAP_COMPLETION_MARKER_KEY,
|
|
3731
4013
|
marker
|
|
3732
4014
|
);
|
|
@@ -3765,7 +4047,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3765
4047
|
const warnings = [];
|
|
3766
4048
|
const primarySession = auth.tinyCloudSession;
|
|
3767
4049
|
const defaultSpaceId = this.ownedSpaceId("default");
|
|
3768
|
-
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest ===
|
|
4050
|
+
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest === import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default;
|
|
3769
4051
|
for (const step of steps) {
|
|
3770
4052
|
if (step.kind !== "session") continue;
|
|
3771
4053
|
if (step.space === "default" && canReusePrimaryBootstrapSession && primarySession) {
|
|
@@ -3780,7 +4062,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3780
4062
|
try {
|
|
3781
4063
|
session = await auth.createBootstrapSession({
|
|
3782
4064
|
spaceId: step.spaceId,
|
|
3783
|
-
capabilityRequest: step.request ??
|
|
4065
|
+
capabilityRequest: step.request ?? import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS[step.space],
|
|
3784
4066
|
rawAbilities
|
|
3785
4067
|
});
|
|
3786
4068
|
} catch (err) {
|
|
@@ -3810,7 +4092,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3810
4092
|
if (!session) {
|
|
3811
4093
|
throw new Error(`Missing bootstrap session for ${step.space}`);
|
|
3812
4094
|
}
|
|
3813
|
-
const activated = await (0,
|
|
4095
|
+
const activated = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader);
|
|
3814
4096
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
3815
4097
|
throw Object.assign(
|
|
3816
4098
|
new Error(
|
|
@@ -3821,7 +4103,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3821
4103
|
}
|
|
3822
4104
|
this.registerBootstrapRuntimeGrant(
|
|
3823
4105
|
session,
|
|
3824
|
-
|
|
4106
|
+
import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS[step.space],
|
|
3825
4107
|
rawAbilitiesBySpace.get(step.space)
|
|
3826
4108
|
);
|
|
3827
4109
|
}
|
|
@@ -3870,7 +4152,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3870
4152
|
}
|
|
3871
4153
|
if (step.kind === "seed-applications") {
|
|
3872
4154
|
const registered = await this.account.applications.register(
|
|
3873
|
-
step.manifests.length > 0 ? [...step.manifests] :
|
|
4155
|
+
step.manifests.length > 0 ? [...step.manifests] : import_sdk_core10.TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
|
|
3874
4156
|
// The write is an INSERT OR REPLACE and is safe to repeat during a
|
|
3875
4157
|
// repair, so skip the manifest-hash pre-read.
|
|
3876
4158
|
{ assumeUnregistered: true }
|
|
@@ -3889,7 +4171,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3889
4171
|
migrations: [
|
|
3890
4172
|
{
|
|
3891
4173
|
id: "001_initial",
|
|
3892
|
-
sql: [...
|
|
4174
|
+
sql: [...import_sdk_core10.SECRET_RECORDS_SCHEMA]
|
|
3893
4175
|
}
|
|
3894
4176
|
]
|
|
3895
4177
|
});
|
|
@@ -4056,7 +4338,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4056
4338
|
provenance: "primary"
|
|
4057
4339
|
});
|
|
4058
4340
|
}
|
|
4059
|
-
async writeManifestRegistryRecords() {
|
|
4341
|
+
async writeManifestRegistryRecords(account, signal) {
|
|
4060
4342
|
const request = this.capabilityRequest;
|
|
4061
4343
|
if (!request || request.registryRecords.length === 0) {
|
|
4062
4344
|
return;
|
|
@@ -4064,9 +4346,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4064
4346
|
if (!this.auth || !this.signer) {
|
|
4065
4347
|
throw new Error("Manifest registry write requires wallet mode");
|
|
4066
4348
|
}
|
|
4067
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
4068
|
-
await this.ensureOwnedSpaceHostedById(accountSpaceId);
|
|
4069
|
-
|
|
4349
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
4350
|
+
await this.ensureOwnedSpaceHostedById(accountSpaceId, signal);
|
|
4351
|
+
if (signal.aborted) throw signal.reason;
|
|
4352
|
+
const result = await account.applications.register(request.manifests);
|
|
4070
4353
|
if (!result.ok) {
|
|
4071
4354
|
throw Object.assign(
|
|
4072
4355
|
new Error(`Failed to write manifest registry records: ${result.error.message}`),
|
|
@@ -4074,34 +4357,113 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4074
4357
|
);
|
|
4075
4358
|
}
|
|
4076
4359
|
}
|
|
4360
|
+
createAccountRegistryServices(context, signal) {
|
|
4361
|
+
const session = context.session;
|
|
4362
|
+
if (!session) throw new Error("Account registry requires an active service session");
|
|
4363
|
+
const contexts = [context];
|
|
4364
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
4365
|
+
const createScopedContext = (spaceId) => {
|
|
4366
|
+
const scoped = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
4367
|
+
invoke: context.invoke,
|
|
4368
|
+
invokeAny: context.invokeAny,
|
|
4369
|
+
fetch: context.fetch,
|
|
4370
|
+
hosts: context.hosts,
|
|
4371
|
+
telemetry: this.config.telemetry
|
|
4372
|
+
}));
|
|
4373
|
+
scoped.setOperationAbortSignal(signal);
|
|
4374
|
+
scoped.setSession({ ...session, spaceId });
|
|
4375
|
+
contexts.push(scoped);
|
|
4376
|
+
return scoped;
|
|
4377
|
+
};
|
|
4378
|
+
const sql = new import_sdk_core10.SQLService({});
|
|
4379
|
+
const sqlContext = createScopedContext(accountSpaceId);
|
|
4380
|
+
sql.initialize(sqlContext);
|
|
4381
|
+
const spaces = new import_sdk_core10.SpaceService({
|
|
4382
|
+
hosts: context.hosts,
|
|
4383
|
+
session,
|
|
4384
|
+
invoke: context.invoke,
|
|
4385
|
+
fetch: (url, init) => context.fetch(url, {
|
|
4386
|
+
...init,
|
|
4387
|
+
signal: init?.signal ? AbortSignal.any([init.signal, signal]) : signal
|
|
4388
|
+
}),
|
|
4389
|
+
userDid: this.did,
|
|
4390
|
+
createKVService: (spaceId) => {
|
|
4391
|
+
const kv = new import_sdk_core10.KVService({});
|
|
4392
|
+
kv.initialize(createScopedContext(spaceId));
|
|
4393
|
+
return kv;
|
|
4394
|
+
}
|
|
4395
|
+
});
|
|
4396
|
+
return {
|
|
4397
|
+
contexts,
|
|
4398
|
+
account: new import_sdk_core6.AccountService({
|
|
4399
|
+
getDid: () => this.did,
|
|
4400
|
+
getHost: () => context.hosts[0] ?? this.config.host,
|
|
4401
|
+
getPrimarySpaceId: () => session.spaceId,
|
|
4402
|
+
getAccountSpaceId: () => accountSpaceId,
|
|
4403
|
+
getSpaces: () => spaces,
|
|
4404
|
+
getAccountDb: () => sql.db("account"),
|
|
4405
|
+
ensureAccountSpaceHosted: () => this.ensureOwnedSpaceHostedById(accountSpaceId, signal)
|
|
4406
|
+
})
|
|
4407
|
+
};
|
|
4408
|
+
}
|
|
4077
4409
|
scheduleAccountRegistrySync() {
|
|
4078
4410
|
const session = this.currentTinyCloudSession();
|
|
4079
4411
|
if (!session || this.pendingAccountRegistrySync?.session === session) {
|
|
4080
4412
|
return;
|
|
4081
4413
|
}
|
|
4414
|
+
const controller = new AbortController();
|
|
4415
|
+
const deadline = setTimeout(
|
|
4416
|
+
() => controller.abort(new DOMException("Account registry deadline exceeded", "TimeoutError")),
|
|
4417
|
+
this.accountRegistryDeadlineMs
|
|
4418
|
+
);
|
|
4082
4419
|
const promise = this.enqueueAccountRegistryOperation(session, async () => {
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4420
|
+
const sharedContext = this._serviceContext;
|
|
4421
|
+
if (!sharedContext) return;
|
|
4422
|
+
const context = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
4423
|
+
invoke: sharedContext.invoke,
|
|
4424
|
+
invokeAny: sharedContext.invokeAny,
|
|
4425
|
+
fetch: sharedContext.fetch,
|
|
4426
|
+
hosts: sharedContext.hosts,
|
|
4427
|
+
telemetry: this.config.telemetry
|
|
4428
|
+
}));
|
|
4429
|
+
context.setOperationAbortSignal(controller.signal);
|
|
4430
|
+
const current = this.currentTinyCloudSession();
|
|
4431
|
+
if (!current) return;
|
|
4432
|
+
context.setSession({
|
|
4433
|
+
delegationHeader: current.delegationHeader,
|
|
4434
|
+
delegationCid: current.delegationCid,
|
|
4435
|
+
spaceId: current.spaceId,
|
|
4436
|
+
verificationMethod: current.verificationMethod,
|
|
4437
|
+
jwk: current.jwk
|
|
4438
|
+
});
|
|
4439
|
+
const registry = this.createAccountRegistryServices(context, controller.signal);
|
|
4440
|
+
try {
|
|
4441
|
+
await this.withAccountRegistryRetry(async () => {
|
|
4442
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
4443
|
+
if (this.currentTinyCloudSession() !== session) return;
|
|
4444
|
+
await registry.account.index.ensure();
|
|
4445
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
4446
|
+
if (this.currentTinyCloudSession() !== session) return;
|
|
4447
|
+
await this.writeManifestRegistryRecords(registry.account, controller.signal);
|
|
4448
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
4449
|
+
if (this.currentTinyCloudSession() !== session) return;
|
|
4450
|
+
if (this.currentSessionCanListSpaces()) {
|
|
4451
|
+
const result = await registry.account.spaces.syncAccessible();
|
|
4452
|
+
if (controller.signal.aborted) throw controller.signal.reason;
|
|
4453
|
+
if (!result.ok) {
|
|
4454
|
+
throw Object.assign(
|
|
4455
|
+
new Error(`Failed to sync account spaces: ${result.error.message}`),
|
|
4456
|
+
{ cause: result.error }
|
|
4457
|
+
);
|
|
4458
|
+
}
|
|
4102
4459
|
}
|
|
4460
|
+
}, controller.signal);
|
|
4461
|
+
} finally {
|
|
4462
|
+
for (const operationContext of registry.contexts) {
|
|
4463
|
+
operationContext.retire();
|
|
4103
4464
|
}
|
|
4104
|
-
|
|
4465
|
+
clearTimeout(deadline);
|
|
4466
|
+
}
|
|
4105
4467
|
});
|
|
4106
4468
|
this.pendingAccountRegistrySync = { session, promise };
|
|
4107
4469
|
const clearPendingSync = () => {
|
|
@@ -4110,6 +4472,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4110
4472
|
}
|
|
4111
4473
|
};
|
|
4112
4474
|
void promise.then(clearPendingSync, clearPendingSync);
|
|
4475
|
+
void promise.then(
|
|
4476
|
+
() => clearTimeout(deadline),
|
|
4477
|
+
() => clearTimeout(deadline)
|
|
4478
|
+
);
|
|
4113
4479
|
}
|
|
4114
4480
|
enqueueAccountRegistryOperation(session, task) {
|
|
4115
4481
|
const operation = this.accountRegistryTail.then(async () => {
|
|
@@ -4145,15 +4511,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4145
4511
|
(operation) => operation.service === "space" && this.actionContains(operation.action, "tinycloud.space/list")
|
|
4146
4512
|
);
|
|
4147
4513
|
}
|
|
4148
|
-
async withAccountRegistryRetry(task) {
|
|
4514
|
+
async withAccountRegistryRetry(task, signal) {
|
|
4149
4515
|
const delays = [250, 1e3, 3e3];
|
|
4150
4516
|
let lastError;
|
|
4151
4517
|
for (let attempt = 0; attempt < delays.length; attempt += 1) {
|
|
4518
|
+
if (signal.aborted) {
|
|
4519
|
+
console.warn("TinyCloud account registry sync stopped: deadline exceeded", signal.reason);
|
|
4520
|
+
return;
|
|
4521
|
+
}
|
|
4152
4522
|
try {
|
|
4153
4523
|
await task();
|
|
4154
4524
|
return;
|
|
4155
4525
|
} catch (error) {
|
|
4156
|
-
|
|
4526
|
+
if (signal.aborted) {
|
|
4527
|
+
console.warn("TinyCloud account registry sync stopped: deadline exceeded", error);
|
|
4528
|
+
return;
|
|
4529
|
+
}
|
|
4530
|
+
const verdict = (0, import_sdk_core10.authorizationVerdictOf)(error);
|
|
4157
4531
|
const message = error instanceof Error ? error.message : String(error);
|
|
4158
4532
|
const isAuthorizationVerdict = verdict === void 0 ? /Unauthorized Action|\b(?:401|403)\b/.test(message) : verdict !== "other";
|
|
4159
4533
|
if (isAuthorizationVerdict) {
|
|
@@ -4163,13 +4537,29 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4163
4537
|
);
|
|
4164
4538
|
return;
|
|
4165
4539
|
}
|
|
4166
|
-
if ((0,
|
|
4167
|
-
console.warn(
|
|
4540
|
+
if ((0, import_sdk_core10.isStorageFullError)(error) || (0, import_sdk_core10.isStorageFullError)(error?.cause) || message.includes(import_sdk_core10.STORAGE_FULL_MESSAGE) || message.includes(import_sdk_core10.STORAGE_WRITE_TOO_LARGE_MESSAGE)) {
|
|
4541
|
+
console.warn(
|
|
4542
|
+
"TinyCloud account registry sync stopped: storage is full",
|
|
4543
|
+
error
|
|
4544
|
+
);
|
|
4168
4545
|
return;
|
|
4169
4546
|
}
|
|
4170
4547
|
lastError = error;
|
|
4171
4548
|
if (attempt < delays.length - 1) {
|
|
4172
|
-
await new Promise((resolve) =>
|
|
4549
|
+
await new Promise((resolve, reject2) => {
|
|
4550
|
+
const timer = setTimeout(() => {
|
|
4551
|
+
signal.removeEventListener("abort", onAbort);
|
|
4552
|
+
resolve();
|
|
4553
|
+
}, delays[attempt]);
|
|
4554
|
+
const onAbort = () => {
|
|
4555
|
+
clearTimeout(timer);
|
|
4556
|
+
signal.removeEventListener("abort", onAbort);
|
|
4557
|
+
reject2(signal.reason);
|
|
4558
|
+
};
|
|
4559
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
4560
|
+
}).catch((error2) => {
|
|
4561
|
+
if (!signal.aborted) throw error2;
|
|
4562
|
+
});
|
|
4173
4563
|
}
|
|
4174
4564
|
}
|
|
4175
4565
|
}
|
|
@@ -4185,7 +4575,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4185
4575
|
}
|
|
4186
4576
|
const networkIds = /* @__PURE__ */ new Set();
|
|
4187
4577
|
for (const resource of request.resources) {
|
|
4188
|
-
if (resource.service ===
|
|
4578
|
+
if (resource.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
|
|
4189
4579
|
networkIds.add(resource.path);
|
|
4190
4580
|
}
|
|
4191
4581
|
}
|
|
@@ -4196,7 +4586,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4196
4586
|
return;
|
|
4197
4587
|
}
|
|
4198
4588
|
for (const networkId of this.requestedEncryptionNetworkIds()) {
|
|
4199
|
-
const parsed = (0,
|
|
4589
|
+
const parsed = (0, import_sdk_core10.parseNetworkId)(networkId);
|
|
4200
4590
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
4201
4591
|
continue;
|
|
4202
4592
|
}
|
|
@@ -4219,7 +4609,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4219
4609
|
* self-revealing: the next write to the space fails immediately and loudly
|
|
4220
4610
|
* with `404 Space not found`.
|
|
4221
4611
|
*/
|
|
4222
|
-
async ensureOwnedSpaceHostedById(spaceId) {
|
|
4612
|
+
async ensureOwnedSpaceHostedById(spaceId, signal) {
|
|
4223
4613
|
if (!this.auth) {
|
|
4224
4614
|
throw new Error("Owned space hosting requires wallet mode");
|
|
4225
4615
|
}
|
|
@@ -4234,7 +4624,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4234
4624
|
if (!host) {
|
|
4235
4625
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
4236
4626
|
}
|
|
4237
|
-
const activation = await (0,
|
|
4627
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader, signal);
|
|
4238
4628
|
if (activation.success && !activation.skipped?.includes(spaceId)) {
|
|
4239
4629
|
this.confirmedHostedSpaceIds.add(spaceId);
|
|
4240
4630
|
return;
|
|
@@ -4245,15 +4635,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4245
4635
|
{ cause: activation }
|
|
4246
4636
|
);
|
|
4247
4637
|
}
|
|
4248
|
-
const
|
|
4638
|
+
const authorization = this.auth;
|
|
4639
|
+
const created = signal ? await authorization.hostOwnedSpaceResult(spaceId, void 0, signal) : await authorization.hostOwnedSpaceResult(spaceId);
|
|
4249
4640
|
if (!created.success) {
|
|
4250
4641
|
throw Object.assign(
|
|
4251
4642
|
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
4252
4643
|
{ cause: created }
|
|
4253
4644
|
);
|
|
4254
4645
|
}
|
|
4255
|
-
|
|
4256
|
-
const retry = await (0,
|
|
4646
|
+
if (signal?.aborted) throw signal.reason;
|
|
4647
|
+
const retry = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader, signal);
|
|
4257
4648
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
4258
4649
|
throw Object.assign(
|
|
4259
4650
|
new Error(
|
|
@@ -4301,7 +4692,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4301
4692
|
{ cause: hosted }
|
|
4302
4693
|
);
|
|
4303
4694
|
}
|
|
4304
|
-
const activation = await (0,
|
|
4695
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
4305
4696
|
host,
|
|
4306
4697
|
session.delegationHeader
|
|
4307
4698
|
);
|
|
@@ -4489,7 +4880,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4489
4880
|
}
|
|
4490
4881
|
let restoredAddress;
|
|
4491
4882
|
try {
|
|
4492
|
-
restoredAddress = hasPersistedProof ? (0,
|
|
4883
|
+
restoredAddress = hasPersistedProof ? (0, import_sdk_core10.canonicalizeAddress)(sessionData.address) : void 0;
|
|
4493
4884
|
} catch {
|
|
4494
4885
|
throw new InvalidRestoredSessionError("Persisted session has an invalid wallet address.");
|
|
4495
4886
|
}
|
|
@@ -4531,7 +4922,35 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4531
4922
|
const stagedHost = resolvedHost ?? this.config.host;
|
|
4532
4923
|
const stagedAddress = restoredAddress;
|
|
4533
4924
|
const stagedChainId = sessionData.chainId ?? 1;
|
|
4534
|
-
|
|
4925
|
+
let replicationPrincipal;
|
|
4926
|
+
let compactReplicationSession;
|
|
4927
|
+
let replicationScopeError;
|
|
4928
|
+
if (this.config.replication?.enabled) {
|
|
4929
|
+
if (stagedAddress !== void 0) {
|
|
4930
|
+
replicationPrincipal = (0, import_sdk_core10.pkhDid)(stagedAddress, stagedChainId);
|
|
4931
|
+
} else {
|
|
4932
|
+
const { replicationScopeFromSignedSession } = await getNodeReplicationLoaders().authority();
|
|
4933
|
+
const signedScope = replicationScopeFromSignedSession({
|
|
4934
|
+
delegationHeader: sessionData.delegationHeader,
|
|
4935
|
+
delegationCid: sessionData.delegationCid,
|
|
4936
|
+
verificationMethod: restoredVerificationMethod,
|
|
4937
|
+
persistedSpace: sessionData.spaceId
|
|
4938
|
+
});
|
|
4939
|
+
if (!signedScope) {
|
|
4940
|
+
replicationScopeError = "Persisted space does not match the locally verified delegation scope.";
|
|
4941
|
+
} else {
|
|
4942
|
+
replicationPrincipal = signedScope.principal;
|
|
4943
|
+
compactReplicationSession = {
|
|
4944
|
+
delegationHeader: sessionData.delegationHeader,
|
|
4945
|
+
delegationCid: sessionData.delegationCid,
|
|
4946
|
+
spaceId: signedScope.space,
|
|
4947
|
+
verificationMethod: restoredVerificationMethod,
|
|
4948
|
+
jwk: stagedJwk
|
|
4949
|
+
};
|
|
4950
|
+
}
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
const stagedNodeDid = stagedAddress ? (0, import_sdk_core10.pkhDid)(stagedAddress, stagedChainId) : canonicalVerificationMethod;
|
|
4535
4954
|
const serviceSession = {
|
|
4536
4955
|
delegationHeader: sessionData.delegationHeader,
|
|
4537
4956
|
delegationCid: sessionData.delegationCid,
|
|
@@ -4559,7 +4978,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4559
4978
|
stagedSessionExpiry,
|
|
4560
4979
|
stagedRecap
|
|
4561
4980
|
);
|
|
4562
|
-
const stagedAccountSpaceId = stagedAddress ? this.wasmBindings.makeSpaceId(stagedAddress, stagedChainId,
|
|
4981
|
+
const stagedAccountSpaceId = stagedAddress ? this.wasmBindings.makeSpaceId(stagedAddress, stagedChainId, import_sdk_core10.ACCOUNT_REGISTRY_SPACE) : void 0;
|
|
4563
4982
|
const stagedGraph = this.stageRestoredServiceGraph({
|
|
4564
4983
|
host: stagedHost,
|
|
4565
4984
|
manager: stagedManager,
|
|
@@ -4609,7 +5028,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4609
5028
|
} else {
|
|
4610
5029
|
this._restoredTcSession = stagedTcSession;
|
|
4611
5030
|
}
|
|
5031
|
+
this.replicationDelegateSession = compactReplicationSession;
|
|
5032
|
+
this.replicationScopeError = replicationScopeError;
|
|
5033
|
+
if (this.replicationRuntime) await (await this.replicationRuntime).unbind();
|
|
4612
5034
|
oldGraph.retire();
|
|
5035
|
+
if (replicationScopeError) {
|
|
5036
|
+
stagedGraph.serviceContext.emit("replication.state", {
|
|
5037
|
+
state: "unavailable",
|
|
5038
|
+
code: "SESSION_SCOPE_MISMATCH",
|
|
5039
|
+
detail: replicationScopeError
|
|
5040
|
+
});
|
|
5041
|
+
}
|
|
5042
|
+
await this.bindReplicationRuntime(stagedGraph.serviceContext, serviceSession, stagedGraph.kv, replicationPrincipal);
|
|
4613
5043
|
oldCore?.retireServices?.();
|
|
4614
5044
|
}
|
|
4615
5045
|
stagePrimarySessionState(session, verificationMethod, host, sessionExpiry, recap) {
|
|
@@ -4660,7 +5090,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4660
5090
|
}
|
|
4661
5091
|
stageRestoredServiceGraph(input) {
|
|
4662
5092
|
const graph = this.createServiceGraphLifetime();
|
|
4663
|
-
const core = this.auth ? new
|
|
5093
|
+
const core = this.auth ? new import_sdk_core10.TinyCloud(this.auth, {
|
|
4664
5094
|
invokeAny: graph.invokeAny,
|
|
4665
5095
|
telemetry: this.config.telemetry
|
|
4666
5096
|
}) : null;
|
|
@@ -4669,23 +5099,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4669
5099
|
const coreContext = graph.track(core.serviceContext);
|
|
4670
5100
|
coreContext.setSession(input.serviceSession);
|
|
4671
5101
|
}
|
|
4672
|
-
const serviceContext = graph.track(new
|
|
5102
|
+
const serviceContext = graph.track(new import_sdk_core10.ServiceContext({
|
|
4673
5103
|
invoke: graph.invoke,
|
|
4674
5104
|
invokeAny: graph.invokeAny,
|
|
4675
5105
|
fetch: graph.fetch,
|
|
4676
5106
|
hosts: [input.host],
|
|
4677
5107
|
telemetry: this.config.telemetry
|
|
4678
5108
|
}));
|
|
4679
|
-
const kv = new
|
|
5109
|
+
const kv = new import_sdk_core10.KVService({});
|
|
4680
5110
|
kv.initialize(serviceContext);
|
|
4681
5111
|
serviceContext.registerService("kv", kv);
|
|
4682
|
-
const sql = new
|
|
5112
|
+
const sql = new import_sdk_core10.SQLService({});
|
|
4683
5113
|
sql.initialize(serviceContext);
|
|
4684
5114
|
serviceContext.registerService("sql", sql);
|
|
4685
|
-
const duckdb = new
|
|
5115
|
+
const duckdb = new import_sdk_core10.DuckDbService({});
|
|
4686
5116
|
duckdb.initialize(serviceContext);
|
|
4687
5117
|
serviceContext.registerService("duckdb", duckdb);
|
|
4688
|
-
const hooks = new
|
|
5118
|
+
const hooks = new import_sdk_core10.HooksService({});
|
|
4689
5119
|
hooks.initialize(serviceContext);
|
|
4690
5120
|
serviceContext.registerService("hooks", hooks);
|
|
4691
5121
|
serviceContext.setSession(input.serviceSession);
|
|
@@ -4708,7 +5138,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4708
5138
|
});
|
|
4709
5139
|
vault.initialize(serviceContext);
|
|
4710
5140
|
serviceContext.registerService("vault", vault);
|
|
4711
|
-
const capabilityRegistry = new
|
|
5141
|
+
const capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
4712
5142
|
if (input.tinyCloudSession) {
|
|
4713
5143
|
const session = input.tinyCloudSession;
|
|
4714
5144
|
const delegations = input.recap.map((entry) => ({
|
|
@@ -4732,7 +5162,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4732
5162
|
}, delegations);
|
|
4733
5163
|
}
|
|
4734
5164
|
}
|
|
4735
|
-
const delegationManager = new
|
|
5165
|
+
const delegationManager = new import_sdk_core10.DelegationManager({
|
|
4736
5166
|
hosts: [input.host],
|
|
4737
5167
|
accountSpaceId: input.accountSpaceId,
|
|
4738
5168
|
session: input.serviceSession,
|
|
@@ -4741,7 +5171,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4741
5171
|
fetch: graph.fetch
|
|
4742
5172
|
});
|
|
4743
5173
|
const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
|
|
4744
|
-
const sharingService = new
|
|
5174
|
+
const sharingService = new import_sdk_core10.SharingService({
|
|
4745
5175
|
hosts: [input.host],
|
|
4746
5176
|
invoke: graph.invoke,
|
|
4747
5177
|
fetch: graph.fetch,
|
|
@@ -4754,8 +5184,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4754
5184
|
return this.wasmBindings.computeCid(data, codec);
|
|
4755
5185
|
},
|
|
4756
5186
|
createKVService: (config) => {
|
|
4757
|
-
const service = new
|
|
4758
|
-
const context = graph.track(new
|
|
5187
|
+
const service = new import_sdk_core10.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
5188
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
4759
5189
|
invoke: config.invoke,
|
|
4760
5190
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
4761
5191
|
hosts: config.hosts,
|
|
@@ -4763,6 +5193,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4763
5193
|
}));
|
|
4764
5194
|
context.setSession(config.session);
|
|
4765
5195
|
service.initialize(context);
|
|
5196
|
+
this.attachReplicationKV(config.session.spaceId, service);
|
|
4766
5197
|
return service;
|
|
4767
5198
|
}
|
|
4768
5199
|
});
|
|
@@ -4784,7 +5215,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4784
5215
|
return delegation;
|
|
4785
5216
|
} : void 0
|
|
4786
5217
|
});
|
|
4787
|
-
const spaceService = new
|
|
5218
|
+
const spaceService = new import_sdk_core10.SpaceService({
|
|
4788
5219
|
hosts: [input.host],
|
|
4789
5220
|
session: input.serviceSession,
|
|
4790
5221
|
invoke: graph.invoke,
|
|
@@ -4793,8 +5224,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4793
5224
|
userDid: input.nodeDid,
|
|
4794
5225
|
createKVService: (spaceId) => {
|
|
4795
5226
|
graph.assertActive();
|
|
4796
|
-
const scopedKv = new
|
|
4797
|
-
const context = graph.track(new
|
|
5227
|
+
const scopedKv = new import_sdk_core10.KVService({});
|
|
5228
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
4798
5229
|
invoke: graph.invoke,
|
|
4799
5230
|
invokeAny: graph.invokeAny,
|
|
4800
5231
|
fetch: graph.fetch,
|
|
@@ -4803,12 +5234,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4803
5234
|
}));
|
|
4804
5235
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
4805
5236
|
scopedKv.initialize(context);
|
|
5237
|
+
this.attachReplicationKV(spaceId, scopedKv);
|
|
4806
5238
|
return scopedKv;
|
|
4807
5239
|
},
|
|
4808
5240
|
createVaultService: (spaceId) => {
|
|
4809
5241
|
graph.assertActive();
|
|
4810
|
-
const scopedKv = new
|
|
4811
|
-
const context = graph.track(new
|
|
5242
|
+
const scopedKv = new import_sdk_core10.KVService({});
|
|
5243
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
4812
5244
|
invoke: graph.invoke,
|
|
4813
5245
|
invokeAny: graph.invokeAny,
|
|
4814
5246
|
fetch: graph.fetch,
|
|
@@ -4817,6 +5249,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4817
5249
|
}));
|
|
4818
5250
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
4819
5251
|
scopedKv.initialize(context);
|
|
5252
|
+
this.attachReplicationKV(spaceId, scopedKv);
|
|
4820
5253
|
const scopedVault = this.createVaultService(spaceId, scopedKv, encryption, {
|
|
4821
5254
|
host: input.host,
|
|
4822
5255
|
did: input.nodeDid,
|
|
@@ -4894,7 +5327,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4894
5327
|
if (address === void 0 || chainId === void 0) {
|
|
4895
5328
|
return void 0;
|
|
4896
5329
|
}
|
|
4897
|
-
const resolved = await (0,
|
|
5330
|
+
const resolved = await (0, import_sdk_core10.resolveTinyCloudHosts)((0, import_sdk_core10.pkhDid)(address, chainId), {
|
|
4898
5331
|
registryUrl: this.config.tinycloudRegistryUrl,
|
|
4899
5332
|
fallbackHosts: this.config.tinycloudFallbackHosts,
|
|
4900
5333
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
@@ -4946,7 +5379,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4946
5379
|
nodeAudience: input.nodeAudience,
|
|
4947
5380
|
...input.role === "policy-enforcement" ? { enforcerDid: input.audienceDid } : {}
|
|
4948
5381
|
};
|
|
4949
|
-
const root = await (0,
|
|
5382
|
+
const root = await (0, import_sdk_core10.signCompactUcanRootAuthorization)({
|
|
4950
5383
|
issuerDid: ownerDid,
|
|
4951
5384
|
audienceDid: input.audienceDid,
|
|
4952
5385
|
attenuation: unifiedRootAttenuation(input.capabilities),
|
|
@@ -4988,7 +5421,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4988
5421
|
if (decision.needsApproval) return void 0;
|
|
4989
5422
|
throw new Error(decision.reason ?? "OpenKey automatic credential signing was rejected");
|
|
4990
5423
|
}
|
|
4991
|
-
if (typeof decision.signature !== "string" || !await (0,
|
|
5424
|
+
if (typeof decision.signature !== "string" || !await (0, import_sdk_core10.verifyEip191MessageSignature)(
|
|
4992
5425
|
request.message,
|
|
4993
5426
|
decision.signature,
|
|
4994
5427
|
request.address
|
|
@@ -5013,7 +5446,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5013
5446
|
if (approval) {
|
|
5014
5447
|
const decision = await approval(request);
|
|
5015
5448
|
if (!decision.approved) throw new Error(decision.reason ?? "Credential signing was rejected");
|
|
5016
|
-
if (decision.signature !== void 0 && !await (0,
|
|
5449
|
+
if (decision.signature !== void 0 && !await (0, import_sdk_core10.verifyEip191MessageSignature)(
|
|
5017
5450
|
request.message,
|
|
5018
5451
|
decision.signature,
|
|
5019
5452
|
request.address
|
|
@@ -5096,10 +5529,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5096
5529
|
nonce: this.config.nonce,
|
|
5097
5530
|
siweConfig: this.config.siweConfig,
|
|
5098
5531
|
manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
|
|
5099
|
-
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ?
|
|
5100
|
-
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions
|
|
5532
|
+
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ? import_sdk_core10.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
|
|
5533
|
+
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions,
|
|
5534
|
+
replication: this.config.replication?.enabled === true ? {
|
|
5535
|
+
enabled: true,
|
|
5536
|
+
prefixes: this.config.replication.prefixes,
|
|
5537
|
+
allowSecrets: this.config.replication.allowSecrets === true
|
|
5538
|
+
} : void 0
|
|
5101
5539
|
});
|
|
5102
|
-
this.tc = new
|
|
5540
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
5103
5541
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
5104
5542
|
telemetry: this.config.telemetry
|
|
5105
5543
|
});
|
|
@@ -5149,10 +5587,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5149
5587
|
nonce: this.config.nonce,
|
|
5150
5588
|
siweConfig: this.config.siweConfig,
|
|
5151
5589
|
manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
|
|
5152
|
-
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ?
|
|
5153
|
-
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions
|
|
5590
|
+
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ? import_sdk_core10.BOOTSTRAP_DEFAULT_ONLY_SESSION_REQUEST : import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default : this.config.capabilityRequest,
|
|
5591
|
+
includeAccountRegistryPermissions: useBootstrapSignInRequest ? false : this.config.includeAccountRegistryPermissions,
|
|
5592
|
+
replication: this.config.replication?.enabled === true ? {
|
|
5593
|
+
enabled: true,
|
|
5594
|
+
prefixes: this.config.replication.prefixes,
|
|
5595
|
+
allowSecrets: this.config.replication.allowSecrets === true
|
|
5596
|
+
} : void 0
|
|
5154
5597
|
});
|
|
5155
|
-
this.tc = new
|
|
5598
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
5156
5599
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
5157
5600
|
telemetry: this.config.telemetry
|
|
5158
5601
|
});
|
|
@@ -5162,7 +5605,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5162
5605
|
* Initialize the service context and KV service after sign-in.
|
|
5163
5606
|
* @internal
|
|
5164
5607
|
*/
|
|
5165
|
-
initializeServices() {
|
|
5608
|
+
async initializeServices() {
|
|
5166
5609
|
const session = this.currentTinyCloudSession();
|
|
5167
5610
|
if (!session) {
|
|
5168
5611
|
return;
|
|
@@ -5173,28 +5616,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5173
5616
|
this._serviceGraph.fetch
|
|
5174
5617
|
);
|
|
5175
5618
|
this._serviceGraph.track(this.tc.serviceContext);
|
|
5176
|
-
this._serviceContext = this._serviceGraph.track(new
|
|
5619
|
+
this._serviceContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
5177
5620
|
invoke: this._serviceGraph.invoke,
|
|
5178
5621
|
invokeAny: this._serviceGraph.invokeAny,
|
|
5179
5622
|
fetch: this._serviceGraph.fetch,
|
|
5180
5623
|
hosts: [this.config.host],
|
|
5181
5624
|
telemetry: this.config.telemetry
|
|
5182
5625
|
}));
|
|
5183
|
-
this._kv = new
|
|
5626
|
+
this._kv = new import_sdk_core10.KVService({});
|
|
5184
5627
|
this._kv.initialize(this._serviceContext);
|
|
5185
5628
|
this._serviceContext.registerService("kv", this._kv);
|
|
5186
5629
|
const features = this.nodeFeatures;
|
|
5187
5630
|
if (features.length === 0 || features.includes("sql")) {
|
|
5188
|
-
this._sql = new
|
|
5631
|
+
this._sql = new import_sdk_core10.SQLService({});
|
|
5189
5632
|
this._sql.initialize(this._serviceContext);
|
|
5190
5633
|
this._serviceContext.registerService("sql", this._sql);
|
|
5191
5634
|
}
|
|
5192
5635
|
if (features.length === 0 || features.includes("duckdb")) {
|
|
5193
|
-
this._duckdb = new
|
|
5636
|
+
this._duckdb = new import_sdk_core10.DuckDbService({});
|
|
5194
5637
|
this._duckdb.initialize(this._serviceContext);
|
|
5195
5638
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
5196
5639
|
}
|
|
5197
|
-
this._hooks = new
|
|
5640
|
+
this._hooks = new import_sdk_core10.HooksService({});
|
|
5198
5641
|
this._hooks.initialize(this._serviceContext);
|
|
5199
5642
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
5200
5643
|
const serviceSession = {
|
|
@@ -5205,16 +5648,22 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5205
5648
|
jwk: session.jwk
|
|
5206
5649
|
};
|
|
5207
5650
|
this._serviceContext.setSession(serviceSession);
|
|
5651
|
+
await this.bindReplicationRuntime(this._serviceContext, serviceSession, this._kv);
|
|
5208
5652
|
this.tc.serviceContext.setSession(serviceSession);
|
|
5209
5653
|
this._vault = this.createVaultService(session.spaceId, this._kv);
|
|
5210
5654
|
this._vault.initialize(this._serviceContext);
|
|
5211
5655
|
this._serviceContext.registerService("vault", this._vault);
|
|
5212
5656
|
this.initializeV2Services(serviceSession);
|
|
5213
5657
|
}
|
|
5658
|
+
attachReplicationKV(spaceId, kvService) {
|
|
5659
|
+
if (!this.replicationRuntime) return;
|
|
5660
|
+
const attached = this.replicationRuntime.then((runtime) => runtime.attach(spaceId, kvService));
|
|
5661
|
+
kvService.setReadThroughReady(attached);
|
|
5662
|
+
}
|
|
5214
5663
|
createSpaceScopedKVService(spaceId) {
|
|
5215
|
-
const kvService = new
|
|
5664
|
+
const kvService = new import_sdk_core10.KVService({});
|
|
5216
5665
|
if (this._serviceContext) {
|
|
5217
|
-
const spaceScopedContext = this._serviceGraph.track(new
|
|
5666
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
5218
5667
|
invoke: this._serviceContext.invoke,
|
|
5219
5668
|
invokeAny: this._serviceContext.invokeAny,
|
|
5220
5669
|
fetch: this._serviceContext.fetch,
|
|
@@ -5226,6 +5675,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5226
5675
|
spaceScopedContext.setSession({ ...session, spaceId });
|
|
5227
5676
|
}
|
|
5228
5677
|
kvService.initialize(spaceScopedContext);
|
|
5678
|
+
this.attachReplicationKV(spaceId, kvService);
|
|
5229
5679
|
}
|
|
5230
5680
|
return kvService;
|
|
5231
5681
|
}
|
|
@@ -5306,7 +5756,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5306
5756
|
const shared = wasm.vault_x25519_dh(receiverPrivateKey, peerPublic);
|
|
5307
5757
|
return columnDecrypt(shared, ciphertext);
|
|
5308
5758
|
},
|
|
5309
|
-
verifyNodeSignature: (nodeId, message, signature) => (0,
|
|
5759
|
+
verifyNodeSignature: (nodeId, message, signature) => (0, import_sdk_core10.verifyDidKeyEd25519Signature)(nodeId, message, signature)
|
|
5310
5760
|
};
|
|
5311
5761
|
}
|
|
5312
5762
|
/**
|
|
@@ -5322,7 +5772,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5322
5772
|
if (cached) return cached;
|
|
5323
5773
|
const response = await fetch(`${this.config.host}/info`);
|
|
5324
5774
|
if (!response.ok) {
|
|
5325
|
-
throw await (0,
|
|
5775
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, "Failed to fetch node info");
|
|
5326
5776
|
}
|
|
5327
5777
|
const info = await response.json();
|
|
5328
5778
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -5372,7 +5822,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5372
5822
|
);
|
|
5373
5823
|
if (response.status === 404) return null;
|
|
5374
5824
|
if (!response.ok) {
|
|
5375
|
-
throw await (0,
|
|
5825
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, `Failed to fetch encryption network ${networkId}`);
|
|
5376
5826
|
}
|
|
5377
5827
|
const body = await response.json();
|
|
5378
5828
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -5403,17 +5853,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5403
5853
|
);
|
|
5404
5854
|
graph.assertActive();
|
|
5405
5855
|
if (!response.ok) {
|
|
5406
|
-
const permissionHint = response.status === 401 || response.status === 403 ? (0,
|
|
5856
|
+
const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services3.parsePermissionHint)({
|
|
5407
5857
|
service: "tinycloud.encryption",
|
|
5408
5858
|
path: networkId,
|
|
5409
5859
|
actions: ["tinycloud.encryption/decrypt"]
|
|
5410
5860
|
}) : void 0;
|
|
5411
|
-
throw new
|
|
5861
|
+
throw new import_sdk_core10.DecryptTransportResponseError(response.status, permissionHint);
|
|
5412
5862
|
}
|
|
5413
5863
|
return await response.json();
|
|
5414
5864
|
}
|
|
5415
5865
|
};
|
|
5416
|
-
return new
|
|
5866
|
+
return new import_sdk_core10.EncryptionService({
|
|
5417
5867
|
crypto: crypto2,
|
|
5418
5868
|
signer: {
|
|
5419
5869
|
signDecryptInvocation: async (input) => {
|
|
@@ -5427,7 +5877,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5427
5877
|
graph.assertActive();
|
|
5428
5878
|
return {
|
|
5429
5879
|
...signed,
|
|
5430
|
-
canonicalBody: (0,
|
|
5880
|
+
canonicalBody: (0, import_sdk_core10.canonicalizeEncryptionJson)(
|
|
5431
5881
|
input.body
|
|
5432
5882
|
)
|
|
5433
5883
|
};
|
|
@@ -5459,7 +5909,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5459
5909
|
if (!address || !didPrincipalMatches2(principal, did)) {
|
|
5460
5910
|
return null;
|
|
5461
5911
|
}
|
|
5462
|
-
const publicSpaceId = (0,
|
|
5912
|
+
const publicSpaceId = (0, import_sdk_core10.makePublicSpaceId)(address, chainId);
|
|
5463
5913
|
const encodedKey = discoveryKey.split("/").map(encodeURIComponent).join("/");
|
|
5464
5914
|
const response = await graph.fetch(
|
|
5465
5915
|
`${host}/public/${encodeURIComponent(publicSpaceId)}/kv/${encodedKey}`,
|
|
@@ -5491,7 +5941,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5491
5941
|
createVaultService(spaceId, kv, encryptionService = this.getEncryptionService(), nodeContext) {
|
|
5492
5942
|
const wasm = this.wasmBindings;
|
|
5493
5943
|
const serviceGraph = nodeContext?.serviceGraph ?? this._serviceGraph;
|
|
5494
|
-
const vaultCrypto = (0,
|
|
5944
|
+
const vaultCrypto = (0, import_sdk_core10.createVaultCrypto)({
|
|
5495
5945
|
vault_encrypt: wasm.vault_encrypt,
|
|
5496
5946
|
vault_decrypt: wasm.vault_decrypt,
|
|
5497
5947
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -5506,7 +5956,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5506
5956
|
const chainId = nodeContext?.chainId ?? this._chainId;
|
|
5507
5957
|
const host = nodeContext?.host ?? this.config.host;
|
|
5508
5958
|
const ownerDid = this.ownerDidFromSpaceId(spaceId) ?? did;
|
|
5509
|
-
return new
|
|
5959
|
+
return new import_sdk_core10.DataVaultService({
|
|
5510
5960
|
spaceId,
|
|
5511
5961
|
crypto: vaultCrypto,
|
|
5512
5962
|
encryption: {
|
|
@@ -5531,8 +5981,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5531
5981
|
serviceGraph.assertActive();
|
|
5532
5982
|
return self._publicKV ?? self.tc.publicKV;
|
|
5533
5983
|
},
|
|
5534
|
-
readPublicSpace: (host2, targetSpaceId, key) =>
|
|
5535
|
-
makePublicSpaceId:
|
|
5984
|
+
readPublicSpace: (host2, targetSpaceId, key) => import_sdk_core10.TinyCloud.readPublicSpace(host2, targetSpaceId, key),
|
|
5985
|
+
makePublicSpaceId: import_sdk_core10.TinyCloud.makePublicSpaceId,
|
|
5536
5986
|
did,
|
|
5537
5987
|
address: address ?? "",
|
|
5538
5988
|
chainId,
|
|
@@ -5546,7 +5996,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5546
5996
|
*/
|
|
5547
5997
|
initializeV2Services(serviceSession) {
|
|
5548
5998
|
const graph = this._serviceGraph;
|
|
5549
|
-
this._capabilityRegistry = new
|
|
5999
|
+
this._capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
5550
6000
|
const tcSession = this.auth?.tinyCloudSession;
|
|
5551
6001
|
if (tcSession && this._address) {
|
|
5552
6002
|
const sessionKey = {
|
|
@@ -5586,7 +6036,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5586
6036
|
}
|
|
5587
6037
|
this._capabilityRegistry.registerKey(sessionKey, delegations);
|
|
5588
6038
|
}
|
|
5589
|
-
this._delegationManager = new
|
|
6039
|
+
this._delegationManager = new import_sdk_core10.DelegationManager({
|
|
5590
6040
|
hosts: [this.config.host],
|
|
5591
6041
|
accountSpaceId: this.accountSpaceId,
|
|
5592
6042
|
session: serviceSession,
|
|
@@ -5594,7 +6044,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5594
6044
|
invokeAny: graph.invokeAny,
|
|
5595
6045
|
fetch: graph.fetch
|
|
5596
6046
|
});
|
|
5597
|
-
this._spaceService = new
|
|
6047
|
+
this._spaceService = new import_sdk_core10.SpaceService({
|
|
5598
6048
|
hosts: [this.config.host],
|
|
5599
6049
|
session: serviceSession,
|
|
5600
6050
|
invoke: graph.invoke,
|
|
@@ -5659,7 +6109,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5659
6109
|
await this.account.spaces.register(space);
|
|
5660
6110
|
}
|
|
5661
6111
|
});
|
|
5662
|
-
this._sharingService = new
|
|
6112
|
+
this._sharingService = new import_sdk_core10.SharingService({
|
|
5663
6113
|
hosts: [this.config.host],
|
|
5664
6114
|
session: serviceSession,
|
|
5665
6115
|
invoke: graph.invoke,
|
|
@@ -5679,8 +6129,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5679
6129
|
},
|
|
5680
6130
|
createKVService: (config) => {
|
|
5681
6131
|
graph.assertActive();
|
|
5682
|
-
const service = new
|
|
5683
|
-
const context = graph.track(new
|
|
6132
|
+
const service = new import_sdk_core10.KVService({ prefix: config.pathPrefix?.replace(/\/$/, "") });
|
|
6133
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
5684
6134
|
invoke: config.invoke,
|
|
5685
6135
|
fetch: config.fetch ?? graph.fetch,
|
|
5686
6136
|
hosts: config.hosts,
|
|
@@ -5688,6 +6138,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5688
6138
|
}));
|
|
5689
6139
|
context.setSession(config.session);
|
|
5690
6140
|
service.initialize(context);
|
|
6141
|
+
this.attachReplicationKV(config.session.spaceId, service);
|
|
5691
6142
|
return service;
|
|
5692
6143
|
},
|
|
5693
6144
|
onRootDelegationNeeded: this.signer ? async (params) => {
|
|
@@ -5773,15 +6224,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5773
6224
|
}
|
|
5774
6225
|
const permissions = ownerDelegationPermissions(params);
|
|
5775
6226
|
const now = /* @__PURE__ */ new Date();
|
|
5776
|
-
if (!(params.expiresAt instanceof Date) || params.expiresAt.getTime() <= now.getTime() || params.expiresAt.getTime() - now.getTime() >
|
|
6227
|
+
if (!(params.expiresAt instanceof Date) || params.expiresAt.getTime() <= now.getTime() || params.expiresAt.getTime() - now.getTime() > import_sdk_core10.EXPIRY.MAX_MS) {
|
|
5777
6228
|
throw new Error("Owner delegation expiry must be explicit, future, and within EXPIRY.MAX_MS");
|
|
5778
6229
|
}
|
|
5779
6230
|
if (!this.signer) throw new Error("Owner wallet signer is required");
|
|
5780
6231
|
const session = this.currentTinyCloudSession();
|
|
5781
6232
|
if (!session) throw new Error("Owner session is required");
|
|
5782
|
-
const ownerDid = (0,
|
|
6233
|
+
const ownerDid = (0, import_sdk_core10.pkhDid)(session.address, session.chainId);
|
|
5783
6234
|
for (const permission of permissions) {
|
|
5784
|
-
if (permission.service ===
|
|
6235
|
+
if (permission.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && !(0, import_sdk_core10.principalDidEquals)((0, import_sdk_core10.parseNetworkId)(permission.path).ownerDid, ownerDid)) {
|
|
5785
6236
|
throw new Error("Owner delegation cannot grant a foreign encryption network");
|
|
5786
6237
|
}
|
|
5787
6238
|
}
|
|
@@ -5802,7 +6253,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5802
6253
|
const signature = await this.signer.signMessage(prepared.siwe);
|
|
5803
6254
|
assertOwnerGraphActive();
|
|
5804
6255
|
const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature });
|
|
5805
|
-
const activation = await (0,
|
|
6256
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(host, delegationSession.delegationHeader);
|
|
5806
6257
|
assertOwnerGraphActive();
|
|
5807
6258
|
if (!activation.success) {
|
|
5808
6259
|
throw Object.assign(
|
|
@@ -5838,7 +6289,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5838
6289
|
/** Register a signed policy and sibling roots with this Node's Policy/v3 runtime. */
|
|
5839
6290
|
async registerPolicy(params) {
|
|
5840
6291
|
this._serviceGraph.assertActive();
|
|
5841
|
-
return (0,
|
|
6292
|
+
return (0, import_sdk_core10.registerPolicyV3)({
|
|
5842
6293
|
...params,
|
|
5843
6294
|
nodeOrigin: this.config.host,
|
|
5844
6295
|
fetch: globalThis.fetch.bind(globalThis)
|
|
@@ -5865,23 +6316,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5865
6316
|
jti: base64UrlEncode(jtiDigest.slice(0, 16)),
|
|
5866
6317
|
expiresAt: new Date(input.expiresAt).toISOString().replace(/\.\d{3}Z$/, "Z")
|
|
5867
6318
|
};
|
|
5868
|
-
const requestBodyDigest = base64UrlEncode(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode((0,
|
|
6319
|
+
const requestBodyDigest = base64UrlEncode(new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode((0, import_sdk_core10.canonicalizeEncryptionJson)(body)))));
|
|
5869
6320
|
const request = { ...body, requestBodyDigest };
|
|
5870
6321
|
const authorization = authorizationHeader(this.invokeAnyWithRuntimePermissions(serviceSession, [{ spaceId: session.spaceId, service: "kv", path: input.resourcePath, action: "tinycloud.kv/get" }]));
|
|
5871
6322
|
const response = await fetch(`${this.config.host}/policy/v3/deliveries/authorize`, {
|
|
5872
6323
|
method: "POST",
|
|
5873
6324
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
5874
|
-
body: (0,
|
|
6325
|
+
body: (0, import_sdk_core10.canonicalizeEncryptionJson)(request)
|
|
5875
6326
|
});
|
|
5876
|
-
if (!response.ok) throw await (0,
|
|
5877
|
-
const verified = (0,
|
|
6327
|
+
if (!response.ok) throw await (0, import_sdk_core10.httpResponseError)(response, "V3 share delivery authorization failed");
|
|
6328
|
+
const verified = (0, import_sdk_core10.validateShareDeliveryAuthorizationV3Bytes)(new Uint8Array(await response.arrayBuffer()), {
|
|
5878
6329
|
request,
|
|
5879
6330
|
senderKeyDid: this.credentialHolderDid,
|
|
5880
6331
|
deliveryAudience: input.deliveryAudience
|
|
5881
6332
|
});
|
|
5882
6333
|
const requestDigest = new Uint8Array(await crypto.subtle.digest(
|
|
5883
6334
|
"SHA-256",
|
|
5884
|
-
new TextEncoder().encode(`${
|
|
6335
|
+
new TextEncoder().encode(`${import_sdk_core10.CREDENTIAL_INVITATION_REQUEST_DOMAIN}${(0, import_sdk_core10.canonicalizeEncryptionJson)(verified.request)}`)
|
|
5885
6336
|
));
|
|
5886
6337
|
return {
|
|
5887
6338
|
...verified,
|
|
@@ -5949,7 +6400,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5949
6400
|
if (!this._sql) {
|
|
5950
6401
|
const features = this.nodeFeatures;
|
|
5951
6402
|
if (features.length > 0 && !features.includes("sql")) {
|
|
5952
|
-
throw new
|
|
6403
|
+
throw new import_sdk_core10.UnsupportedFeatureError("sql", this.config.host, features);
|
|
5953
6404
|
}
|
|
5954
6405
|
throw new Error("Not signed in. Call signIn() first.");
|
|
5955
6406
|
}
|
|
@@ -5973,8 +6424,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5973
6424
|
if (!this._serviceContext || !this._serviceContext.session) {
|
|
5974
6425
|
throw new Error("Not signed in. Call signIn() first.");
|
|
5975
6426
|
}
|
|
5976
|
-
const sql = new
|
|
5977
|
-
const spaceScopedContext = this._serviceGraph.track(new
|
|
6427
|
+
const sql = new import_sdk_core10.SQLService({});
|
|
6428
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
5978
6429
|
invoke: this._serviceContext.invoke,
|
|
5979
6430
|
invokeAny: this._serviceContext.invokeAny,
|
|
5980
6431
|
fetch: this._serviceContext.fetch,
|
|
@@ -6003,8 +6454,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6003
6454
|
if (!this._serviceContext || !this._serviceContext.session) {
|
|
6004
6455
|
throw new Error("Not signed in. Call signIn() first.");
|
|
6005
6456
|
}
|
|
6006
|
-
const kv = new
|
|
6007
|
-
const spaceScopedContext = this._serviceGraph.track(new
|
|
6457
|
+
const kv = new import_sdk_core10.KVService({});
|
|
6458
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
6008
6459
|
invoke: this._serviceContext.invoke,
|
|
6009
6460
|
invokeAny: this._serviceContext.invokeAny,
|
|
6010
6461
|
fetch: this._serviceContext.fetch,
|
|
@@ -6012,6 +6463,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6012
6463
|
}));
|
|
6013
6464
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
6014
6465
|
kv.initialize(spaceScopedContext);
|
|
6466
|
+
this.attachReplicationKV(spaceId, kv);
|
|
6015
6467
|
return kv;
|
|
6016
6468
|
}
|
|
6017
6469
|
/**
|
|
@@ -6021,7 +6473,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6021
6473
|
if (!this._duckdb) {
|
|
6022
6474
|
const features = this.nodeFeatures;
|
|
6023
6475
|
if (features.length > 0 && !features.includes("duckdb")) {
|
|
6024
|
-
throw new
|
|
6476
|
+
throw new import_sdk_core10.UnsupportedFeatureError("duckdb", this.config.host, features);
|
|
6025
6477
|
}
|
|
6026
6478
|
throw new Error("Not signed in. Call signIn() first.");
|
|
6027
6479
|
}
|
|
@@ -6065,7 +6517,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6065
6517
|
type: NETWORK_ADMIN_TYPE,
|
|
6066
6518
|
targetNode,
|
|
6067
6519
|
networkId,
|
|
6068
|
-
bodyHash: (0,
|
|
6520
|
+
bodyHash: (0, import_sdk_core10.canonicalHashHex)(
|
|
6069
6521
|
crypto2.sha256,
|
|
6070
6522
|
body
|
|
6071
6523
|
),
|
|
@@ -6083,7 +6535,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6083
6535
|
Authorization: signed.authorization,
|
|
6084
6536
|
"Content-Type": "application/json"
|
|
6085
6537
|
},
|
|
6086
|
-
body: (0,
|
|
6538
|
+
body: (0, import_sdk_core10.canonicalizeEncryptionJson)(
|
|
6087
6539
|
body
|
|
6088
6540
|
)
|
|
6089
6541
|
});
|
|
@@ -6095,7 +6547,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6095
6547
|
);
|
|
6096
6548
|
}
|
|
6097
6549
|
if (!response.ok) {
|
|
6098
|
-
throw await (0,
|
|
6550
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, `Failed to create encryption network ${networkId}`);
|
|
6099
6551
|
}
|
|
6100
6552
|
const created = await response.json();
|
|
6101
6553
|
return created.descriptor;
|
|
@@ -6114,7 +6566,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6114
6566
|
return existing;
|
|
6115
6567
|
}
|
|
6116
6568
|
}
|
|
6117
|
-
const parsed = (0,
|
|
6569
|
+
const parsed = (0, import_sdk_core10.parseNetworkId)(networkId);
|
|
6118
6570
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
6119
6571
|
throw new Error(
|
|
6120
6572
|
`Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
|
|
@@ -6162,14 +6614,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6162
6614
|
* normal KV and encryption invocation paths.
|
|
6163
6615
|
*/
|
|
6164
6616
|
async readSecret(input) {
|
|
6165
|
-
const resolved = (0,
|
|
6617
|
+
const resolved = (0, import_sdk_core10.resolveSecretPath)(input.name, { scope: input.scope });
|
|
6166
6618
|
const targetSpace = input.space.startsWith("tinycloud:") ? input.space : this.ownedSpaceId(input.space);
|
|
6167
6619
|
const result = await this.getBaseVault(targetSpace).readNetworkEncrypted(
|
|
6168
6620
|
resolved.vaultKey
|
|
6169
6621
|
);
|
|
6170
6622
|
if (result.status !== "ok") {
|
|
6171
6623
|
if (result.status === "permission_required") {
|
|
6172
|
-
const hint = (0,
|
|
6624
|
+
const hint = (0, import_sdk_services3.parsePermissionHint)(result.hint);
|
|
6173
6625
|
if (hint === void 0) return { status: "read_failed" };
|
|
6174
6626
|
return {
|
|
6175
6627
|
status: "permission_required",
|
|
@@ -6195,7 +6647,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6195
6647
|
const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
|
|
6196
6648
|
let secrets = this._baseSecrets.get(resolvedSpace);
|
|
6197
6649
|
if (!secrets) {
|
|
6198
|
-
secrets = new
|
|
6650
|
+
secrets = new import_sdk_core10.SecretsService(() => this.getBaseVault(resolvedSpace));
|
|
6199
6651
|
this._baseSecrets.set(resolvedSpace, secrets);
|
|
6200
6652
|
}
|
|
6201
6653
|
return secrets;
|
|
@@ -6338,7 +6790,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6338
6790
|
for (const grant of this.runtimePermissionGrants) {
|
|
6339
6791
|
if (grant.provenance === "primary") continue;
|
|
6340
6792
|
for (const operation of grant.operations) {
|
|
6341
|
-
const service =
|
|
6793
|
+
const service = import_sdk_core10.SERVICE_SHORT_TO_LONG[operation.service];
|
|
6342
6794
|
if (service === void 0 || typeof operation.path !== "string" || typeof operation.action !== "string") {
|
|
6343
6795
|
continue;
|
|
6344
6796
|
}
|
|
@@ -6356,7 +6808,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6356
6808
|
service,
|
|
6357
6809
|
...space === void 0 ? {} : { space },
|
|
6358
6810
|
path: operation.path,
|
|
6359
|
-
caveats: (0,
|
|
6811
|
+
caveats: (0, import_sdk_core10.canonicalizeRecapCaveats)(caveats)
|
|
6360
6812
|
});
|
|
6361
6813
|
const existing = grouped.get(identity);
|
|
6362
6814
|
if (existing === void 0) {
|
|
@@ -6401,7 +6853,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6401
6853
|
delegationCid: grant.delegationCid,
|
|
6402
6854
|
spaceId: grant.spaceId,
|
|
6403
6855
|
jwk: this.sessionKeyJwk,
|
|
6404
|
-
address: (0,
|
|
6856
|
+
address: (0, import_sdk_core10.canonicalizeAddress)(grant.address),
|
|
6405
6857
|
chainId: grant.chainId,
|
|
6406
6858
|
siwe: grant.siwe,
|
|
6407
6859
|
signature: grant.signature
|
|
@@ -6422,10 +6874,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6422
6874
|
async useRuntimeDelegation(delegation) {
|
|
6423
6875
|
const session = this.currentTinyCloudSession();
|
|
6424
6876
|
if (!session) {
|
|
6425
|
-
throw new
|
|
6877
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6426
6878
|
}
|
|
6427
6879
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
6428
|
-
throw new
|
|
6880
|
+
throw new import_sdk_core10.SessionExpiredError(delegation.expiry);
|
|
6429
6881
|
}
|
|
6430
6882
|
const expectedDids = [session.verificationMethod, this.sessionDid];
|
|
6431
6883
|
if (!expectedDids.some((did) => didPrincipalMatches2(delegation.delegateDID, did))) {
|
|
@@ -6436,7 +6888,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6436
6888
|
const targetHost = delegation.host ?? this.config.host;
|
|
6437
6889
|
let activateResult;
|
|
6438
6890
|
try {
|
|
6439
|
-
activateResult = await (0,
|
|
6891
|
+
activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6440
6892
|
targetHost,
|
|
6441
6893
|
delegation.delegationHeader
|
|
6442
6894
|
);
|
|
@@ -6478,13 +6930,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6478
6930
|
}
|
|
6479
6931
|
const session = this.currentTinyCloudSession();
|
|
6480
6932
|
if (!session) {
|
|
6481
|
-
throw new
|
|
6933
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6482
6934
|
}
|
|
6483
6935
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
6484
6936
|
if (sessionExpiry !== void 0) {
|
|
6485
6937
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
6486
6938
|
if (sessionExpiry.getTime() <= Date.now() + marginMs) {
|
|
6487
|
-
throw new
|
|
6939
|
+
throw new import_sdk_core10.SessionExpiredError(sessionExpiry);
|
|
6488
6940
|
}
|
|
6489
6941
|
}
|
|
6490
6942
|
const expanded = this.expandPermissionEntries(permissions);
|
|
@@ -6560,7 +7012,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6560
7012
|
...prepared,
|
|
6561
7013
|
signature
|
|
6562
7014
|
});
|
|
6563
|
-
const activateResult = await (0,
|
|
7015
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6564
7016
|
this.config.host,
|
|
6565
7017
|
delegatedSession.delegationHeader
|
|
6566
7018
|
);
|
|
@@ -6733,10 +7185,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6733
7185
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
6734
7186
|
}
|
|
6735
7187
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
6736
|
-
const kvActions = [
|
|
7188
|
+
const kvActions = [import_sdk_core10.KV.PUT, import_sdk_core10.KV.GET, import_sdk_core10.KV.DEL, import_sdk_core10.KV.LIST, import_sdk_core10.KV.METADATA];
|
|
6737
7189
|
const abilities = { kv: { "": kvActions } };
|
|
6738
7190
|
const now = /* @__PURE__ */ new Date();
|
|
6739
|
-
const expiryMs =
|
|
7191
|
+
const expiryMs = import_sdk_core10.EXPIRY.EPHEMERAL_MS;
|
|
6740
7192
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
6741
7193
|
const prepared = this.wasmBindings.prepareSession({
|
|
6742
7194
|
abilities,
|
|
@@ -6754,7 +7206,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6754
7206
|
...prepared,
|
|
6755
7207
|
signature
|
|
6756
7208
|
});
|
|
6757
|
-
const activateResult = await (0,
|
|
7209
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6758
7210
|
this.config.host,
|
|
6759
7211
|
delegationSession.delegationHeader
|
|
6760
7212
|
);
|
|
@@ -6784,8 +7236,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6784
7236
|
}]);
|
|
6785
7237
|
}
|
|
6786
7238
|
if (this._serviceContext) {
|
|
6787
|
-
const publicKV = new
|
|
6788
|
-
const publicContext = this._serviceGraph.track(new
|
|
7239
|
+
const publicKV = new import_sdk_core10.KVService({ prefix: "" });
|
|
7240
|
+
const publicContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
6789
7241
|
invoke: this._serviceGraph.invoke,
|
|
6790
7242
|
fetch: this._serviceGraph.fetch,
|
|
6791
7243
|
hosts: this._serviceContext.hosts,
|
|
@@ -6937,14 +7389,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6937
7389
|
}
|
|
6938
7390
|
const session = this.currentTinyCloudSession();
|
|
6939
7391
|
if (!session) {
|
|
6940
|
-
throw new
|
|
7392
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6941
7393
|
}
|
|
6942
7394
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
6943
7395
|
if (sessionExpiry !== void 0) {
|
|
6944
7396
|
const now2 = Date.now();
|
|
6945
7397
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
6946
7398
|
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
6947
|
-
throw new
|
|
7399
|
+
throw new import_sdk_core10.SessionExpiredError(sessionExpiry);
|
|
6948
7400
|
}
|
|
6949
7401
|
}
|
|
6950
7402
|
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -6974,31 +7426,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6974
7426
|
);
|
|
6975
7427
|
return { delegation: delegation2, prompted: true };
|
|
6976
7428
|
}
|
|
6977
|
-
const
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
)
|
|
6985
|
-
|
|
6986
|
-
|
|
6987
|
-
|
|
6988
|
-
|
|
6989
|
-
}
|
|
6990
|
-
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
6991
|
-
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
6992
|
-
did,
|
|
6993
|
-
expandedEntries,
|
|
6994
|
-
runtimeExpiration,
|
|
6995
|
-
runtimeGrant,
|
|
6996
|
-
runtimeOperations,
|
|
6997
|
-
onPrepared
|
|
6998
|
-
);
|
|
6999
|
-
return { delegation: delegation2, prompted: false };
|
|
7429
|
+
const plan = this.planDerivation(
|
|
7430
|
+
expandedEntries,
|
|
7431
|
+
session,
|
|
7432
|
+
effectiveExpiration,
|
|
7433
|
+
Date.now()
|
|
7434
|
+
);
|
|
7435
|
+
if ("refused" in plan) {
|
|
7436
|
+
if (plan.refused === "SESSION_EXPIRING") {
|
|
7437
|
+
throw new import_sdk_core10.SessionExpiredError(plan.expiredAt ?? sessionExpiry ?? /* @__PURE__ */ new Date(0));
|
|
7438
|
+
}
|
|
7439
|
+
if (plan.refused === "CAVEATED_AUTHORITY") {
|
|
7440
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(plan.caveated ?? []);
|
|
7000
7441
|
}
|
|
7001
|
-
throw new
|
|
7442
|
+
throw new import_sdk_core10.PermissionNotInManifestError(plan.missing ?? [], plan.granted ?? []);
|
|
7443
|
+
}
|
|
7444
|
+
if (plan.path === "runtime") {
|
|
7445
|
+
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
7446
|
+
did,
|
|
7447
|
+
expandedEntries,
|
|
7448
|
+
plan.effectiveExpiration,
|
|
7449
|
+
plan.grant,
|
|
7450
|
+
plan.operations,
|
|
7451
|
+
onPrepared
|
|
7452
|
+
);
|
|
7453
|
+
return { delegation: delegation2, prompted: false };
|
|
7002
7454
|
}
|
|
7003
7455
|
const delegation = await this.createDelegationViaWasmPath(
|
|
7004
7456
|
did,
|
|
@@ -7009,6 +7461,149 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7009
7461
|
);
|
|
7010
7462
|
return { delegation, prompted: false };
|
|
7011
7463
|
}
|
|
7464
|
+
/**
|
|
7465
|
+
* What `delegateTo` would select for `entries`, without signing or any
|
|
7466
|
+
* network call (TC-858 plan v3 §4.3): the session path when the signed
|
|
7467
|
+
* recap covers every entry, the runtime-grant path otherwise, or a
|
|
7468
|
+
* refusal. A refusal of `CAVEATED_AUTHORITY` means coverage exists only
|
|
7469
|
+
* through caveated branches, which the action-only WASM child-delegation
|
|
7470
|
+
* boundary cannot preserve — replication never derives authority through
|
|
7471
|
+
* them. `expiredAt`/`missing`/`granted`/`caveated` carry the payload
|
|
7472
|
+
* `delegateTo` turns back into its typed errors.
|
|
7473
|
+
* @internal
|
|
7474
|
+
*/
|
|
7475
|
+
planDerivation(expandedEntries, session, effectiveExpiration, nowMs) {
|
|
7476
|
+
const caveatedRequest = expandedEntries.filter(
|
|
7477
|
+
(entry) => !(0, import_sdk_core10.recapCaveatsEqual)(entry.caveats, void 0)
|
|
7478
|
+
);
|
|
7479
|
+
if (caveatedRequest.length > 0) {
|
|
7480
|
+
return { refused: "CAVEATED_AUTHORITY", caveated: caveatedRequest };
|
|
7481
|
+
}
|
|
7482
|
+
const granted = this.projectSignedRecapCapabilities(session.siwe);
|
|
7483
|
+
const { subset, missing } = this.signedCapabilitySubset(expandedEntries, granted);
|
|
7484
|
+
if (subset) {
|
|
7485
|
+
return {
|
|
7486
|
+
path: "session",
|
|
7487
|
+
parentCid: session.delegationCid,
|
|
7488
|
+
expiresAt: effectiveExpiration.getTime(),
|
|
7489
|
+
effectiveExpiration
|
|
7490
|
+
};
|
|
7491
|
+
}
|
|
7492
|
+
const runtimeOperations = this.permissionEntriesToOperations(expandedEntries, session);
|
|
7493
|
+
const runtimeGrant = this.findGrantForOperations(
|
|
7494
|
+
runtimeOperations,
|
|
7495
|
+
{ excludePrimary: true }
|
|
7496
|
+
);
|
|
7497
|
+
if (runtimeGrant) {
|
|
7498
|
+
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
7499
|
+
if (runtimeGrant.expiresAt.getTime() <= nowMs + marginMs) {
|
|
7500
|
+
return { refused: "SESSION_EXPIRING", expiredAt: runtimeGrant.expiresAt };
|
|
7501
|
+
}
|
|
7502
|
+
const caveated = this.caveatedRuntimeGrantEntries(
|
|
7503
|
+
expandedEntries,
|
|
7504
|
+
runtimeOperations,
|
|
7505
|
+
runtimeGrant
|
|
7506
|
+
);
|
|
7507
|
+
if (caveated.length > 0) {
|
|
7508
|
+
return { refused: "CAVEATED_AUTHORITY", caveated };
|
|
7509
|
+
}
|
|
7510
|
+
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
7511
|
+
return {
|
|
7512
|
+
path: "runtime",
|
|
7513
|
+
parentCid: runtimeGrant.session.delegationCid,
|
|
7514
|
+
expiresAt: runtimeExpiration.getTime(),
|
|
7515
|
+
effectiveExpiration: runtimeExpiration,
|
|
7516
|
+
grant: runtimeGrant,
|
|
7517
|
+
operations: runtimeOperations
|
|
7518
|
+
};
|
|
7519
|
+
}
|
|
7520
|
+
const relaxedGranted = granted.map((entry) => ({ ...entry, caveats: void 0 }));
|
|
7521
|
+
const relaxedRequested = expandedEntries.map((entry) => ({ ...entry, caveats: void 0 }));
|
|
7522
|
+
const relaxed = this.signedCapabilitySubset(relaxedRequested, relaxedGranted);
|
|
7523
|
+
if (relaxed.subset) {
|
|
7524
|
+
return {
|
|
7525
|
+
refused: "CAVEATED_AUTHORITY",
|
|
7526
|
+
caveated: missing.map((entry) => ({ ...entry, caveats: [{ via: "session-recap" }] }))
|
|
7527
|
+
};
|
|
7528
|
+
}
|
|
7529
|
+
return { refused: "NOT_COVERED", missing, granted };
|
|
7530
|
+
}
|
|
7531
|
+
/**
|
|
7532
|
+
* The plan `delegateTo(device, entries)` would follow, as a pure lookup:
|
|
7533
|
+
* no WASM sign and no `POST /delegate`. Backs
|
|
7534
|
+
* `ReplicationAuthority.plan` (and `mint` inside it) so a predicted
|
|
7535
|
+
* parent and expiry can never disagree with what a mint would use (§4.3,
|
|
7536
|
+
* §4.4). Session expiry inside the 60 s margin refuses with
|
|
7537
|
+
* `SESSION_EXPIRING`; the same check delegateTo performs.
|
|
7538
|
+
* @internal
|
|
7539
|
+
*/
|
|
7540
|
+
planDelegation(entries, options) {
|
|
7541
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
7542
|
+
throw new Error("planDelegation requires a non-empty permissions array");
|
|
7543
|
+
}
|
|
7544
|
+
const session = this.currentTinyCloudSession();
|
|
7545
|
+
if (!session) {
|
|
7546
|
+
return { refused: "SESSION_EXPIRING", expiredAt: /* @__PURE__ */ new Date(0) };
|
|
7547
|
+
}
|
|
7548
|
+
const nowMs = Date.now();
|
|
7549
|
+
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
7550
|
+
if (sessionExpiry !== void 0 && sessionExpiry.getTime() <= nowMs + _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS) {
|
|
7551
|
+
return { refused: "SESSION_EXPIRING", expiredAt: sessionExpiry };
|
|
7552
|
+
}
|
|
7553
|
+
const expandedEntries = this.expandPermissionEntries(entries);
|
|
7554
|
+
const expiryMs = resolveExpiryMs(options?.expiry);
|
|
7555
|
+
const expirationTime = new Date(nowMs + expiryMs);
|
|
7556
|
+
const effectiveExpiration = sessionExpiry !== void 0 && sessionExpiry < expirationTime ? sessionExpiry : expirationTime;
|
|
7557
|
+
return this.planDerivation(expandedEntries, session, effectiveExpiration, nowMs);
|
|
7558
|
+
}
|
|
7559
|
+
/**
|
|
7560
|
+
* The replication entries this node's sign-in request carries for the
|
|
7561
|
+
* current replication config and the signed-in or restored address: the
|
|
7562
|
+
* output of the same augmentation step `resolveSignInCapabilities` runs,
|
|
7563
|
+
* with the unrestricted-get and secrets gates applied (§4.1, §4.6).
|
|
7564
|
+
* Empty when replication is off or no address is known. Pure.
|
|
7565
|
+
*/
|
|
7566
|
+
replicationSignInEntries() {
|
|
7567
|
+
if (this.config.replication?.enabled !== true) return [];
|
|
7568
|
+
const auth = this.auth;
|
|
7569
|
+
if (auth === void 0 || typeof auth.replicationSignInEntries !== "function") {
|
|
7570
|
+
return [];
|
|
7571
|
+
}
|
|
7572
|
+
return auth.replicationSignInEntries();
|
|
7573
|
+
}
|
|
7574
|
+
async replicationAuthority() {
|
|
7575
|
+
const { createReplicationAuthority } = await getNodeReplicationLoaders().authority();
|
|
7576
|
+
return createReplicationAuthority({
|
|
7577
|
+
replicationSession: () => this.currentTinyCloudSession() ?? this.replicationDelegateSession,
|
|
7578
|
+
siweExpiration: (siwe) => extractSiweExpiration(siwe),
|
|
7579
|
+
planDelegation: (entries, options) => this.planDelegation(entries, options),
|
|
7580
|
+
mintDelegation: async (deviceDid, entries) => {
|
|
7581
|
+
const result = await this.delegateTo((0, import_sdk_core10.principalDid)(deviceDid), entries);
|
|
7582
|
+
return {
|
|
7583
|
+
ucan: result.delegation.delegationHeader.Authorization,
|
|
7584
|
+
expiresAt: result.delegation.expiry.getTime()
|
|
7585
|
+
};
|
|
7586
|
+
}
|
|
7587
|
+
});
|
|
7588
|
+
}
|
|
7589
|
+
async bindReplicationRuntime(context, session, kv, principal) {
|
|
7590
|
+
if (!this.replicationRuntime) return;
|
|
7591
|
+
const identityPrincipal = principal ?? (this._address === void 0 ? void 0 : (0, import_sdk_core10.pkhDid)(this._address, this._chainId));
|
|
7592
|
+
if (identityPrincipal === void 0) return;
|
|
7593
|
+
const runtime = await this.replicationRuntime;
|
|
7594
|
+
const authority = await this.replicationAuthority();
|
|
7595
|
+
await runtime.bind({
|
|
7596
|
+
context,
|
|
7597
|
+
session,
|
|
7598
|
+
principal: identityPrincipal,
|
|
7599
|
+
authority,
|
|
7600
|
+
primaryKV: [{ space: session.spaceId, kv }]
|
|
7601
|
+
});
|
|
7602
|
+
}
|
|
7603
|
+
/** Stable control facade for this node's optional replication runtime. */
|
|
7604
|
+
get replication() {
|
|
7605
|
+
return this.replicationControl;
|
|
7606
|
+
}
|
|
7012
7607
|
/**
|
|
7013
7608
|
* Materialize one manifest-declared delegation using the current session key.
|
|
7014
7609
|
* Delivery is intentionally out of band; callers decide how to transmit the
|
|
@@ -7082,7 +7677,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7082
7677
|
const spaceId = resolvedSpaces.size === 1 ? [...resolvedSpaces][0] : session.spaceId;
|
|
7083
7678
|
const abilities = {};
|
|
7084
7679
|
for (const entry of entries) {
|
|
7085
|
-
const shortService =
|
|
7680
|
+
const shortService = import_sdk_core10.SERVICE_LONG_TO_SHORT[entry.service];
|
|
7086
7681
|
if (shortService === void 0) {
|
|
7087
7682
|
throw new Error(
|
|
7088
7683
|
`delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
|
|
@@ -7139,7 +7734,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7139
7734
|
if (onPrepared) {
|
|
7140
7735
|
await onPrepared(delegation);
|
|
7141
7736
|
}
|
|
7142
|
-
const activateResult = await (0,
|
|
7737
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7143
7738
|
this.config.host,
|
|
7144
7739
|
delegationHeader
|
|
7145
7740
|
);
|
|
@@ -7181,7 +7776,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7181
7776
|
if (onPrepared) {
|
|
7182
7777
|
await onPrepared(delegation);
|
|
7183
7778
|
}
|
|
7184
|
-
const activateResult = await (0,
|
|
7779
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7185
7780
|
targetHost,
|
|
7186
7781
|
delegationHeader
|
|
7187
7782
|
);
|
|
@@ -7210,7 +7805,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7210
7805
|
return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
|
|
7211
7806
|
}
|
|
7212
7807
|
expandPermissionEntries(permissions) {
|
|
7213
|
-
return (0,
|
|
7808
|
+
return (0, import_sdk_core10.expandPermissionEntries)(permissions);
|
|
7214
7809
|
}
|
|
7215
7810
|
/**
|
|
7216
7811
|
* The current WASM child-delegation APIs accept action-only maps. Refuse any
|
|
@@ -7218,10 +7813,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7218
7813
|
*/
|
|
7219
7814
|
assertDelegationCaveatsPreservable(entries) {
|
|
7220
7815
|
const caveated = entries.filter(
|
|
7221
|
-
(entry) => !(0,
|
|
7816
|
+
(entry) => !(0, import_sdk_core10.recapCaveatsEqual)(entry.caveats, void 0)
|
|
7222
7817
|
);
|
|
7223
7818
|
if (caveated.length > 0) {
|
|
7224
|
-
throw new
|
|
7819
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(caveated);
|
|
7225
7820
|
}
|
|
7226
7821
|
}
|
|
7227
7822
|
/**
|
|
@@ -7231,6 +7826,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7231
7826
|
* it only accepts action maps, so reject the selected constrained branch.
|
|
7232
7827
|
*/
|
|
7233
7828
|
assertRuntimeGrantCaveatsPreservable(entries, requestedOperations, grant) {
|
|
7829
|
+
const caveated = this.caveatedRuntimeGrantEntries(entries, requestedOperations, grant);
|
|
7830
|
+
if (caveated.length > 0) {
|
|
7831
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(caveated);
|
|
7832
|
+
}
|
|
7833
|
+
}
|
|
7834
|
+
/**
|
|
7835
|
+
* The entries of `grant` that cover a requested operation while carrying
|
|
7836
|
+
* caveats — the branches {@link assertRuntimeGrantCaveatsPreservable}
|
|
7837
|
+
* rejects and {@link planDerivation} classifies as `CAVEATED_AUTHORITY`.
|
|
7838
|
+
* Shared so the pure plan and the mint path can't disagree.
|
|
7839
|
+
*/
|
|
7840
|
+
caveatedRuntimeGrantEntries(entries, requestedOperations, grant) {
|
|
7234
7841
|
let operationIndex = 0;
|
|
7235
7842
|
const caveated = [];
|
|
7236
7843
|
for (const entry of entries) {
|
|
@@ -7238,7 +7845,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7238
7845
|
const requested = requestedOperations[operationIndex++];
|
|
7239
7846
|
if (!requested) continue;
|
|
7240
7847
|
const constrained = grant.operations.find(
|
|
7241
|
-
(granted) => this.operationCovers(granted, requested) && !(0,
|
|
7848
|
+
(granted) => this.operationCovers(granted, requested) && !(0, import_sdk_core10.recapCaveatsEqual)(granted.caveats, void 0)
|
|
7242
7849
|
);
|
|
7243
7850
|
if (constrained) {
|
|
7244
7851
|
caveated.push({
|
|
@@ -7249,15 +7856,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7249
7856
|
}
|
|
7250
7857
|
}
|
|
7251
7858
|
}
|
|
7252
|
-
|
|
7253
|
-
throw new import_sdk_core9.CaveatedDelegationUnsupportedError(caveated);
|
|
7254
|
-
}
|
|
7859
|
+
return caveated;
|
|
7255
7860
|
}
|
|
7256
7861
|
/** Reject caveated parent branches before action-only child signing. */
|
|
7257
7862
|
assertPortableDelegationCaveatsPreservable(delegation) {
|
|
7258
7863
|
const entries = [];
|
|
7259
7864
|
const add = (service, space, path, actions, caveats) => {
|
|
7260
|
-
if ((0,
|
|
7865
|
+
if ((0, import_sdk_core10.recapCaveatsEqual)(caveats, void 0)) return;
|
|
7261
7866
|
entries.push({
|
|
7262
7867
|
service: service.startsWith("tinycloud.") ? service : `tinycloud.${service}`,
|
|
7263
7868
|
space,
|
|
@@ -7277,11 +7882,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7277
7882
|
add(resource.service, resource.space, resource.path, resource.actions, resource.caveats);
|
|
7278
7883
|
}
|
|
7279
7884
|
if (entries.length > 0) {
|
|
7280
|
-
throw new
|
|
7885
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(entries);
|
|
7281
7886
|
}
|
|
7282
7887
|
}
|
|
7283
7888
|
shortServiceName(service) {
|
|
7284
|
-
const short =
|
|
7889
|
+
const short = import_sdk_core10.SERVICE_LONG_TO_SHORT[service];
|
|
7285
7890
|
if (short === void 0) {
|
|
7286
7891
|
throw new Error(
|
|
7287
7892
|
`unknown service '${service}' \u2014 no short-form mapping`
|
|
@@ -7308,7 +7913,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7308
7913
|
return abilities;
|
|
7309
7914
|
}
|
|
7310
7915
|
isEncryptionPermissionEntry(entry) {
|
|
7311
|
-
return entry.service ===
|
|
7916
|
+
return entry.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && this.isEncryptionNetworkOperation("encryption", entry.path, entry.space);
|
|
7312
7917
|
}
|
|
7313
7918
|
isRawRevocationPermissionEntry(entry) {
|
|
7314
7919
|
return entry.service === "tinycloud.delegation" && entry.path === "" && entry.space?.startsWith("urn:cid:") === true && entry.actions.includes("tinycloud.delegation/revoke");
|
|
@@ -7356,7 +7961,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7356
7961
|
const missing = requested.filter((entry) => {
|
|
7357
7962
|
const raw = this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry);
|
|
7358
7963
|
const comparable = raw && this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry;
|
|
7359
|
-
return !(0,
|
|
7964
|
+
return !(0, import_sdk_core10.isCapabilitySubset)([comparable], raw ? rawGranted : spaceGranted).subset;
|
|
7360
7965
|
});
|
|
7361
7966
|
return { subset: missing.length === 0, missing };
|
|
7362
7967
|
}
|
|
@@ -7592,7 +8197,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7592
8197
|
if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
|
|
7593
8198
|
return false;
|
|
7594
8199
|
}
|
|
7595
|
-
if (requested.caveats !== void 0 && !(0,
|
|
8200
|
+
if (requested.caveats !== void 0 && !(0, import_sdk_core10.recapCaveatsEqual)(granted.caveats, requested.caveats)) {
|
|
7596
8201
|
return false;
|
|
7597
8202
|
}
|
|
7598
8203
|
if (granted.resource !== void 0 || requested.resource !== void 0) {
|
|
@@ -7614,7 +8219,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7614
8219
|
if (grantedAction === requestedAction) {
|
|
7615
8220
|
return true;
|
|
7616
8221
|
}
|
|
7617
|
-
if ((0,
|
|
8222
|
+
if ((0, import_sdk_core10.isExplicitOnlyAction)(requestedAction)) {
|
|
7618
8223
|
return false;
|
|
7619
8224
|
}
|
|
7620
8225
|
if (grantedAction.endsWith("/*")) {
|
|
@@ -7726,7 +8331,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7726
8331
|
if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
7727
8332
|
const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
|
|
7728
8333
|
if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
|
|
7729
|
-
resolvedDelegateDID = (0,
|
|
8334
|
+
resolvedDelegateDID = (0, import_sdk_core10.pkhDid)(address, 1);
|
|
7730
8335
|
}
|
|
7731
8336
|
const entries = legacyParamsToPermissionEntries(
|
|
7732
8337
|
params.actions,
|
|
@@ -7741,7 +8346,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7741
8346
|
);
|
|
7742
8347
|
return result.delegation;
|
|
7743
8348
|
} catch (err) {
|
|
7744
|
-
if (err instanceof
|
|
8349
|
+
if (err instanceof import_sdk_core10.PermissionNotInManifestError) {
|
|
7745
8350
|
} else {
|
|
7746
8351
|
throw err;
|
|
7747
8352
|
}
|
|
@@ -7798,7 +8403,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7798
8403
|
...prepared,
|
|
7799
8404
|
signature
|
|
7800
8405
|
});
|
|
7801
|
-
const activateResult = await (0,
|
|
8406
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7802
8407
|
this.config.host,
|
|
7803
8408
|
delegationSession.delegationHeader
|
|
7804
8409
|
);
|
|
@@ -7823,12 +8428,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7823
8428
|
};
|
|
7824
8429
|
const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
|
|
7825
8430
|
if (hasKvActions && params.includePublicSpace !== false) {
|
|
7826
|
-
const publicSpaceId = (0,
|
|
8431
|
+
const publicSpaceId = (0, import_sdk_core10.makePublicSpaceId)(
|
|
7827
8432
|
this.wasmBindings.ensureEip55(session.address),
|
|
7828
8433
|
session.chainId
|
|
7829
8434
|
);
|
|
7830
8435
|
const publicAbilities = {
|
|
7831
|
-
kv: { "": [
|
|
8436
|
+
kv: { "": [import_sdk_core10.KV.GET, import_sdk_core10.KV.PUT, import_sdk_core10.KV.METADATA] }
|
|
7832
8437
|
};
|
|
7833
8438
|
const publicPrepared = this.wasmBindings.prepareSession({
|
|
7834
8439
|
abilities: publicAbilities,
|
|
@@ -7846,7 +8451,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7846
8451
|
...publicPrepared,
|
|
7847
8452
|
signature: publicSignature
|
|
7848
8453
|
});
|
|
7849
|
-
const publicActivateResult = await (0,
|
|
8454
|
+
const publicActivateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7850
8455
|
this.config.host,
|
|
7851
8456
|
publicSession.delegationHeader
|
|
7852
8457
|
);
|
|
@@ -7856,7 +8461,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7856
8461
|
delegationHeader: publicSession.delegationHeader,
|
|
7857
8462
|
spaceId: publicSpaceId,
|
|
7858
8463
|
path: "",
|
|
7859
|
-
actions: [
|
|
8464
|
+
actions: [import_sdk_core10.KV.GET, import_sdk_core10.KV.PUT, import_sdk_core10.KV.METADATA],
|
|
7860
8465
|
disableSubDelegation: params.disableSubDelegation ?? false,
|
|
7861
8466
|
expiry: expirationTime,
|
|
7862
8467
|
delegateDID: params.delegateDID,
|
|
@@ -7951,7 +8556,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7951
8556
|
...prepared,
|
|
7952
8557
|
signature
|
|
7953
8558
|
});
|
|
7954
|
-
const activateResult = await (0,
|
|
8559
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7955
8560
|
targetHost,
|
|
7956
8561
|
invokerSession.delegationHeader
|
|
7957
8562
|
);
|
|
@@ -8071,7 +8676,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8071
8676
|
...prepared,
|
|
8072
8677
|
signature
|
|
8073
8678
|
});
|
|
8074
|
-
const activateResult = await (0,
|
|
8679
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
8075
8680
|
targetHost,
|
|
8076
8681
|
subDelegationSession.delegationHeader
|
|
8077
8682
|
);
|
|
@@ -8116,7 +8721,6 @@ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
|
8116
8721
|
var TinyCloudNode = _TinyCloudNode;
|
|
8117
8722
|
|
|
8118
8723
|
// src/core.ts
|
|
8119
|
-
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
8120
8724
|
var import_sdk_core13 = require("@tinycloud/sdk-core");
|
|
8121
8725
|
var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
8122
8726
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
@@ -8126,6 +8730,7 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
|
|
|
8126
8730
|
var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
8127
8731
|
var import_sdk_core20 = require("@tinycloud/sdk-core");
|
|
8128
8732
|
var import_sdk_core21 = require("@tinycloud/sdk-core");
|
|
8733
|
+
var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
8129
8734
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8130
8735
|
0 && (module.exports = {
|
|
8131
8736
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -8219,6 +8824,7 @@ var import_sdk_core21 = require("@tinycloud/sdk-core");
|
|
|
8219
8824
|
pkhDid,
|
|
8220
8825
|
principalDid,
|
|
8221
8826
|
principalDidEquals,
|
|
8827
|
+
registerReplicationLoaders,
|
|
8222
8828
|
resolveManifest,
|
|
8223
8829
|
resolveSecretListPrefix,
|
|
8224
8830
|
resolveSecretPath,
|