chore: quality of life improvements

This commit is contained in:
Ralph Khreish
2025-10-12 19:22:14 +02:00
parent 0dfb33b402
commit e2e3e6f748
3 changed files with 60 additions and 20 deletions

View File

@@ -187,19 +187,29 @@ export class AuthCommand extends Command {
if (credentials.expiresAt) { if (credentials.expiresAt) {
const expiresAt = new Date(credentials.expiresAt); const expiresAt = new Date(credentials.expiresAt);
const now = new Date(); const now = new Date();
const hoursRemaining = Math.floor( const timeRemaining = expiresAt.getTime() - now.getTime();
(expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60) const hoursRemaining = Math.floor(timeRemaining / (1000 * 60 * 60));
); const minutesRemaining = Math.floor(timeRemaining / (1000 * 60));
if (hoursRemaining > 0) { if (timeRemaining > 0) {
console.log( // Token is still valid
chalk.gray( if (hoursRemaining > 0) {
` Expires: ${expiresAt.toLocaleString()} (${hoursRemaining} hours remaining)` console.log(
) chalk.gray(
); ` Expires at: ${expiresAt.toLocaleString()} (${hoursRemaining} hours remaining)`
)
);
} else {
console.log(
chalk.gray(
` Expires at: ${expiresAt.toLocaleString()} (${minutesRemaining} minutes remaining)`
)
);
}
} else { } else {
// Token has expired
console.log( console.log(
chalk.yellow(` Token expired at: ${expiresAt.toLocaleString()}`) chalk.yellow(` Expired at: ${expiresAt.toLocaleString()}`)
); );
} }
} else { } else {

View File

@@ -90,18 +90,28 @@ export class AuthManager {
allowExpired: true allowExpired: true
}); });
// Only attempt refresh if we have expired credentials with a refresh token // Check if we have any credentials at all
if (expiredCredentials && expiredCredentials.refreshToken) { if (!expiredCredentials) {
try { // No credentials found
this.logger.info('Token expired, attempting automatic refresh...'); return null;
return await this.refreshToken();
} catch (error) {
this.logger.warn('Automatic token refresh failed:', error);
return null;
}
} }
return null; // Check if refresh token is available
if (!expiredCredentials.refreshToken) {
this.logger.warn(
'Token expired but no refresh token available. Please re-authenticate.'
);
return null;
}
// Attempt refresh
try {
this.logger.info('Token expired, attempting automatic refresh...');
return await this.refreshToken();
} catch (error) {
this.logger.warn('Automatic token refresh failed:', error);
return null;
}
} }
return credentials; return credentials;

View File

@@ -199,6 +199,26 @@ describe('AuthManager - Token Auto-Refresh Integration', () => {
expect(credentials).toBeNull(); expect(credentials).toBeNull();
}); });
it('should return null if credentials missing expiresAt', async () => {
const credentialsWithoutExpiry: AuthCredentials = {
token: 'test-token',
refreshToken: 'refresh-token',
userId: 'test-user-id',
email: 'test@example.com',
// Missing expiresAt
savedAt: new Date().toISOString()
} as any;
credentialStore.saveCredentials(credentialsWithoutExpiry);
authManager = AuthManager.getInstance();
const credentials = await authManager.getCredentials();
// Should return null because no valid expiration
expect(credentials).toBeNull();
});
}); });
describe('Clock Skew Tolerance', () => { describe('Clock Skew Tolerance', () => {