diff --git a/extensions/kiro-auth/cli-credentials.ts b/extensions/kiro-auth/cli-credentials.ts index 500418502..3c8ee3171 100644 --- a/extensions/kiro-auth/cli-credentials.ts +++ b/extensions/kiro-auth/cli-credentials.ts @@ -172,26 +172,14 @@ const DEFAULT_EXPIRATION_BUFFER_MS = 5 * 60 * 1000; /** * Checks if a token is expired or about to expire. * - * A token is considered expired if the current time plus the buffer - * is greater than or equal to the expiration time. This ensures we - * don't attempt to use a token that will expire during an operation. + * Note: This checks the access_token expiration. Even if the access token + * is expired, kiro-cli can still work if the refresh_token is valid. + * We use this primarily for informational purposes - kiro-cli handles + * the actual token refresh internally. * * @param token The token to check * @param bufferMs Buffer time before expiration (default: 5 minutes / 300000ms) * @returns true if token is expired or expires within buffer - * - * @example - * ```ts - * const token = extractKiroCliToken(); - * if (token && isTokenExpired(token)) { - * console.log("Token expired, please re-authenticate"); - * } - * - * // With custom buffer (1 minute) - * if (token && isTokenExpired(token, 60000)) { - * console.log("Token expires within 1 minute"); - * } - * ``` */ export function isTokenExpired( token: KiroCliToken, @@ -200,6 +188,24 @@ export function isTokenExpired( const expirationTime = new Date(token.expires_at).getTime(); const currentTime = Date.now(); + // Handle invalid date parsing (NaN) + if (Number.isNaN(expirationTime)) { + // If we can't parse the expiration, assume token is valid + // and let kiro-cli handle the actual validation + return false; + } + // Token is expired if current time + buffer >= expiration time return currentTime + bufferMs >= expirationTime; } + +/** + * Checks if a token has a valid refresh token that kiro-cli can use. + * Even if the access token is expired, kiro-cli can refresh it. + * + * @param token The token to check + * @returns true if the token has a refresh token + */ +export function hasValidRefreshToken(token: KiroCliToken): boolean { + return Boolean(token.refresh_token && token.refresh_token.length > 0); +} diff --git a/extensions/kiro-auth/index.ts b/extensions/kiro-auth/index.ts index 2a7240f5f..2f1472240 100644 --- a/extensions/kiro-auth/index.ts +++ b/extensions/kiro-auth/index.ts @@ -1,6 +1,9 @@ import { emptyPluginConfigSchema } from "clawdbot/plugin-sdk"; -import { extractKiroCliToken, isTokenExpired } from "./cli-credentials.js"; +import { + extractKiroCliToken, + hasValidRefreshToken, +} from "./cli-credentials.js"; import { findKiroCli } from "./cli-detector.js"; const PROVIDER_ID = "kiro-cli"; @@ -60,16 +63,16 @@ const kiroPlugin = { ); } - // Check token not expired - if (isTokenExpired(token)) { - spin.stop("Token expired"); + // Check we have a refresh token (kiro-cli handles access token refresh) + if (!hasValidRefreshToken(token)) { + spin.stop("Invalid credentials"); await ctx.prompter.note( - "Your kiro-cli token has expired.\n" + + "Your kiro-cli credentials are incomplete.\n" + "Run `kiro-cli chat` to re-authenticate.", "Re-authentication required", ); throw new Error( - "kiro-cli token expired. Run `kiro-cli chat` to refresh.", + "kiro-cli credentials incomplete. Run `kiro-cli chat` to refresh.", ); } @@ -101,9 +104,9 @@ const kiroPlugin = { refreshOAuth: async (cred) => { // Re-read token from SQLite - kiro-cli handles the actual OAuth refresh const token = extractKiroCliToken(); - if (!token || isTokenExpired(token)) { + if (!token || !hasValidRefreshToken(token)) { throw new Error( - "kiro-cli token expired. Run `kiro-cli chat` to refresh.", + "kiro-cli credentials invalid. Run `kiro-cli chat` to refresh.", ); } return {