diff --git a/gpgui/src-tauri/src/auth.rs b/gpgui/src-tauri/src/auth.rs index 00f753d..2cb9afe 100644 --- a/gpgui/src-tauri/src/auth.rs +++ b/gpgui/src-tauri/src/auth.rs @@ -131,7 +131,7 @@ fn setup_webview( ) -> tauri::Result<()> { window.with_webview(move |wv| { let wv = wv.inner(); - let event_tx = event_tx.clone(); + let event_tx_clone = event_tx.clone(); if clear_cookies { clear_webview_cookies(&wv); @@ -146,25 +146,22 @@ fn setup_webview( // Empty URI indicates that an error occurred if uri.is_empty() { warn!("Empty URI loaded"); - if let Err(err) = event_tx.blocking_send(AuthEvent::Error(AuthError::TokenInvalid)) - { - warn!("Error sending event: {}", err); - } + send_auth_error(&event_tx_clone, AuthError::TokenInvalid); return; } - // TODO, redact URI debug!("Loaded URI: {}", uri); if let Some(main_res) = wv.main_resource() { - parse_auth_data(&main_res, event_tx.clone()); + parse_auth_data(&main_res, event_tx_clone.clone()); } else { warn!("No main_resource"); } }); - wv.connect_load_failed(|_wv, event, err_msg, err| { - warn!("Load failed: {:?}, {}, {:?}", event, err_msg, err); + wv.connect_load_failed(move |_wv, event, _uri, err| { + warn!("Load failed: {:?}, {:?}", event, err); + send_auth_error(&event_tx, AuthError::TokenInvalid); false }); }) @@ -175,9 +172,7 @@ fn setup_window(window: &Window, event_tx: mpsc::Sender) -> EventHand window.on_window_event(move |event| { if let CloseRequested { api, .. } = event { api.prevent_close(); - if let Err(err) = event_tx_clone.blocking_send(AuthEvent::Cancel) { - warn!("Error sending event: {}", err) - } + send_auth_event(&event_tx_clone, AuthEvent::Cancel); } }); @@ -335,9 +330,7 @@ fn parse_auth_data(main_res: &WebResource, event_tx: mpsc::Sender) { } Err(err) => { debug!("Error reading auth data from HTML: {:?}", err); - if let Err(err) = event_tx.blocking_send(AuthEvent::Error(err)) { - warn!("Error sending event: {}", err) - } + send_auth_error(&event_tx, err); } } } @@ -395,7 +388,15 @@ fn parse_xml_tag(html: &str, tag: &str) -> Option { } fn send_auth_data(event_tx: &mpsc::Sender, auth_data: AuthData) { - if let Err(err) = event_tx.blocking_send(AuthEvent::Success(auth_data)) { + send_auth_event(event_tx, AuthEvent::Success(auth_data)); +} + +fn send_auth_error(event_tx: &mpsc::Sender, err: AuthError) { + send_auth_event(event_tx, AuthEvent::Error(err)); +} + +fn send_auth_event(event_tx: &mpsc::Sender, auth_event: AuthEvent) { + if let Err(err) = event_tx.blocking_send(auth_event) { warn!("Error sending event: {}", err) } } diff --git a/gpgui/src/App.tsx b/gpgui/src/App.tsx index 4255a89..5fc4c26 100644 --- a/gpgui/src/App.tsx +++ b/gpgui/src/App.tsx @@ -37,16 +37,16 @@ export default function App() { }, []); useEffect(() => { - authService.onAuthSuccess((data) => {}); authService.onAuthError(async () => { const preloginResponse = await portalService.prelogin(portalAddress); - // Retry SAML login when auth error occurs - authService.emitAuthRequest({ - samlBinding: preloginResponse.samlAuthMethod!, - samlRequest: preloginResponse.samlAuthRequest!, - }); + if (portalService.isSamlAuth(preloginResponse)) { + // Retry SAML login when auth error occurs + await authService.emitAuthRequest({ + samlBinding: preloginResponse.samlAuthMethod, + samlRequest: preloginResponse.samlAuthRequest, + }); + } }); - authService.onAuthCancel(() => {}); }, [portalAddress]); function closeNotification() { @@ -70,18 +70,33 @@ export default function App() { async function handleConnect(e: FormEvent) { e.preventDefault(); - setProcessing(true); + // setProcessing(true); + setStatus("processing"); try { const response = await portalService.prelogin(portalAddress); if (portalService.isSamlAuth(response)) { const { samlAuthMethod, samlAuthRequest } = response; + setStatus("authenticating"); const authData = await authService.samlLogin( samlAuthMethod, samlAuthRequest ); - console.log("authData", authData); + if (!authData) { + throw new Error("User cancelled"); + } + + const portalConfigResponse = await portalService.fetchConfig( + portalAddress, + { + user: authData.username, + "prelogin-cookie": authData.prelogin_cookie, + "portal-userauthcookie": authData.portal_userauthcookie, + } + ); + + console.log("portalConfigResponse", portalConfigResponse); } else if (portalService.isPasswordAuth(response)) { setPasswordAuthOpen(true); setPasswordAuth({ @@ -94,17 +109,17 @@ export default function App() { } } catch (e) { console.error(e); - setProcessing(false); + setStatus("disconnected"); } } function handleCancel() { // TODO cancel the request first - setProcessing(false); + setStatus("disconnected"); } async function handleDisconnect() { - setProcessing(true); + setStatus("processing"); try { await vpnService.disconnect(); @@ -116,18 +131,20 @@ export default function App() { message: err.message, }); } finally { - setProcessing(false); + setStatus("disconnected"); } } - async function handlePasswordAuth({ username, password }: Credentials) { + async function handlePasswordAuth({ + username: user, + password: passwd, + }: Credentials) { try { setPasswordAuthenticating(true); - const portalConfigResponse = await portalService.fetchConfig({ - portal: portalAddress, - username, - password, - }); + const portalConfigResponse = await portalService.fetchConfig( + portalAddress, + { user, passwd } + ); const { gateways, preferredGateway, userAuthCookie } = portalConfigResponse; @@ -139,13 +156,13 @@ export default function App() { const token = await gatewayService.login({ gateway: preferredGateway, - username, - password, + user, + passwd, userAuthCookie, }); await vpnService.connect(preferredGateway.address!, token); - setProcessing(false); + // setProcessing(false); } catch (err: any) { console.error(err); setNotification({ @@ -162,7 +179,8 @@ export default function App() { function cancelPasswordAuth() { setPasswordAuthenticating(false); setPasswordAuthOpen(false); - setProcessing(false); + // setProcessing(false); + setStatus("disconnected"); } return ( @@ -193,10 +211,11 @@ export default function App() { Connect )} - {status === "connecting" && ( + {["processing", "authenticating", "connecting"].includes(status) && (