diff --git a/crates/context_server/src/oauth.rs b/crates/context_server/src/oauth.rs index 1a314de2fca9b9987336decb15b208ffd7759dea..44bcbbd557a67f40cbcf7621c52ddbd8d818b9d4 100644 --- a/crates/context_server/src/oauth.rs +++ b/crates/context_server/src/oauth.rs @@ -1107,15 +1107,19 @@ pub async fn start_callback_server() -> Result<( let (status_code, body) = match &result { Ok(_) => ( 200, - "

Authorization successful

\ -

You can close this tab and return to Zed.

", + http_client::oauth_callback_page( + "Authorization Successful", + "You can close this tab and return to Zed.", + ), ), Err(err) => { log::error!("OAuth callback error: {}", err); ( 400, - "

Authorization failed

\ -

Something went wrong. Please try again from Zed.

", + http_client::oauth_callback_page( + "Authorization Failed", + "Something went wrong. Please try again from Zed.", + ), ) } }; diff --git a/crates/http_client/src/http_client.rs b/crates/http_client/src/http_client.rs index bbbe3b1a832332bd6bee693b4c0b916b4f4c182a..b1f097fdac62107f2ba7aa9d571a4688f775fee4 100644 --- a/crates/http_client/src/http_client.rs +++ b/crates/http_client/src/http_client.rs @@ -291,6 +291,92 @@ impl HttpClient for HttpClientWithUrl { } } +/// Generate a styled HTML page for OAuth callback responses. +/// +/// Returns a complete HTML document (no HTTP headers) with a centered card +/// layout styled to match Zed's dark theme. The `title` is rendered as a +/// heading and `message` as body text below it. +pub fn oauth_callback_page(title: &str, message: &str) -> String { + format!( + r#" + + + + +{title} — Zed + + + +
+
+ +
+

{title}

+

{message}

+
Zed
+
+ +"#, + title = title, + message = message, + ) +} + pub fn read_proxy_from_env() -> Option { const ENV_VARS: &[&str] = &[ "ALL_PROXY", diff --git a/crates/language_models/src/provider/openai_subscribed.rs b/crates/language_models/src/provider/openai_subscribed.rs index 8751d8ad32d2be8be8c4b50206e2458aa1d3133e..e8fb7f058710b98c384f8df31575d7f3fbd1bf08 100644 --- a/crates/language_models/src/provider/openai_subscribed.rs +++ b/crates/language_models/src/provider/openai_subscribed.rs @@ -684,11 +684,16 @@ async fn await_oauth_callback(expected_state: &str) -> Result { } } - let html = b"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n\ -

Signed in to Zed

\ -

Authentication successful. You can close this tab.

\ - "; - stream.write_all(html).await.log_err(); + let page = http_client::oauth_callback_page( + "Signed In", + "You've signed into Zed via your ChatGPT subscription. You can close this tab and return to Zed.", + ); + let response = format!( + "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: {}\r\n\r\n{}", + page.len(), + page + ); + stream.write_all(response.as_bytes()).await.log_err(); let received_state = received_state.ok_or_else(|| anyhow!("Missing state in OAuth callback"))?;