@tinycloud/cli 1.1.0-beta.6 → 1.1.0-beta.7

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.
@@ -1779,7 +1779,7 @@ import {
1779
1779
  profileStoreMetadataPath,
1780
1780
  readAdditionalDelegations,
1781
1781
  readAuthRequests,
1782
- upsertProfileRecord,
1782
+ updateProfileStore,
1783
1783
  withProfileLock as withProfileLock2,
1784
1784
  writeJsonAtomic
1785
1785
  } from "@tinycloud/operations/state";
@@ -13123,17 +13123,15 @@ function didWithoutFragment(did) {
13123
13123
  async function loadAdditionalDelegations(profile) {
13124
13124
  return readAdditionalDelegations(profile);
13125
13125
  }
13126
- async function saveAdditionalDelegations(profile, entries) {
13127
- await replaceSharedRecords(profile, "additional-delegations", entries);
13126
+ async function appendAdditionalDelegations(profile, entries) {
13127
+ const { mergeDelegationsWithoutRequest } = await import("@tinycloud/operations/delegation-binding");
13128
+ await updateProfileStore(profile, "additional-delegations", (stored) => ({
13129
+ records: mergeDelegationsWithoutRequest(stored, entries.map((entry) => ({ ...entry }))),
13130
+ result: void 0
13131
+ }));
13128
13132
  }
13129
13133
  async function appendAdditionalDelegation(profile, entry) {
13130
- await upsertProfileRecord(
13131
- profile,
13132
- "additional-delegations",
13133
- entry.delegation.cid,
13134
- entry,
13135
- (candidate) => candidate.delegation.cid
13136
- );
13134
+ await appendAdditionalDelegations(profile, [entry]);
13137
13135
  }
13138
13136
  async function loadPermissionRequestArtifacts(profile) {
13139
13137
  const raw = await readAuthRequests(profile);
@@ -13147,9 +13145,6 @@ async function appendPermissionRequestArtifact(profile, artifact) {
13147
13145
  await writeSharedRecords(profile, "auth-requests", next);
13148
13146
  });
13149
13147
  }
13150
- async function replaceSharedRecords(profile, store, entries) {
13151
- await withProfileLock2(profile, () => writeSharedRecords(profile, store, entries));
13152
- }
13153
13148
  async function writeSharedRecords(profile, store, entries) {
13154
13149
  const path = store === "additional-delegations" ? additionalDelegationsPath(profile) : permissionRequestsPath(profile);
13155
13150
  await writeJsonAtomic(path, entries);
@@ -13163,13 +13158,48 @@ async function getLastPermissionRequestArtifact(profile) {
13163
13158
  const existing = await loadPermissionRequestArtifacts(profile);
13164
13159
  return existing.at(-1) ?? null;
13165
13160
  }
13166
- async function replayAdditionalDelegations(node, profile) {
13161
+ async function replayAdditionalDelegations(node, profile, options) {
13162
+ const {
13163
+ operationSpaceResolver,
13164
+ prepareStoredDelegationReplay,
13165
+ replayStoredDelegation,
13166
+ storedDelegationKind
13167
+ } = await import("@tinycloud/operations/delegation-binding");
13168
+ const activator = node;
13169
+ const migrated = await prepareStoredDelegationReplay(profile, activator, {
13170
+ host: options.host,
13171
+ migrate: options.migrate
13172
+ });
13173
+ const resolveSpace = operationSpaceResolver(node, options.ownerSpace);
13167
13174
  const entries = await loadAdditionalDelegations(profile);
13168
- for (const entry of entries) {
13175
+ for (const stored of entries) {
13176
+ const kind = storedDelegationKind(stored);
13177
+ if (kind === "compact" || kind === "signed-login") {
13178
+ const installed = await replayStoredDelegation(activator, stored, {
13179
+ host: options.host,
13180
+ migrated,
13181
+ resolveSpace
13182
+ });
13183
+ if (installed === void 0 && process.env.TC_DEBUG_REPLAY === "1") {
13184
+ process.stderr.write("[replay] skipping a stored delegation refused by validation or its request binding\n");
13185
+ }
13186
+ continue;
13187
+ }
13188
+ if (kind === "refused") {
13189
+ if (process.env.TC_DEBUG_REPLAY === "1") {
13190
+ process.stderr.write("[replay] skipping a malformed stored record or one bound to a request it cannot be held to\n");
13191
+ }
13192
+ continue;
13193
+ }
13194
+ const entry = stored;
13169
13195
  const expiry = entry.delegation.expiry instanceof Date ? entry.delegation.expiry : new Date(entry.delegation.expiry);
13170
13196
  if (expiry.getTime() <= Date.now()) continue;
13171
13197
  try {
13172
- await node.useRuntimeDelegation({ ...entry.delegation, expiry });
13198
+ await node.useRuntimeDelegation({
13199
+ ...entry.delegation,
13200
+ delegationHeader: { Authorization: entry.delegation.delegationHeader.Authorization },
13201
+ expiry
13202
+ });
13173
13203
  } catch (err2) {
13174
13204
  if (process.env.TC_DEBUG_REPLAY === "1") {
13175
13205
  process.stderr.write(`[replay] skipping ${entry.delegation.cid}: ${err2.message}
@@ -13474,6 +13504,7 @@ async function createSDKInstance(ctx, options) {
13474
13504
  host: ctx.host,
13475
13505
  privateKey: effectivePrivateKey
13476
13506
  });
13507
+ let restoredOwnSession2 = false;
13477
13508
  if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
13478
13509
  await node2.restoreSession({
13479
13510
  delegationHeader: session.delegationHeader,
@@ -13486,16 +13517,22 @@ async function createSDKInstance(ctx, options) {
13486
13517
  siwe: session.siwe,
13487
13518
  signature: session.signature
13488
13519
  });
13520
+ restoredOwnSession2 = true;
13489
13521
  } else {
13490
13522
  await node2.signIn();
13491
13523
  }
13492
- await replayAdditionalDelegations(node2, ctx.profile);
13524
+ await replayAdditionalDelegations(node2, ctx.profile, {
13525
+ host: ctx.host,
13526
+ ownerSpace: profile.spaceId,
13527
+ migrate: restoredOwnSession2 && options?.privateKey === void 0
13528
+ });
13493
13529
  return node2;
13494
13530
  }
13495
13531
  const node = new TinyCloudNode({
13496
13532
  host: ctx.host,
13497
13533
  privateKey: options?.privateKey
13498
13534
  });
13535
+ let restoredOwnSession = false;
13499
13536
  if (options?.privateKey) {
13500
13537
  await node.signIn();
13501
13538
  } else if (session && session.delegationHeader && session.delegationCid && session.spaceId) {
@@ -13510,8 +13547,13 @@ async function createSDKInstance(ctx, options) {
13510
13547
  siwe: session.siwe,
13511
13548
  signature: session.signature
13512
13549
  });
13550
+ restoredOwnSession = true;
13513
13551
  }
13514
- await replayAdditionalDelegations(node, ctx.profile);
13552
+ await replayAdditionalDelegations(node, ctx.profile, {
13553
+ host: ctx.host,
13554
+ ownerSpace: profile?.spaceId,
13555
+ migrate: restoredOwnSession
13556
+ });
13515
13557
  return node;
13516
13558
  }
13517
13559
  async function bootstrapDelegatedSession(ctx, delegation) {
@@ -13605,7 +13647,7 @@ async function ensureAuthenticated(ctx, options) {
13605
13647
  }
13606
13648
  const profile = await ProfileManager.getProfile(ctx.profile).catch(() => null);
13607
13649
  if (profile?.authMethod === "local" && profile.privateKey) {
13608
- return createSDKInstance(ctx, { privateKey: profile.privateKey });
13650
+ return createSDKInstance(ctx);
13609
13651
  }
13610
13652
  const session = await ProfileManager.getSession(ctx.profile);
13611
13653
  if (!session) {
@@ -15496,6 +15538,15 @@ function registerAuthCommand(program) {
15496
15538
  return;
15497
15539
  }
15498
15540
  const imported = normalizeDelegationImport(parsed);
15541
+ const { activateUnboundCompactImport, storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
15542
+ const kind = storedDelegationKind({ delegation: imported.delegation });
15543
+ if (kind === "refused") {
15544
+ throw new CLIError(
15545
+ "INVALID_AUTH_IMPORT",
15546
+ "Imported delegation must carry exactly one string Authorization header.",
15547
+ ExitCode.USAGE_ERROR
15548
+ );
15549
+ }
15499
15550
  let node;
15500
15551
  try {
15501
15552
  node = await ensureAuthenticated(ctx);
@@ -15505,18 +15556,33 @@ function registerAuthCommand(program) {
15505
15556
  if (session || resolveProfilePosture(profile) !== "delegate-session") throw error;
15506
15557
  node = (await bootstrapDelegatedSession(ctx, imported.delegation)).node;
15507
15558
  }
15508
- await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
15509
- imported.delegation,
15510
- imported.permissions
15511
- ));
15512
15559
  const targetsSessionKey = typeof imported.delegation.delegateDID === "string" && principalDidEquals(imported.delegation.delegateDID, node.sessionDid);
15513
15560
  let activated = false;
15514
- if (targetsSessionKey) {
15515
- await node.useRuntimeDelegation(imported.delegation);
15561
+ let permissions = imported.permissions;
15562
+ if (targetsSessionKey && kind === "compact") {
15563
+ const record = await activateUnboundCompactImport(
15564
+ node,
15565
+ imported.delegation,
15566
+ ctx.host
15567
+ );
15568
+ await appendAdditionalDelegation(ctx.profile, record);
15569
+ permissions = record.permissions;
15516
15570
  activated = true;
15571
+ } else {
15572
+ await appendAdditionalDelegation(ctx.profile, storedAdditionalDelegation(
15573
+ imported.delegation,
15574
+ imported.permissions
15575
+ ));
15576
+ if (targetsSessionKey) {
15577
+ await node.useRuntimeDelegation({
15578
+ ...imported.delegation,
15579
+ delegationHeader: { Authorization: imported.delegation.delegationHeader.Authorization }
15580
+ });
15581
+ activated = true;
15582
+ }
15517
15583
  }
15518
15584
  await appendGrantHistory(ctx.profile, {
15519
- addedCaps: imported.permissions,
15585
+ addedCaps: permissions,
15520
15586
  source: "cli",
15521
15587
  delegationCid: imported.delegation.cid,
15522
15588
  expiry: imported.delegation.expiry.toISOString()
@@ -15527,7 +15593,7 @@ function registerAuthCommand(program) {
15527
15593
  kind: "tinycloud.auth.delegation",
15528
15594
  requestId: imported.requestId ?? null,
15529
15595
  delegationCid: imported.delegation.cid,
15530
- permissions: imported.permissions,
15596
+ permissions,
15531
15597
  expiry: imported.delegation.expiry.toISOString()
15532
15598
  });
15533
15599
  } catch (error) {
@@ -15901,8 +15967,6 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
15901
15967
  for (const { delegation } of grants) await node.useRuntimeDelegation(delegation);
15902
15968
  if (grants.length === 0) return;
15903
15969
  await ProfileManager.withLock(profileName, async () => {
15904
- const existing = await loadAdditionalDelegations(profileName);
15905
- const replacing = new Set(grants.map(({ delegation }) => delegation.cid));
15906
15970
  for (const { delegation, effective } of grants) {
15907
15971
  await appendGrantHistory(profileName, {
15908
15972
  addedCaps: effective,
@@ -15911,10 +15975,10 @@ async function activateAndStoreOpenKeyGrants(profileName, node, grants, source)
15911
15975
  expiry: delegation.expiry.toISOString()
15912
15976
  });
15913
15977
  }
15914
- await saveAdditionalDelegations(profileName, [
15915
- ...existing.filter(({ delegation }) => !replacing.has(delegation.cid)),
15916
- ...grants.map(({ delegation, effective }) => storedAdditionalDelegation(delegation, effective))
15917
- ]);
15978
+ await appendAdditionalDelegations(
15979
+ profileName,
15980
+ grants.map(({ delegation, effective }) => storedAdditionalDelegation(delegation, effective))
15981
+ );
15918
15982
  });
15919
15983
  }
15920
15984
  async function ensureDelegationAuthority(params) {
@@ -29981,7 +30045,13 @@ async function readHasKey(name, issues) {
29981
30045
  }
29982
30046
  async function readDelegations(name, issues) {
29983
30047
  try {
29984
- return await loadAdditionalDelegations(name);
30048
+ const entries = await loadAdditionalDelegations(name);
30049
+ const { storedDelegationKind } = await import("@tinycloud/operations/delegation-binding");
30050
+ const readable = entries.filter((entry) => storedDelegationKind(entry) !== "refused");
30051
+ if (readable.length < entries.length) {
30052
+ issues.push(`delegations: ${entries.length - readable.length} unreadable stored record(s) skipped`);
30053
+ }
30054
+ return readable;
29985
30055
  } catch (error) {
29986
30056
  issues.push(`delegations: ${messageFromError(error)}`);
29987
30057
  return [];