Files
OmniRoute/src/lib/oauth/providers/codex.js
diegosouzapw 33c28f73db refactor(phase5-6): domain persistence, policy engine, OAuth extraction, proxy decoupling
Phase 5 — Foundation & Security:
- SQLite domain state persistence (5 tables, 4 modules: fallback, budget, lockout, circuit breaker)
- Write-through cache pattern for state survival across restarts
- Race condition fix in route.js (Promise-based singleton)
- Default password hardening (.env.example)
- Server init error handling improvement

Phase 6 — Architecture Refactoring:
- OAuth providers extracted into 12 individual modules (providers.js 1051→144 lines)
- Policy Engine (lockout→budget→fallback) with evaluateRequest/evaluateFirstAllowed
- Deterministic round-robin via persistent counter Map
- Telemetry window fix with proper recordedAt timestamps
- Proxy decoupled from API settings (direct import vs HTTP self-fetch)

Tests: 295 pass (22 new: domain-persistence 16, policy-engine 6)
Docs: CHANGELOG, README, ARCHITECTURE.md updated
2026-02-15 08:12:12 -03:00

54 lines
1.5 KiB
JavaScript

import { CODEX_CONFIG } from "../constants/oauth.js";
export const codex = {
config: CODEX_CONFIG,
flowType: "authorization_code_pkce",
fixedPort: 1455,
callbackPath: "/auth/callback",
buildAuthUrl: (config, redirectUri, state, codeChallenge) => {
const params = {
response_type: "code",
client_id: config.clientId,
redirect_uri: redirectUri,
scope: config.scope,
code_challenge: codeChallenge,
code_challenge_method: config.codeChallengeMethod,
...config.extraParams,
state: state,
};
const queryString = Object.entries(params)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join("&");
return `${config.authorizeUrl}?${queryString}`;
},
exchangeToken: async (config, code, redirectUri, codeVerifier) => {
const response = await fetch(config.tokenUrl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json",
},
body: new URLSearchParams({
grant_type: "authorization_code",
client_id: config.clientId,
code: code,
redirect_uri: redirectUri,
code_verifier: codeVerifier,
}),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Token exchange failed: ${error}`);
}
return await response.json();
},
mapTokens: (tokens) => ({
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
idToken: tokens.id_token,
expiresIn: tokens.expires_in,
}),
};