atris 3.44.0 → 3.46.0

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/utils/auth.js CHANGED
@@ -407,13 +407,27 @@ async function validateAccessToken(token, apiRequestJson) {
407
407
  });
408
408
  }
409
409
 
410
+ function refreshProviderHint(provider, refreshToken) {
411
+ const hint = typeof provider === 'string' ? provider.trim().toLowerCase() : '';
412
+ if (!hint) return null;
413
+ // provider=google makes /auth/refresh skip app-JWT refresh and POST the
414
+ // minted refresh JWT to Google OAuth, which returns google_refresh_failed.
415
+ // Only send that hint when the stored token is actually a Google OAuth
416
+ // refresh token (they start with 1//). Pack refresh already strips this.
417
+ if (hint === 'google' && !String(refreshToken || '').startsWith('1//')) {
418
+ return null;
419
+ }
420
+ return hint;
421
+ }
422
+
410
423
  async function refreshAccessToken(refreshToken, provider, apiRequestJson) {
411
424
  if (!refreshToken) {
412
425
  return { ok: false, status: 0, error: 'Missing refresh token' };
413
426
  }
414
427
  const body = { refresh_token: refreshToken };
415
- if (provider) {
416
- body.provider = provider;
428
+ const hint = refreshProviderHint(provider, refreshToken);
429
+ if (hint) {
430
+ body.provider = hint;
417
431
  }
418
432
  return apiRequestJson('/auth/refresh', {
419
433
  method: 'POST',
@@ -421,6 +435,24 @@ async function refreshAccessToken(refreshToken, provider, apiRequestJson) {
421
435
  });
422
436
  }
423
437
 
438
+ function isAuthFailure(result) {
439
+ const status = result && result.status;
440
+ return status === 401 || status === 403;
441
+ }
442
+
443
+ function printAuthRequired() {
444
+ console.error('Auth problem. Run: atris login');
445
+ console.error('Check with: atris whoami');
446
+ }
447
+
448
+ function abortOnAuthFailure(result, printedWake = false, exitFn = (code) => process.exit(code)) {
449
+ if (!isAuthFailure(result)) return false;
450
+ if (printedWake) console.log('auth failed');
451
+ printAuthRequired();
452
+ exitFn(1);
453
+ return true;
454
+ }
455
+
424
456
  async function performTokenRefresh(credentials, apiRequestJson) {
425
457
  if (!credentials || !credentials.refresh_token) {
426
458
  return { ok: false, error: 'missing_refresh_token' };
@@ -535,13 +567,24 @@ async function ensureValidCredentials(apiRequestJson, options = {}) {
535
567
  updatedProvider !== credentials.provider ||
536
568
  updatedUserId !== credentials.user_id)
537
569
  ) {
538
- saveCredentials(
539
- credentials.token,
540
- credentials.refresh_token,
541
- updatedEmail,
542
- updatedUserId,
543
- updatedProvider
544
- );
570
+ if (credentials.source_profile) {
571
+ const { source_profile, source, ...rest } = { ...credentials };
572
+ saveProfile(credentials.source_profile, {
573
+ ...rest,
574
+ email: updatedEmail,
575
+ user_id: updatedUserId,
576
+ provider: updatedProvider,
577
+ saved_at: new Date().toISOString(),
578
+ });
579
+ } else {
580
+ saveCredentials(
581
+ credentials.token,
582
+ credentials.refresh_token,
583
+ updatedEmail,
584
+ updatedUserId,
585
+ updatedProvider
586
+ );
587
+ }
545
588
  }
546
589
 
547
590
  return {
@@ -639,8 +682,12 @@ module.exports = {
639
682
  promptUser,
640
683
  validateAccessToken,
641
684
  refreshAccessToken,
685
+ refreshProviderHint,
642
686
  performTokenRefresh,
643
687
  ensureValidCredentials,
688
+ isAuthFailure,
689
+ printAuthRequired,
690
+ abortOnAuthFailure,
644
691
  fetchMyAgents,
645
692
  displayAccountSummary,
646
693
  // Profile switching