fix: show oauth url and code properly on device auth popup

- Auth flow now waits for user's Enter before starting
- Start auth only when user presses Enter on DeviceAuth popup
- Proper error handling: missing GOOGLE_CLIENT_ID shows clear message
- Error messages displayed in popup with Retry option
- Popup shows instructions before auth, URL+code during auth
- Handle both verification_url and verification_uri field names from Google
- Check HTTP status code and show error_description on failures
- AuthError propagated to render function for display
- Popup border turns green when URL+code are ready
This commit is contained in:
Ruben Rosario
2026-06-20 19:56:41 +01:00
parent 320a9c2572
commit 985e8c9bc9
5 changed files with 138 additions and 61 deletions
+19 -3
View File
@@ -70,6 +70,12 @@ impl ApiClient {
}
pub async fn authenticate(&self) -> Result<(String, String), ApiError> {
if self.client_id.is_empty() {
return Err(ApiError::Auth(
"GOOGLE_CLIENT_ID not set".to_string(),
));
}
let params = serde_json::json!({
"client_id": self.client_id,
"scope": "https://www.googleapis.com/auth/tasks",
@@ -81,16 +87,26 @@ impl ApiClient {
.json(&params)
.send()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
.map_err(|e| ApiError::Network(format!("HTTP request failed: {}", e)))?;
let status = resp.status();
let data: serde_json::Value = resp
.json()
.await
.map_err(|e| ApiError::Network(e.to_string()))?;
.map_err(|e| ApiError::Api(format!("Invalid response (status {}): {}", status, e)))?;
if !status.is_success() {
let err_desc = data["error_description"]
.as_str()
.or_else(|| data["error"].as_str())
.unwrap_or("unknown error");
return Err(ApiError::Api(format!("OAuth error ({}): {}", status, err_desc)));
}
let url = data["verification_url"]
.as_str()
.unwrap_or(&data["verification_url"].to_string())
.or_else(|| data["verification_uri"].as_str())
.unwrap_or("https://www.google.com/device")
.to_string();
let code = data["user_code"]
.as_str()