diff --git a/apps/app/src/routes/auth.sign-in.tsx b/apps/app/src/routes/auth.sign-in.tsx index 254b4db3e5..17ff188878 100644 --- a/apps/app/src/routes/auth.sign-in.tsx +++ b/apps/app/src/routes/auth.sign-in.tsx @@ -1,6 +1,6 @@ -import { SignedOut, useSignIn } from "@clerk/clerk-react"; +import { SignedIn, SignedOut, useSignIn } from "@clerk/clerk-react"; import type { OAuthStrategy } from "@clerk/types"; -import { createFileRoute, LinkProps } from "@tanstack/react-router"; +import { createFileRoute, LinkProps, useNavigate } from "@tanstack/react-router"; import { zodValidator } from "@tanstack/zod-adapter"; import { createURL } from "../utils"; import { schema as connectSchema } from "./auth.connect"; @@ -20,11 +20,12 @@ function Component() { return null; } + const navigate = useNavigate(); const search = Route.useSearch(); const redirectUrl = createURL("/auth/sso-callback", search).toString(); - const redirectUrlComplete = search + const redirectUrlComplete = search?.c ? createURL("/auth/connect", search).toString() : ("/" satisfies LinkProps["to"]); @@ -47,14 +48,13 @@ function Component() {

- Welcome Back + Welcome

-

- Sign in to continue to Hyprnote -

- +

+ Sign in to continue to Hyprnote +

+
+
diff --git a/apps/app/src/routes/auth.sso-callback.tsx b/apps/app/src/routes/auth.sso-callback.tsx index 15423a007f..3534ba34e5 100644 --- a/apps/app/src/routes/auth.sso-callback.tsx +++ b/apps/app/src/routes/auth.sso-callback.tsx @@ -12,7 +12,7 @@ export const Route = createFileRoute("/auth/sso-callback")({ function Component() { const search = Route.useSearch(); - const redirectUrl = search + const redirectUrl = search?.c ? createURL("/auth/connect", search).toString() : ("/" satisfies LinkProps["to"]); diff --git a/apps/desktop/src/routes/login.tsx b/apps/desktop/src/routes/login.tsx index 70d5fe00ee..64bb063eb4 100644 --- a/apps/desktop/src/routes/login.tsx +++ b/apps/desktop/src/routes/login.tsx @@ -3,13 +3,12 @@ import { commands } from "@/types"; import { Trans } from "@lingui/react/macro"; import { useQuery } from "@tanstack/react-query"; import { createFileRoute, useNavigate } from "@tanstack/react-router"; -import { Channel } from "@tauri-apps/api/core"; import { message } from "@tauri-apps/plugin-dialog"; import { open } from "@tauri-apps/plugin-shell"; import { Pause, Play } from "lucide-react"; import { useEffect, useState } from "react"; -import { type AuthEvent, commands as authCommands, type RequestParams } from "@hypr/plugin-auth"; +import { commands as authCommands, events, type RequestParams } from "@hypr/plugin-auth"; import { commands as miscCommands } from "@hypr/plugin-misc"; import { commands as sfxCommands } from "@hypr/plugin-sfx"; import { Button } from "@hypr/ui/components/ui/button"; @@ -33,17 +32,32 @@ function Component() { const navigate = useNavigate(); const [port, setPort] = useState(null); - const [status, setStatus] = useState("Idle"); useEffect(() => { let cleanup: (() => void) | undefined; + let unlisten: (() => void) | undefined; - const channel = new Channel(); - channel.onmessage = setStatus; - - authCommands.startOauthServer(channel).then((port) => { + authCommands.startOauthServer().then((port) => { setPort(port); + + events.authEvent.listen(({ payload }) => { + if (payload === "success") { + commands.setupDb().then(() => { + navigate({ to: "/onboarding", replace: true }); + }); + return; + } + + if (payload.error) { + message("Error occurred while authenticating!"); + return; + } + }).then((fn) => { + unlisten = fn; + }); + cleanup = () => { + unlisten?.(); authCommands.stopOauthServer(port); }; }); @@ -51,20 +65,6 @@ function Component() { return () => cleanup?.(); }, []); - useEffect(() => { - if (status === "Success") { - commands.setupDb().then(() => { - navigate({ to: "/onboarding", replace: true }); - }); - return; - } - - if (status === "Error") { - message("Error occurred while authenticating!"); - return; - } - }, [status]); - const url = useQuery({ queryKey: ["oauth-url", port], enabled: !!port, @@ -124,7 +124,11 @@ function Component() { AI notepad for meetings - + Get Started diff --git a/plugins/auth/js/bindings.gen.ts b/plugins/auth/js/bindings.gen.ts index 89c9f68964..69d5aae383 100644 --- a/plugins/auth/js/bindings.gen.ts +++ b/plugins/auth/js/bindings.gen.ts @@ -7,8 +7,8 @@ export const commands = { -async startOauthServer(channel: TAURI_CHANNEL) : Promise { - return await TAURI_INVOKE("plugin:auth|start_oauth_server", { channel }); +async startOauthServer() : Promise { + return await TAURI_INVOKE("plugin:auth|start_oauth_server"); }, async stopOauthServer(port: number) : Promise { return await TAURI_INVOKE("plugin:auth|stop_oauth_server", { port }); @@ -27,6 +27,11 @@ async getFromStore(key: StoreKey) : Promise { /** user-defined events **/ +export const events = __makeEvents__<{ +authEvent: AuthEvent +}>({ +authEvent: "plugin:auth:auth-event" +}) /** user-defined constants **/ @@ -34,11 +39,10 @@ async getFromStore(key: StoreKey) : Promise { /** user-defined types **/ -export type AuthEvent = "Success" | "Error" +export type AuthEvent = "success" | { error: string } export type RequestParams = { c: string; f: string; p: number } export type ResponseParams = { ui: string; ai: string; st: string; dt: string } export type StoreKey = "auth-user-id" | "auth-account-id" -export type TAURI_CHANNEL = null export type VaultKey = "remote-database" | "remote-server" /** tauri-specta globals **/ diff --git a/plugins/auth/src/commands.rs b/plugins/auth/src/commands.rs index 51502f50bb..a335059233 100644 --- a/plugins/auth/src/commands.rs +++ b/plugins/auth/src/commands.rs @@ -1,12 +1,9 @@ -use crate::{store::StoreKey, vault::VaultKey, AuthEvent, AuthPluginExt}; +use crate::{store::StoreKey, vault::VaultKey, AuthPluginExt}; #[tauri::command] #[specta::specta] -pub fn start_oauth_server( - app: tauri::AppHandle, - channel: tauri::ipc::Channel, -) -> Result { - app.start_oauth_server(channel) +pub fn start_oauth_server(app: tauri::AppHandle) -> Result { + app.start_oauth_server() } #[tauri::command] diff --git a/plugins/auth/src/events.rs b/plugins/auth/src/events.rs new file mode 100644 index 0000000000..bb74bc6559 --- /dev/null +++ b/plugins/auth/src/events.rs @@ -0,0 +1,7 @@ +#[derive(serde::Serialize, Clone, specta::Type, tauri_specta::Event)] +pub enum AuthEvent { + #[serde(rename = "success")] + Success, + #[serde(rename = "error")] + Error(String), +} diff --git a/plugins/auth/src/ext.rs b/plugins/auth/src/ext.rs index 02a9984b0d..4171cbce9b 100644 --- a/plugins/auth/src/ext.rs +++ b/plugins/auth/src/ext.rs @@ -1,20 +1,14 @@ -use tauri::ipc::Channel; +use tauri_specta::Event; use crate::{ - store, - store::StoreKey, + events::AuthEvent, + store::{self, StoreKey}, vault::{Vault, VaultKey}, ResponseParams, CALLBACK_TEMPLATE_KEY, }; -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, specta::Type)] -pub enum AuthEvent { - Success, - Error, -} - pub trait AuthPluginExt { - fn start_oauth_server(&self, channel: Channel) -> Result; + fn start_oauth_server(&self) -> Result; fn stop_oauth_server(&self, port: u16) -> Result<(), String>; fn init_vault(&self, account_id: impl AsRef) -> Result<(), String>; fn reset_vault(&self) -> Result<(), String>; @@ -23,7 +17,8 @@ pub trait AuthPluginExt { } impl> AuthPluginExt for T { - fn start_oauth_server(&self, channel: Channel) -> Result { + fn start_oauth_server(&self) -> Result { + let app = self.app_handle().clone(); let store = store::get_store(self); let env = self.state::().inner().clone(); @@ -70,11 +65,11 @@ impl> AuthPluginExt for T { } store.save().unwrap(); - channel.send(AuthEvent::Success).unwrap(); + AuthEvent::Success.emit(&app).unwrap(); } Err(err) => { tracing::error!(error = ?err, url = ?u, "failed_to_parse_callback_params"); - channel.send(AuthEvent::Error).unwrap(); + AuthEvent::Error(err.to_string()).emit(&app).unwrap(); } } }, @@ -120,7 +115,6 @@ impl> AuthPluginExt for T { #[cfg(test)] mod tests { - use super::*; use crate::RequestParams; #[test] diff --git a/plugins/auth/src/lib.rs b/plugins/auth/src/lib.rs index deb648d4f2..eb08472b3b 100644 --- a/plugins/auth/src/lib.rs +++ b/plugins/auth/src/lib.rs @@ -2,11 +2,13 @@ use tauri::Manager; mod commands; mod error; +mod events; mod ext; mod store; mod vault; pub use error::*; +pub use events::*; pub use ext::*; pub use store::*; pub use vault::*; @@ -21,6 +23,7 @@ const CALLBACK_TEMPLATE_VALUE: &str = include_str!("../templates/callback.jinja" fn make_specta_builder() -> tauri_specta::Builder { tauri_specta::Builder::::new() .plugin_name(PLUGIN_NAME) + .events(tauri_specta::collect_events![events::AuthEvent]) .commands(tauri_specta::collect_commands![ commands::start_oauth_server::, commands::stop_oauth_server::, @@ -38,7 +41,9 @@ pub fn init() -> tauri::plugin::TauriPlugin { tauri::plugin::Builder::new(PLUGIN_NAME) .invoke_handler(specta_builder.invoke_handler()) - .setup(|app, _api| { + .setup(move |app, _api| { + specta_builder.mount_events(app); + let mut env = minijinja::Environment::new(); env.add_template(CALLBACK_TEMPLATE_KEY, CALLBACK_TEMPLATE_VALUE) .unwrap();