mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-03 13:52:09 +03:00
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
54 lines
1.5 KiB
JavaScript
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,
|
|
}),
|
|
};
|