Cleanup rust login server a bit more (#2331)

Remove some extra abstractions.

---------

Co-authored-by: easong-openai <easong@openai.com>
This commit is contained in:
pakrym-oai
2025-08-14 19:42:14 -07:00
committed by GitHub
parent d0b907d399
commit 76df07350a
5 changed files with 208 additions and 283 deletions

View File

@@ -1,3 +1,6 @@
use codex_login::CLIENT_ID;
use codex_login::ServerOptions;
use codex_login::run_login_server;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use ratatui::buffer::Buffer;
@@ -22,6 +25,10 @@ use crate::onboarding::onboarding_screen::KeyboardHandler;
use crate::onboarding::onboarding_screen::StepStateProvider;
use crate::shimmer::shimmer_spans;
use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::thread::JoinHandle;
use super::onboarding_screen::StepState;
// no additional imports
@@ -39,12 +46,14 @@ pub(crate) enum SignInState {
#[derive(Debug)]
/// Used to manage the lifecycle of SpawnedLogin and ensure it gets cleaned up.
pub(crate) struct ContinueInBrowserState {
login_child: Option<codex_login::SpawnedLogin>,
auth_url: String,
shutdown_flag: Option<Arc<AtomicBool>>,
_login_wait_handle: Option<JoinHandle<()>>,
}
impl Drop for ContinueInBrowserState {
fn drop(&mut self) {
if let Some(child) = &self.login_child {
child.cancel();
if let Some(flag) = &self.shutdown_flag {
flag.store(true, Ordering::SeqCst);
}
}
}
@@ -184,16 +193,12 @@ impl AuthModeWidget {
let mut lines = vec![Line::from(spans), Line::from("")];
if let SignInState::ChatGptContinueInBrowser(state) = &self.sign_in_state {
if let Some(url) = state
.login_child
.as_ref()
.and_then(|child| child.get_login_url())
{
if !state.auth_url.is_empty() {
lines.push(Line::from(" If the link doesn't open automatically, open the following link to authenticate:"));
lines.push(Line::from(vec![
Span::raw(" "),
Span::styled(
url,
state.auth_url.as_str(),
Style::default()
.fg(LIGHT_BLUE)
.add_modifier(Modifier::UNDERLINED),
@@ -289,12 +294,17 @@ impl AuthModeWidget {
fn start_chatgpt_login(&mut self) {
self.error = None;
match codex_login::spawn_login_with_chatgpt(&self.codex_home) {
let opts = ServerOptions::new(self.codex_home.clone(), CLIENT_ID.to_string());
let server = run_login_server(opts, None);
match server {
Ok(child) => {
self.spawn_completion_poller(child.clone());
let auth_url = child.auth_url.clone();
let shutdown_flag = child.shutdown_flag.clone();
self.sign_in_state =
SignInState::ChatGptContinueInBrowser(ContinueInBrowserState {
login_child: Some(child),
auth_url,
shutdown_flag: Some(shutdown_flag),
_login_wait_handle: Some(self.spawn_completion_poller(child)),
});
self.event_tx.send(AppEvent::RequestRedraw);
}
@@ -316,23 +326,17 @@ impl AuthModeWidget {
self.event_tx.send(AppEvent::RequestRedraw);
}
fn spawn_completion_poller(&self, child: codex_login::SpawnedLogin) {
fn spawn_completion_poller(&self, child: codex_login::LoginServer) -> JoinHandle<()> {
let event_tx = self.event_tx.clone();
std::thread::spawn(move || {
loop {
if let Some(success) = child.get_auth_result() {
if success {
event_tx.send(AppEvent::OnboardingAuthComplete(Ok(())));
} else {
event_tx.send(AppEvent::OnboardingAuthComplete(Err(
"login failed".to_string()
)));
}
break;
}
std::thread::sleep(std::time::Duration::from_millis(250));
if let Ok(()) = child.block_until_done() {
event_tx.send(AppEvent::OnboardingAuthComplete(Ok(())));
} else {
event_tx.send(AppEvent::OnboardingAuthComplete(Err(
"login failed".to_string()
)));
}
});
})
}
}