refactor: migrate OAuth result handling from sessionStorage to cookies and update connector callback implementation

- Removed the ConnectorCallbackPage component and replaced it with a route handler that sets the OAuth result in a cookie.
- Updated the useConnectorDialog hook to read from the cookie instead of sessionStorage, ensuring a more consistent state management approach.
This commit is contained in:
Anish Sarkar 2026-03-18 17:00:54 +05:30
parent 8baba0693d
commit 95f11521c3
3 changed files with 52 additions and 38 deletions

View file

@ -1,34 +0,0 @@
"use client";
import { useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { Spinner } from "@/components/ui/spinner";
const OAUTH_RESULT_KEY = "connector_oauth_result";
export default function ConnectorCallbackPage({
params,
}: {
params: { search_space_id: string };
}) {
const router = useRouter();
const searchParams = useSearchParams();
useEffect(() => {
const result = {
success: searchParams.get("success"),
error: searchParams.get("error"),
connector: searchParams.get("connector"),
connectorId: searchParams.get("connectorId"),
};
sessionStorage.setItem(OAUTH_RESULT_KEY, JSON.stringify(result));
router.replace(`/dashboard/${params.search_space_id}/new-chat`);
}, [searchParams, router, params.search_space_id]);
return (
<div className="flex items-center justify-center h-screen">
<Spinner size="lg" />
</div>
);
}

View file

@ -0,0 +1,33 @@
import { type NextRequest, NextResponse } from "next/server";
const OAUTH_RESULT_COOKIE = "connector_oauth_result";
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ search_space_id: string }> }
) {
const { search_space_id } = await params;
const searchParams = request.nextUrl.searchParams;
const result = JSON.stringify({
success: searchParams.get("success"),
error: searchParams.get("error"),
connector: searchParams.get("connector"),
connectorId: searchParams.get("connectorId"),
});
const redirectUrl = new URL(
`/dashboard/${search_space_id}/new-chat`,
request.url
);
const response = NextResponse.redirect(redirectUrl, { status: 302 });
response.cookies.set(OAUTH_RESULT_COOKIE, result, {
path: "/",
maxAge: 60,
httpOnly: false,
sameSite: "lax",
});
return response;
}

View file

@ -40,7 +40,19 @@ import {
validateIndexingConfigState,
} from "../constants/connector-popup.schemas";
const OAUTH_RESULT_KEY = "connector_oauth_result";
const OAUTH_RESULT_COOKIE = "connector_oauth_result";
function readOAuthResultCookie(): string | null {
const match = document.cookie
.split("; ")
.find((row) => row.startsWith(`${OAUTH_RESULT_COOKIE}=`));
return match ? decodeURIComponent(match.split("=").slice(1).join("=")) : null;
}
function clearOAuthResultCookie(): void {
// biome-ignore lint: only standard way to expire a cookie
document.cookie = `${OAUTH_RESULT_COOKIE}=; path=/; max-age=0`;
}
export const useConnectorDialog = () => {
const searchSpaceId = useAtomValue(activeSearchSpaceIdAtom);
@ -188,11 +200,11 @@ export const useConnectorDialog = () => {
// Track whether the current indexing config came from an OAuth redirect
const [isFromOAuth, setIsFromOAuth] = useState(false);
// Consume OAuth result from sessionStorage (set by /connectors/callback page)
// Consume OAuth result from cookie (set by /connectors/callback route handler)
useEffect(() => {
const raw = sessionStorage.getItem(OAUTH_RESULT_KEY);
const raw = readOAuthResultCookie();
if (!raw || !searchSpaceId) return;
sessionStorage.removeItem(OAUTH_RESULT_KEY);
clearOAuthResultCookie();
let result: {
success: string | null;
@ -1188,6 +1200,9 @@ export const useConnectorDialog = () => {
setConnectorName(null);
setConnectorConfig(null);
} else {
setEditingConnector(null);
setConnectorName(null);
setConnectorConfig(null);
setIsOpen(false);
}