@tinycloud/node-sdk 3.11.0 → 3.12.0-beta.1
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/NodeUserAuthorization-BtoDI9in.d.cts +900 -0
- package/dist/NodeUserAuthorization-BtoDI9in.d.ts +900 -0
- package/dist/{TinyCloudNode-BlNcvo1c.d.ts → TinyCloudNode-C24728N_.d.cts} +30 -874
- package/dist/{TinyCloudNode-CnVaWnAX.d.cts → TinyCloudNode-DLrINr98.d.ts} +30 -874
- package/dist/{WasmKeyProvider-BKCPRC-c.d.cts → WasmKeyProvider-OA0LqmTg.d.cts} +2 -0
- package/dist/{WasmKeyProvider-BKCPRC-c.d.ts → WasmKeyProvider-OA0LqmTg.d.ts} +2 -0
- package/dist/{authority-DHIk5QvV.d.ts → authority-BQN2Z3st.d.ts} +1 -1
- package/dist/{authority-B2SLx27M.d.cts → authority-DDdheOL6.d.cts} +1 -1
- package/dist/core.cjs +179 -100
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +6 -5
- package/dist/core.d.ts +6 -5
- package/dist/core.js +180 -101
- package/dist/core.js.map +1 -1
- package/dist/credentials-core.d.cts +1 -1
- package/dist/credentials-core.d.ts +1 -1
- package/dist/credentials.d.cts +1 -1
- package/dist/credentials.d.ts +1 -1
- package/dist/{delegation-Ckc3UETl.d.cts → delegation-BQbAuKad.d.cts} +1 -1
- package/dist/{delegation-Ckc3UETl.d.ts → delegation-BQbAuKad.d.ts} +1 -1
- package/dist/encryption-keys.d.cts +3 -2
- package/dist/encryption-keys.d.ts +3 -2
- package/dist/index.cjs +179 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +180 -101
- package/dist/index.js.map +1 -1
- package/dist/replication/authority.d.cts +4 -3
- package/dist/replication/authority.d.ts +4 -3
- package/dist/space-hosting.cjs +141 -0
- package/dist/space-hosting.cjs.map +1 -0
- package/dist/space-hosting.d.cts +69 -0
- package/dist/space-hosting.d.ts +69 -0
- package/dist/space-hosting.js +115 -0
- package/dist/space-hosting.js.map +1 -0
- package/package.json +11 -1
|
@@ -90,6 +90,8 @@ declare class FileSessionStorage implements ISessionStorage {
|
|
|
90
90
|
save(address: string, session: PersistedSessionData): Promise<void>;
|
|
91
91
|
/**
|
|
92
92
|
* Load a session for an address.
|
|
93
|
+
*
|
|
94
|
+
* Rejects when the file exists but cannot be read or parsed; the file is left in place.
|
|
93
95
|
*/
|
|
94
96
|
load(address: string): Promise<PersistedSessionData | null>;
|
|
95
97
|
/**
|
|
@@ -90,6 +90,8 @@ declare class FileSessionStorage implements ISessionStorage {
|
|
|
90
90
|
save(address: string, session: PersistedSessionData): Promise<void>;
|
|
91
91
|
/**
|
|
92
92
|
* Load a session for an address.
|
|
93
|
+
*
|
|
94
|
+
* Rejects when the file exists but cannot be read or parsed; the file is left in place.
|
|
93
95
|
*/
|
|
94
96
|
load(address: string): Promise<PersistedSessionData | null>;
|
|
95
97
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaLocalEraseOutcome, ReplicaPurgeLocalCopyResult, ReplicaPurgeTrigger, ReplicaPurgeFailedEvent, ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-DLrINr98.js';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReplicationOptions, PermissionEntry, TinyCloudSession, KVReplicaStorage, ServiceContext, IWasmBindings, WasmRecapEntry } from '@tinycloud/sdk-core';
|
|
2
2
|
import { ReplicaConsentAnchor, AuthorityRefusal, ReplicationAuthority } from '@tinycloud/sdk-services';
|
|
3
3
|
import { ReplicaLocalEraseOutcome, ReplicaPurgeLocalCopyResult, ReplicaPurgeTrigger, ReplicaPurgeFailedEvent, ReplicaSessionStamp, ReplicaDenyInput } from '@tinycloud/sdk-services/kv/replication';
|
|
4
|
-
import { T as TinyCloudNode } from './TinyCloudNode-
|
|
4
|
+
import { T as TinyCloudNode } from './TinyCloudNode-C24728N_.cjs';
|
|
5
5
|
|
|
6
6
|
/** Constructor-time validation; the space-dependent secrets check runs at sign-in and open. */
|
|
7
7
|
declare function assertValidReplicationConfig(replication: (ReplicationOptions & {
|
package/dist/core.cjs
CHANGED
|
@@ -268,10 +268,22 @@ var FileSessionStorage = class {
|
|
|
268
268
|
async save(address, session) {
|
|
269
269
|
const filePath = this.getFilePath(address);
|
|
270
270
|
const data = JSON.stringify(session, null, 2);
|
|
271
|
-
|
|
271
|
+
const tempPath = `${filePath}.${process.pid}.${process.hrtime.bigint()}.tmp`;
|
|
272
|
+
try {
|
|
273
|
+
(0, import_fs.writeFileSync)(tempPath, data, { mode: 384, flag: "wx" });
|
|
274
|
+
(0, import_fs.renameSync)(tempPath, filePath);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
try {
|
|
277
|
+
(0, import_fs.unlinkSync)(tempPath);
|
|
278
|
+
} catch {
|
|
279
|
+
}
|
|
280
|
+
throw error;
|
|
281
|
+
}
|
|
272
282
|
}
|
|
273
283
|
/**
|
|
274
284
|
* Load a session for an address.
|
|
285
|
+
*
|
|
286
|
+
* Rejects when the file exists but cannot be read or parsed; the file is left in place.
|
|
275
287
|
*/
|
|
276
288
|
async load(address) {
|
|
277
289
|
const filePath = this.getFilePath(address);
|
|
@@ -295,11 +307,9 @@ var FileSessionStorage = class {
|
|
|
295
307
|
}
|
|
296
308
|
return session;
|
|
297
309
|
} catch (error) {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
return null;
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Could not read session file ${filePath}: ${error}`
|
|
312
|
+
);
|
|
303
313
|
}
|
|
304
314
|
}
|
|
305
315
|
/**
|
|
@@ -453,6 +463,18 @@ function refuseCaveated(input) {
|
|
|
453
463
|
var import_sdk_core4 = require("@tinycloud/sdk-core");
|
|
454
464
|
var defaultSignStrategy = { type: "auto-sign" };
|
|
455
465
|
|
|
466
|
+
// src/storage/clearPersistedSessionIfOwn.ts
|
|
467
|
+
async function clearPersistedSessionIfOwn(storage, address, ownSignature) {
|
|
468
|
+
if (ownSignature !== void 0) {
|
|
469
|
+
try {
|
|
470
|
+
const stored = await storage.load(address);
|
|
471
|
+
if (stored !== null && stored.signature !== ownSignature) return;
|
|
472
|
+
} catch {
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
await storage.clear(address);
|
|
476
|
+
}
|
|
477
|
+
|
|
456
478
|
// src/authorization/NodeUserAuthorization.ts
|
|
457
479
|
function assertMaxExpiresAt(value) {
|
|
458
480
|
if (value === void 0 || typeof value === "function") return;
|
|
@@ -546,6 +568,8 @@ var NodeUserAuthorization = class {
|
|
|
546
568
|
* delegation lists them: the node answers a repeat with empty lists.
|
|
547
569
|
*/
|
|
548
570
|
this._lastActivationActivatedSpaceIds = [];
|
|
571
|
+
/** See {@link spaceHosting}. Written only from node answers. */
|
|
572
|
+
this._spaceHosting = "unknown";
|
|
549
573
|
this.wasm = config.wasmBindings;
|
|
550
574
|
this.signer = config.signer;
|
|
551
575
|
this.signStrategy = config.signStrategy ?? defaultSignStrategy;
|
|
@@ -705,6 +729,7 @@ var NodeUserAuthorization = class {
|
|
|
705
729
|
this.registryVerdict = void 0;
|
|
706
730
|
this._lastActivationSkippedSpaceIds = [];
|
|
707
731
|
this._lastActivationActivatedSpaceIds = [];
|
|
732
|
+
this._spaceHosting = "unknown";
|
|
708
733
|
if (!session) {
|
|
709
734
|
this._session = void 0;
|
|
710
735
|
this._tinyCloudSession = void 0;
|
|
@@ -845,6 +870,18 @@ var NodeUserAuthorization = class {
|
|
|
845
870
|
get lastActivationActivatedSpaceIds() {
|
|
846
871
|
return [...this._lastActivationActivatedSpaceIds];
|
|
847
872
|
}
|
|
873
|
+
/**
|
|
874
|
+
* The node's last answer for whether this session's primary space is hosted:
|
|
875
|
+
* recorded from the sign-in activation, or by {@link noteSpaceHosting}.
|
|
876
|
+
* `unknown` until one of them answers, and after a restore.
|
|
877
|
+
*/
|
|
878
|
+
get spaceHosting() {
|
|
879
|
+
return this._spaceHosting;
|
|
880
|
+
}
|
|
881
|
+
/** @internal Record the hosting probe's answer for the primary space. */
|
|
882
|
+
noteSpaceHosting(hosting) {
|
|
883
|
+
this._spaceHosting = hosting;
|
|
884
|
+
}
|
|
848
885
|
/**
|
|
849
886
|
* Compute the `abilities` map the WASM `prepareSession` call should
|
|
850
887
|
* see at sign-in time.
|
|
@@ -1305,103 +1342,55 @@ var NodeUserAuthorization = class {
|
|
|
1305
1342
|
this._tinyCloudSession.delegationHeader
|
|
1306
1343
|
);
|
|
1307
1344
|
this.recordActivationSkippedSpaces(result, primarySpaceId);
|
|
1345
|
+
if (!result.success && result.status !== 404) {
|
|
1346
|
+
throw Object.assign(
|
|
1347
|
+
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
1348
|
+
{ cause: result }
|
|
1349
|
+
);
|
|
1350
|
+
}
|
|
1351
|
+
await this.ensurePrimarySpaceHosted(this._spaceHosting);
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* The create step of {@link ensureSpaceExists}: given the node's answer for
|
|
1355
|
+
* the primary space, host it through the space creation handler when it is
|
|
1356
|
+
* `not-hosted`. Any other answer, and a missing handler, change nothing. The
|
|
1357
|
+
* caller supplies the answer (sign-in's activation, or the hosting probe);
|
|
1358
|
+
* an empty activation list is never one.
|
|
1359
|
+
*
|
|
1360
|
+
* @throws Error if the creation handler fails or times out, or hosting fails
|
|
1361
|
+
*/
|
|
1362
|
+
async ensurePrimarySpaceHosted(hosting) {
|
|
1363
|
+
if (hosting !== "not-hosted") {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
const session = this._tinyCloudSession;
|
|
1367
|
+
if (!session) {
|
|
1368
|
+
throw new Error("Must be signed in to host the primary space");
|
|
1369
|
+
}
|
|
1308
1370
|
const handler = this.spaceCreationHandler ?? (this.autoCreateSpace ? new import_sdk_core5.AutoApproveSpaceCreationHandler() : void 0);
|
|
1371
|
+
if (!handler) {
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
await this.ensureTinyCloudHosts();
|
|
1375
|
+
const host = this.primaryTinyCloudHost;
|
|
1376
|
+
const primarySpaceId = session.spaceId;
|
|
1309
1377
|
const creationContext = {
|
|
1310
1378
|
spaceId: primarySpaceId,
|
|
1311
1379
|
address: this._address,
|
|
1312
1380
|
chainId: this._chainId,
|
|
1313
1381
|
host
|
|
1314
1382
|
};
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
return;
|
|
1327
|
-
}
|
|
1328
|
-
try {
|
|
1329
|
-
const created = await this.hostSpace();
|
|
1330
|
-
if (!created.success) {
|
|
1331
|
-
const err2 = Object.assign(
|
|
1332
|
-
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
1333
|
-
{ cause: created }
|
|
1334
|
-
);
|
|
1335
|
-
throw err2;
|
|
1336
|
-
}
|
|
1337
|
-
} catch (error) {
|
|
1338
|
-
handler.onSpaceCreationFailed?.(
|
|
1339
|
-
creationContext,
|
|
1340
|
-
error instanceof Error ? error : new Error(String(error))
|
|
1341
|
-
);
|
|
1342
|
-
throw error;
|
|
1343
|
-
}
|
|
1344
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1345
|
-
const retryResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
1346
|
-
host,
|
|
1347
|
-
this._tinyCloudSession.delegationHeader
|
|
1348
|
-
);
|
|
1349
|
-
if (!retryResult.success) {
|
|
1350
|
-
const err2 = Object.assign(
|
|
1351
|
-
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
1352
|
-
{ cause: retryResult }
|
|
1353
|
-
);
|
|
1354
|
-
handler.onSpaceCreationFailed?.(creationContext, err2);
|
|
1355
|
-
throw err2;
|
|
1356
|
-
}
|
|
1357
|
-
handler.onSpaceCreated?.(creationContext);
|
|
1358
|
-
return;
|
|
1359
|
-
}
|
|
1360
|
-
if (result.status === 404) {
|
|
1361
|
-
if (!handler) {
|
|
1362
|
-
return;
|
|
1363
|
-
}
|
|
1364
|
-
await this.guardSpaceCreation(handler, creationContext);
|
|
1365
|
-
const confirmed = await handler.confirmSpaceCreation(creationContext);
|
|
1366
|
-
if (!confirmed) {
|
|
1367
|
-
return;
|
|
1368
|
-
}
|
|
1369
|
-
try {
|
|
1370
|
-
const created = await this.hostSpace();
|
|
1371
|
-
if (!created.success) {
|
|
1372
|
-
const err2 = Object.assign(
|
|
1373
|
-
new Error(`Failed to create space ${primarySpaceId}: ${describeHostFailure(created)}`),
|
|
1374
|
-
{ cause: created }
|
|
1375
|
-
);
|
|
1376
|
-
throw err2;
|
|
1377
|
-
}
|
|
1378
|
-
} catch (error) {
|
|
1379
|
-
handler.onSpaceCreationFailed?.(
|
|
1380
|
-
creationContext,
|
|
1381
|
-
error instanceof Error ? error : new Error(String(error))
|
|
1382
|
-
);
|
|
1383
|
-
throw error;
|
|
1384
|
-
}
|
|
1385
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1386
|
-
const retryResult = await (0, import_sdk_core5.activateSessionWithHost)(
|
|
1387
|
-
host,
|
|
1388
|
-
this._tinyCloudSession.delegationHeader
|
|
1389
|
-
);
|
|
1390
|
-
if (!retryResult.success) {
|
|
1391
|
-
const err2 = Object.assign(
|
|
1392
|
-
new Error(`Failed to activate session after creating space: ${describeHostFailure(retryResult)}`),
|
|
1393
|
-
{ cause: retryResult }
|
|
1394
|
-
);
|
|
1395
|
-
handler.onSpaceCreationFailed?.(creationContext, err2);
|
|
1396
|
-
throw err2;
|
|
1397
|
-
}
|
|
1398
|
-
handler.onSpaceCreated?.(creationContext);
|
|
1399
|
-
return;
|
|
1400
|
-
}
|
|
1401
|
-
throw Object.assign(
|
|
1402
|
-
new Error(`Failed to activate session: ${describeHostFailure(result)}`),
|
|
1403
|
-
{ cause: result }
|
|
1404
|
-
);
|
|
1383
|
+
const { createPrimarySpace } = await import("./space-hosting.cjs");
|
|
1384
|
+
await createPrimarySpace({
|
|
1385
|
+
handler,
|
|
1386
|
+
context: creationContext,
|
|
1387
|
+
guard: () => this.guardSpaceCreation(handler, creationContext),
|
|
1388
|
+
host: () => this.hostSpace(primarySpaceId),
|
|
1389
|
+
onHosted: () => {
|
|
1390
|
+
this._spaceHosting = "hosted";
|
|
1391
|
+
},
|
|
1392
|
+
activate: () => (0, import_sdk_core5.activateSessionWithHost)(host, session.delegationHeader)
|
|
1393
|
+
});
|
|
1405
1394
|
}
|
|
1406
1395
|
/** {@link assertMayCreateSpace}, reporting a refusal to the creation handler before rethrowing it. */
|
|
1407
1396
|
async guardSpaceCreation(handler, context) {
|
|
@@ -1417,10 +1406,12 @@ var NodeUserAuthorization = class {
|
|
|
1417
1406
|
if (result.success) {
|
|
1418
1407
|
this._lastActivationSkippedSpaceIds = result.skipped ?? [];
|
|
1419
1408
|
this._lastActivationActivatedSpaceIds = result.activated ?? [];
|
|
1409
|
+
this._spaceHosting = this._lastActivationSkippedSpaceIds.includes(primarySpaceId) ? "not-hosted" : this._lastActivationActivatedSpaceIds.includes(primarySpaceId) ? "hosted" : "unknown";
|
|
1420
1410
|
return;
|
|
1421
1411
|
}
|
|
1422
1412
|
this._lastActivationActivatedSpaceIds = [];
|
|
1423
1413
|
this._lastActivationSkippedSpaceIds = result.status === 404 ? [primarySpaceId] : [];
|
|
1414
|
+
this._spaceHosting = result.status === 404 ? "not-hosted" : "unknown";
|
|
1424
1415
|
}
|
|
1425
1416
|
async createBootstrapSession(options) {
|
|
1426
1417
|
refuseCaveated(options.capabilityRequest.manifests);
|
|
@@ -2269,12 +2260,13 @@ var NodeUserAuthorization = class {
|
|
|
2269
2260
|
};
|
|
2270
2261
|
}
|
|
2271
2262
|
/**
|
|
2272
|
-
* Clear persisted session data.
|
|
2263
|
+
* Clear persisted session data. With `ownSignature`, a stored session that provably has a different
|
|
2264
|
+
* signature (a newer sign-in for the same address) is left alone.
|
|
2273
2265
|
*/
|
|
2274
|
-
async clearPersistedSession(address) {
|
|
2266
|
+
async clearPersistedSession(address, ownSignature) {
|
|
2275
2267
|
const targetAddress = address ?? this._address;
|
|
2276
2268
|
if (targetAddress) {
|
|
2277
|
-
await this.sessionStorage
|
|
2269
|
+
await clearPersistedSessionIfOwn(this.sessionStorage, targetAddress, ownSignature);
|
|
2278
2270
|
}
|
|
2279
2271
|
}
|
|
2280
2272
|
/**
|
|
@@ -4051,6 +4043,8 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4051
4043
|
* hosting is confirmed against the session that was active at the time.
|
|
4052
4044
|
*/
|
|
4053
4045
|
this.confirmedHostedSpaceIds = /* @__PURE__ */ new Set();
|
|
4046
|
+
/** The primary space's hosting answer when no authorization layer holds it (a session-only restore). */
|
|
4047
|
+
this._restoredSpaceHosting = "unknown";
|
|
4054
4048
|
/**
|
|
4055
4049
|
* Owned space ids known to be hosted for the current session: the sign-in
|
|
4056
4050
|
* activation listed them as `activated`, or this session hosted them. Unlike
|
|
@@ -4389,6 +4383,84 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4389
4383
|
));
|
|
4390
4384
|
}
|
|
4391
4385
|
}
|
|
4386
|
+
/**
|
|
4387
|
+
* Whether the TinyCloud node hosts the primary space (the default) or a named
|
|
4388
|
+
* or full-id space: `"hosted"`, `"not-hosted"`, or `"unknown"` when the node
|
|
4389
|
+
* cannot say.
|
|
4390
|
+
*
|
|
4391
|
+
* Sends one authorized read the session already holds on that space (a kv
|
|
4392
|
+
* list under a granted prefix, else kv metadata, `tinycloud.space/info`, or
|
|
4393
|
+
* a kv get of a key that does not exist), signed for that space. A session
|
|
4394
|
+
* with no such read sends nothing and answers `unknown`. A 401/403 registers
|
|
4395
|
+
* the session delegation with the node once and asks again once. Network
|
|
4396
|
+
* failures, 5xx and a 5 s timeout answer `unknown`; this never throws.
|
|
4397
|
+
*
|
|
4398
|
+
* `hosted` is remembered for the session and `not-hosted` never is. The
|
|
4399
|
+
* answer for the primary space is also what {@link spaceHosting} reports; a
|
|
4400
|
+
* `unknown` answer leaves the previous one in place.
|
|
4401
|
+
*/
|
|
4402
|
+
async checkSpaceHosting(space) {
|
|
4403
|
+
try {
|
|
4404
|
+
return await this.probeSpaceHosting(space);
|
|
4405
|
+
} catch {
|
|
4406
|
+
return "unknown";
|
|
4407
|
+
}
|
|
4408
|
+
}
|
|
4409
|
+
/**
|
|
4410
|
+
* The node's last answer for the primary space: recorded at sign-in from the
|
|
4411
|
+
* activation, or by {@link checkSpaceHosting}. `unknown` after a restore until
|
|
4412
|
+
* something asks.
|
|
4413
|
+
*/
|
|
4414
|
+
get spaceHosting() {
|
|
4415
|
+
return this.auth ? this.auth.spaceHosting : this._restoredSpaceHosting;
|
|
4416
|
+
}
|
|
4417
|
+
async probeSpaceHosting(space) {
|
|
4418
|
+
const context = this._serviceContext;
|
|
4419
|
+
const session = context?.session;
|
|
4420
|
+
const host = context?.hosts[0];
|
|
4421
|
+
if (!context || !session || !host) {
|
|
4422
|
+
return "unknown";
|
|
4423
|
+
}
|
|
4424
|
+
const spaceId = space === void 0 ? session.spaceId : space.startsWith("tinycloud:") ? space : this.ownedSpaceId(space);
|
|
4425
|
+
const graph = this._serviceGraph;
|
|
4426
|
+
const epoch = this.sessionEpoch;
|
|
4427
|
+
const assertCurrent = () => {
|
|
4428
|
+
graph.assertActive();
|
|
4429
|
+
if (epoch !== this.sessionEpoch || graph !== this._serviceGraph || this._serviceContext !== context) {
|
|
4430
|
+
throw new Error("The session changed during the hosting check.");
|
|
4431
|
+
}
|
|
4432
|
+
};
|
|
4433
|
+
const { askSpaceHosting } = await import("./space-hosting.cjs");
|
|
4434
|
+
assertCurrent();
|
|
4435
|
+
this.pruneExpiredRuntimePermissionGrants();
|
|
4436
|
+
const primary = this.currentTinyCloudSession();
|
|
4437
|
+
const answer = await askSpaceHosting({
|
|
4438
|
+
spaceId,
|
|
4439
|
+
operations: [
|
|
4440
|
+
...this.runtimePermissionGrants.flatMap((grant) => grant.operations),
|
|
4441
|
+
...primary ? this.recapOperationsFromSession(primary) : []
|
|
4442
|
+
],
|
|
4443
|
+
covers: (granted, requested) => this.operationCovers(granted, requested),
|
|
4444
|
+
scope: context,
|
|
4445
|
+
host,
|
|
4446
|
+
fetch: unrecordedFetchOf(context),
|
|
4447
|
+
sign: (entries) => {
|
|
4448
|
+
assertCurrent();
|
|
4449
|
+
return graph.invokeAny({ ...session, spaceId }, entries);
|
|
4450
|
+
},
|
|
4451
|
+
// A session saved but never registered on this node is refused: it registers once.
|
|
4452
|
+
activate: (signal) => {
|
|
4453
|
+
assertCurrent();
|
|
4454
|
+
return (0, import_sdk_core11.activateSessionWithHost)(host, session.delegationHeader, AbortSignal.any([signal, graph.signal]));
|
|
4455
|
+
}
|
|
4456
|
+
});
|
|
4457
|
+
assertCurrent();
|
|
4458
|
+
if (answer !== "unknown" && this.spaceIdsEqual(spaceId, session.spaceId)) {
|
|
4459
|
+
if (this.auth) this.auth.noteSpaceHosting(answer);
|
|
4460
|
+
else this._restoredSpaceHosting = answer;
|
|
4461
|
+
}
|
|
4462
|
+
return answer;
|
|
4463
|
+
}
|
|
4392
4464
|
get nodeFeatures() {
|
|
4393
4465
|
return this.auth?.nodeFeatures ?? this._restoredNodeFeatures ?? [];
|
|
4394
4466
|
}
|
|
@@ -4757,6 +4829,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4757
4829
|
const leavingChainId = this._chainId;
|
|
4758
4830
|
const leavingPrincipal = this.replicaSessionPrincipal ?? (leavingAddress ? (0, import_sdk_core11.pkhDid)(leavingAddress, leavingChainId) : void 0);
|
|
4759
4831
|
const leavingAuth = this.auth;
|
|
4832
|
+
const leavingSignature = leavingAuth?.tinyCloudSession?.signature ?? this._restoredTcSession?.signature;
|
|
4760
4833
|
const leavingContext = this._serviceContext;
|
|
4761
4834
|
let denied;
|
|
4762
4835
|
let erased;
|
|
@@ -4773,7 +4846,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4773
4846
|
if (denied) erased = await this.eraseReplicaLocalCopy("sign_out", denied.status);
|
|
4774
4847
|
} finally {
|
|
4775
4848
|
if (leavingAddress) {
|
|
4776
|
-
await (leavingAuth ? leavingAuth.clearPersistedSession(leavingAddress) : this.config.sessionStorage
|
|
4849
|
+
await (leavingAuth ? leavingAuth.clearPersistedSession(leavingAddress, leavingSignature) : this.config.sessionStorage && clearPersistedSessionIfOwn(this.config.sessionStorage, leavingAddress, leavingSignature));
|
|
4777
4850
|
}
|
|
4778
4851
|
}
|
|
4779
4852
|
}
|
|
@@ -4879,6 +4952,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
4879
4952
|
this._spaceService = void 0;
|
|
4880
4953
|
this.runtimePermissionGrants = [];
|
|
4881
4954
|
this._recapOperationsCache = void 0;
|
|
4955
|
+
this._restoredSpaceHosting = "unknown";
|
|
4882
4956
|
this.confirmedHostedSpaceIds.clear();
|
|
4883
4957
|
this.hostedOwnedSpaceIds.clear();
|
|
4884
4958
|
this.cancelOwnedSpaceHosts();
|
|
@@ -5072,6 +5146,10 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
5072
5146
|
const primarySession = this.currentTinyCloudSession();
|
|
5073
5147
|
if (primarySession) {
|
|
5074
5148
|
this.registerPrimarySessionGrant(primarySession);
|
|
5149
|
+
if (this.auth?.spaceHosting === "unknown") {
|
|
5150
|
+
await this.checkSpaceHosting();
|
|
5151
|
+
this.assertSessionEpoch(epoch, "Sign-in");
|
|
5152
|
+
}
|
|
5075
5153
|
}
|
|
5076
5154
|
const bootstrapped = await this.bootstrapAccountIfNeeded();
|
|
5077
5155
|
this.assertSessionEpoch(epoch, "Sign-in");
|
|
@@ -6451,6 +6529,7 @@ var _TinyCloudNode = class _TinyCloudNode {
|
|
|
6451
6529
|
this.tc = stagedGraph.core;
|
|
6452
6530
|
this._recapOperationsCache = stagedPrimary.cache;
|
|
6453
6531
|
this.runtimePermissionGrants = stagedPrimary.grants;
|
|
6532
|
+
this._restoredSpaceHosting = "unknown";
|
|
6454
6533
|
this.confirmedHostedSpaceIds.clear();
|
|
6455
6534
|
this.hostedOwnedSpaceIds.clear();
|
|
6456
6535
|
this.cancelOwnedSpaceHosts();
|