fix(web):update login cutover flows

This commit is contained in:
Anish Sarkar 2026-06-24 03:55:40 +05:30
parent d2a8d088c7
commit 9fedd0a81f
3 changed files with 14 additions and 27 deletions

View file

@ -11,6 +11,7 @@ import { useRuntimeConfig } from "@/components/providers/runtime-config";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import { getAuthErrorDetails, isNetworkError } from "@/lib/auth-errors"; import { getAuthErrorDetails, isNetworkError } from "@/lib/auth-errors";
import { getPostLoginRedirectPath } from "@/lib/auth-utils";
import { ValidationError } from "@/lib/error"; import { ValidationError } from "@/lib/error";
import { trackLoginAttempt, trackLoginFailure, trackLoginSuccess } from "@/lib/posthog/events"; import { trackLoginAttempt, trackLoginFailure, trackLoginSuccess } from "@/lib/posthog/events";
@ -47,14 +48,9 @@ export function LocalLoginForm() {
// Track successful login // Track successful login
trackLoginSuccess("local"); trackLoginSuccess("local");
// Set flag so TokenHandler knows local login was already tracked
if (typeof window !== "undefined") {
sessionStorage.setItem("login_success_tracked", "true");
}
// Small delay to show success message // Small delay to show success message
setTimeout(() => { setTimeout(() => {
router.push("/auth/callback"); router.push(getPostLoginRedirectPath());
}, 500); }, 500);
} catch (err) { } catch (err) {
if (err instanceof ValidationError) { if (err instanceof ValidationError) {

View file

@ -30,8 +30,7 @@ function LoginContent() {
const logout = searchParams.get("logout"); const logout = searchParams.get("logout");
const returnUrl = searchParams.get("returnUrl"); const returnUrl = searchParams.get("returnUrl");
// Save returnUrl to localStorage so it persists through OAuth flows (e.g., Google) // Save returnUrl for client-side login flows that can redirect directly after success.
// This is read by TokenHandler after successful authentication
if (returnUrl) { if (returnUrl) {
setRedirectPath(decodeURIComponent(returnUrl)); setRedirectPath(decodeURIComponent(returnUrl));
} }

View file

@ -1,12 +1,10 @@
"use client"; "use client";
import { useAtom } from "jotai";
import { Crop, Eye, EyeOff, Rocket, RotateCcw, Zap } from "lucide-react"; import { Crop, Eye, EyeOff, Rocket, RotateCcw, Zap } from "lucide-react";
import Image from "next/image"; import Image from "next/image";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
import { loginMutationAtom } from "@/atoms/auth/auth-mutation.atoms";
import { DEFAULT_SHORTCUTS, keyEventToAccelerator } from "@/components/desktop/shortcut-recorder"; import { DEFAULT_SHORTCUTS, keyEventToAccelerator } from "@/components/desktop/shortcut-recorder";
import { useIsGoogleAuth } from "@/components/providers/runtime-config"; import { useIsGoogleAuth } from "@/components/providers/runtime-config";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
@ -17,7 +15,7 @@ import { ShortcutKbd } from "@/components/ui/shortcut-kbd";
import { Spinner } from "@/components/ui/spinner"; import { Spinner } from "@/components/ui/spinner";
import { useElectronAPI } from "@/hooks/use-platform"; import { useElectronAPI } from "@/hooks/use-platform";
import { searchSpacesApiService } from "@/lib/apis/search-spaces-api.service"; import { searchSpacesApiService } from "@/lib/apis/search-spaces-api.service";
import { setBearerToken, setRefreshToken } from "@/lib/auth-utils"; import { getPostLoginRedirectPath } from "@/lib/auth-utils";
type ShortcutKey = "generalAssist" | "quickAsk" | "screenshotAssist"; type ShortcutKey = "generalAssist" | "quickAsk" | "screenshotAssist";
type ShortcutMap = typeof DEFAULT_SHORTCUTS; type ShortcutMap = typeof DEFAULT_SHORTCUTS;
@ -189,12 +187,12 @@ export default function DesktopLoginPage() {
const router = useRouter(); const router = useRouter();
const api = useElectronAPI(); const api = useElectronAPI();
const isGoogleAuth = useIsGoogleAuth(); const isGoogleAuth = useIsGoogleAuth();
const [{ mutateAsync: login, isPending: isLoggingIn }] = useAtom(loginMutationAtom);
const [email, setEmail] = useState(""); const [email, setEmail] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const [loginError, setLoginError] = useState<string | null>(null); const [loginError, setLoginError] = useState<string | null>(null);
const [isLoggingIn, setIsLoggingIn] = useState(false);
const [isGoogleRedirecting, setIsGoogleRedirecting] = useState(false); const [isGoogleRedirecting, setIsGoogleRedirecting] = useState(false);
const [shortcuts, setShortcuts] = useState(DEFAULT_SHORTCUTS); const [shortcuts, setShortcuts] = useState(DEFAULT_SHORTCUTS);
@ -242,7 +240,7 @@ export default function DesktopLoginPage() {
try { try {
await api?.startGoogleOAuth?.(); await api?.startGoogleOAuth?.();
await autoSetSearchSpace(); await autoSetSearchSpace();
router.push("/auth/callback"); router.push(getPostLoginRedirectPath());
} catch (error) { } catch (error) {
setIsGoogleRedirecting(false); setIsGoogleRedirecting(false);
toast.error(error instanceof Error ? error.message : "Google sign-in failed"); toast.error(error instanceof Error ? error.message : "Google sign-in failed");
@ -265,27 +263,19 @@ export default function DesktopLoginPage() {
const handleLocalLogin = async (e: React.FormEvent) => { const handleLocalLogin = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setLoginError(null); setLoginError(null);
if (isLoggingIn) return;
setIsLoggingIn(true);
try { try {
const data = await login({ if (!api?.loginPassword) {
username: email, throw new Error("Desktop password login is not available");
password,
grant_type: "password",
});
const refreshToken = (data as { refresh_token?: string | null }).refresh_token;
if (typeof window !== "undefined") {
sessionStorage.setItem("login_success_tracked", "true");
} }
await api.loginPassword(email, password);
setBearerToken(data.access_token);
if (refreshToken) {
setRefreshToken(refreshToken);
}
await autoSetSearchSpace(); await autoSetSearchSpace();
setTimeout(() => { setTimeout(() => {
router.push("/auth/callback"); router.push(getPostLoginRedirectPath());
}, 300); }, 300);
} catch (err) { } catch (err) {
if (err instanceof Error) { if (err instanceof Error) {
@ -293,6 +283,8 @@ export default function DesktopLoginPage() {
} else { } else {
setLoginError("Login failed. Please check your credentials."); setLoginError("Login failed. Please check your credentials.");
} }
} finally {
setIsLoggingIn(false);
} }
}; };