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) {
const expiresAt = new Date(credentials.expiresAt);
const now = new Date();
const hoursRemaining = Math.floor(
(expiresAt.getTime() - now.getTime()) / (1000 * 60 * 60)
);
const timeRemaining = expiresAt.getTime() - now.getTime();
const hoursRemaining = Math.floor(timeRemaining / (1000 * 60 * 60));
const minutesRemaining = Math.floor(timeRemaining / (1000 * 60));
if (timeRemaining > 0) {
// Token is still valid
if (hoursRemaining > 0) {
console.log(
chalk.gray(
` Expires: ${expiresAt.toLocaleString()} (${hoursRemaining} hours remaining)`
` Expires at: ${expiresAt.toLocaleString()} (${hoursRemaining} hours remaining)`
)
);
} else {
console.log(
chalk.yellow(` Token expired at: ${expiresAt.toLocaleString()}`)
chalk.gray(
` Expires at: ${expiresAt.toLocaleString()} (${minutesRemaining} minutes remaining)`
)
);
}
} else {
// Token has expired
console.log(
chalk.yellow(` Expired at: ${expiresAt.toLocaleString()}`)
);
}
} else {

View File

@@ -90,8 +90,21 @@ export class AuthManager {
allowExpired: true
});
// Only attempt refresh if we have expired credentials with a refresh token
if (expiredCredentials && expiredCredentials.refreshToken) {
// Check if we have any credentials at all
if (!expiredCredentials) {
// No credentials found
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();
@@ -101,9 +114,6 @@ export class AuthManager {
}
}
return null;
}
return credentials;
}

View File

@@ -199,6 +199,26 @@ describe('AuthManager - Token Auto-Refresh Integration', () => {
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', () => {