Spaces:
Configuration error
Configuration error
| /** | |
| * Token Extractor Module | |
| * Extracts OAuth tokens from Antigravity's SQLite database | |
| * | |
| * The database is automatically updated by Antigravity when tokens refresh, | |
| * so this approach doesn't require any manual intervention. | |
| */ | |
| import { | |
| TOKEN_REFRESH_INTERVAL_MS, | |
| ANTIGRAVITY_AUTH_PORT | |
| } from '../constants.js'; | |
| import { getAuthStatus } from './database.js'; | |
| import { logger } from '../utils/logger.js'; | |
| // Cache for the extracted token | |
| let cachedToken = null; | |
| let tokenExtractedAt = null; | |
| /** | |
| * Extract the chat params from Antigravity's HTML page (fallback method) | |
| */ | |
| async function extractChatParams() { | |
| try { | |
| const response = await fetch(`http://127.0.0.1:${ANTIGRAVITY_AUTH_PORT}/`); | |
| const html = await response.text(); | |
| // Find the base64-encoded chatParams in the HTML | |
| const match = html.match(/window\.chatParams\s*=\s*'([^']+)'/); | |
| if (!match) { | |
| throw new Error('Could not find chatParams in Antigravity page'); | |
| } | |
| // Decode base64 | |
| const base64Data = match[1]; | |
| const jsonString = Buffer.from(base64Data, 'base64').toString('utf-8'); | |
| const config = JSON.parse(jsonString); | |
| return config; | |
| } catch (error) { | |
| if (error.code === 'ECONNREFUSED') { | |
| throw new Error( | |
| `Cannot connect to Antigravity on port ${ANTIGRAVITY_AUTH_PORT}. ` + | |
| 'Make sure Antigravity is running.' | |
| ); | |
| } | |
| throw error; | |
| } | |
| } | |
| /** | |
| * Get fresh token data - tries DB first, falls back to HTML page | |
| */ | |
| async function getTokenData() { | |
| // Try database first (preferred - always has fresh token) | |
| try { | |
| const dbData = getAuthStatus(); | |
| if (dbData?.apiKey) { | |
| logger.info('[Token] Got fresh token from SQLite database'); | |
| return dbData; | |
| } | |
| } catch (err) { | |
| logger.warn('[Token] DB extraction failed, trying HTML page...'); | |
| } | |
| // Fallback to HTML page | |
| try { | |
| const pageData = await extractChatParams(); | |
| if (pageData?.apiKey) { | |
| logger.warn('[Token] Got token from HTML page (may be stale)'); | |
| return pageData; | |
| } | |
| } catch (err) { | |
| logger.warn(`[Token] HTML page extraction failed: ${err.message}`); | |
| } | |
| throw new Error( | |
| 'Could not extract token from Antigravity. ' + | |
| 'Make sure Antigravity is running and you are logged in.' | |
| ); | |
| } | |
| /** | |
| * Check if the cached token needs refresh | |
| */ | |
| function needsRefresh() { | |
| if (!cachedToken || !tokenExtractedAt) { | |
| return true; | |
| } | |
| return Date.now() - tokenExtractedAt > TOKEN_REFRESH_INTERVAL_MS; | |
| } | |
| /** | |
| * Get the current OAuth token (with caching) | |
| */ | |
| export async function getToken() { | |
| if (needsRefresh()) { | |
| const data = await getTokenData(); | |
| cachedToken = data.apiKey; | |
| tokenExtractedAt = Date.now(); | |
| } | |
| return cachedToken; | |
| } | |
| /** | |
| * Force refresh the token (useful if requests start failing) | |
| */ | |
| export async function forceRefresh() { | |
| cachedToken = null; | |
| tokenExtractedAt = null; | |
| return getToken(); | |
| } | |
| export default { | |
| getToken, | |
| forceRefresh | |
| }; | |