// Re-export from open-sse with local logger import * as log from "../utils/logger.js"; import { updateProviderConnection } from "../../lib/localDb.js"; import { TOKEN_EXPIRY_BUFFER_MS as BUFFER_MS, refreshAccessToken as _refreshAccessToken, refreshClaudeOAuthToken as _refreshClaudeOAuthToken, refreshGoogleToken as _refreshGoogleToken, refreshQwenToken as _refreshQwenToken, refreshCodexToken as _refreshCodexToken, refreshIflowToken as _refreshIflowToken, refreshGitHubToken as _refreshGitHubToken, refreshCopilotToken as _refreshCopilotToken, getAccessToken as _getAccessToken, refreshTokenByProvider as _refreshTokenByProvider, formatProviderCredentials as _formatProviderCredentials, getAllAccessTokens as _getAllAccessTokens } from "open-sse/services/tokenRefresh.js"; export const TOKEN_EXPIRY_BUFFER_MS = BUFFER_MS; // Wrap functions with local logger export const refreshAccessToken = (provider, refreshToken, credentials) => _refreshAccessToken(provider, refreshToken, credentials, log); export const refreshClaudeOAuthToken = (refreshToken) => _refreshClaudeOAuthToken(refreshToken, log); export const refreshGoogleToken = (refreshToken, clientId, clientSecret) => _refreshGoogleToken(refreshToken, clientId, clientSecret, log); export const refreshQwenToken = (refreshToken) => _refreshQwenToken(refreshToken, log); export const refreshCodexToken = (refreshToken) => _refreshCodexToken(refreshToken, log); export const refreshIflowToken = (refreshToken) => _refreshIflowToken(refreshToken, log); export const refreshGitHubToken = (refreshToken) => _refreshGitHubToken(refreshToken, log); export const refreshCopilotToken = (githubAccessToken) => _refreshCopilotToken(githubAccessToken, log); export const getAccessToken = (provider, credentials) => _getAccessToken(provider, credentials, log); export const refreshTokenByProvider = (provider, credentials) => _refreshTokenByProvider(provider, credentials, log); export const formatProviderCredentials = (provider, credentials) => _formatProviderCredentials(provider, credentials, log); export const getAllAccessTokens = (userInfo) => _getAllAccessTokens(userInfo, log); // Local-specific: Update credentials in localDb export async function updateProviderCredentials(connectionId, newCredentials) { try { const updates = {}; if (newCredentials.accessToken) { updates.accessToken = newCredentials.accessToken; } if (newCredentials.refreshToken) { updates.refreshToken = newCredentials.refreshToken; } if (newCredentials.expiresIn) { updates.expiresAt = new Date(Date.now() + newCredentials.expiresIn * 1000).toISOString(); updates.expiresIn = newCredentials.expiresIn; } if (newCredentials.providerSpecificData) { updates.providerSpecificData = newCredentials.providerSpecificData; } const result = await updateProviderConnection(connectionId, updates); log.info("TOKEN_REFRESH", "Credentials updated in localDb", { connectionId, success: !!result }); return !!result; } catch (error) { log.error("TOKEN_REFRESH", "Error updating credentials in localDb", { connectionId, error: error.message, }); return false; } } // Local-specific: Check and refresh token proactively export async function checkAndRefreshToken(provider, credentials) { let updatedCredentials = { ...credentials }; // Check regular token expiry if (updatedCredentials.expiresAt) { const expiresAt = new Date(updatedCredentials.expiresAt).getTime(); const now = Date.now(); if (expiresAt - now < TOKEN_EXPIRY_BUFFER_MS) { log.info("TOKEN_REFRESH", "Token expiring soon, refreshing proactively", { provider, expiresIn: Math.round((expiresAt - now) / 1000) }); const newCredentials = await getAccessToken(provider, updatedCredentials); if (newCredentials && newCredentials.accessToken) { await updateProviderCredentials(updatedCredentials.connectionId, newCredentials); updatedCredentials = { ...updatedCredentials, accessToken: newCredentials.accessToken, refreshToken: newCredentials.refreshToken || updatedCredentials.refreshToken, expiresAt: newCredentials.expiresIn ? new Date(Date.now() + newCredentials.expiresIn * 1000).toISOString() : updatedCredentials.expiresAt }; } } } // Check GitHub copilot token expiry if (provider === "github" && updatedCredentials.providerSpecificData?.copilotTokenExpiresAt) { const copilotExpiresAt = updatedCredentials.providerSpecificData.copilotTokenExpiresAt * 1000; const now = Date.now(); if (copilotExpiresAt - now < TOKEN_EXPIRY_BUFFER_MS) { log.info("TOKEN_REFRESH", "Copilot token expiring soon, refreshing proactively", { provider, expiresIn: Math.round((copilotExpiresAt - now) / 1000) }); const copilotToken = await refreshCopilotToken(updatedCredentials.accessToken); if (copilotToken) { await updateProviderCredentials(updatedCredentials.connectionId, { providerSpecificData: { ...updatedCredentials.providerSpecificData, copilotToken: copilotToken.token, copilotTokenExpiresAt: copilotToken.expiresAt } }); updatedCredentials.providerSpecificData = { ...updatedCredentials.providerSpecificData, copilotToken: copilotToken.token, copilotTokenExpiresAt: copilotToken.expiresAt }; } } } return updatedCredentials; } // Local-specific: Refresh GitHub and Copilot tokens together export async function refreshGitHubAndCopilotTokens(credentials) { const newGitHubCredentials = await refreshGitHubToken(credentials.refreshToken); if (newGitHubCredentials?.accessToken) { const copilotToken = await refreshCopilotToken(newGitHubCredentials.accessToken); if (copilotToken) { return { ...newGitHubCredentials, providerSpecificData: { copilotToken: copilotToken.token, copilotTokenExpiresAt: copilotToken.expiresAt } }; } } return newGitHubCredentials; }