mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-26 21:39:43 +02:00
fix(web):update auth token consumers
This commit is contained in:
parent
411bb0019e
commit
71045e552d
4 changed files with 173 additions and 103 deletions
|
|
@ -3,17 +3,18 @@
|
|||
import { useEffect } from "react";
|
||||
import { useGlobalLoadingEffect } from "@/hooks/use-global-loading";
|
||||
import { searchSpacesApiService } from "@/lib/apis/search-spaces-api.service";
|
||||
import { getAndClearRedirectPath, setBearerToken, setRefreshToken } from "@/lib/auth-utils";
|
||||
import { getAndClearRedirectPath } from "@/lib/auth-utils";
|
||||
import { buildBackendUrl } from "@/lib/env-config";
|
||||
import { trackLoginSuccess } from "@/lib/posthog/events";
|
||||
|
||||
interface TokenHandlerProps {
|
||||
redirectPath?: string; // Default path to redirect after storing token (if no saved path)
|
||||
tokenParamName?: string; // Name of the URL parameter containing the token
|
||||
tokenParamName?: string; // Deprecated: tokens are no longer read from URLs
|
||||
}
|
||||
|
||||
/**
|
||||
* Client component that extracts a token from URL parameters and stores it in localStorage
|
||||
* After storing the token, it redirects the user back to the page they were on before
|
||||
* Client component that finalizes a cookie session after OAuth/local login.
|
||||
* After confirming the session, it redirects the user back to the page they were on before
|
||||
* being redirected to login (if available), or to the default redirectPath.
|
||||
*
|
||||
* @param redirectPath - Default path to redirect after storing token (default: '/dashboard')
|
||||
|
|
@ -21,7 +22,7 @@ interface TokenHandlerProps {
|
|||
*/
|
||||
const TokenHandler = ({
|
||||
redirectPath = "/dashboard",
|
||||
tokenParamName = "token",
|
||||
tokenParamName: _tokenParamName = "token",
|
||||
}: TokenHandlerProps) => {
|
||||
// Always show loading for this component - spinner animation won't reset
|
||||
useGlobalLoadingEffect(true);
|
||||
|
|
@ -30,51 +31,47 @@ const TokenHandler = ({
|
|||
if (typeof window === "undefined") return;
|
||||
|
||||
const run = async () => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const token = params.get(tokenParamName);
|
||||
const refreshToken = params.get("refresh_token");
|
||||
|
||||
if (token) {
|
||||
try {
|
||||
const alreadyTracked = sessionStorage.getItem("login_success_tracked");
|
||||
if (!alreadyTracked) {
|
||||
trackLoginSuccess("google");
|
||||
}
|
||||
sessionStorage.removeItem("login_success_tracked");
|
||||
|
||||
setBearerToken(token);
|
||||
|
||||
if (refreshToken) {
|
||||
setRefreshToken(refreshToken);
|
||||
}
|
||||
|
||||
// Auto-set active search space in desktop if not already set
|
||||
if (window.electronAPI?.getActiveSearchSpace) {
|
||||
try {
|
||||
const stored = await window.electronAPI.getActiveSearchSpace();
|
||||
if (!stored) {
|
||||
const spaces = await searchSpacesApiService.getSearchSpaces();
|
||||
if (spaces?.length) {
|
||||
await window.electronAPI.setActiveSearchSpace?.(String(spaces[0].id));
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// non-critical
|
||||
}
|
||||
}
|
||||
|
||||
const savedRedirectPath = getAndClearRedirectPath();
|
||||
const finalRedirectPath = savedRedirectPath || redirectPath;
|
||||
window.location.href = finalRedirectPath;
|
||||
} catch (error) {
|
||||
console.error("Error storing token in localStorage:", error);
|
||||
window.location.href = redirectPath;
|
||||
try {
|
||||
const sessionResponse = await fetch(buildBackendUrl("/auth/session"), {
|
||||
credentials: "include",
|
||||
});
|
||||
if (!sessionResponse.ok) {
|
||||
window.location.href = "/login";
|
||||
return;
|
||||
}
|
||||
|
||||
const alreadyTracked = sessionStorage.getItem("login_success_tracked");
|
||||
if (!alreadyTracked) {
|
||||
trackLoginSuccess("google");
|
||||
}
|
||||
sessionStorage.removeItem("login_success_tracked");
|
||||
|
||||
// Auto-set active search space in desktop if not already set
|
||||
if (window.electronAPI?.getActiveSearchSpace) {
|
||||
try {
|
||||
const stored = await window.electronAPI.getActiveSearchSpace();
|
||||
if (!stored) {
|
||||
const spaces = await searchSpacesApiService.getSearchSpaces();
|
||||
if (spaces?.length) {
|
||||
await window.electronAPI.setActiveSearchSpace?.(String(spaces[0].id));
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// non-critical
|
||||
}
|
||||
}
|
||||
|
||||
const savedRedirectPath = getAndClearRedirectPath();
|
||||
const finalRedirectPath = savedRedirectPath || redirectPath;
|
||||
window.location.href = finalRedirectPath;
|
||||
} catch (error) {
|
||||
console.error("Error finalizing session:", error);
|
||||
window.location.href = redirectPath;
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
}, [tokenParamName, redirectPath]);
|
||||
}, [redirectPath]);
|
||||
|
||||
// Return null - the global provider handles the loading UI
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -2,16 +2,17 @@
|
|||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { getBearerToken } from "@/lib/auth-utils";
|
||||
import { useSession } from "@/hooks/use-session";
|
||||
|
||||
export function AuthRedirect() {
|
||||
const router = useRouter();
|
||||
const session = useSession();
|
||||
|
||||
useEffect(() => {
|
||||
if (getBearerToken()) {
|
||||
if (session.status === "authenticated") {
|
||||
router.replace("/dashboard");
|
||||
}
|
||||
}, [router]);
|
||||
}, [router, session.status]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
"use client";
|
||||
|
||||
import { useAtomValue } from "jotai";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { currentUserAtom } from "@/atoms/user/user-query.atoms";
|
||||
import { useSession } from "@/hooks/use-session";
|
||||
import { isPublicRoute } from "@/lib/auth-utils";
|
||||
import { identifyUser, resetUser } from "@/lib/posthog/events";
|
||||
|
||||
/**
|
||||
|
|
@ -12,7 +15,15 @@ import { identifyUser, resetUser } from "@/lib/posthog/events";
|
|||
*
|
||||
* This should be rendered inside the PostHogProvider.
|
||||
*/
|
||||
export function PostHogIdentify() {
|
||||
function PostHogReset() {
|
||||
useEffect(() => {
|
||||
resetUser();
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function PostHogUserIdentify() {
|
||||
const { data: user, isSuccess, isError } = useAtomValue(currentUserAtom);
|
||||
const previousUserIdRef = useRef<string | null>(null);
|
||||
|
||||
|
|
@ -47,3 +58,27 @@ export function PostHogIdentify() {
|
|||
// This component doesn't render anything
|
||||
return null;
|
||||
}
|
||||
|
||||
function SessionGatedPostHogIdentify() {
|
||||
const session = useSession();
|
||||
|
||||
if (session.status === "loading") {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (session.status === "unauthenticated") {
|
||||
return <PostHogReset />;
|
||||
}
|
||||
|
||||
return <PostHogUserIdentify />;
|
||||
}
|
||||
|
||||
export function PostHogIdentify() {
|
||||
const pathname = usePathname();
|
||||
|
||||
if (isPublicRoute(pathname)) {
|
||||
return <PostHogReset />;
|
||||
}
|
||||
|
||||
return <SessionGatedPostHogIdentify />;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue