aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ui/src/stores/auth.svelte.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/stores/auth.svelte.ts')
-rw-r--r--ui/src/stores/auth.svelte.ts54
1 files changed, 51 insertions, 3 deletions
diff --git a/ui/src/stores/auth.svelte.ts b/ui/src/stores/auth.svelte.ts
index 3d58245..eb9dccd 100644
--- a/ui/src/stores/auth.svelte.ts
+++ b/ui/src/stores/auth.svelte.ts
@@ -1,11 +1,14 @@
import { invoke } from "@tauri-apps/api/core";
import { open } from "@tauri-apps/plugin-shell";
+import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import type { Account, DeviceCodeResponse } from "../types";
import { uiState } from "./ui.svelte";
+import { logsState } from "./logs.svelte";
export class AuthState {
currentAccount = $state<Account | null>(null);
isLoginModalOpen = $state(false);
+ isLogoutConfirmOpen = $state(false);
loginMode = $state<"select" | "offline" | "microsoft">("select");
offlineUsername = $state("");
deviceCodeData = $state<DeviceCodeResponse | null>(null);
@@ -14,6 +17,7 @@ export class AuthState {
private pollInterval: ReturnType<typeof setInterval> | null = null;
private isPollingRequestActive = false;
+ private authProgressUnlisten: UnlistenFn | null = null;
async checkAccount() {
try {
@@ -26,15 +30,29 @@ export class AuthState {
openLoginModal() {
if (this.currentAccount) {
- if (confirm("Logout " + this.currentAccount.username + "?")) {
- invoke("logout").then(() => (this.currentAccount = null));
- }
+ // Show custom logout confirmation dialog
+ this.isLogoutConfirmOpen = true;
return;
}
this.resetLoginState();
this.isLoginModalOpen = true;
}
+ cancelLogout() {
+ this.isLogoutConfirmOpen = false;
+ }
+
+ async confirmLogout() {
+ this.isLogoutConfirmOpen = false;
+ try {
+ await invoke("logout");
+ this.currentAccount = null;
+ uiState.setStatus("Logged out successfully");
+ } catch (e) {
+ console.error("Logout failed:", e);
+ }
+ }
+
closeLoginModal() {
this.stopPolling();
this.isLoginModalOpen = false;
@@ -65,6 +83,9 @@ export class AuthState {
this.msLoginStatus = "Waiting for authorization...";
this.stopPolling();
+ // Setup auth progress listener
+ this.setupAuthProgressListener();
+
try {
this.deviceCodeData = (await invoke(
"start_microsoft_login"
@@ -78,6 +99,7 @@ export class AuthState {
}
open(this.deviceCodeData.verification_uri);
+ logsState.addLog("info", "Auth", "Microsoft login started, waiting for browser authorization...");
console.log("Starting polling for token...");
const intervalMs = (this.deviceCodeData.interval || 5) * 1000;
@@ -87,6 +109,7 @@ export class AuthState {
);
}
} catch (e) {
+ logsState.addLog("error", "Auth", `Failed to start Microsoft login: ${e}`);
alert("Failed to start Microsoft login: " + e);
this.loginMode = "select";
} finally {
@@ -94,6 +117,27 @@ export class AuthState {
}
}
+ private async setupAuthProgressListener() {
+ // Clean up previous listener if exists
+ if (this.authProgressUnlisten) {
+ this.authProgressUnlisten();
+ this.authProgressUnlisten = null;
+ }
+
+ this.authProgressUnlisten = await listen<string>("auth-progress", (event) => {
+ const message = event.payload;
+ this.msLoginStatus = message;
+ logsState.addLog("info", "Auth", message);
+ });
+ }
+
+ private cleanupAuthListener() {
+ if (this.authProgressUnlisten) {
+ this.authProgressUnlisten();
+ this.authProgressUnlisten = null;
+ }
+ }
+
stopPolling() {
if (this.pollInterval) {
clearInterval(this.pollInterval);
@@ -113,7 +157,9 @@ export class AuthState {
console.log("Login Successful!", this.currentAccount);
this.stopPolling();
+ this.cleanupAuthListener();
this.isLoginModalOpen = false;
+ logsState.addLog("info", "Auth", `Login successful! Welcome, ${this.currentAccount.username}`);
uiState.setStatus("Welcome back, " + this.currentAccount.username);
} catch (e: any) {
const errStr = e.toString();
@@ -122,12 +168,14 @@ export class AuthState {
} else {
console.error("Polling Error:", errStr);
this.msLoginStatus = "Error: " + errStr;
+ logsState.addLog("error", "Auth", `Login error: ${errStr}`);
if (
errStr.includes("expired_token") ||
errStr.includes("access_denied")
) {
this.stopPolling();
+ this.cleanupAuthListener();
alert("Login failed: " + errStr);
this.loginMode = "select";
}