@tinycloud/node-sdk 3.2.0-beta.1 → 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-C7-YdUWg.d.cts → WasmKeyProvider-DjfRu9aL.d.cts} +163 -3
- package/dist/{core-C7-YdUWg.d.ts → WasmKeyProvider-DjfRu9aL.d.ts} +163 -3
- package/dist/authority-mTQEgN56.d.cts +97 -0
- package/dist/authority-mTQEgN56.d.ts +97 -0
- package/dist/core.cjs +1076 -447
- 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 +753 -120
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +2382 -495
- 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 +2032 -131
- 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);
|
|
@@ -1761,6 +1964,18 @@ var RuntimeDelegationRejectedError = class extends Error {
|
|
|
1761
1964
|
this.reason = reason;
|
|
1762
1965
|
}
|
|
1763
1966
|
};
|
|
1967
|
+
function activationRejectionReason(error) {
|
|
1968
|
+
if (typeof error !== "object" || error === null) return "activation_rejected";
|
|
1969
|
+
if ("code" in error && error.code === "ACTIVATION_TRANSPORT_FAILED") {
|
|
1970
|
+
return "activation_unavailable";
|
|
1971
|
+
}
|
|
1972
|
+
const cause = "cause" in error ? error.cause : void 0;
|
|
1973
|
+
const status = typeof cause === "object" && cause !== null && "status" in cause ? cause.status : void 0;
|
|
1974
|
+
if (typeof status !== "number") return "activation_rejected";
|
|
1975
|
+
if (status === 408 || status === 429 || status >= 500) return "activation_unavailable";
|
|
1976
|
+
if (status === 401) return "activation_unauthenticated";
|
|
1977
|
+
return "activation_rejected";
|
|
1978
|
+
}
|
|
1764
1979
|
function reject(reason, message) {
|
|
1765
1980
|
throw new RuntimeDelegationRejectedError(reason, message);
|
|
1766
1981
|
}
|
|
@@ -1781,7 +1996,7 @@ function normalizedHost(host) {
|
|
|
1781
1996
|
}
|
|
1782
1997
|
function didPrincipalsMatch(left, right) {
|
|
1783
1998
|
try {
|
|
1784
|
-
return (0,
|
|
1999
|
+
return (0, import_sdk_core5.principalDidEquals)(left, right);
|
|
1785
2000
|
} catch {
|
|
1786
2001
|
return left === right;
|
|
1787
2002
|
}
|
|
@@ -1796,7 +2011,7 @@ function compactUcanPayload(authorization) {
|
|
|
1796
2011
|
}
|
|
1797
2012
|
try {
|
|
1798
2013
|
const payload = JSON.parse(
|
|
1799
|
-
new TextDecoder("utf-8", { fatal: true }).decode((0,
|
|
2014
|
+
new TextDecoder("utf-8", { fatal: true }).decode((0, import_sdk_core5.decodeBase64Url)(parts[1]))
|
|
1800
2015
|
);
|
|
1801
2016
|
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
1802
2017
|
throw new Error("payload is not an object");
|
|
@@ -1824,7 +2039,7 @@ function canonicalPermissionEntries(permissions) {
|
|
|
1824
2039
|
...permission,
|
|
1825
2040
|
actions: [...permission.actions].sort()
|
|
1826
2041
|
})).sort(
|
|
1827
|
-
(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))
|
|
1828
2043
|
);
|
|
1829
2044
|
}
|
|
1830
2045
|
function signedCaveats(value) {
|
|
@@ -1834,13 +2049,13 @@ function signedCaveats(value) {
|
|
|
1834
2049
|
throw new Error("Validated runtime delegation has malformed signed ReCap caveats.");
|
|
1835
2050
|
}
|
|
1836
2051
|
const cloned = JSON.parse(JSON.stringify(value));
|
|
1837
|
-
return (0,
|
|
2052
|
+
return (0, import_sdk_core5.canonicalizeRecapCaveats)(cloned) === (0, import_sdk_core5.canonicalizeRecapCaveats)(void 0) ? void 0 : cloned;
|
|
1838
2053
|
}
|
|
1839
2054
|
function groupedSignedEntries(service, space, path, abilities) {
|
|
1840
2055
|
const groups = /* @__PURE__ */ new Map();
|
|
1841
2056
|
for (const [action, rawCaveats] of Object.entries(abilities)) {
|
|
1842
2057
|
const caveats = signedCaveats(rawCaveats);
|
|
1843
|
-
const identity = (0,
|
|
2058
|
+
const identity = (0, import_sdk_core5.canonicalizeRecapCaveats)(caveats);
|
|
1844
2059
|
const group = groups.get(identity) ?? { actions: [], caveats };
|
|
1845
2060
|
group.actions.push(action);
|
|
1846
2061
|
groups.set(identity, group);
|
|
@@ -1999,7 +2214,7 @@ function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
|
1999
2214
|
reject("authority_invalid", "Runtime delegation has signed authority outside its space.");
|
|
2000
2215
|
}
|
|
2001
2216
|
const caveats = signedCaveats(entry.caveats ?? []);
|
|
2002
|
-
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)]);
|
|
2003
2218
|
const group = groups.get(key) ?? {
|
|
2004
2219
|
service,
|
|
2005
2220
|
...raw ? {} : { space: entry.space },
|
|
@@ -2023,7 +2238,7 @@ function signedAuthorityFromSessionGrant(node, delegation, authorization, cid) {
|
|
|
2023
2238
|
function canonicalResourcesFromPortableDelegation(delegation) {
|
|
2024
2239
|
if (delegation.resources !== void 0 && delegation.resources.length > 0) {
|
|
2025
2240
|
return delegation.resources.map((resource) => ({ ...resource, actions: [...resource.actions].sort() })).sort(
|
|
2026
|
-
(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))
|
|
2027
2242
|
);
|
|
2028
2243
|
}
|
|
2029
2244
|
const byService = /* @__PURE__ */ new Map();
|
|
@@ -2047,7 +2262,7 @@ function canonicalResourcesFromPortableDelegation(delegation) {
|
|
|
2047
2262
|
function resourcesMatch(actual, expected) {
|
|
2048
2263
|
const comparable = (resource) => ({
|
|
2049
2264
|
...resource,
|
|
2050
|
-
caveats: (0,
|
|
2265
|
+
caveats: (0, import_sdk_core5.canonicalizeRecapCaveats)(resource.caveats)
|
|
2051
2266
|
});
|
|
2052
2267
|
return JSON.stringify(actual.map(comparable)) === JSON.stringify(expected.map(comparable));
|
|
2053
2268
|
}
|
|
@@ -2139,13 +2354,16 @@ async function activateValidatedRuntimeDelegation(node, delegation, options) {
|
|
|
2139
2354
|
...compact ? {} : { siweProof: delegation.siweProof }
|
|
2140
2355
|
};
|
|
2141
2356
|
try {
|
|
2142
|
-
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") {
|
|
2143
2358
|
await node.useDelegation(installedCandidate);
|
|
2144
2359
|
} else {
|
|
2145
2360
|
await node.useRuntimeDelegation(installedCandidate);
|
|
2146
2361
|
}
|
|
2147
2362
|
} catch (error) {
|
|
2148
|
-
reject(
|
|
2363
|
+
reject(
|
|
2364
|
+
activationRejectionReason(error),
|
|
2365
|
+
error instanceof Error ? error.message : String(error)
|
|
2366
|
+
);
|
|
2149
2367
|
}
|
|
2150
2368
|
const installed = node.getRuntimePermissionDelegations().find((candidate) => candidate.cid === cid);
|
|
2151
2369
|
if (!installed) {
|
|
@@ -2218,21 +2436,52 @@ function deserializeDelegation(data) {
|
|
|
2218
2436
|
};
|
|
2219
2437
|
}
|
|
2220
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
|
+
|
|
2221
2470
|
// src/TinyCloudNode.ts
|
|
2222
|
-
var
|
|
2223
|
-
var
|
|
2471
|
+
var import_sdk_core10 = require("@tinycloud/sdk-core");
|
|
2472
|
+
var import_sdk_services3 = require("@tinycloud/sdk-services");
|
|
2224
2473
|
|
|
2225
2474
|
// src/account/AccountService.ts
|
|
2226
|
-
var
|
|
2475
|
+
var import_sdk_core6 = require("@tinycloud/sdk-core");
|
|
2227
2476
|
|
|
2228
2477
|
// src/DelegatedAccess.ts
|
|
2229
|
-
var
|
|
2478
|
+
var import_sdk_core7 = require("@tinycloud/sdk-core");
|
|
2230
2479
|
var DelegatedAccess = class {
|
|
2231
2480
|
constructor(session, delegation, host, invoke, invokeAny, telemetry) {
|
|
2232
2481
|
this.session = session;
|
|
2233
2482
|
this._delegation = delegation;
|
|
2234
2483
|
this.host = host;
|
|
2235
|
-
this._serviceContext = new
|
|
2484
|
+
this._serviceContext = new import_sdk_core7.ServiceContext({
|
|
2236
2485
|
invoke,
|
|
2237
2486
|
invokeAny,
|
|
2238
2487
|
fetch: globalThis.fetch.bind(globalThis),
|
|
@@ -2240,16 +2489,16 @@ var DelegatedAccess = class {
|
|
|
2240
2489
|
telemetry
|
|
2241
2490
|
});
|
|
2242
2491
|
const prefix = this._delegation.path.replace(/\/$/, "");
|
|
2243
|
-
this._kv = new
|
|
2492
|
+
this._kv = new import_sdk_core7.KVService({ prefix });
|
|
2244
2493
|
this._kv.initialize(this._serviceContext);
|
|
2245
2494
|
this._serviceContext.registerService("kv", this._kv);
|
|
2246
|
-
this._sql = new
|
|
2495
|
+
this._sql = new import_sdk_core7.SQLService({});
|
|
2247
2496
|
this._sql.initialize(this._serviceContext);
|
|
2248
2497
|
this._serviceContext.registerService("sql", this._sql);
|
|
2249
|
-
this._duckdb = new
|
|
2498
|
+
this._duckdb = new import_sdk_core7.DuckDbService({});
|
|
2250
2499
|
this._duckdb.initialize(this._serviceContext);
|
|
2251
2500
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
2252
|
-
this._hooks = new
|
|
2501
|
+
this._hooks = new import_sdk_core7.HooksService({});
|
|
2253
2502
|
this._hooks.initialize(this._serviceContext);
|
|
2254
2503
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
2255
2504
|
const serviceSession = {
|
|
@@ -2399,7 +2648,7 @@ function createWasmKeyProvider(sessionManager) {
|
|
|
2399
2648
|
}
|
|
2400
2649
|
|
|
2401
2650
|
// src/delegateToHelpers.ts
|
|
2402
|
-
var
|
|
2651
|
+
var import_sdk_core8 = require("@tinycloud/sdk-core");
|
|
2403
2652
|
function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
2404
2653
|
const byService = /* @__PURE__ */ new Map();
|
|
2405
2654
|
for (const a of actions) {
|
|
@@ -2430,7 +2679,7 @@ function legacyParamsToPermissionEntries(actions, path, spaceIdOverride) {
|
|
|
2430
2679
|
}
|
|
2431
2680
|
return entries;
|
|
2432
2681
|
}
|
|
2433
|
-
var DEFAULT_DELEGATION_EXPIRY_MS =
|
|
2682
|
+
var DEFAULT_DELEGATION_EXPIRY_MS = import_sdk_core8.EXPIRY.SESSION_MS;
|
|
2434
2683
|
function resolveExpiryMs(expiry) {
|
|
2435
2684
|
if (expiry === void 0) {
|
|
2436
2685
|
return DEFAULT_DELEGATION_EXPIRY_MS;
|
|
@@ -2443,10 +2692,10 @@ function resolveExpiryMs(expiry) {
|
|
|
2443
2692
|
}
|
|
2444
2693
|
return expiry;
|
|
2445
2694
|
}
|
|
2446
|
-
return (0,
|
|
2695
|
+
return (0, import_sdk_core8.parseExpiry)(expiry);
|
|
2447
2696
|
}
|
|
2448
2697
|
function extractSiweExpiration(siwe) {
|
|
2449
|
-
const parsed = new
|
|
2698
|
+
const parsed = new import_sdk_core8.SiweMessage(siwe);
|
|
2450
2699
|
if (parsed.expirationTime === void 0 || parsed.expirationTime === null) {
|
|
2451
2700
|
return void 0;
|
|
2452
2701
|
}
|
|
@@ -2460,7 +2709,7 @@ function extractSiweExpiration(siwe) {
|
|
|
2460
2709
|
}
|
|
2461
2710
|
|
|
2462
2711
|
// src/NodeSecretsService.ts
|
|
2463
|
-
var
|
|
2712
|
+
var import_sdk_core9 = require("@tinycloud/sdk-core");
|
|
2464
2713
|
var SECRETS_SPACE = "secrets";
|
|
2465
2714
|
function ok() {
|
|
2466
2715
|
return { ok: true, data: void 0 };
|
|
@@ -2493,7 +2742,7 @@ function secretActionName(action) {
|
|
|
2493
2742
|
}
|
|
2494
2743
|
function secretPermissionEntries(name, options, action, space, encryptionNetworkId) {
|
|
2495
2744
|
const entries = [];
|
|
2496
|
-
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;
|
|
2497
2746
|
entries.push({
|
|
2498
2747
|
service: "tinycloud.kv",
|
|
2499
2748
|
space,
|
|
@@ -2590,7 +2839,7 @@ var NodeSecretsService = class {
|
|
|
2590
2839
|
);
|
|
2591
2840
|
} catch (error) {
|
|
2592
2841
|
return secretsError(
|
|
2593
|
-
|
|
2842
|
+
import_sdk_core9.ErrorCodes.INVALID_INPUT,
|
|
2594
2843
|
error instanceof Error ? error.message : String(error),
|
|
2595
2844
|
error instanceof Error ? error : void 0
|
|
2596
2845
|
);
|
|
@@ -2600,7 +2849,7 @@ var NodeSecretsService = class {
|
|
|
2600
2849
|
}
|
|
2601
2850
|
if (!this.config.canEscalate()) {
|
|
2602
2851
|
return secretsError(
|
|
2603
|
-
|
|
2852
|
+
import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
|
|
2604
2853
|
`Cannot autosign ${displayActionUrn(action)} for ${target}; TinyCloudNode needs wallet mode with a signer or privateKey.`
|
|
2605
2854
|
);
|
|
2606
2855
|
}
|
|
@@ -2609,7 +2858,7 @@ var NodeSecretsService = class {
|
|
|
2609
2858
|
return this.restoreUnlockAfterEscalation();
|
|
2610
2859
|
} catch (error) {
|
|
2611
2860
|
return secretsError(
|
|
2612
|
-
|
|
2861
|
+
import_sdk_core9.ErrorCodes.PERMISSION_DENIED,
|
|
2613
2862
|
error instanceof Error ? error.message : `Autosign escalation for ${displayActionUrn(action)} on ${target} failed.`,
|
|
2614
2863
|
error instanceof Error ? error : void 0
|
|
2615
2864
|
);
|
|
@@ -2630,10 +2879,10 @@ var NodeSecretsService = class {
|
|
|
2630
2879
|
return false;
|
|
2631
2880
|
}
|
|
2632
2881
|
const manifests = Array.isArray(manifest) ? manifest : [manifest];
|
|
2633
|
-
const requestedEntries = (0,
|
|
2882
|
+
const requestedEntries = (0, import_sdk_core9.expandPermissionEntries)(permissionEntries);
|
|
2634
2883
|
return requestedEntries.every(
|
|
2635
2884
|
(entry) => manifests.some((candidate) => {
|
|
2636
|
-
const resolved = (0,
|
|
2885
|
+
const resolved = (0, import_sdk_core9.resolveManifest)(candidate);
|
|
2637
2886
|
return resolved.resources.some(
|
|
2638
2887
|
(resource) => resource.service === entry.service && spaceMatches(
|
|
2639
2888
|
resource.space,
|
|
@@ -2649,8 +2898,8 @@ var NodeSecretsService = class {
|
|
|
2649
2898
|
// src/TinyCloudNode.ts
|
|
2650
2899
|
var DEFAULT_HOST = "https://node.tinycloud.xyz";
|
|
2651
2900
|
var DEFAULT_ENCRYPTION_NETWORK_NAME = "default";
|
|
2652
|
-
var NETWORK_CREATE_ACTION2 =
|
|
2653
|
-
var DECRYPT_ACTION2 =
|
|
2901
|
+
var NETWORK_CREATE_ACTION2 = import_sdk_core10.ENCRYPTION.NETWORK_CREATE;
|
|
2902
|
+
var DECRYPT_ACTION2 = import_sdk_core10.ENCRYPTION.DECRYPT;
|
|
2654
2903
|
var BOOTSTRAP_COMPLETION_MARKER_KEY = "system/bootstrap/complete";
|
|
2655
2904
|
var BOOTSTRAP_COMPLETION_MARKER_VERSION = 1;
|
|
2656
2905
|
var ACCEPTED_MARKER_VERSIONS = [BOOTSTRAP_COMPLETION_MARKER_VERSION];
|
|
@@ -2659,24 +2908,24 @@ function isSecretPayload(value) {
|
|
|
2659
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";
|
|
2660
2909
|
}
|
|
2661
2910
|
var ROOT_DELEGATION_ACTIONS = [
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
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
|
|
2678
2927
|
];
|
|
2679
|
-
var DEFAULT_SESSION_EXPIRATION_MS =
|
|
2928
|
+
var DEFAULT_SESSION_EXPIRATION_MS = import_sdk_core10.EXPIRY.SESSION_MS;
|
|
2680
2929
|
function unifiedRootAttenuation(capabilities) {
|
|
2681
2930
|
const attenuation = {};
|
|
2682
2931
|
for (const capability of capabilities) {
|
|
@@ -2722,7 +2971,7 @@ function isInteractiveSigner(config) {
|
|
|
2722
2971
|
}
|
|
2723
2972
|
function didPrincipalMatches2(actual, expected) {
|
|
2724
2973
|
try {
|
|
2725
|
-
return (0,
|
|
2974
|
+
return (0, import_sdk_core10.principalDidEquals)(actual, expected);
|
|
2726
2975
|
} catch {
|
|
2727
2976
|
return actual === expected;
|
|
2728
2977
|
}
|
|
@@ -2933,7 +3182,7 @@ function ownerDelegationPermissions(params) {
|
|
|
2933
3182
|
}
|
|
2934
3183
|
const slash = action.indexOf("/");
|
|
2935
3184
|
const service = slash === -1 ? "" : action.slice(0, slash);
|
|
2936
|
-
if (
|
|
3185
|
+
if (import_sdk_core10.SERVICE_LONG_TO_SHORT[service] === void 0) {
|
|
2937
3186
|
throw new Error("Owner delegation capabilities are unsupported");
|
|
2938
3187
|
}
|
|
2939
3188
|
const actions = byService.get(service) ?? [];
|
|
@@ -2949,7 +3198,7 @@ function ownerDelegationPermissions(params) {
|
|
|
2949
3198
|
}
|
|
2950
3199
|
const resources = /* @__PURE__ */ new Set();
|
|
2951
3200
|
for (const permission of permissions) {
|
|
2952
|
-
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) {
|
|
2953
3202
|
throw new Error("Owner delegation requires bounded capabilities");
|
|
2954
3203
|
}
|
|
2955
3204
|
const resourceKey = `${permission.service}\0${permission.path}`;
|
|
@@ -2964,9 +3213,9 @@ function ownerDelegationPermissions(params) {
|
|
|
2964
3213
|
}
|
|
2965
3214
|
actions.add(action);
|
|
2966
3215
|
}
|
|
2967
|
-
if (permission.service ===
|
|
3216
|
+
if (permission.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE) {
|
|
2968
3217
|
try {
|
|
2969
|
-
(0,
|
|
3218
|
+
(0, import_sdk_core10.parseNetworkId)(permission.path);
|
|
2970
3219
|
} catch {
|
|
2971
3220
|
throw new Error("Owner delegation encryption permission requires a canonical network URN");
|
|
2972
3221
|
}
|
|
@@ -2978,11 +3227,11 @@ function ownerPermissionsToAbilities(permissions) {
|
|
|
2978
3227
|
const abilities = {};
|
|
2979
3228
|
const rawAbilities = {};
|
|
2980
3229
|
for (const permission of permissions) {
|
|
2981
|
-
if (permission.service ===
|
|
3230
|
+
if (permission.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE) {
|
|
2982
3231
|
rawAbilities[permission.path] = [...permission.actions];
|
|
2983
3232
|
continue;
|
|
2984
3233
|
}
|
|
2985
|
-
const shortService =
|
|
3234
|
+
const shortService = import_sdk_core10.SERVICE_LONG_TO_SHORT[permission.service];
|
|
2986
3235
|
abilities[shortService] ?? (abilities[shortService] = {});
|
|
2987
3236
|
abilities[shortService][permission.path] = [...permission.actions];
|
|
2988
3237
|
}
|
|
@@ -3114,6 +3363,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3114
3363
|
this.confirmedHostedSpaceIds = /* @__PURE__ */ new Set();
|
|
3115
3364
|
/** Serializes account-registry writes for the active node instance. */
|
|
3116
3365
|
this.accountRegistryTail = Promise.resolve();
|
|
3366
|
+
/** Bounds best-effort registry work on the sign-in critical path. */
|
|
3367
|
+
this.accountRegistryDeadlineMs = 4e3;
|
|
3117
3368
|
/**
|
|
3118
3369
|
* True when the last signIn() detected an interactive signer and skipped
|
|
3119
3370
|
* client-side bootstrap. Apps can read this to know whether bootstrap was
|
|
@@ -3185,18 +3436,53 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3185
3436
|
if (!granted?.caveats?.length) {
|
|
3186
3437
|
return entry;
|
|
3187
3438
|
}
|
|
3188
|
-
if (entry.caveats !== void 0 && !(0,
|
|
3439
|
+
if (entry.caveats !== void 0 && !(0, import_sdk_core10.recapCaveatsEqual)(entry.caveats, granted.caveats)) {
|
|
3189
3440
|
throw new Error("Invocation caveats do not match signed ReCap authority.");
|
|
3190
3441
|
}
|
|
3191
3442
|
return { ...entry, caveats: cloneRecapCaveats(granted.caveats) };
|
|
3192
3443
|
});
|
|
3193
3444
|
return this.wasmBindings.invokeAny(invocationSession, caveatPreservingEntries, facts);
|
|
3194
3445
|
};
|
|
3446
|
+
assertValidReplicationConfig(config.replication);
|
|
3195
3447
|
this.explicitHost = config.host;
|
|
3196
3448
|
this.config = {
|
|
3197
3449
|
...config,
|
|
3198
3450
|
host: config.host ?? DEFAULT_HOST
|
|
3199
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
|
+
}
|
|
3200
3486
|
if (config.wasmBindings) {
|
|
3201
3487
|
this.wasmBindings = config.wasmBindings;
|
|
3202
3488
|
} else if (_TinyCloudNode.nodeDefaults) {
|
|
@@ -3220,13 +3506,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3220
3506
|
}
|
|
3221
3507
|
this.sessionKeyJwk = JSON.parse(jwkStr);
|
|
3222
3508
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
3223
|
-
this._capabilityRegistry = new
|
|
3509
|
+
this._capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
3224
3510
|
this._keyProvider = new WasmKeyProvider({
|
|
3225
3511
|
sessionManager: this.sessionManager
|
|
3226
3512
|
});
|
|
3227
|
-
this.notificationHandler = config.notificationHandler ?? new
|
|
3513
|
+
this.notificationHandler = config.notificationHandler ?? new import_sdk_core10.SilentNotificationHandler();
|
|
3228
3514
|
const receiveOnlyGraph = this._serviceGraph;
|
|
3229
|
-
this._sharingService = new
|
|
3515
|
+
this._sharingService = new import_sdk_core10.SharingService({
|
|
3230
3516
|
hosts: [this.config.host],
|
|
3231
3517
|
// session: undefined - not needed for receive()
|
|
3232
3518
|
invoke: receiveOnlyGraph.invoke,
|
|
@@ -3242,8 +3528,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3242
3528
|
// delegationManager: undefined - not needed for receive()
|
|
3243
3529
|
createKVService: (config2) => {
|
|
3244
3530
|
const prefix = config2.pathPrefix?.replace(/\/$/, "");
|
|
3245
|
-
const kvService = new
|
|
3246
|
-
const kvContext = receiveOnlyGraph.track(new
|
|
3531
|
+
const kvService = new import_sdk_core10.KVService({ prefix });
|
|
3532
|
+
const kvContext = receiveOnlyGraph.track(new import_sdk_core10.ServiceContext({
|
|
3247
3533
|
invoke: config2.invoke,
|
|
3248
3534
|
fetch: config2.fetch ?? globalThis.fetch.bind(globalThis),
|
|
3249
3535
|
hosts: config2.hosts,
|
|
@@ -3316,10 +3602,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3316
3602
|
nonce: config.nonce,
|
|
3317
3603
|
siweConfig: config.siweConfig,
|
|
3318
3604
|
manifest: useBootstrapSignInRequest ? void 0 : config.manifest,
|
|
3319
|
-
capabilityRequest: useBootstrapSignInRequest ? config.includeAccountRegistryPermissions === false ?
|
|
3320
|
-
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
|
|
3321
3614
|
});
|
|
3322
|
-
this.tc = new
|
|
3615
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
3323
3616
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
3324
3617
|
telemetry: config.telemetry
|
|
3325
3618
|
});
|
|
@@ -3399,7 +3692,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3399
3692
|
/** Publish the active owner Node as a session-signed registry record. */
|
|
3400
3693
|
async publishActiveNodeLocation(registryUrl, fetchFn = globalThis.fetch.bind(globalThis)) {
|
|
3401
3694
|
const node = await this.activeNodeIdentity();
|
|
3402
|
-
return (0,
|
|
3695
|
+
return (0, import_sdk_core10.publishLocationRecord)({
|
|
3403
3696
|
registryUrl,
|
|
3404
3697
|
subject: this.credentialHolderDid,
|
|
3405
3698
|
nodeOrigin: node.origin,
|
|
@@ -3416,7 +3709,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3416
3709
|
*/
|
|
3417
3710
|
get did() {
|
|
3418
3711
|
if (this._address) {
|
|
3419
|
-
return (0,
|
|
3712
|
+
return (0, import_sdk_core10.pkhDid)(this._address, this._chainId);
|
|
3420
3713
|
}
|
|
3421
3714
|
return this.sessionManager.getDID(this.sessionKeyId);
|
|
3422
3715
|
}
|
|
@@ -3453,7 +3746,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3453
3746
|
/** Normalize signed capabilities without collapsing nested encryption into raw authority. */
|
|
3454
3747
|
projectSignedRecapCapabilities(siwe) {
|
|
3455
3748
|
const projected = this.parseRecapWithCaveats(siwe).map((entry) => {
|
|
3456
|
-
const normalized = (0,
|
|
3749
|
+
const normalized = (0, import_sdk_core10.parseRecapCapabilities)(() => [entry], siwe)[0];
|
|
3457
3750
|
if (normalized.service !== "tinycloud.encryption") return normalized;
|
|
3458
3751
|
if (!this.isEncryptionNetworkOperation("encryption", entry.path, entry.space)) {
|
|
3459
3752
|
return { ...normalized, space: entry.space };
|
|
@@ -3498,14 +3791,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3498
3791
|
if (!this._address) {
|
|
3499
3792
|
return void 0;
|
|
3500
3793
|
}
|
|
3501
|
-
return this.wasmBindings.makeSpaceId(this._address, this._chainId,
|
|
3794
|
+
return this.wasmBindings.makeSpaceId(this._address, this._chainId, import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
3502
3795
|
}
|
|
3503
3796
|
/**
|
|
3504
3797
|
* Account-level application and delegation helpers.
|
|
3505
3798
|
*/
|
|
3506
3799
|
get account() {
|
|
3507
3800
|
if (!this._account) {
|
|
3508
|
-
this._account = new
|
|
3801
|
+
this._account = new import_sdk_core6.AccountService({
|
|
3509
3802
|
getDid: () => this.did,
|
|
3510
3803
|
getHost: () => this.hosts[0] ?? this.config.host,
|
|
3511
3804
|
getPrimarySpaceId: () => this.spaceId,
|
|
@@ -3551,7 +3844,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3551
3844
|
}
|
|
3552
3845
|
await this.accountRegistryTail;
|
|
3553
3846
|
await this.wasmBindings.ensureInitialized?.();
|
|
3554
|
-
this._address = (0,
|
|
3847
|
+
this._address = (0, import_sdk_core10.canonicalizeAddress)(await this.signer.getAddress());
|
|
3555
3848
|
this._chainId = await this.signer.getChainId();
|
|
3556
3849
|
this._kv = void 0;
|
|
3557
3850
|
this._sql = void 0;
|
|
@@ -3568,6 +3861,9 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3568
3861
|
this.confirmedHostedSpaceIds.clear();
|
|
3569
3862
|
await this.tc.signIn(options);
|
|
3570
3863
|
this.syncResolvedHostFromAuth();
|
|
3864
|
+
this.replicationDelegateSession = void 0;
|
|
3865
|
+
this.replicationScopeError = void 0;
|
|
3866
|
+
if (this.replicationRuntime) await (await this.replicationRuntime).unbind();
|
|
3571
3867
|
const oldGraph = this._serviceGraph;
|
|
3572
3868
|
this._serviceGraph = this.createServiceGraphLifetime();
|
|
3573
3869
|
oldGraph.retire();
|
|
@@ -3577,7 +3873,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3577
3873
|
this.sessionKeyId = signedInSession.sessionKey;
|
|
3578
3874
|
this.sessionKeyJwk = signedInSession.jwk;
|
|
3579
3875
|
}
|
|
3580
|
-
this.initializeServices();
|
|
3876
|
+
await this.initializeServices();
|
|
3581
3877
|
const primarySession = this.currentTinyCloudSession();
|
|
3582
3878
|
if (primarySession) {
|
|
3583
3879
|
this.registerPrimarySessionGrant(primarySession);
|
|
@@ -3585,10 +3881,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3585
3881
|
const bootstrapped = await this.bootstrapAccountIfNeeded();
|
|
3586
3882
|
await this.ensureRequestedEncryptionNetworks();
|
|
3587
3883
|
if (!bootstrapped && this.config.manifest === void 0 && this.config.capabilityRequest === void 0) {
|
|
3588
|
-
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(
|
|
3884
|
+
await this.ensureOwnedSpaceHostedById(this.ownedSpaceId(import_sdk_core10.SECRETS_SPACE));
|
|
3589
3885
|
}
|
|
3590
3886
|
if (!bootstrapped) {
|
|
3591
3887
|
this.scheduleAccountRegistrySync();
|
|
3888
|
+
await this.accountRegistryTail;
|
|
3592
3889
|
}
|
|
3593
3890
|
this.notificationHandler.success("Successfully signed in");
|
|
3594
3891
|
}
|
|
@@ -3616,7 +3913,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3616
3913
|
this._bootstrapStatus = { skipped: true, reason: "interactive-signer" };
|
|
3617
3914
|
return false;
|
|
3618
3915
|
}
|
|
3619
|
-
const steps = (0,
|
|
3916
|
+
const steps = (0, import_sdk_core10.bootstrapSteps)(this._address, this._chainId);
|
|
3620
3917
|
try {
|
|
3621
3918
|
const decision = await this.resolveBootstrapDecision(steps);
|
|
3622
3919
|
if (decision.action === "skip") {
|
|
@@ -3654,7 +3951,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3654
3951
|
if (!auth) {
|
|
3655
3952
|
throw new Error("Account bootstrap requires an active wallet session");
|
|
3656
3953
|
}
|
|
3657
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
3954
|
+
const accountSpaceId = this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE);
|
|
3658
3955
|
const skipped = auth.lastActivationSkippedSpaceIds;
|
|
3659
3956
|
if (skipped.includes(accountSpaceId)) return { action: "run", mode: "fresh" };
|
|
3660
3957
|
if (skipped.some((spaceId) => enshrinedSpaceIds.has(spaceId))) {
|
|
@@ -3677,7 +3974,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3677
3974
|
}
|
|
3678
3975
|
return { action: "run", mode: "repair" };
|
|
3679
3976
|
}
|
|
3680
|
-
if (marker.error.code ===
|
|
3977
|
+
if (marker.error.code === import_sdk_core10.ErrorCodes.KV_NOT_FOUND && this.markerReadIsUnhostedSpace(marker.error.meta)) {
|
|
3681
3978
|
return { action: "run", mode: "fresh" };
|
|
3682
3979
|
}
|
|
3683
3980
|
} catch (err) {
|
|
@@ -3691,7 +3988,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3691
3988
|
return { action: "run", mode: "repair" };
|
|
3692
3989
|
}
|
|
3693
3990
|
async readBootstrapCompletionMarker() {
|
|
3694
|
-
return this.kvForSpace(this.ownedSpaceId(
|
|
3991
|
+
return this.kvForSpace(this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE)).get(
|
|
3695
3992
|
BOOTSTRAP_COMPLETION_MARKER_KEY
|
|
3696
3993
|
);
|
|
3697
3994
|
}
|
|
@@ -3700,7 +3997,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3700
3997
|
throw new Error("Bootstrap completion marker requires an active wallet session");
|
|
3701
3998
|
}
|
|
3702
3999
|
const canonicalStepIds = new Set(
|
|
3703
|
-
(0,
|
|
4000
|
+
(0, import_sdk_core10.bootstrapSteps)(this._address, this._chainId).map((step) => step.id)
|
|
3704
4001
|
);
|
|
3705
4002
|
const providedStepIds = new Set(steps.map((step) => step.id));
|
|
3706
4003
|
if (canonicalStepIds.size !== providedStepIds.size || [...canonicalStepIds].some((stepId) => !providedStepIds.has(stepId))) {
|
|
@@ -3711,7 +4008,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3711
4008
|
stepIds: [...canonicalStepIds],
|
|
3712
4009
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3713
4010
|
};
|
|
3714
|
-
const written = await this.kvForSpace(this.ownedSpaceId(
|
|
4011
|
+
const written = await this.kvForSpace(this.ownedSpaceId(import_sdk_core10.ACCOUNT_REGISTRY_SPACE)).put(
|
|
3715
4012
|
BOOTSTRAP_COMPLETION_MARKER_KEY,
|
|
3716
4013
|
marker
|
|
3717
4014
|
);
|
|
@@ -3750,7 +4047,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3750
4047
|
const warnings = [];
|
|
3751
4048
|
const primarySession = auth.tinyCloudSession;
|
|
3752
4049
|
const defaultSpaceId = this.ownedSpaceId("default");
|
|
3753
|
-
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest ===
|
|
4050
|
+
const canReusePrimaryBootstrapSession = primarySession?.spaceId === defaultSpaceId && auth.capabilityRequest === import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS.default;
|
|
3754
4051
|
for (const step of steps) {
|
|
3755
4052
|
if (step.kind !== "session") continue;
|
|
3756
4053
|
if (step.space === "default" && canReusePrimaryBootstrapSession && primarySession) {
|
|
@@ -3765,7 +4062,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3765
4062
|
try {
|
|
3766
4063
|
session = await auth.createBootstrapSession({
|
|
3767
4064
|
spaceId: step.spaceId,
|
|
3768
|
-
capabilityRequest: step.request ??
|
|
4065
|
+
capabilityRequest: step.request ?? import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS[step.space],
|
|
3769
4066
|
rawAbilities
|
|
3770
4067
|
});
|
|
3771
4068
|
} catch (err) {
|
|
@@ -3795,7 +4092,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3795
4092
|
if (!session) {
|
|
3796
4093
|
throw new Error(`Missing bootstrap session for ${step.space}`);
|
|
3797
4094
|
}
|
|
3798
|
-
const activated = await (0,
|
|
4095
|
+
const activated = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader);
|
|
3799
4096
|
if (!activated.success || activated.skipped?.includes(step.spaceId)) {
|
|
3800
4097
|
throw Object.assign(
|
|
3801
4098
|
new Error(
|
|
@@ -3806,7 +4103,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3806
4103
|
}
|
|
3807
4104
|
this.registerBootstrapRuntimeGrant(
|
|
3808
4105
|
session,
|
|
3809
|
-
|
|
4106
|
+
import_sdk_core10.BOOTSTRAP_SESSION_REQUESTS[step.space],
|
|
3810
4107
|
rawAbilitiesBySpace.get(step.space)
|
|
3811
4108
|
);
|
|
3812
4109
|
}
|
|
@@ -3855,7 +4152,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3855
4152
|
}
|
|
3856
4153
|
if (step.kind === "seed-applications") {
|
|
3857
4154
|
const registered = await this.account.applications.register(
|
|
3858
|
-
step.manifests.length > 0 ? [...step.manifests] :
|
|
4155
|
+
step.manifests.length > 0 ? [...step.manifests] : import_sdk_core10.TINYCLOUD_SECRETS_BOOTSTRAP_MANIFEST,
|
|
3859
4156
|
// The write is an INSERT OR REPLACE and is safe to repeat during a
|
|
3860
4157
|
// repair, so skip the manifest-hash pre-read.
|
|
3861
4158
|
{ assumeUnregistered: true }
|
|
@@ -3874,7 +4171,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
3874
4171
|
migrations: [
|
|
3875
4172
|
{
|
|
3876
4173
|
id: "001_initial",
|
|
3877
|
-
sql: [...
|
|
4174
|
+
sql: [...import_sdk_core10.SECRET_RECORDS_SCHEMA]
|
|
3878
4175
|
}
|
|
3879
4176
|
]
|
|
3880
4177
|
});
|
|
@@ -4041,7 +4338,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4041
4338
|
provenance: "primary"
|
|
4042
4339
|
});
|
|
4043
4340
|
}
|
|
4044
|
-
async writeManifestRegistryRecords() {
|
|
4341
|
+
async writeManifestRegistryRecords(account, signal) {
|
|
4045
4342
|
const request = this.capabilityRequest;
|
|
4046
4343
|
if (!request || request.registryRecords.length === 0) {
|
|
4047
4344
|
return;
|
|
@@ -4049,9 +4346,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4049
4346
|
if (!this.auth || !this.signer) {
|
|
4050
4347
|
throw new Error("Manifest registry write requires wallet mode");
|
|
4051
4348
|
}
|
|
4052
|
-
const accountSpaceId = this.ownedSpaceId(
|
|
4053
|
-
await this.ensureOwnedSpaceHostedById(accountSpaceId);
|
|
4054
|
-
|
|
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);
|
|
4055
4353
|
if (!result.ok) {
|
|
4056
4354
|
throw Object.assign(
|
|
4057
4355
|
new Error(`Failed to write manifest registry records: ${result.error.message}`),
|
|
@@ -4059,34 +4357,113 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4059
4357
|
);
|
|
4060
4358
|
}
|
|
4061
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
|
+
}
|
|
4062
4409
|
scheduleAccountRegistrySync() {
|
|
4063
4410
|
const session = this.currentTinyCloudSession();
|
|
4064
4411
|
if (!session || this.pendingAccountRegistrySync?.session === session) {
|
|
4065
4412
|
return;
|
|
4066
4413
|
}
|
|
4414
|
+
const controller = new AbortController();
|
|
4415
|
+
const deadline = setTimeout(
|
|
4416
|
+
() => controller.abort(new DOMException("Account registry deadline exceeded", "TimeoutError")),
|
|
4417
|
+
this.accountRegistryDeadlineMs
|
|
4418
|
+
);
|
|
4067
4419
|
const promise = this.enqueueAccountRegistryOperation(session, async () => {
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
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
|
+
}
|
|
4087
4459
|
}
|
|
4460
|
+
}, controller.signal);
|
|
4461
|
+
} finally {
|
|
4462
|
+
for (const operationContext of registry.contexts) {
|
|
4463
|
+
operationContext.retire();
|
|
4088
4464
|
}
|
|
4089
|
-
|
|
4465
|
+
clearTimeout(deadline);
|
|
4466
|
+
}
|
|
4090
4467
|
});
|
|
4091
4468
|
this.pendingAccountRegistrySync = { session, promise };
|
|
4092
4469
|
const clearPendingSync = () => {
|
|
@@ -4095,6 +4472,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4095
4472
|
}
|
|
4096
4473
|
};
|
|
4097
4474
|
void promise.then(clearPendingSync, clearPendingSync);
|
|
4475
|
+
void promise.then(
|
|
4476
|
+
() => clearTimeout(deadline),
|
|
4477
|
+
() => clearTimeout(deadline)
|
|
4478
|
+
);
|
|
4098
4479
|
}
|
|
4099
4480
|
enqueueAccountRegistryOperation(session, task) {
|
|
4100
4481
|
const operation = this.accountRegistryTail.then(async () => {
|
|
@@ -4130,15 +4511,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4130
4511
|
(operation) => operation.service === "space" && this.actionContains(operation.action, "tinycloud.space/list")
|
|
4131
4512
|
);
|
|
4132
4513
|
}
|
|
4133
|
-
async withAccountRegistryRetry(task) {
|
|
4514
|
+
async withAccountRegistryRetry(task, signal) {
|
|
4134
4515
|
const delays = [250, 1e3, 3e3];
|
|
4135
4516
|
let lastError;
|
|
4136
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
|
+
}
|
|
4137
4522
|
try {
|
|
4138
4523
|
await task();
|
|
4139
4524
|
return;
|
|
4140
4525
|
} catch (error) {
|
|
4141
|
-
|
|
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);
|
|
4142
4531
|
const message = error instanceof Error ? error.message : String(error);
|
|
4143
4532
|
const isAuthorizationVerdict = verdict === void 0 ? /Unauthorized Action|\b(?:401|403)\b/.test(message) : verdict !== "other";
|
|
4144
4533
|
if (isAuthorizationVerdict) {
|
|
@@ -4148,13 +4537,29 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4148
4537
|
);
|
|
4149
4538
|
return;
|
|
4150
4539
|
}
|
|
4151
|
-
if ((0,
|
|
4152
|
-
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
|
+
);
|
|
4153
4545
|
return;
|
|
4154
4546
|
}
|
|
4155
4547
|
lastError = error;
|
|
4156
4548
|
if (attempt < delays.length - 1) {
|
|
4157
|
-
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
|
+
});
|
|
4158
4563
|
}
|
|
4159
4564
|
}
|
|
4160
4565
|
}
|
|
@@ -4170,7 +4575,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4170
4575
|
}
|
|
4171
4576
|
const networkIds = /* @__PURE__ */ new Set();
|
|
4172
4577
|
for (const resource of request.resources) {
|
|
4173
|
-
if (resource.service ===
|
|
4578
|
+
if (resource.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && resource.path.startsWith("urn:tinycloud:encryption:") && resource.actions.includes(DECRYPT_ACTION2)) {
|
|
4174
4579
|
networkIds.add(resource.path);
|
|
4175
4580
|
}
|
|
4176
4581
|
}
|
|
@@ -4181,7 +4586,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4181
4586
|
return;
|
|
4182
4587
|
}
|
|
4183
4588
|
for (const networkId of this.requestedEncryptionNetworkIds()) {
|
|
4184
|
-
const parsed = (0,
|
|
4589
|
+
const parsed = (0, import_sdk_core10.parseNetworkId)(networkId);
|
|
4185
4590
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
4186
4591
|
continue;
|
|
4187
4592
|
}
|
|
@@ -4204,7 +4609,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4204
4609
|
* self-revealing: the next write to the space fails immediately and loudly
|
|
4205
4610
|
* with `404 Space not found`.
|
|
4206
4611
|
*/
|
|
4207
|
-
async ensureOwnedSpaceHostedById(spaceId) {
|
|
4612
|
+
async ensureOwnedSpaceHostedById(spaceId, signal) {
|
|
4208
4613
|
if (!this.auth) {
|
|
4209
4614
|
throw new Error("Owned space hosting requires wallet mode");
|
|
4210
4615
|
}
|
|
@@ -4219,7 +4624,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4219
4624
|
if (!host) {
|
|
4220
4625
|
throw new Error("Owned space hosting requires a TinyCloud host");
|
|
4221
4626
|
}
|
|
4222
|
-
const activation = await (0,
|
|
4627
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader, signal);
|
|
4223
4628
|
if (activation.success && !activation.skipped?.includes(spaceId)) {
|
|
4224
4629
|
this.confirmedHostedSpaceIds.add(spaceId);
|
|
4225
4630
|
return;
|
|
@@ -4230,15 +4635,16 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4230
4635
|
{ cause: activation }
|
|
4231
4636
|
);
|
|
4232
4637
|
}
|
|
4233
|
-
const
|
|
4638
|
+
const authorization = this.auth;
|
|
4639
|
+
const created = signal ? await authorization.hostOwnedSpaceResult(spaceId, void 0, signal) : await authorization.hostOwnedSpaceResult(spaceId);
|
|
4234
4640
|
if (!created.success) {
|
|
4235
4641
|
throw Object.assign(
|
|
4236
4642
|
new Error(`Failed to create owned space ${spaceId}: ${describeHostFailure2(created)}`),
|
|
4237
4643
|
{ cause: created }
|
|
4238
4644
|
);
|
|
4239
4645
|
}
|
|
4240
|
-
|
|
4241
|
-
const retry = await (0,
|
|
4646
|
+
if (signal?.aborted) throw signal.reason;
|
|
4647
|
+
const retry = await (0, import_sdk_core10.activateSessionWithHost)(host, session.delegationHeader, signal);
|
|
4242
4648
|
if (!retry.success || retry.skipped?.includes(spaceId)) {
|
|
4243
4649
|
throw Object.assign(
|
|
4244
4650
|
new Error(
|
|
@@ -4286,7 +4692,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4286
4692
|
{ cause: hosted }
|
|
4287
4693
|
);
|
|
4288
4694
|
}
|
|
4289
|
-
const activation = await (0,
|
|
4695
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
4290
4696
|
host,
|
|
4291
4697
|
session.delegationHeader
|
|
4292
4698
|
);
|
|
@@ -4474,7 +4880,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4474
4880
|
}
|
|
4475
4881
|
let restoredAddress;
|
|
4476
4882
|
try {
|
|
4477
|
-
restoredAddress = hasPersistedProof ? (0,
|
|
4883
|
+
restoredAddress = hasPersistedProof ? (0, import_sdk_core10.canonicalizeAddress)(sessionData.address) : void 0;
|
|
4478
4884
|
} catch {
|
|
4479
4885
|
throw new InvalidRestoredSessionError("Persisted session has an invalid wallet address.");
|
|
4480
4886
|
}
|
|
@@ -4516,7 +4922,35 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4516
4922
|
const stagedHost = resolvedHost ?? this.config.host;
|
|
4517
4923
|
const stagedAddress = restoredAddress;
|
|
4518
4924
|
const stagedChainId = sessionData.chainId ?? 1;
|
|
4519
|
-
|
|
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;
|
|
4520
4954
|
const serviceSession = {
|
|
4521
4955
|
delegationHeader: sessionData.delegationHeader,
|
|
4522
4956
|
delegationCid: sessionData.delegationCid,
|
|
@@ -4544,7 +4978,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4544
4978
|
stagedSessionExpiry,
|
|
4545
4979
|
stagedRecap
|
|
4546
4980
|
);
|
|
4547
|
-
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;
|
|
4548
4982
|
const stagedGraph = this.stageRestoredServiceGraph({
|
|
4549
4983
|
host: stagedHost,
|
|
4550
4984
|
manager: stagedManager,
|
|
@@ -4594,7 +5028,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4594
5028
|
} else {
|
|
4595
5029
|
this._restoredTcSession = stagedTcSession;
|
|
4596
5030
|
}
|
|
5031
|
+
this.replicationDelegateSession = compactReplicationSession;
|
|
5032
|
+
this.replicationScopeError = replicationScopeError;
|
|
5033
|
+
if (this.replicationRuntime) await (await this.replicationRuntime).unbind();
|
|
4597
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);
|
|
4598
5043
|
oldCore?.retireServices?.();
|
|
4599
5044
|
}
|
|
4600
5045
|
stagePrimarySessionState(session, verificationMethod, host, sessionExpiry, recap) {
|
|
@@ -4645,7 +5090,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4645
5090
|
}
|
|
4646
5091
|
stageRestoredServiceGraph(input) {
|
|
4647
5092
|
const graph = this.createServiceGraphLifetime();
|
|
4648
|
-
const core = this.auth ? new
|
|
5093
|
+
const core = this.auth ? new import_sdk_core10.TinyCloud(this.auth, {
|
|
4649
5094
|
invokeAny: graph.invokeAny,
|
|
4650
5095
|
telemetry: this.config.telemetry
|
|
4651
5096
|
}) : null;
|
|
@@ -4654,23 +5099,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4654
5099
|
const coreContext = graph.track(core.serviceContext);
|
|
4655
5100
|
coreContext.setSession(input.serviceSession);
|
|
4656
5101
|
}
|
|
4657
|
-
const serviceContext = graph.track(new
|
|
5102
|
+
const serviceContext = graph.track(new import_sdk_core10.ServiceContext({
|
|
4658
5103
|
invoke: graph.invoke,
|
|
4659
5104
|
invokeAny: graph.invokeAny,
|
|
4660
5105
|
fetch: graph.fetch,
|
|
4661
5106
|
hosts: [input.host],
|
|
4662
5107
|
telemetry: this.config.telemetry
|
|
4663
5108
|
}));
|
|
4664
|
-
const kv = new
|
|
5109
|
+
const kv = new import_sdk_core10.KVService({});
|
|
4665
5110
|
kv.initialize(serviceContext);
|
|
4666
5111
|
serviceContext.registerService("kv", kv);
|
|
4667
|
-
const sql = new
|
|
5112
|
+
const sql = new import_sdk_core10.SQLService({});
|
|
4668
5113
|
sql.initialize(serviceContext);
|
|
4669
5114
|
serviceContext.registerService("sql", sql);
|
|
4670
|
-
const duckdb = new
|
|
5115
|
+
const duckdb = new import_sdk_core10.DuckDbService({});
|
|
4671
5116
|
duckdb.initialize(serviceContext);
|
|
4672
5117
|
serviceContext.registerService("duckdb", duckdb);
|
|
4673
|
-
const hooks = new
|
|
5118
|
+
const hooks = new import_sdk_core10.HooksService({});
|
|
4674
5119
|
hooks.initialize(serviceContext);
|
|
4675
5120
|
serviceContext.registerService("hooks", hooks);
|
|
4676
5121
|
serviceContext.setSession(input.serviceSession);
|
|
@@ -4693,7 +5138,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4693
5138
|
});
|
|
4694
5139
|
vault.initialize(serviceContext);
|
|
4695
5140
|
serviceContext.registerService("vault", vault);
|
|
4696
|
-
const capabilityRegistry = new
|
|
5141
|
+
const capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
4697
5142
|
if (input.tinyCloudSession) {
|
|
4698
5143
|
const session = input.tinyCloudSession;
|
|
4699
5144
|
const delegations = input.recap.map((entry) => ({
|
|
@@ -4717,7 +5162,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4717
5162
|
}, delegations);
|
|
4718
5163
|
}
|
|
4719
5164
|
}
|
|
4720
|
-
const delegationManager = new
|
|
5165
|
+
const delegationManager = new import_sdk_core10.DelegationManager({
|
|
4721
5166
|
hosts: [input.host],
|
|
4722
5167
|
accountSpaceId: input.accountSpaceId,
|
|
4723
5168
|
session: input.serviceSession,
|
|
@@ -4726,7 +5171,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4726
5171
|
fetch: graph.fetch
|
|
4727
5172
|
});
|
|
4728
5173
|
const keyProvider = new WasmKeyProvider({ sessionManager: input.manager });
|
|
4729
|
-
const sharingService = new
|
|
5174
|
+
const sharingService = new import_sdk_core10.SharingService({
|
|
4730
5175
|
hosts: [input.host],
|
|
4731
5176
|
invoke: graph.invoke,
|
|
4732
5177
|
fetch: graph.fetch,
|
|
@@ -4739,8 +5184,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4739
5184
|
return this.wasmBindings.computeCid(data, codec);
|
|
4740
5185
|
},
|
|
4741
5186
|
createKVService: (config) => {
|
|
4742
|
-
const service = new
|
|
4743
|
-
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({
|
|
4744
5189
|
invoke: config.invoke,
|
|
4745
5190
|
fetch: config.fetch ?? globalThis.fetch.bind(globalThis),
|
|
4746
5191
|
hosts: config.hosts,
|
|
@@ -4748,6 +5193,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4748
5193
|
}));
|
|
4749
5194
|
context.setSession(config.session);
|
|
4750
5195
|
service.initialize(context);
|
|
5196
|
+
this.attachReplicationKV(config.session.spaceId, service);
|
|
4751
5197
|
return service;
|
|
4752
5198
|
}
|
|
4753
5199
|
});
|
|
@@ -4769,7 +5215,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4769
5215
|
return delegation;
|
|
4770
5216
|
} : void 0
|
|
4771
5217
|
});
|
|
4772
|
-
const spaceService = new
|
|
5218
|
+
const spaceService = new import_sdk_core10.SpaceService({
|
|
4773
5219
|
hosts: [input.host],
|
|
4774
5220
|
session: input.serviceSession,
|
|
4775
5221
|
invoke: graph.invoke,
|
|
@@ -4778,8 +5224,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4778
5224
|
userDid: input.nodeDid,
|
|
4779
5225
|
createKVService: (spaceId) => {
|
|
4780
5226
|
graph.assertActive();
|
|
4781
|
-
const scopedKv = new
|
|
4782
|
-
const context = graph.track(new
|
|
5227
|
+
const scopedKv = new import_sdk_core10.KVService({});
|
|
5228
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
4783
5229
|
invoke: graph.invoke,
|
|
4784
5230
|
invokeAny: graph.invokeAny,
|
|
4785
5231
|
fetch: graph.fetch,
|
|
@@ -4788,12 +5234,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4788
5234
|
}));
|
|
4789
5235
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
4790
5236
|
scopedKv.initialize(context);
|
|
5237
|
+
this.attachReplicationKV(spaceId, scopedKv);
|
|
4791
5238
|
return scopedKv;
|
|
4792
5239
|
},
|
|
4793
5240
|
createVaultService: (spaceId) => {
|
|
4794
5241
|
graph.assertActive();
|
|
4795
|
-
const scopedKv = new
|
|
4796
|
-
const context = graph.track(new
|
|
5242
|
+
const scopedKv = new import_sdk_core10.KVService({});
|
|
5243
|
+
const context = graph.track(new import_sdk_core10.ServiceContext({
|
|
4797
5244
|
invoke: graph.invoke,
|
|
4798
5245
|
invokeAny: graph.invokeAny,
|
|
4799
5246
|
fetch: graph.fetch,
|
|
@@ -4802,6 +5249,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4802
5249
|
}));
|
|
4803
5250
|
context.setSession({ ...input.serviceSession, spaceId });
|
|
4804
5251
|
scopedKv.initialize(context);
|
|
5252
|
+
this.attachReplicationKV(spaceId, scopedKv);
|
|
4805
5253
|
const scopedVault = this.createVaultService(spaceId, scopedKv, encryption, {
|
|
4806
5254
|
host: input.host,
|
|
4807
5255
|
did: input.nodeDid,
|
|
@@ -4879,7 +5327,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4879
5327
|
if (address === void 0 || chainId === void 0) {
|
|
4880
5328
|
return void 0;
|
|
4881
5329
|
}
|
|
4882
|
-
const resolved = await (0,
|
|
5330
|
+
const resolved = await (0, import_sdk_core10.resolveTinyCloudHosts)((0, import_sdk_core10.pkhDid)(address, chainId), {
|
|
4883
5331
|
registryUrl: this.config.tinycloudRegistryUrl,
|
|
4884
5332
|
fallbackHosts: this.config.tinycloudFallbackHosts,
|
|
4885
5333
|
autoDiscoverLocalNode: this.config.autoDiscoverLocalNode,
|
|
@@ -4931,7 +5379,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4931
5379
|
nodeAudience: input.nodeAudience,
|
|
4932
5380
|
...input.role === "policy-enforcement" ? { enforcerDid: input.audienceDid } : {}
|
|
4933
5381
|
};
|
|
4934
|
-
const root = await (0,
|
|
5382
|
+
const root = await (0, import_sdk_core10.signCompactUcanRootAuthorization)({
|
|
4935
5383
|
issuerDid: ownerDid,
|
|
4936
5384
|
audienceDid: input.audienceDid,
|
|
4937
5385
|
attenuation: unifiedRootAttenuation(input.capabilities),
|
|
@@ -4973,7 +5421,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4973
5421
|
if (decision.needsApproval) return void 0;
|
|
4974
5422
|
throw new Error(decision.reason ?? "OpenKey automatic credential signing was rejected");
|
|
4975
5423
|
}
|
|
4976
|
-
if (typeof decision.signature !== "string" || !await (0,
|
|
5424
|
+
if (typeof decision.signature !== "string" || !await (0, import_sdk_core10.verifyEip191MessageSignature)(
|
|
4977
5425
|
request.message,
|
|
4978
5426
|
decision.signature,
|
|
4979
5427
|
request.address
|
|
@@ -4998,7 +5446,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4998
5446
|
if (approval) {
|
|
4999
5447
|
const decision = await approval(request);
|
|
5000
5448
|
if (!decision.approved) throw new Error(decision.reason ?? "Credential signing was rejected");
|
|
5001
|
-
if (decision.signature !== void 0 && !await (0,
|
|
5449
|
+
if (decision.signature !== void 0 && !await (0, import_sdk_core10.verifyEip191MessageSignature)(
|
|
5002
5450
|
request.message,
|
|
5003
5451
|
decision.signature,
|
|
5004
5452
|
request.address
|
|
@@ -5081,10 +5529,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5081
5529
|
nonce: this.config.nonce,
|
|
5082
5530
|
siweConfig: this.config.siweConfig,
|
|
5083
5531
|
manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
|
|
5084
|
-
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ?
|
|
5085
|
-
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
|
|
5086
5539
|
});
|
|
5087
|
-
this.tc = new
|
|
5540
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
5088
5541
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
5089
5542
|
telemetry: this.config.telemetry
|
|
5090
5543
|
});
|
|
@@ -5134,10 +5587,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5134
5587
|
nonce: this.config.nonce,
|
|
5135
5588
|
siweConfig: this.config.siweConfig,
|
|
5136
5589
|
manifest: useBootstrapSignInRequest ? void 0 : this.config.manifest,
|
|
5137
|
-
capabilityRequest: useBootstrapSignInRequest ? this.config.includeAccountRegistryPermissions === false ?
|
|
5138
|
-
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
|
|
5139
5597
|
});
|
|
5140
|
-
this.tc = new
|
|
5598
|
+
this.tc = new import_sdk_core10.TinyCloud(this.auth, {
|
|
5141
5599
|
invokeAny: this.invokeAnyWithRuntimePermissions,
|
|
5142
5600
|
telemetry: this.config.telemetry
|
|
5143
5601
|
});
|
|
@@ -5147,7 +5605,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5147
5605
|
* Initialize the service context and KV service after sign-in.
|
|
5148
5606
|
* @internal
|
|
5149
5607
|
*/
|
|
5150
|
-
initializeServices() {
|
|
5608
|
+
async initializeServices() {
|
|
5151
5609
|
const session = this.currentTinyCloudSession();
|
|
5152
5610
|
if (!session) {
|
|
5153
5611
|
return;
|
|
@@ -5158,28 +5616,28 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5158
5616
|
this._serviceGraph.fetch
|
|
5159
5617
|
);
|
|
5160
5618
|
this._serviceGraph.track(this.tc.serviceContext);
|
|
5161
|
-
this._serviceContext = this._serviceGraph.track(new
|
|
5619
|
+
this._serviceContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
5162
5620
|
invoke: this._serviceGraph.invoke,
|
|
5163
5621
|
invokeAny: this._serviceGraph.invokeAny,
|
|
5164
5622
|
fetch: this._serviceGraph.fetch,
|
|
5165
5623
|
hosts: [this.config.host],
|
|
5166
5624
|
telemetry: this.config.telemetry
|
|
5167
5625
|
}));
|
|
5168
|
-
this._kv = new
|
|
5626
|
+
this._kv = new import_sdk_core10.KVService({});
|
|
5169
5627
|
this._kv.initialize(this._serviceContext);
|
|
5170
5628
|
this._serviceContext.registerService("kv", this._kv);
|
|
5171
5629
|
const features = this.nodeFeatures;
|
|
5172
5630
|
if (features.length === 0 || features.includes("sql")) {
|
|
5173
|
-
this._sql = new
|
|
5631
|
+
this._sql = new import_sdk_core10.SQLService({});
|
|
5174
5632
|
this._sql.initialize(this._serviceContext);
|
|
5175
5633
|
this._serviceContext.registerService("sql", this._sql);
|
|
5176
5634
|
}
|
|
5177
5635
|
if (features.length === 0 || features.includes("duckdb")) {
|
|
5178
|
-
this._duckdb = new
|
|
5636
|
+
this._duckdb = new import_sdk_core10.DuckDbService({});
|
|
5179
5637
|
this._duckdb.initialize(this._serviceContext);
|
|
5180
5638
|
this._serviceContext.registerService("duckdb", this._duckdb);
|
|
5181
5639
|
}
|
|
5182
|
-
this._hooks = new
|
|
5640
|
+
this._hooks = new import_sdk_core10.HooksService({});
|
|
5183
5641
|
this._hooks.initialize(this._serviceContext);
|
|
5184
5642
|
this._serviceContext.registerService("hooks", this._hooks);
|
|
5185
5643
|
const serviceSession = {
|
|
@@ -5190,16 +5648,22 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5190
5648
|
jwk: session.jwk
|
|
5191
5649
|
};
|
|
5192
5650
|
this._serviceContext.setSession(serviceSession);
|
|
5651
|
+
await this.bindReplicationRuntime(this._serviceContext, serviceSession, this._kv);
|
|
5193
5652
|
this.tc.serviceContext.setSession(serviceSession);
|
|
5194
5653
|
this._vault = this.createVaultService(session.spaceId, this._kv);
|
|
5195
5654
|
this._vault.initialize(this._serviceContext);
|
|
5196
5655
|
this._serviceContext.registerService("vault", this._vault);
|
|
5197
5656
|
this.initializeV2Services(serviceSession);
|
|
5198
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
|
+
}
|
|
5199
5663
|
createSpaceScopedKVService(spaceId) {
|
|
5200
|
-
const kvService = new
|
|
5664
|
+
const kvService = new import_sdk_core10.KVService({});
|
|
5201
5665
|
if (this._serviceContext) {
|
|
5202
|
-
const spaceScopedContext = this._serviceGraph.track(new
|
|
5666
|
+
const spaceScopedContext = this._serviceGraph.track(new import_sdk_core10.ServiceContext({
|
|
5203
5667
|
invoke: this._serviceContext.invoke,
|
|
5204
5668
|
invokeAny: this._serviceContext.invokeAny,
|
|
5205
5669
|
fetch: this._serviceContext.fetch,
|
|
@@ -5211,6 +5675,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5211
5675
|
spaceScopedContext.setSession({ ...session, spaceId });
|
|
5212
5676
|
}
|
|
5213
5677
|
kvService.initialize(spaceScopedContext);
|
|
5678
|
+
this.attachReplicationKV(spaceId, kvService);
|
|
5214
5679
|
}
|
|
5215
5680
|
return kvService;
|
|
5216
5681
|
}
|
|
@@ -5291,7 +5756,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5291
5756
|
const shared = wasm.vault_x25519_dh(receiverPrivateKey, peerPublic);
|
|
5292
5757
|
return columnDecrypt(shared, ciphertext);
|
|
5293
5758
|
},
|
|
5294
|
-
verifyNodeSignature: (nodeId, message, signature) => (0,
|
|
5759
|
+
verifyNodeSignature: (nodeId, message, signature) => (0, import_sdk_core10.verifyDidKeyEd25519Signature)(nodeId, message, signature)
|
|
5295
5760
|
};
|
|
5296
5761
|
}
|
|
5297
5762
|
/**
|
|
@@ -5307,7 +5772,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5307
5772
|
if (cached) return cached;
|
|
5308
5773
|
const response = await fetch(`${this.config.host}/info`);
|
|
5309
5774
|
if (!response.ok) {
|
|
5310
|
-
throw await (0,
|
|
5775
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, "Failed to fetch node info");
|
|
5311
5776
|
}
|
|
5312
5777
|
const info = await response.json();
|
|
5313
5778
|
if (typeof info.nodeId !== "string" || info.nodeId.length === 0) {
|
|
@@ -5357,7 +5822,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5357
5822
|
);
|
|
5358
5823
|
if (response.status === 404) return null;
|
|
5359
5824
|
if (!response.ok) {
|
|
5360
|
-
throw await (0,
|
|
5825
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, `Failed to fetch encryption network ${networkId}`);
|
|
5361
5826
|
}
|
|
5362
5827
|
const body = await response.json();
|
|
5363
5828
|
return "descriptor" in body && body.descriptor ? body.descriptor : body;
|
|
@@ -5388,17 +5853,17 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5388
5853
|
);
|
|
5389
5854
|
graph.assertActive();
|
|
5390
5855
|
if (!response.ok) {
|
|
5391
|
-
const permissionHint = response.status === 401 || response.status === 403 ? (0,
|
|
5856
|
+
const permissionHint = response.status === 401 || response.status === 403 ? (0, import_sdk_services3.parsePermissionHint)({
|
|
5392
5857
|
service: "tinycloud.encryption",
|
|
5393
5858
|
path: networkId,
|
|
5394
5859
|
actions: ["tinycloud.encryption/decrypt"]
|
|
5395
5860
|
}) : void 0;
|
|
5396
|
-
throw new
|
|
5861
|
+
throw new import_sdk_core10.DecryptTransportResponseError(response.status, permissionHint);
|
|
5397
5862
|
}
|
|
5398
5863
|
return await response.json();
|
|
5399
5864
|
}
|
|
5400
5865
|
};
|
|
5401
|
-
return new
|
|
5866
|
+
return new import_sdk_core10.EncryptionService({
|
|
5402
5867
|
crypto: crypto2,
|
|
5403
5868
|
signer: {
|
|
5404
5869
|
signDecryptInvocation: async (input) => {
|
|
@@ -5412,7 +5877,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5412
5877
|
graph.assertActive();
|
|
5413
5878
|
return {
|
|
5414
5879
|
...signed,
|
|
5415
|
-
canonicalBody: (0,
|
|
5880
|
+
canonicalBody: (0, import_sdk_core10.canonicalizeEncryptionJson)(
|
|
5416
5881
|
input.body
|
|
5417
5882
|
)
|
|
5418
5883
|
};
|
|
@@ -5444,7 +5909,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5444
5909
|
if (!address || !didPrincipalMatches2(principal, did)) {
|
|
5445
5910
|
return null;
|
|
5446
5911
|
}
|
|
5447
|
-
const publicSpaceId = (0,
|
|
5912
|
+
const publicSpaceId = (0, import_sdk_core10.makePublicSpaceId)(address, chainId);
|
|
5448
5913
|
const encodedKey = discoveryKey.split("/").map(encodeURIComponent).join("/");
|
|
5449
5914
|
const response = await graph.fetch(
|
|
5450
5915
|
`${host}/public/${encodeURIComponent(publicSpaceId)}/kv/${encodedKey}`,
|
|
@@ -5476,7 +5941,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5476
5941
|
createVaultService(spaceId, kv, encryptionService = this.getEncryptionService(), nodeContext) {
|
|
5477
5942
|
const wasm = this.wasmBindings;
|
|
5478
5943
|
const serviceGraph = nodeContext?.serviceGraph ?? this._serviceGraph;
|
|
5479
|
-
const vaultCrypto = (0,
|
|
5944
|
+
const vaultCrypto = (0, import_sdk_core10.createVaultCrypto)({
|
|
5480
5945
|
vault_encrypt: wasm.vault_encrypt,
|
|
5481
5946
|
vault_decrypt: wasm.vault_decrypt,
|
|
5482
5947
|
vault_derive_key: wasm.vault_derive_key,
|
|
@@ -5491,7 +5956,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5491
5956
|
const chainId = nodeContext?.chainId ?? this._chainId;
|
|
5492
5957
|
const host = nodeContext?.host ?? this.config.host;
|
|
5493
5958
|
const ownerDid = this.ownerDidFromSpaceId(spaceId) ?? did;
|
|
5494
|
-
return new
|
|
5959
|
+
return new import_sdk_core10.DataVaultService({
|
|
5495
5960
|
spaceId,
|
|
5496
5961
|
crypto: vaultCrypto,
|
|
5497
5962
|
encryption: {
|
|
@@ -5516,8 +5981,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5516
5981
|
serviceGraph.assertActive();
|
|
5517
5982
|
return self._publicKV ?? self.tc.publicKV;
|
|
5518
5983
|
},
|
|
5519
|
-
readPublicSpace: (host2, targetSpaceId, key) =>
|
|
5520
|
-
makePublicSpaceId:
|
|
5984
|
+
readPublicSpace: (host2, targetSpaceId, key) => import_sdk_core10.TinyCloud.readPublicSpace(host2, targetSpaceId, key),
|
|
5985
|
+
makePublicSpaceId: import_sdk_core10.TinyCloud.makePublicSpaceId,
|
|
5521
5986
|
did,
|
|
5522
5987
|
address: address ?? "",
|
|
5523
5988
|
chainId,
|
|
@@ -5531,7 +5996,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5531
5996
|
*/
|
|
5532
5997
|
initializeV2Services(serviceSession) {
|
|
5533
5998
|
const graph = this._serviceGraph;
|
|
5534
|
-
this._capabilityRegistry = new
|
|
5999
|
+
this._capabilityRegistry = new import_sdk_core10.CapabilityKeyRegistry();
|
|
5535
6000
|
const tcSession = this.auth?.tinyCloudSession;
|
|
5536
6001
|
if (tcSession && this._address) {
|
|
5537
6002
|
const sessionKey = {
|
|
@@ -5571,7 +6036,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5571
6036
|
}
|
|
5572
6037
|
this._capabilityRegistry.registerKey(sessionKey, delegations);
|
|
5573
6038
|
}
|
|
5574
|
-
this._delegationManager = new
|
|
6039
|
+
this._delegationManager = new import_sdk_core10.DelegationManager({
|
|
5575
6040
|
hosts: [this.config.host],
|
|
5576
6041
|
accountSpaceId: this.accountSpaceId,
|
|
5577
6042
|
session: serviceSession,
|
|
@@ -5579,7 +6044,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5579
6044
|
invokeAny: graph.invokeAny,
|
|
5580
6045
|
fetch: graph.fetch
|
|
5581
6046
|
});
|
|
5582
|
-
this._spaceService = new
|
|
6047
|
+
this._spaceService = new import_sdk_core10.SpaceService({
|
|
5583
6048
|
hosts: [this.config.host],
|
|
5584
6049
|
session: serviceSession,
|
|
5585
6050
|
invoke: graph.invoke,
|
|
@@ -5644,7 +6109,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5644
6109
|
await this.account.spaces.register(space);
|
|
5645
6110
|
}
|
|
5646
6111
|
});
|
|
5647
|
-
this._sharingService = new
|
|
6112
|
+
this._sharingService = new import_sdk_core10.SharingService({
|
|
5648
6113
|
hosts: [this.config.host],
|
|
5649
6114
|
session: serviceSession,
|
|
5650
6115
|
invoke: graph.invoke,
|
|
@@ -5664,8 +6129,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5664
6129
|
},
|
|
5665
6130
|
createKVService: (config) => {
|
|
5666
6131
|
graph.assertActive();
|
|
5667
|
-
const service = new
|
|
5668
|
-
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({
|
|
5669
6134
|
invoke: config.invoke,
|
|
5670
6135
|
fetch: config.fetch ?? graph.fetch,
|
|
5671
6136
|
hosts: config.hosts,
|
|
@@ -5673,6 +6138,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5673
6138
|
}));
|
|
5674
6139
|
context.setSession(config.session);
|
|
5675
6140
|
service.initialize(context);
|
|
6141
|
+
this.attachReplicationKV(config.session.spaceId, service);
|
|
5676
6142
|
return service;
|
|
5677
6143
|
},
|
|
5678
6144
|
onRootDelegationNeeded: this.signer ? async (params) => {
|
|
@@ -5758,15 +6224,15 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5758
6224
|
}
|
|
5759
6225
|
const permissions = ownerDelegationPermissions(params);
|
|
5760
6226
|
const now = /* @__PURE__ */ new Date();
|
|
5761
|
-
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) {
|
|
5762
6228
|
throw new Error("Owner delegation expiry must be explicit, future, and within EXPIRY.MAX_MS");
|
|
5763
6229
|
}
|
|
5764
6230
|
if (!this.signer) throw new Error("Owner wallet signer is required");
|
|
5765
6231
|
const session = this.currentTinyCloudSession();
|
|
5766
6232
|
if (!session) throw new Error("Owner session is required");
|
|
5767
|
-
const ownerDid = (0,
|
|
6233
|
+
const ownerDid = (0, import_sdk_core10.pkhDid)(session.address, session.chainId);
|
|
5768
6234
|
for (const permission of permissions) {
|
|
5769
|
-
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)) {
|
|
5770
6236
|
throw new Error("Owner delegation cannot grant a foreign encryption network");
|
|
5771
6237
|
}
|
|
5772
6238
|
}
|
|
@@ -5787,7 +6253,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5787
6253
|
const signature = await this.signer.signMessage(prepared.siwe);
|
|
5788
6254
|
assertOwnerGraphActive();
|
|
5789
6255
|
const delegationSession = this.wasmBindings.completeSessionSetup({ ...prepared, signature });
|
|
5790
|
-
const activation = await (0,
|
|
6256
|
+
const activation = await (0, import_sdk_core10.activateSessionWithHost)(host, delegationSession.delegationHeader);
|
|
5791
6257
|
assertOwnerGraphActive();
|
|
5792
6258
|
if (!activation.success) {
|
|
5793
6259
|
throw Object.assign(
|
|
@@ -5823,7 +6289,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5823
6289
|
/** Register a signed policy and sibling roots with this Node's Policy/v3 runtime. */
|
|
5824
6290
|
async registerPolicy(params) {
|
|
5825
6291
|
this._serviceGraph.assertActive();
|
|
5826
|
-
return (0,
|
|
6292
|
+
return (0, import_sdk_core10.registerPolicyV3)({
|
|
5827
6293
|
...params,
|
|
5828
6294
|
nodeOrigin: this.config.host,
|
|
5829
6295
|
fetch: globalThis.fetch.bind(globalThis)
|
|
@@ -5850,23 +6316,23 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5850
6316
|
jti: base64UrlEncode(jtiDigest.slice(0, 16)),
|
|
5851
6317
|
expiresAt: new Date(input.expiresAt).toISOString().replace(/\.\d{3}Z$/, "Z")
|
|
5852
6318
|
};
|
|
5853
|
-
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)))));
|
|
5854
6320
|
const request = { ...body, requestBodyDigest };
|
|
5855
6321
|
const authorization = authorizationHeader(this.invokeAnyWithRuntimePermissions(serviceSession, [{ spaceId: session.spaceId, service: "kv", path: input.resourcePath, action: "tinycloud.kv/get" }]));
|
|
5856
6322
|
const response = await fetch(`${this.config.host}/policy/v3/deliveries/authorize`, {
|
|
5857
6323
|
method: "POST",
|
|
5858
6324
|
headers: { accept: "application/json", "content-type": "application/json", authorization },
|
|
5859
|
-
body: (0,
|
|
6325
|
+
body: (0, import_sdk_core10.canonicalizeEncryptionJson)(request)
|
|
5860
6326
|
});
|
|
5861
|
-
if (!response.ok) throw await (0,
|
|
5862
|
-
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()), {
|
|
5863
6329
|
request,
|
|
5864
6330
|
senderKeyDid: this.credentialHolderDid,
|
|
5865
6331
|
deliveryAudience: input.deliveryAudience
|
|
5866
6332
|
});
|
|
5867
6333
|
const requestDigest = new Uint8Array(await crypto.subtle.digest(
|
|
5868
6334
|
"SHA-256",
|
|
5869
|
-
new TextEncoder().encode(`${
|
|
6335
|
+
new TextEncoder().encode(`${import_sdk_core10.CREDENTIAL_INVITATION_REQUEST_DOMAIN}${(0, import_sdk_core10.canonicalizeEncryptionJson)(verified.request)}`)
|
|
5870
6336
|
));
|
|
5871
6337
|
return {
|
|
5872
6338
|
...verified,
|
|
@@ -5934,7 +6400,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5934
6400
|
if (!this._sql) {
|
|
5935
6401
|
const features = this.nodeFeatures;
|
|
5936
6402
|
if (features.length > 0 && !features.includes("sql")) {
|
|
5937
|
-
throw new
|
|
6403
|
+
throw new import_sdk_core10.UnsupportedFeatureError("sql", this.config.host, features);
|
|
5938
6404
|
}
|
|
5939
6405
|
throw new Error("Not signed in. Call signIn() first.");
|
|
5940
6406
|
}
|
|
@@ -5958,8 +6424,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5958
6424
|
if (!this._serviceContext || !this._serviceContext.session) {
|
|
5959
6425
|
throw new Error("Not signed in. Call signIn() first.");
|
|
5960
6426
|
}
|
|
5961
|
-
const sql = new
|
|
5962
|
-
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({
|
|
5963
6429
|
invoke: this._serviceContext.invoke,
|
|
5964
6430
|
invokeAny: this._serviceContext.invokeAny,
|
|
5965
6431
|
fetch: this._serviceContext.fetch,
|
|
@@ -5988,8 +6454,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5988
6454
|
if (!this._serviceContext || !this._serviceContext.session) {
|
|
5989
6455
|
throw new Error("Not signed in. Call signIn() first.");
|
|
5990
6456
|
}
|
|
5991
|
-
const kv = new
|
|
5992
|
-
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({
|
|
5993
6459
|
invoke: this._serviceContext.invoke,
|
|
5994
6460
|
invokeAny: this._serviceContext.invokeAny,
|
|
5995
6461
|
fetch: this._serviceContext.fetch,
|
|
@@ -5997,6 +6463,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5997
6463
|
}));
|
|
5998
6464
|
spaceScopedContext.setSession({ ...this._serviceContext.session, spaceId });
|
|
5999
6465
|
kv.initialize(spaceScopedContext);
|
|
6466
|
+
this.attachReplicationKV(spaceId, kv);
|
|
6000
6467
|
return kv;
|
|
6001
6468
|
}
|
|
6002
6469
|
/**
|
|
@@ -6006,7 +6473,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6006
6473
|
if (!this._duckdb) {
|
|
6007
6474
|
const features = this.nodeFeatures;
|
|
6008
6475
|
if (features.length > 0 && !features.includes("duckdb")) {
|
|
6009
|
-
throw new
|
|
6476
|
+
throw new import_sdk_core10.UnsupportedFeatureError("duckdb", this.config.host, features);
|
|
6010
6477
|
}
|
|
6011
6478
|
throw new Error("Not signed in. Call signIn() first.");
|
|
6012
6479
|
}
|
|
@@ -6050,7 +6517,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6050
6517
|
type: NETWORK_ADMIN_TYPE,
|
|
6051
6518
|
targetNode,
|
|
6052
6519
|
networkId,
|
|
6053
|
-
bodyHash: (0,
|
|
6520
|
+
bodyHash: (0, import_sdk_core10.canonicalHashHex)(
|
|
6054
6521
|
crypto2.sha256,
|
|
6055
6522
|
body
|
|
6056
6523
|
),
|
|
@@ -6068,7 +6535,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6068
6535
|
Authorization: signed.authorization,
|
|
6069
6536
|
"Content-Type": "application/json"
|
|
6070
6537
|
},
|
|
6071
|
-
body: (0,
|
|
6538
|
+
body: (0, import_sdk_core10.canonicalizeEncryptionJson)(
|
|
6072
6539
|
body
|
|
6073
6540
|
)
|
|
6074
6541
|
});
|
|
@@ -6080,7 +6547,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6080
6547
|
);
|
|
6081
6548
|
}
|
|
6082
6549
|
if (!response.ok) {
|
|
6083
|
-
throw await (0,
|
|
6550
|
+
throw await (0, import_sdk_core10.httpResponseError)(response, `Failed to create encryption network ${networkId}`);
|
|
6084
6551
|
}
|
|
6085
6552
|
const created = await response.json();
|
|
6086
6553
|
return created.descriptor;
|
|
@@ -6099,7 +6566,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6099
6566
|
return existing;
|
|
6100
6567
|
}
|
|
6101
6568
|
}
|
|
6102
|
-
const parsed = (0,
|
|
6569
|
+
const parsed = (0, import_sdk_core10.parseNetworkId)(networkId);
|
|
6103
6570
|
if (!didPrincipalMatches2(parsed.ownerDid, this.did)) {
|
|
6104
6571
|
throw new Error(
|
|
6105
6572
|
`Cannot create encryption network ${networkId}: owner ${parsed.ownerDid} does not match signed-in DID ${this.did}`
|
|
@@ -6147,14 +6614,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6147
6614
|
* normal KV and encryption invocation paths.
|
|
6148
6615
|
*/
|
|
6149
6616
|
async readSecret(input) {
|
|
6150
|
-
const resolved = (0,
|
|
6617
|
+
const resolved = (0, import_sdk_core10.resolveSecretPath)(input.name, { scope: input.scope });
|
|
6151
6618
|
const targetSpace = input.space.startsWith("tinycloud:") ? input.space : this.ownedSpaceId(input.space);
|
|
6152
6619
|
const result = await this.getBaseVault(targetSpace).readNetworkEncrypted(
|
|
6153
6620
|
resolved.vaultKey
|
|
6154
6621
|
);
|
|
6155
6622
|
if (result.status !== "ok") {
|
|
6156
6623
|
if (result.status === "permission_required") {
|
|
6157
|
-
const hint = (0,
|
|
6624
|
+
const hint = (0, import_sdk_services3.parsePermissionHint)(result.hint);
|
|
6158
6625
|
if (hint === void 0) return { status: "read_failed" };
|
|
6159
6626
|
return {
|
|
6160
6627
|
status: "permission_required",
|
|
@@ -6180,7 +6647,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6180
6647
|
const resolvedSpace = spaceId.startsWith("tinycloud:") ? spaceId : this.ownedSpaceId(spaceId);
|
|
6181
6648
|
let secrets = this._baseSecrets.get(resolvedSpace);
|
|
6182
6649
|
if (!secrets) {
|
|
6183
|
-
secrets = new
|
|
6650
|
+
secrets = new import_sdk_core10.SecretsService(() => this.getBaseVault(resolvedSpace));
|
|
6184
6651
|
this._baseSecrets.set(resolvedSpace, secrets);
|
|
6185
6652
|
}
|
|
6186
6653
|
return secrets;
|
|
@@ -6323,7 +6790,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6323
6790
|
for (const grant of this.runtimePermissionGrants) {
|
|
6324
6791
|
if (grant.provenance === "primary") continue;
|
|
6325
6792
|
for (const operation of grant.operations) {
|
|
6326
|
-
const service =
|
|
6793
|
+
const service = import_sdk_core10.SERVICE_SHORT_TO_LONG[operation.service];
|
|
6327
6794
|
if (service === void 0 || typeof operation.path !== "string" || typeof operation.action !== "string") {
|
|
6328
6795
|
continue;
|
|
6329
6796
|
}
|
|
@@ -6341,7 +6808,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6341
6808
|
service,
|
|
6342
6809
|
...space === void 0 ? {} : { space },
|
|
6343
6810
|
path: operation.path,
|
|
6344
|
-
caveats: (0,
|
|
6811
|
+
caveats: (0, import_sdk_core10.canonicalizeRecapCaveats)(caveats)
|
|
6345
6812
|
});
|
|
6346
6813
|
const existing = grouped.get(identity);
|
|
6347
6814
|
if (existing === void 0) {
|
|
@@ -6386,7 +6853,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6386
6853
|
delegationCid: grant.delegationCid,
|
|
6387
6854
|
spaceId: grant.spaceId,
|
|
6388
6855
|
jwk: this.sessionKeyJwk,
|
|
6389
|
-
address: (0,
|
|
6856
|
+
address: (0, import_sdk_core10.canonicalizeAddress)(grant.address),
|
|
6390
6857
|
chainId: grant.chainId,
|
|
6391
6858
|
siwe: grant.siwe,
|
|
6392
6859
|
signature: grant.signature
|
|
@@ -6407,10 +6874,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6407
6874
|
async useRuntimeDelegation(delegation) {
|
|
6408
6875
|
const session = this.currentTinyCloudSession();
|
|
6409
6876
|
if (!session) {
|
|
6410
|
-
throw new
|
|
6877
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6411
6878
|
}
|
|
6412
6879
|
if (delegation.expiry.getTime() <= Date.now()) {
|
|
6413
|
-
throw new
|
|
6880
|
+
throw new import_sdk_core10.SessionExpiredError(delegation.expiry);
|
|
6414
6881
|
}
|
|
6415
6882
|
const expectedDids = [session.verificationMethod, this.sessionDid];
|
|
6416
6883
|
if (!expectedDids.some((did) => didPrincipalMatches2(delegation.delegateDID, did))) {
|
|
@@ -6419,10 +6886,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6419
6886
|
);
|
|
6420
6887
|
}
|
|
6421
6888
|
const targetHost = delegation.host ?? this.config.host;
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6889
|
+
let activateResult;
|
|
6890
|
+
try {
|
|
6891
|
+
activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6892
|
+
targetHost,
|
|
6893
|
+
delegation.delegationHeader
|
|
6894
|
+
);
|
|
6895
|
+
} catch (cause) {
|
|
6896
|
+
throw Object.assign(
|
|
6897
|
+
new Error("The TinyCloud host could not be reached to activate the delegation."),
|
|
6898
|
+
{ code: "ACTIVATION_TRANSPORT_FAILED", cause }
|
|
6899
|
+
);
|
|
6900
|
+
}
|
|
6426
6901
|
if (!activateResult.success) {
|
|
6427
6902
|
if (this.operationsFromDelegation(delegation).some(
|
|
6428
6903
|
(operation) => operation.resource?.startsWith("urn:cid:") === true && operation.service === "delegation" && operation.action === "tinycloud.delegation/revoke"
|
|
@@ -6455,13 +6930,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6455
6930
|
}
|
|
6456
6931
|
const session = this.currentTinyCloudSession();
|
|
6457
6932
|
if (!session) {
|
|
6458
|
-
throw new
|
|
6933
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6459
6934
|
}
|
|
6460
6935
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
6461
6936
|
if (sessionExpiry !== void 0) {
|
|
6462
6937
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
6463
6938
|
if (sessionExpiry.getTime() <= Date.now() + marginMs) {
|
|
6464
|
-
throw new
|
|
6939
|
+
throw new import_sdk_core10.SessionExpiredError(sessionExpiry);
|
|
6465
6940
|
}
|
|
6466
6941
|
}
|
|
6467
6942
|
const expanded = this.expandPermissionEntries(permissions);
|
|
@@ -6537,7 +7012,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6537
7012
|
...prepared,
|
|
6538
7013
|
signature
|
|
6539
7014
|
});
|
|
6540
|
-
const activateResult = await (0,
|
|
7015
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6541
7016
|
this.config.host,
|
|
6542
7017
|
delegatedSession.delegationHeader
|
|
6543
7018
|
);
|
|
@@ -6710,10 +7185,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6710
7185
|
throw new Error("Public space not enabled. Set enablePublicSpace: true in config.");
|
|
6711
7186
|
}
|
|
6712
7187
|
await this.auth.hostPublicSpace(publicSpaceId);
|
|
6713
|
-
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];
|
|
6714
7189
|
const abilities = { kv: { "": kvActions } };
|
|
6715
7190
|
const now = /* @__PURE__ */ new Date();
|
|
6716
|
-
const expiryMs =
|
|
7191
|
+
const expiryMs = import_sdk_core10.EXPIRY.EPHEMERAL_MS;
|
|
6717
7192
|
const expirationTime = new Date(now.getTime() + expiryMs);
|
|
6718
7193
|
const prepared = this.wasmBindings.prepareSession({
|
|
6719
7194
|
abilities,
|
|
@@ -6731,7 +7206,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6731
7206
|
...prepared,
|
|
6732
7207
|
signature
|
|
6733
7208
|
});
|
|
6734
|
-
const activateResult = await (0,
|
|
7209
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
6735
7210
|
this.config.host,
|
|
6736
7211
|
delegationSession.delegationHeader
|
|
6737
7212
|
);
|
|
@@ -6761,8 +7236,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6761
7236
|
}]);
|
|
6762
7237
|
}
|
|
6763
7238
|
if (this._serviceContext) {
|
|
6764
|
-
const publicKV = new
|
|
6765
|
-
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({
|
|
6766
7241
|
invoke: this._serviceGraph.invoke,
|
|
6767
7242
|
fetch: this._serviceGraph.fetch,
|
|
6768
7243
|
hosts: this._serviceContext.hosts,
|
|
@@ -6914,14 +7389,14 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6914
7389
|
}
|
|
6915
7390
|
const session = this.currentTinyCloudSession();
|
|
6916
7391
|
if (!session) {
|
|
6917
|
-
throw new
|
|
7392
|
+
throw new import_sdk_core10.SessionExpiredError(/* @__PURE__ */ new Date(0));
|
|
6918
7393
|
}
|
|
6919
7394
|
const sessionExpiry = extractSiweExpiration(session.siwe);
|
|
6920
7395
|
if (sessionExpiry !== void 0) {
|
|
6921
7396
|
const now2 = Date.now();
|
|
6922
7397
|
const marginMs = _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS;
|
|
6923
7398
|
if (sessionExpiry.getTime() <= now2 + marginMs) {
|
|
6924
|
-
throw new
|
|
7399
|
+
throw new import_sdk_core10.SessionExpiredError(sessionExpiry);
|
|
6925
7400
|
}
|
|
6926
7401
|
}
|
|
6927
7402
|
if (!Array.isArray(permissions) || permissions.length === 0) {
|
|
@@ -6951,31 +7426,31 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6951
7426
|
);
|
|
6952
7427
|
return { delegation: delegation2, prompted: true };
|
|
6953
7428
|
}
|
|
6954
|
-
const
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
)
|
|
6962
|
-
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
}
|
|
6967
|
-
const runtimeExpiration = runtimeGrant.expiresAt < effectiveExpiration ? runtimeGrant.expiresAt : effectiveExpiration;
|
|
6968
|
-
const delegation2 = await this.createDelegationViaRuntimeGrant(
|
|
6969
|
-
did,
|
|
6970
|
-
expandedEntries,
|
|
6971
|
-
runtimeExpiration,
|
|
6972
|
-
runtimeGrant,
|
|
6973
|
-
runtimeOperations,
|
|
6974
|
-
onPrepared
|
|
6975
|
-
);
|
|
6976
|
-
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 ?? []);
|
|
6977
7441
|
}
|
|
6978
|
-
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 };
|
|
6979
7454
|
}
|
|
6980
7455
|
const delegation = await this.createDelegationViaWasmPath(
|
|
6981
7456
|
did,
|
|
@@ -6986,6 +7461,149 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6986
7461
|
);
|
|
6987
7462
|
return { delegation, prompted: false };
|
|
6988
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
|
+
}
|
|
6989
7607
|
/**
|
|
6990
7608
|
* Materialize one manifest-declared delegation using the current session key.
|
|
6991
7609
|
* Delivery is intentionally out of band; callers decide how to transmit the
|
|
@@ -7059,7 +7677,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7059
7677
|
const spaceId = resolvedSpaces.size === 1 ? [...resolvedSpaces][0] : session.spaceId;
|
|
7060
7678
|
const abilities = {};
|
|
7061
7679
|
for (const entry of entries) {
|
|
7062
|
-
const shortService =
|
|
7680
|
+
const shortService = import_sdk_core10.SERVICE_LONG_TO_SHORT[entry.service];
|
|
7063
7681
|
if (shortService === void 0) {
|
|
7064
7682
|
throw new Error(
|
|
7065
7683
|
`delegateTo: unknown service '${entry.service}' \u2014 no short-form mapping`
|
|
@@ -7116,7 +7734,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7116
7734
|
if (onPrepared) {
|
|
7117
7735
|
await onPrepared(delegation);
|
|
7118
7736
|
}
|
|
7119
|
-
const activateResult = await (0,
|
|
7737
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7120
7738
|
this.config.host,
|
|
7121
7739
|
delegationHeader
|
|
7122
7740
|
);
|
|
@@ -7158,7 +7776,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7158
7776
|
if (onPrepared) {
|
|
7159
7777
|
await onPrepared(delegation);
|
|
7160
7778
|
}
|
|
7161
|
-
const activateResult = await (0,
|
|
7779
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7162
7780
|
targetHost,
|
|
7163
7781
|
delegationHeader
|
|
7164
7782
|
);
|
|
@@ -7187,7 +7805,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7187
7805
|
return this.wasmBindings.makeSpaceId(session.address, session.chainId, space);
|
|
7188
7806
|
}
|
|
7189
7807
|
expandPermissionEntries(permissions) {
|
|
7190
|
-
return (0,
|
|
7808
|
+
return (0, import_sdk_core10.expandPermissionEntries)(permissions);
|
|
7191
7809
|
}
|
|
7192
7810
|
/**
|
|
7193
7811
|
* The current WASM child-delegation APIs accept action-only maps. Refuse any
|
|
@@ -7195,10 +7813,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7195
7813
|
*/
|
|
7196
7814
|
assertDelegationCaveatsPreservable(entries) {
|
|
7197
7815
|
const caveated = entries.filter(
|
|
7198
|
-
(entry) => !(0,
|
|
7816
|
+
(entry) => !(0, import_sdk_core10.recapCaveatsEqual)(entry.caveats, void 0)
|
|
7199
7817
|
);
|
|
7200
7818
|
if (caveated.length > 0) {
|
|
7201
|
-
throw new
|
|
7819
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(caveated);
|
|
7202
7820
|
}
|
|
7203
7821
|
}
|
|
7204
7822
|
/**
|
|
@@ -7208,6 +7826,18 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7208
7826
|
* it only accepts action maps, so reject the selected constrained branch.
|
|
7209
7827
|
*/
|
|
7210
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) {
|
|
7211
7841
|
let operationIndex = 0;
|
|
7212
7842
|
const caveated = [];
|
|
7213
7843
|
for (const entry of entries) {
|
|
@@ -7215,7 +7845,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7215
7845
|
const requested = requestedOperations[operationIndex++];
|
|
7216
7846
|
if (!requested) continue;
|
|
7217
7847
|
const constrained = grant.operations.find(
|
|
7218
|
-
(granted) => this.operationCovers(granted, requested) && !(0,
|
|
7848
|
+
(granted) => this.operationCovers(granted, requested) && !(0, import_sdk_core10.recapCaveatsEqual)(granted.caveats, void 0)
|
|
7219
7849
|
);
|
|
7220
7850
|
if (constrained) {
|
|
7221
7851
|
caveated.push({
|
|
@@ -7226,15 +7856,13 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7226
7856
|
}
|
|
7227
7857
|
}
|
|
7228
7858
|
}
|
|
7229
|
-
|
|
7230
|
-
throw new import_sdk_core9.CaveatedDelegationUnsupportedError(caveated);
|
|
7231
|
-
}
|
|
7859
|
+
return caveated;
|
|
7232
7860
|
}
|
|
7233
7861
|
/** Reject caveated parent branches before action-only child signing. */
|
|
7234
7862
|
assertPortableDelegationCaveatsPreservable(delegation) {
|
|
7235
7863
|
const entries = [];
|
|
7236
7864
|
const add = (service, space, path, actions, caveats) => {
|
|
7237
|
-
if ((0,
|
|
7865
|
+
if ((0, import_sdk_core10.recapCaveatsEqual)(caveats, void 0)) return;
|
|
7238
7866
|
entries.push({
|
|
7239
7867
|
service: service.startsWith("tinycloud.") ? service : `tinycloud.${service}`,
|
|
7240
7868
|
space,
|
|
@@ -7254,11 +7882,11 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7254
7882
|
add(resource.service, resource.space, resource.path, resource.actions, resource.caveats);
|
|
7255
7883
|
}
|
|
7256
7884
|
if (entries.length > 0) {
|
|
7257
|
-
throw new
|
|
7885
|
+
throw new import_sdk_core10.CaveatedDelegationUnsupportedError(entries);
|
|
7258
7886
|
}
|
|
7259
7887
|
}
|
|
7260
7888
|
shortServiceName(service) {
|
|
7261
|
-
const short =
|
|
7889
|
+
const short = import_sdk_core10.SERVICE_LONG_TO_SHORT[service];
|
|
7262
7890
|
if (short === void 0) {
|
|
7263
7891
|
throw new Error(
|
|
7264
7892
|
`unknown service '${service}' \u2014 no short-form mapping`
|
|
@@ -7285,7 +7913,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7285
7913
|
return abilities;
|
|
7286
7914
|
}
|
|
7287
7915
|
isEncryptionPermissionEntry(entry) {
|
|
7288
|
-
return entry.service ===
|
|
7916
|
+
return entry.service === import_sdk_core10.ENCRYPTION_PERMISSION_SERVICE && this.isEncryptionNetworkOperation("encryption", entry.path, entry.space);
|
|
7289
7917
|
}
|
|
7290
7918
|
isRawRevocationPermissionEntry(entry) {
|
|
7291
7919
|
return entry.service === "tinycloud.delegation" && entry.path === "" && entry.space?.startsWith("urn:cid:") === true && entry.actions.includes("tinycloud.delegation/revoke");
|
|
@@ -7333,7 +7961,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7333
7961
|
const missing = requested.filter((entry) => {
|
|
7334
7962
|
const raw = this.isEncryptionPermissionEntry(entry) || this.isRawRevocationPermissionEntry(entry);
|
|
7335
7963
|
const comparable = raw && this.isEncryptionPermissionEntry(entry) ? { ...entry, space: "encryption" } : entry;
|
|
7336
|
-
return !(0,
|
|
7964
|
+
return !(0, import_sdk_core10.isCapabilitySubset)([comparable], raw ? rawGranted : spaceGranted).subset;
|
|
7337
7965
|
});
|
|
7338
7966
|
return { subset: missing.length === 0, missing };
|
|
7339
7967
|
}
|
|
@@ -7569,7 +8197,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7569
8197
|
if (granted.service !== requested.service || !this.actionContains(granted.action, requested.action)) {
|
|
7570
8198
|
return false;
|
|
7571
8199
|
}
|
|
7572
|
-
if (requested.caveats !== void 0 && !(0,
|
|
8200
|
+
if (requested.caveats !== void 0 && !(0, import_sdk_core10.recapCaveatsEqual)(granted.caveats, requested.caveats)) {
|
|
7573
8201
|
return false;
|
|
7574
8202
|
}
|
|
7575
8203
|
if (granted.resource !== void 0 || requested.resource !== void 0) {
|
|
@@ -7591,7 +8219,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7591
8219
|
if (grantedAction === requestedAction) {
|
|
7592
8220
|
return true;
|
|
7593
8221
|
}
|
|
7594
|
-
if ((0,
|
|
8222
|
+
if ((0, import_sdk_core10.isExplicitOnlyAction)(requestedAction)) {
|
|
7595
8223
|
return false;
|
|
7596
8224
|
}
|
|
7597
8225
|
if (grantedAction.endsWith("/*")) {
|
|
@@ -7703,7 +8331,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7703
8331
|
if (resolvedDelegateDID.endsWith(".eth") && this.config.ensResolver) {
|
|
7704
8332
|
const address = await this.config.ensResolver.resolveAddress(resolvedDelegateDID);
|
|
7705
8333
|
if (!address) throw new Error(`Could not resolve ENS name: ${resolvedDelegateDID}`);
|
|
7706
|
-
resolvedDelegateDID = (0,
|
|
8334
|
+
resolvedDelegateDID = (0, import_sdk_core10.pkhDid)(address, 1);
|
|
7707
8335
|
}
|
|
7708
8336
|
const entries = legacyParamsToPermissionEntries(
|
|
7709
8337
|
params.actions,
|
|
@@ -7718,7 +8346,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7718
8346
|
);
|
|
7719
8347
|
return result.delegation;
|
|
7720
8348
|
} catch (err) {
|
|
7721
|
-
if (err instanceof
|
|
8349
|
+
if (err instanceof import_sdk_core10.PermissionNotInManifestError) {
|
|
7722
8350
|
} else {
|
|
7723
8351
|
throw err;
|
|
7724
8352
|
}
|
|
@@ -7775,7 +8403,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7775
8403
|
...prepared,
|
|
7776
8404
|
signature
|
|
7777
8405
|
});
|
|
7778
|
-
const activateResult = await (0,
|
|
8406
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7779
8407
|
this.config.host,
|
|
7780
8408
|
delegationSession.delegationHeader
|
|
7781
8409
|
);
|
|
@@ -7800,12 +8428,12 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7800
8428
|
};
|
|
7801
8429
|
const hasKvActions = params.actions.some((a) => a.startsWith("tinycloud.kv/"));
|
|
7802
8430
|
if (hasKvActions && params.includePublicSpace !== false) {
|
|
7803
|
-
const publicSpaceId = (0,
|
|
8431
|
+
const publicSpaceId = (0, import_sdk_core10.makePublicSpaceId)(
|
|
7804
8432
|
this.wasmBindings.ensureEip55(session.address),
|
|
7805
8433
|
session.chainId
|
|
7806
8434
|
);
|
|
7807
8435
|
const publicAbilities = {
|
|
7808
|
-
kv: { "": [
|
|
8436
|
+
kv: { "": [import_sdk_core10.KV.GET, import_sdk_core10.KV.PUT, import_sdk_core10.KV.METADATA] }
|
|
7809
8437
|
};
|
|
7810
8438
|
const publicPrepared = this.wasmBindings.prepareSession({
|
|
7811
8439
|
abilities: publicAbilities,
|
|
@@ -7823,7 +8451,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7823
8451
|
...publicPrepared,
|
|
7824
8452
|
signature: publicSignature
|
|
7825
8453
|
});
|
|
7826
|
-
const publicActivateResult = await (0,
|
|
8454
|
+
const publicActivateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7827
8455
|
this.config.host,
|
|
7828
8456
|
publicSession.delegationHeader
|
|
7829
8457
|
);
|
|
@@ -7833,7 +8461,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7833
8461
|
delegationHeader: publicSession.delegationHeader,
|
|
7834
8462
|
spaceId: publicSpaceId,
|
|
7835
8463
|
path: "",
|
|
7836
|
-
actions: [
|
|
8464
|
+
actions: [import_sdk_core10.KV.GET, import_sdk_core10.KV.PUT, import_sdk_core10.KV.METADATA],
|
|
7837
8465
|
disableSubDelegation: params.disableSubDelegation ?? false,
|
|
7838
8466
|
expiry: expirationTime,
|
|
7839
8467
|
delegateDID: params.delegateDID,
|
|
@@ -7928,7 +8556,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
7928
8556
|
...prepared,
|
|
7929
8557
|
signature
|
|
7930
8558
|
});
|
|
7931
|
-
const activateResult = await (0,
|
|
8559
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
7932
8560
|
targetHost,
|
|
7933
8561
|
invokerSession.delegationHeader
|
|
7934
8562
|
);
|
|
@@ -8048,7 +8676,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
8048
8676
|
...prepared,
|
|
8049
8677
|
signature
|
|
8050
8678
|
});
|
|
8051
|
-
const activateResult = await (0,
|
|
8679
|
+
const activateResult = await (0, import_sdk_core10.activateSessionWithHost)(
|
|
8052
8680
|
targetHost,
|
|
8053
8681
|
subDelegationSession.delegationHeader
|
|
8054
8682
|
);
|
|
@@ -8093,7 +8721,6 @@ _TinyCloudNode.SESSION_EXPIRY_SAFETY_MARGIN_MS = 6e4;
|
|
|
8093
8721
|
var TinyCloudNode = _TinyCloudNode;
|
|
8094
8722
|
|
|
8095
8723
|
// src/core.ts
|
|
8096
|
-
var import_sdk_core12 = require("@tinycloud/sdk-core");
|
|
8097
8724
|
var import_sdk_core13 = require("@tinycloud/sdk-core");
|
|
8098
8725
|
var import_sdk_core14 = require("@tinycloud/sdk-core");
|
|
8099
8726
|
var import_sdk_core15 = require("@tinycloud/sdk-core");
|
|
@@ -8103,6 +8730,7 @@ var import_sdk_core18 = require("@tinycloud/sdk-core");
|
|
|
8103
8730
|
var import_sdk_core19 = require("@tinycloud/sdk-core");
|
|
8104
8731
|
var import_sdk_core20 = require("@tinycloud/sdk-core");
|
|
8105
8732
|
var import_sdk_core21 = require("@tinycloud/sdk-core");
|
|
8733
|
+
var import_sdk_core22 = require("@tinycloud/sdk-core");
|
|
8106
8734
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8107
8735
|
0 && (module.exports = {
|
|
8108
8736
|
ACCOUNT_REGISTRY_PATH,
|
|
@@ -8196,6 +8824,7 @@ var import_sdk_core21 = require("@tinycloud/sdk-core");
|
|
|
8196
8824
|
pkhDid,
|
|
8197
8825
|
principalDid,
|
|
8198
8826
|
principalDidEquals,
|
|
8827
|
+
registerReplicationLoaders,
|
|
8199
8828
|
resolveManifest,
|
|
8200
8829
|
resolveSecretListPrefix,
|
|
8201
8830
|
resolveSecretPath,
|