mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-04 22:02:16 +02:00
fix(web):update login cutover flows
This commit is contained in:
parent
d2a8d088c7
commit
9fedd0a81f
3 changed files with 14 additions and 27 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue