@tokenoftrust/cli 4.1.0 → 4.2.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/cli",
3
- "version": "4.1.0",
3
+ "version": "4.2.1",
4
4
  "description": "Token of Trust developer CLI — clone a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Token of Trust",
package/src/auth.mjs CHANGED
@@ -173,18 +173,24 @@ export async function resolveDeveloperSession(client, env, deps = {}) {
173
173
  { reason: "expired", hint: developerCredentialRecoveryHint(creds) },
174
174
  );
175
175
  }
176
+ const refreshGrant = { refreshToken: creds.refreshToken, clientId: creds.clientId };
176
177
  let refreshed;
177
- try {
178
- refreshed = await refreshAccessToken(
179
- creds.tokenEndpoint,
180
- { refreshToken: creds.refreshToken, clientId: creds.clientId },
181
- fetchImpl,
182
- );
183
- } catch (e) {
184
- throw new AuthUnavailableError(
185
- "couldn't refresh your Token of Trust session.",
186
- { reason: "refreshFailed", hint: developerCredentialRecoveryHint(creds) },
187
- );
178
+ // One retry: a single token-endpoint failure is not "you are not signed in".
179
+ for (let attempt = 0; attempt < 2; attempt++) {
180
+ try {
181
+ refreshed = await refreshAccessToken(creds.tokenEndpoint, refreshGrant, fetchImpl);
182
+ break;
183
+ } catch {
184
+ if (attempt === 1) {
185
+ throw new AuthUnavailableError(
186
+ "couldn't refresh your Token of Trust session.",
187
+ {
188
+ reason: "refreshFailed",
189
+ hint: `the refresh failed. ${developerCredentialRecoveryHint(creds)}`,
190
+ },
191
+ );
192
+ }
193
+ }
188
194
  }
189
195
  const prior = creds;
190
196
  creds = credentialsFromToken({
@@ -1583,11 +1583,17 @@ export async function run(argv, ctx, {
1583
1583
  const diagnostic = recordDiagnostic(e, {
1584
1584
  command: verb, operation: "session_establish", required: true, degraded: false,
1585
1585
  }, env);
1586
- const note = e instanceof AuthUnavailableError
1587
- ? `Candidate not created: ${e.hint || "developer sign-in is required"}.`
1586
+ const authFailure = e instanceof AuthUnavailableError;
1587
+ const note = authFailure
1588
+ ? `Candidate not created: ${e.reason}: ${e.message}${e.hint ? ` ${e.hint}` : ""}`
1588
1589
  : `Candidate not created: couldn't reach Token of Trust (${describeReadbackError(e)}).`;
1589
1590
  if (!args.json) {
1590
- console.error(fail(note, "run `tot login`, then re-run; no candidate ref was pushed"));
1591
+ // The hint already states the next step. A second line that always says
1592
+ // `tot login` flattens refreshFailed into "you are not signed in".
1593
+ console.error(fail(
1594
+ note,
1595
+ authFailure ? null : "run `tot login`, then re-run; no candidate ref was pushed",
1596
+ ));
1591
1597
  console.error(` → ${diagnosticReference(diagnostic, env)}`);
1592
1598
  }
1593
1599
  emitJson(args, buildJsonResult({