| 40 | export const CODEX_OAUTH_DEVICE_VERIFY_URL = `${CODEX_OAUTH_ORIGIN}/codex/device`; |
| 41 | |
| 42 | export function buildCodexAuthorizeUrl(input: { |
| 43 | redirectUri: string; |
| 44 | state: string; |
| 45 | codeChallenge: string; |
| 46 | }): string { |
| 47 | const url = new URL(CODEX_OAUTH_AUTHORIZE_URL); |
| 48 | url.searchParams.set("response_type", "code"); |
| 49 | url.searchParams.set("client_id", CODEX_OAUTH_CLIENT_ID); |
| 50 | url.searchParams.set("redirect_uri", input.redirectUri); |
| 51 | url.searchParams.set("scope", CODEX_OAUTH_SCOPE); |
| 52 | url.searchParams.set("state", input.state); |
| 53 | url.searchParams.set("code_challenge", input.codeChallenge); |
| 54 | url.searchParams.set("code_challenge_method", "S256"); |
| 55 | |
| 56 | // Extra authorize params required by the Codex flow. |
| 57 | url.searchParams.set("id_token_add_organizations", "true"); |
| 58 | url.searchParams.set("codex_cli_simplified_flow", "true"); |
| 59 | url.searchParams.set("originator", "mux"); |
| 60 | |
| 61 | return url.toString(); |
| 62 | } |
| 63 | |
| 64 | export function buildCodexTokenExchangeBody(input: { |
| 65 | code: string; |