mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-03 04:42:39 +02:00
refactor: centralize authentication handling
- Replaced direct localStorage token access with a centralized `getBearerToken` function across various components and hooks to improve code maintainability and security. - Updated API calls to use `authenticatedFetch` for consistent authentication handling. - Enhanced user experience by ensuring proper redirection to login when authentication fails. - Cleaned up unused imports and improved overall code structure for better readability.
This commit is contained in:
parent
6cc9e38e1d
commit
b2a97b39ce
35 changed files with 396 additions and 497 deletions
|
|
@ -2,22 +2,25 @@
|
|||
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useEffect } from "react";
|
||||
import { getAndClearRedirectPath, setBearerToken } from "@/lib/auth-utils";
|
||||
|
||||
interface TokenHandlerProps {
|
||||
redirectPath?: string; // Path to redirect after storing token
|
||||
redirectPath?: string; // Default path to redirect after storing token (if no saved path)
|
||||
tokenParamName?: string; // Name of the URL parameter containing the token
|
||||
storageKey?: string; // Key to use when storing in localStorage
|
||||
storageKey?: string; // Key to use when storing in localStorage (kept for backwards compatibility)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* being redirected to login (if available), or to the default redirectPath.
|
||||
*
|
||||
* @param redirectPath - Path to redirect after storing token (default: '/')
|
||||
* @param redirectPath - Default path to redirect after storing token (default: '/dashboard')
|
||||
* @param tokenParamName - Name of the URL parameter containing the token (default: 'token')
|
||||
* @param storageKey - Key to use when storing in localStorage (default: 'auth_token')
|
||||
* @param storageKey - Key to use when storing in localStorage (default: 'surfsense_bearer_token')
|
||||
*/
|
||||
const TokenHandler = ({
|
||||
redirectPath = "/",
|
||||
redirectPath = "/dashboard",
|
||||
tokenParamName = "token",
|
||||
storageKey = "surfsense_bearer_token",
|
||||
}: TokenHandlerProps) => {
|
||||
|
|
@ -33,14 +36,22 @@ const TokenHandler = ({
|
|||
|
||||
if (token) {
|
||||
try {
|
||||
// Store token in localStorage
|
||||
// Store token in localStorage using both methods for compatibility
|
||||
localStorage.setItem(storageKey, token);
|
||||
// console.log(`Token stored in localStorage with key: ${storageKey}`);
|
||||
setBearerToken(token);
|
||||
|
||||
// Redirect to specified path
|
||||
router.push(redirectPath);
|
||||
// Check if there's a saved redirect path from before the auth flow
|
||||
const savedRedirectPath = getAndClearRedirectPath();
|
||||
|
||||
// Use the saved path if available, otherwise use the default redirectPath
|
||||
const finalRedirectPath = savedRedirectPath || redirectPath;
|
||||
|
||||
// Redirect to the appropriate path
|
||||
router.push(finalRedirectPath);
|
||||
} catch (error) {
|
||||
console.error("Error storing token in localStorage:", error);
|
||||
// Even if there's an error, try to redirect to the default path
|
||||
router.push(redirectPath);
|
||||
}
|
||||
}
|
||||
}, [searchParams, tokenParamName, storageKey, redirectPath, router]);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import { useSearchSpace } from "@/hooks/use-search-space";
|
||||
import { authenticatedFetch, getBearerToken } from "@/lib/auth-utils";
|
||||
|
||||
interface BreadcrumbItemInterface {
|
||||
label: string;
|
||||
|
|
@ -41,17 +42,12 @@ export function DashboardBreadcrumb() {
|
|||
useEffect(() => {
|
||||
if (segments[2] === "editor" && segments[3] && searchSpaceId) {
|
||||
const documentId = segments[3];
|
||||
const token =
|
||||
typeof window !== "undefined" ? localStorage.getItem("surfsense_bearer_token") : null;
|
||||
const token = getBearerToken();
|
||||
|
||||
if (token) {
|
||||
fetch(
|
||||
authenticatedFetch(
|
||||
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/search-spaces/${searchSpaceId}/documents/${documentId}/editor-content`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
{ method: "GET" }
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import { Switch } from "@/components/ui/switch";
|
|||
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { type CommunityPrompt, useCommunityPrompts } from "@/hooks/use-community-prompts";
|
||||
import { authenticatedFetch } from "@/lib/auth-utils";
|
||||
|
||||
interface SetupPromptStepProps {
|
||||
searchSpaceId: number;
|
||||
|
|
@ -74,14 +75,11 @@ export function SetupPromptStep({ searchSpaceId, onComplete }: SetupPromptStepPr
|
|||
|
||||
// Only send update if there's something to update
|
||||
if (Object.keys(payload).length > 0) {
|
||||
const response = await fetch(
|
||||
const response = await authenticatedFetch(
|
||||
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
|
||||
},
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { type CommunityPrompt, useCommunityPrompts } from "@/hooks/use-community-prompts";
|
||||
import { useSearchSpace } from "@/hooks/use-search-space";
|
||||
import { authenticatedFetch } from "@/lib/auth-utils";
|
||||
|
||||
interface PromptConfigManagerProps {
|
||||
searchSpaceId: number;
|
||||
|
|
@ -78,14 +79,11 @@ export function PromptConfigManager({ searchSpaceId }: PromptConfigManagerProps)
|
|||
|
||||
// Only send request if we have something to update
|
||||
if (Object.keys(payload).length > 0) {
|
||||
const response = await fetch(
|
||||
const response = await authenticatedFetch(
|
||||
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
|
||||
},
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { getAuthHeaders } from "@/lib/auth-utils";
|
||||
import { GridPattern } from "./GridPattern";
|
||||
|
||||
interface DocumentUploadTabProps {
|
||||
|
|
@ -168,9 +169,7 @@ export function DocumentUploadTab({ searchSpaceId }: DocumentUploadTabProps) {
|
|||
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/fileupload`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${window.localStorage.getItem("surfsense_bearer_token")}`,
|
||||
},
|
||||
headers: getAuthHeaders(),
|
||||
body: formData,
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import {
|
|||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { authenticatedFetch } from "@/lib/auth-utils";
|
||||
|
||||
const youtubeRegex =
|
||||
/^(https:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})$/;
|
||||
|
|
@ -66,14 +67,11 @@ export function YouTubeTab({ searchSpaceId }: YouTubeTabProps) {
|
|||
|
||||
const videoUrls = videoTags.map((tag) => tag.text);
|
||||
|
||||
const response = await fetch(
|
||||
const response = await authenticatedFetch(
|
||||
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents`,
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
|
||||
},
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
document_type: "YOUTUBE_VIDEO",
|
||||
content: videoUrls,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue