UNPKG

chromium-helper

Version:

CLI tool for searching and exploring Chromium source code via Google's official APIs

142 lines • 6 kB
import { chromium } from 'playwright'; import fs from 'fs/promises'; import path from 'path'; import os from 'os'; import chalk from 'chalk'; export class AuthManager { cookieFile; constructor() { // Store cookies in user's home directory this.cookieFile = path.join(os.homedir(), '.gerrit-cookie'); } async authenticate(options = {}) { console.log(chalk.cyan('šŸ” Starting Gerrit authentication...')); console.log(chalk.gray('This will open Chrome for you to sign in to Gerrit.')); // Try to use the user's actual Chrome browser instead of Playwright's Chromium const browser = await chromium.launch({ headless: false, // Always use headed mode for auth channel: 'chrome', // Use real Chrome args: [ '--disable-blink-features=AutomationControlled', '--no-sandbox' ] }); try { const context = await browser.newContext({ // Use a more complete user agent userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', viewport: { width: 1280, height: 800 }, // Don't indicate automation bypassCSP: true }); const page = await context.newPage(); console.log(chalk.yellow('\nšŸ“‹ Please sign in to your Google account in the browser window...')); console.log(chalk.gray('Waiting for you to complete sign-in...')); console.log(chalk.yellow('\nāš ļø If you see a security warning about the browser:')); console.log(chalk.gray('1. Use "ch auth manual" for manual cookie setup instead')); console.log(chalk.gray('2. Or try signing in anyway - sometimes it works after a few attempts')); // Navigate to Gerrit await page.goto('https://chromium-review.googlesource.com'); // Wait for authentication - poll for cookies let authCookie = null; let attempts = 0; const maxAttempts = 60; // 60 seconds timeout while (attempts < maxAttempts) { await page.waitForTimeout(1000); // Wait 1 second between checks // Get all cookies const cookies = await context.cookies(); // Look for key authentication cookies (only need one!) authCookie = cookies.find(cookie => cookie.name === '__Secure-1PSID' || cookie.name === '__Secure-3PSID'); // If we have either key cookie, we're authenticated if (authCookie) { console.log(chalk.green('\nāœ“ Authentication detected!')); break; } attempts++; } if (!authCookie) { // Get all cookies for debugging const allCookies = await context.cookies(); console.log(chalk.red('\nAvailable cookies:')); allCookies.forEach(cookie => { console.log(chalk.gray(` - ${cookie.name}`)); }); throw new Error('Authentication timeout. Could not find required cookie (__Secure-1PSID or __Secure-3PSID).'); } // Just use the found auth cookie - we only need one! const cookieString = `${authCookie.name}=${authCookie.value}`; // Save to file await this.saveCookies(cookieString); console.log(chalk.green(`\nāœ… Authentication successful! Cookies saved to ${this.cookieFile}`)); console.log(chalk.gray('You can now use gerrit list commands without --auth-cookie parameter')); return cookieString; } finally { await browser.close(); } } async getCookies() { try { const cookies = await fs.readFile(this.cookieFile, 'utf-8'); return cookies.trim(); } catch (error) { return null; } } async saveCookies(cookies) { await fs.writeFile(this.cookieFile, cookies, { mode: 0o600 }); // Secure permissions } async clearCookies() { try { await fs.unlink(this.cookieFile); console.log(chalk.yellow('šŸ—‘ļø Cleared saved authentication')); } catch (error) { // File doesn't exist, that's fine } } async checkAuth() { const cookies = await this.getCookies(); if (!cookies) { return false; } // Test if cookies are still valid try { const response = await fetch('https://chromium-review.googlesource.com/changes/?O=1&S=0&n=1', { headers: { 'Cookie': cookies, 'Accept': 'application/json', } }); return response.ok; } catch { return false; } } } // Helper function to get cookies with fallback export async function getAuthCookies(providedCookie) { // If cookie is provided via parameter, use it if (providedCookie) { return providedCookie; } // Otherwise, try to load from saved file const authManager = new AuthManager(); const savedCookies = await authManager.getCookies(); if (savedCookies) { // Verify they're still valid const isValid = await authManager.checkAuth(); if (isValid) { return savedCookies; } console.log(chalk.yellow('āš ļø Saved authentication has expired')); } throw new Error('No authentication found. Please run:\n' + chalk.cyan(' ch auth manual') + ' (recommended)\n' + chalk.cyan(' ch auth login') + ' (may be blocked by Google)\n' + 'Or provide cookie with --auth-cookie parameter'); } //# sourceMappingURL=auth.js.map