summary refs log tree commit diff
path: root/app/src/oauth.rs
diff options
context:
space:
mode:
authorAshelyn Rose <git@ashen.earth>2025-02-19 16:29:34 -0700
committerAshelyn Rose <git@ashen.earth>2025-02-19 16:29:34 -0700
commit5c6a049c4c962be7bf889897b16a1778bbe63819 (patch)
tree2068b9446594264c10b37fedbf57ccd39ef3e81d /app/src/oauth.rs
parent665a4904f89bb842a7ba211abdda62349eac8a03 (diff)
Refactor: Simplify oauth callback handling
Diffstat (limited to 'app/src/oauth.rs')
-rw-r--r--app/src/oauth.rs29
1 files changed, 27 insertions, 2 deletions
diff --git a/app/src/oauth.rs b/app/src/oauth.rs
index 9334eac..657db30 100644
--- a/app/src/oauth.rs
+++ b/app/src/oauth.rs
@@ -3,6 +3,7 @@ use serde::Deserialize;
 use tauri::async_runtime::RuntimeHandle;
 use tokio::sync::Mutex;
 use tokio::sync::oneshot::{channel, Sender, Receiver};
+use url::{Host, Url};
 use uuid::Uuid;
 
 use crate::OAUTH_CLIENT_NAME;
@@ -58,6 +59,31 @@ impl OAuthController {
         })), runtime_handle)
     }
 
+    pub fn handle_deeplink(&self, urls: &Vec<Url>) -> Option<()> {
+        let matching_url = urls.iter().find(|url| url.domain().is_some_and(|d| d == "oauth-response"));
+        let mut query_pairs = matching_url?.query_pairs();
+
+        let code_and_state = (
+            query_pairs.find(|(key, _)| key == "code").map(|(_, value)| value ),
+            query_pairs.find(|(key, _)| key == "state").map(|(_, value)| value )
+        );
+
+        let has_code_and_state = match code_and_state {
+            (Some(code), Some(state)) => Some((code.to_string(), state.to_string())),
+            _ => None,
+        };
+
+        let (auth_code, state) = has_code_and_state?;
+        let state = Uuid::try_parse(&state).map_err(|_| {
+            println!("Could not parse state field from oauth callback: {state}");
+            ()
+        }).ok()?;
+
+        self.resolve_code(state, auth_code);
+        Some(())
+    }
+
+
     pub async fn add_server(&self, instance_domain: &str) -> Result<AddServerResult, String> {
         let registration_endpoint = format!("https://{instance_domain}/api/v1/apps");
         let http_client = reqwest::Client::builder().user_agent("Foxfleet v0.0.1").build().expect("Could not construct client");
@@ -110,10 +136,9 @@ impl OAuthController {
         })
     }
 
-    pub fn resolve_code(&self, state: StateCode, auth_code: String) {
+    fn resolve_code(&self, state: StateCode, auth_code: String) {
         let runtime = self.1.clone();
         let inner_self = self.0.clone();
-        let state = state.clone();
 
         runtime.spawn(async move {
             if let Some(sender) = inner_self.lock().await.open_callbacks.get_mut(&state).map(|callback| callback.code_channel.0.take() ).flatten() {