Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions codex-rs/login/src/device_code_auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,26 +137,27 @@ async fn poll_for_token(
}
}

fn print_device_code_prompt(code: &str) {
fn print_device_code_prompt(code: &str, issuer_base_url: &str) {
println!(
"\nWelcome to Codex [v{ANSI_GRAY}{version}{ANSI_RESET}]\n{ANSI_GRAY}OpenAI's command-line coding agent{ANSI_RESET}\n\
\nFollow these steps to sign in with ChatGPT using device code authorization:\n\
\n1. Open this link in your browser and sign in to your account\n {ANSI_BLUE}https://auth.openai.com/codex/device{ANSI_RESET}\n\
\n1. Open this link in your browser and sign in to your account\n {ANSI_BLUE}{issuer_base_url}/codex/device{ANSI_RESET}\n\
\n2. Enter this one-time code {ANSI_GRAY}(expires in 15 minutes){ANSI_RESET}\n {ANSI_BLUE}{code}{ANSI_RESET}\n\
\n{ANSI_GRAY}Device codes are a common phishing target. Never share this code.{ANSI_RESET}\n",
version = env!("CARGO_PKG_VERSION"),
code = code
code = code,
issuer_base_url = issuer_base_url
);
}

/// Full device code login flow.
pub async fn run_device_code_login(opts: ServerOptions) -> std::io::Result<()> {
let client = reqwest::Client::new();
let base_url = opts.issuer.trim_end_matches('/');
let api_base_url = format!("{}/api/accounts", opts.issuer.trim_end_matches('/'));
let issuer_base_url = opts.issuer.trim_end_matches('/');
let api_base_url = format!("{issuer_base_url}/api/accounts");
let uc = request_user_code(&client, &api_base_url, &opts.client_id).await?;

print_device_code_prompt(&uc.user_code);
print_device_code_prompt(&uc.user_code, issuer_base_url);

let code_resp = poll_for_token(
&client,
Expand All @@ -171,10 +172,10 @@ pub async fn run_device_code_login(opts: ServerOptions) -> std::io::Result<()> {
code_verifier: code_resp.code_verifier,
code_challenge: code_resp.code_challenge,
};
let redirect_uri = format!("{base_url}/deviceauth/callback");
let redirect_uri = format!("{issuer_base_url}/deviceauth/callback");

let tokens = crate::server::exchange_code_for_tokens(
base_url,
issuer_base_url,
&opts.client_id,
&redirect_uri,
&pkce,
Expand Down