fix: Codex OAuth 添加代理支持和60秒轮询超时

This commit is contained in:
Yoahoug 2026-01-16 23:04:09 +08:00
parent 3042ccd608
commit a25e22d269
2 changed files with 51 additions and 15 deletions

View file

@ -5,6 +5,7 @@ import axios from 'axios';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import path from 'path'; import path from 'path';
import os from 'os'; import os from 'os';
import { getProxyConfigForProvider } from '../utils/proxy-utils.js';
/** /**
* Codex OAuth 配置 * Codex OAuth 配置
@ -25,9 +26,17 @@ const CODEX_CONFIG = {
export class CodexAuth { export class CodexAuth {
constructor(config) { constructor(config) {
this.config = config; this.config = config;
this.httpClient = axios.create({
timeout: 30000 // 配置代理支持
}); const axiosConfig = { timeout: 30000 };
const proxyConfig = getProxyConfigForProvider(config, 'openai-codex-oauth');
if (proxyConfig) {
axiosConfig.httpAgent = proxyConfig.httpAgent;
axiosConfig.httpsAgent = proxyConfig.httpsAgent;
console.log('[Codex Auth] Proxy enabled for OAuth requests');
}
this.httpClient = axios.create(axiosConfig);
this.server = null; // 存储服务器实例 this.server = null; // 存储服务器实例
} }

View file

@ -2358,6 +2358,13 @@ export async function handleCodexOAuth(currentConfig, options = {}) {
} }
const sessionId = state; // 使用 state 作为 session ID const sessionId = state; // 使用 state 作为 session ID
// 轮询计数器
let pollCount = 0;
const maxPollCount = 60; // 最多轮询 60 次60秒
let pollTimer = null;
let isCompleted = false;
global.codexOAuthSessions.set(sessionId, { global.codexOAuthSessions.set(sessionId, {
auth, auth,
state, state,
@ -2366,8 +2373,35 @@ export async function handleCodexOAuth(currentConfig, options = {}) {
createdAt: Date.now() createdAt: Date.now()
}); });
// 启动轮询日志
pollTimer = setInterval(() => {
pollCount++;
if (pollCount <= maxPollCount && !isCompleted) {
console.log(`[Codex Auth] Waiting for callback... (${pollCount}/${maxPollCount}s)`);
}
if (pollCount >= maxPollCount && !isCompleted) {
clearInterval(pollTimer);
console.log('[Codex Auth] Polling timeout (60s), releasing session for next authorization');
// 清理会话和服务器
if (global.codexOAuthSessions.has(sessionId)) {
const session = global.codexOAuthSessions.get(sessionId);
if (session.server) {
session.server.close();
}
global.codexOAuthSessions.delete(sessionId);
}
}
}, 1000);
// 监听回调服务器的 auth-success 事件,自动完成 OAuth 流程 // 监听回调服务器的 auth-success 事件,自动完成 OAuth 流程
server.once('auth-success', async (result) => { server.once('auth-success', async (result) => {
isCompleted = true;
if (pollTimer) {
clearInterval(pollTimer);
}
try { try {
console.log('[Codex Auth] Received auth callback, completing OAuth flow...'); console.log('[Codex Auth] Received auth callback, completing OAuth flow...');
@ -2410,6 +2444,11 @@ export async function handleCodexOAuth(currentConfig, options = {}) {
// 监听 auth-error 事件 // 监听 auth-error 事件
server.once('auth-error', (error) => { server.once('auth-error', (error) => {
isCompleted = true;
if (pollTimer) {
clearInterval(pollTimer);
}
console.error('[Codex Auth] Auth error:', error.message); console.error('[Codex Auth] Auth error:', error.message);
global.codexOAuthSessions.delete(sessionId); global.codexOAuthSessions.delete(sessionId);
@ -2419,18 +2458,6 @@ export async function handleCodexOAuth(currentConfig, options = {}) {
}); });
}); });
// 10 分钟后自动清理会话
setTimeout(() => {
if (global.codexOAuthSessions.has(sessionId)) {
const session = global.codexOAuthSessions.get(sessionId);
if (session.server) {
session.server.close();
}
global.codexOAuthSessions.delete(sessionId);
console.log('[Codex Auth] Session expired and cleaned up');
}
}, 10 * 60 * 1000);
return { return {
success: true, success: true,
authUrl: authUrl, authUrl: authUrl,