diff --git a/surfsense_backend/.env.example b/surfsense_backend/.env.example
index 63b49639c..4a47542aa 100644
--- a/surfsense_backend/.env.example
+++ b/surfsense_backend/.env.example
@@ -28,6 +28,10 @@ NEXT_FRONTEND_URL=http://localhost:3000
AUTH_TYPE=LOCAL
REGISTRATION_ENABLED=TRUE or FALSE
+# CORS Configuration (comma-separated list of allowed origins)
+# Use * to allow all origins, or specify domains like: https://example.com,https://app.example.com
+CORS_ORIGINS=*
+
# Google OAuth Credentials (OPTIONAL - Required only for Gmail and Google Calendar connectors)
GOOGLE_OAUTH_CLIENT_ID=your_google_client_id
GOOGLE_OAUTH_CLIENT_SECRET=your_google_client_secret
diff --git a/surfsense_backend/app/app.py b/surfsense_backend/app/app.py
index ed0269bed..231f99e46 100644
--- a/surfsense_backend/app/app.py
+++ b/surfsense_backend/app/app.py
@@ -50,7 +50,7 @@ app.add_middleware(ProxyHeadersMiddleware, trusted_hosts="*")
# Add CORS middleware
app.add_middleware(
CORSMiddleware,
- allow_origins=["https://ai.kapteinis.lv"], # Only allow our domain
+ allow_origins=config.CORS_ORIGINS, # Configurable via CORS_ORIGINS env var
allow_credentials=True,
allow_methods=["*"], # Allows all methods
allow_headers=["*"], # Allows all headers
diff --git a/surfsense_backend/app/config/__init__.py b/surfsense_backend/app/config/__init__.py
index 7d06643e1..df2744f4d 100644
--- a/surfsense_backend/app/config/__init__.py
+++ b/surfsense_backend/app/config/__init__.py
@@ -135,6 +135,11 @@ class Config:
AUTH_TYPE = os.getenv("AUTH_TYPE")
REGISTRATION_ENABLED = os.getenv("REGISTRATION_ENABLED", "TRUE").upper() == "TRUE"
+ # CORS Configuration
+ # Comma-separated list of allowed origins, defaults to all origins if not set
+ _cors_origins_str = os.getenv("CORS_ORIGINS", "*")
+ CORS_ORIGINS = [origin.strip() for origin in _cors_origins_str.split(",") if origin.strip()]
+
# Google OAuth
GOOGLE_OAUTH_CLIENT_ID = os.getenv("GOOGLE_OAUTH_CLIENT_ID")
GOOGLE_OAUTH_CLIENT_SECRET = os.getenv("GOOGLE_OAUTH_CLIENT_SECRET")
diff --git a/surfsense_web/app/auth/callback/page.tsx b/surfsense_web/app/auth/callback/page.tsx
index da868c316..0589df374 100644
--- a/surfsense_web/app/auth/callback/page.tsx
+++ b/surfsense_web/app/auth/callback/page.tsx
@@ -1,5 +1,6 @@
import { Suspense } from "react";
import TokenHandler from "@/components/TokenHandler";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export default function AuthCallbackPage() {
return (
@@ -15,7 +16,7 @@ export default function AuthCallbackPage() {
diff --git a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/airtable-connector/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/airtable-connector/page.tsx
index 2d82877b3..bf22572be 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/airtable-connector/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/airtable-connector/page.tsx
@@ -22,6 +22,7 @@ import {
type SearchSourceConnector,
useSearchSourceConnectors,
} from "@/hooks/use-search-source-connectors";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export default function AirtableConnectorPage() {
const router = useRouter();
@@ -51,7 +52,7 @@ export default function AirtableConnectorPage() {
{
method: "GET",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
diff --git a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/github-connector/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/github-connector/page.tsx
index 90a02a5f2..536db22c8 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/github-connector/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/github-connector/page.tsx
@@ -38,6 +38,7 @@ import { Input } from "@/components/ui/input";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { EnumConnectorName } from "@/contracts/enums/connector";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
// Assuming useSearchSourceConnectors hook exists and works similarly
import { useSearchSourceConnectors } from "@/hooks/use-search-source-connectors";
@@ -101,7 +102,7 @@ export default function GithubConnectorPage() {
setConnectorName(values.name); // Store the name
setValidatedPat(values.github_pat); // Store the PAT temporarily
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
}
diff --git a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-calendar-connector/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-calendar-connector/page.tsx
index 2fdc95671..b7a45db39 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-calendar-connector/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-calendar-connector/page.tsx
@@ -24,6 +24,7 @@ import {
type SearchSourceConnector,
useSearchSourceConnectors,
} from "@/hooks/use-search-source-connectors";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export default function GoogleCalendarConnectorPage() {
const router = useRouter();
@@ -56,7 +57,7 @@ export default function GoogleCalendarConnectorPage() {
{
method: "GET",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
diff --git a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-gmail-connector/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-gmail-connector/page.tsx
index c1354d03e..88856a200 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-gmail-connector/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/connectors/add/google-gmail-connector/page.tsx
@@ -24,6 +24,7 @@ import {
type SearchSourceConnector,
useSearchSourceConnectors,
} from "@/hooks/use-search-source-connectors";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export default function GoogleGmailConnectorPage() {
const router = useRouter();
@@ -55,7 +56,7 @@ export default function GoogleGmailConnectorPage() {
{
method: "GET",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
diff --git a/surfsense_web/app/dashboard/[search_space_id]/documents/webpage/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/documents/webpage/page.tsx
index 0f78bad7c..9da3ad927 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/documents/webpage/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/documents/webpage/page.tsx
@@ -16,6 +16,7 @@ import {
CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
// URL validation regex - updated to support percent-encoded URLs (e.g., Latvian characters)
const urlRegex = /^https?:\/\/[^\s]+$/;
@@ -69,7 +70,7 @@ export default function WebpageCrawler() {
method: "POST",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify({
document_type: "CRAWLED_URL",
diff --git a/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
index 099909515..8d5bb6c8f 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/onboard/page.tsx
@@ -12,6 +12,7 @@ import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { useGlobalLLMConfigs, useLLMConfigs, useLLMPreferences } from "@/hooks/use-llm-configs";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
const TOTAL_STEPS = 2;
@@ -38,7 +39,7 @@ const OnboardPage = () => {
// Check if user is authenticated
useEffect(() => {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
router.push("/login");
return;
diff --git a/surfsense_web/app/dashboard/layout.tsx b/surfsense_web/app/dashboard/layout.tsx
index bafe7a0cc..0f3b0ddb0 100644
--- a/surfsense_web/app/dashboard/layout.tsx
+++ b/surfsense_web/app/dashboard/layout.tsx
@@ -6,6 +6,7 @@ import { useEffect, useState } from "react";
import { AnnouncementBanner } from "@/components/announcement-banner";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { baseApiService } from "@/lib/apis/base-api.service";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface DashboardLayoutProps {
children: React.ReactNode;
@@ -17,7 +18,7 @@ export default function DashboardLayout({ children }: DashboardLayoutProps) {
useEffect(() => {
// Check if user is authenticated
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
router.push("/login");
return;
diff --git a/surfsense_web/app/dashboard/page.tsx b/surfsense_web/app/dashboard/page.tsx
index d61e714c6..a2fb4bd4f 100644
--- a/surfsense_web/app/dashboard/page.tsx
+++ b/surfsense_web/app/dashboard/page.tsx
@@ -35,6 +35,7 @@ import { Spotlight } from "@/components/ui/spotlight";
import { Tilt } from "@/components/ui/tilt";
import { useUser } from "@/hooks";
import { useSearchSpaces } from "@/hooks/use-search-spaces";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
/**
* Formats a date string into a readable format
@@ -177,7 +178,7 @@ const DashboardPage = () => {
{
method: "DELETE",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
diff --git a/surfsense_web/app/dashboard/searchspaces/page.tsx b/surfsense_web/app/dashboard/searchspaces/page.tsx
index 598536c1b..5fa916266 100644
--- a/surfsense_web/app/dashboard/searchspaces/page.tsx
+++ b/surfsense_web/app/dashboard/searchspaces/page.tsx
@@ -4,6 +4,7 @@ import { motion } from "motion/react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { SearchSpaceForm } from "@/components/search-space-form";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export default function SearchSpacesPage() {
const router = useRouter();
const handleCreateSearchSpace = async (data: { name: string; description: string }) => {
@@ -14,7 +15,7 @@ export default function SearchSpacesPage() {
method: "POST",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(data),
}
diff --git a/surfsense_web/app/dashboard/site-settings/page.tsx b/surfsense_web/app/dashboard/site-settings/page.tsx
index 7cb2497bd..7a9b63925 100644
--- a/surfsense_web/app/dashboard/site-settings/page.tsx
+++ b/surfsense_web/app/dashboard/site-settings/page.tsx
@@ -6,6 +6,7 @@ import { toast } from "sonner";
import { useSiteConfig } from "@/contexts/SiteConfigContext";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Loader2 } from "lucide-react";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface SiteConfigForm {
// Header/Navbar toggles
@@ -67,7 +68,7 @@ export default function SiteSettingsPage() {
const checkSuperuser = async () => {
try {
const backendUrl = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http://localhost:8000";
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
router.push("/login");
@@ -150,7 +151,7 @@ export default function SiteSettingsPage() {
setIsSaving(true);
try {
const backendUrl = process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL || "http://localhost:8000";
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
const response = await fetch(`${backendUrl}/api/v1/site-config`, {
method: "PUT",
diff --git a/surfsense_web/atoms/chats/chat-mutation.atoms.ts b/surfsense_web/atoms/chats/chat-mutation.atoms.ts
index da0795afa..f9d4ba50a 100644
--- a/surfsense_web/atoms/chats/chat-mutation.atoms.ts
+++ b/surfsense_web/atoms/chats/chat-mutation.atoms.ts
@@ -2,13 +2,14 @@ import { atomWithMutation } from "jotai-tanstack-query";
import { toast } from "sonner";
import type { Chat } from "@/app/dashboard/[search_space_id]/chats/chats-client";
import { chatApiService } from "@/lib/apis/chats-api.service";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
import { cacheKeys } from "@/lib/query-client/cache-keys";
import { queryClient } from "@/lib/query-client/client";
import { activeSearchSpaceIdAtom } from "../seach-spaces/seach-space-queries.atom";
export const deleteChatMutationAtom = atomWithMutation((get) => {
const searchSpaceId = get(activeSearchSpaceIdAtom);
- const authToken = localStorage.getItem("surfsense_bearer_token");
+ const authToken = localStorage.getItem(AUTH_TOKEN_KEY);
return {
mutationKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""),
diff --git a/surfsense_web/atoms/chats/chat-querie.atoms.ts b/surfsense_web/atoms/chats/chat-querie.atoms.ts
index 8ea668eb4..28a58de93 100644
--- a/surfsense_web/atoms/chats/chat-querie.atoms.ts
+++ b/surfsense_web/atoms/chats/chat-querie.atoms.ts
@@ -4,6 +4,7 @@ import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-
import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/podcasts-client";
import { activeSearchSpaceIdAtom } from "@/atoms/seach-spaces/seach-space-queries.atom";
import { chatApiService } from "@/lib/apis/chats-api.service";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
import { getPodcastByChatId } from "@/lib/apis/podcasts.api";
import { cacheKeys } from "@/lib/query-client/cache-keys";
@@ -17,7 +18,7 @@ export const activeChatIdAtom = atom(null);
export const activeChatAtom = atomWithQuery((get) => {
const activeChatId = get(activeChatIdAtom);
- const authToken = localStorage.getItem("surfsense_bearer_token");
+ const authToken = localStorage.getItem(AUTH_TOKEN_KEY);
return {
queryKey: cacheKeys.activeSearchSpace.activeChat(activeChatId ?? ""),
@@ -42,7 +43,7 @@ export const activeChatAtom = atomWithQuery((get) => {
export const activeSearchSpaceChatsAtom = atomWithQuery((get) => {
const searchSpaceId = get(activeSearchSpaceIdAtom);
- const authToken = localStorage.getItem("surfsense_bearer_token");
+ const authToken = localStorage.getItem(AUTH_TOKEN_KEY);
return {
queryKey: cacheKeys.activeSearchSpace.chats(searchSpaceId ?? ""),
diff --git a/surfsense_web/components/TokenHandler.tsx b/surfsense_web/components/TokenHandler.tsx
index fd9924b3d..e4c7d6672 100644
--- a/surfsense_web/components/TokenHandler.tsx
+++ b/surfsense_web/components/TokenHandler.tsx
@@ -3,6 +3,7 @@
import { useRouter, useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { baseApiService } from "@/lib/apis/base-api.service";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface TokenHandlerProps {
redirectPath?: string; // Path to redirect after storing token
@@ -20,7 +21,7 @@ interface TokenHandlerProps {
const TokenHandler = ({
redirectPath = "/",
tokenParamName = "token",
- storageKey = "surfsense_bearer_token",
+ storageKey = AUTH_TOKEN_KEY,
}: TokenHandlerProps) => {
const router = useRouter();
const searchParams = useSearchParams();
diff --git a/surfsense_web/components/UserDropdown.tsx b/surfsense_web/components/UserDropdown.tsx
index c0f333019..7afec5687 100644
--- a/surfsense_web/components/UserDropdown.tsx
+++ b/surfsense_web/components/UserDropdown.tsx
@@ -4,6 +4,7 @@ import { BadgeCheck, LogOut, Settings } from "lucide-react";
import { useRouter } from "next/navigation";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
import { baseApiService } from "@/lib/apis/base-api.service";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
@@ -29,7 +30,7 @@ export function UserDropdown({
const handleLogout = () => {
try {
if (typeof window !== "undefined") {
- localStorage.removeItem("surfsense_bearer_token");
+ localStorage.removeItem(AUTH_TOKEN_KEY);
// Clear the baseApiService token to prevent stale auth state
baseApiService.setBearerToken("");
router.push("/");
diff --git a/surfsense_web/components/chat/ChatPanel/ChatPanelContainer.tsx b/surfsense_web/components/chat/ChatPanel/ChatPanelContainer.tsx
index 3edd00400..082955a0a 100644
--- a/surfsense_web/components/chat/ChatPanel/ChatPanelContainer.tsx
+++ b/surfsense_web/components/chat/ChatPanel/ChatPanelContainer.tsx
@@ -7,6 +7,7 @@ import { activeChathatUIAtom } from "@/atoms/chats/ui.atoms";
import { generatePodcast } from "@/lib/apis/podcasts.api";
import { cn } from "@/lib/utils";
import { ChatPanelView } from "./ChatPanelView";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface GeneratePodcastRequest {
type: "CHAT" | "DOCUMENT";
@@ -23,7 +24,7 @@ export function ChatPanelContainer() {
error: chatError,
} = useAtomValue(activeChatAtom);
const activeChatIdState = useAtomValue(activeChatIdAtom);
- const authToken = localStorage.getItem("surfsense_bearer_token");
+ const authToken = localStorage.getItem(AUTH_TOKEN_KEY);
const { isChatPannelOpen } = useAtomValue(activeChathatUIAtom);
const handleGeneratePodcast = async (request: GeneratePodcastRequest) => {
diff --git a/surfsense_web/components/chat/ChatPanel/PodcastPlayer/PodcastPlayer.tsx b/surfsense_web/components/chat/ChatPanel/PodcastPlayer/PodcastPlayer.tsx
index f789ab848..206deef6e 100644
--- a/surfsense_web/components/chat/ChatPanel/PodcastPlayer/PodcastPlayer.tsx
+++ b/surfsense_web/components/chat/ChatPanel/PodcastPlayer/PodcastPlayer.tsx
@@ -8,6 +8,7 @@ import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/pod
import { Button } from "@/components/ui/button";
import { Slider } from "@/components/ui/slider";
import { PodcastPlayerCompactSkeleton } from "./PodcastPlayerCompactSkeleton";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface PodcastPlayerProps {
podcast: PodcastItem | null;
@@ -56,7 +57,7 @@ export function PodcastPlayer({
const loadPodcast = async () => {
setIsFetching(true);
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("Authentication token not found.");
}
diff --git a/surfsense_web/components/sources/DocumentUploadTab.tsx b/surfsense_web/components/sources/DocumentUploadTab.tsx
index c9976bb64..857516ebe 100644
--- a/surfsense_web/components/sources/DocumentUploadTab.tsx
+++ b/surfsense_web/components/sources/DocumentUploadTab.tsx
@@ -15,6 +15,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
import { Progress } from "@/components/ui/progress";
import { Separator } from "@/components/ui/separator";
import { GridPattern } from "./GridPattern";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface DocumentUploadTabProps {
searchSpaceId: string;
@@ -169,7 +170,7 @@ export function DocumentUploadTab({ searchSpaceId }: DocumentUploadTabProps) {
{
method: "POST",
headers: {
- Authorization: `Bearer ${window.localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${window.localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: formData,
}
diff --git a/surfsense_web/components/sources/YouTubeTab.tsx b/surfsense_web/components/sources/YouTubeTab.tsx
index 717a4266d..53972f971 100644
--- a/surfsense_web/components/sources/YouTubeTab.tsx
+++ b/surfsense_web/components/sources/YouTubeTab.tsx
@@ -19,6 +19,7 @@ import {
CardTitle,
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
const youtubeRegex =
/^(https:\/\/)?(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})$/;
@@ -72,7 +73,7 @@ export function YouTubeTab({ searchSpaceId }: YouTubeTabProps) {
method: "POST",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify({
document_type: "YOUTUBE_VIDEO",
diff --git a/surfsense_web/hooks/use-api-key.ts b/surfsense_web/hooks/use-api-key.ts
index 229a8de3e..0045ced6f 100644
--- a/surfsense_web/hooks/use-api-key.ts
+++ b/surfsense_web/hooks/use-api-key.ts
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useState } from "react";
import { toast } from "sonner";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface UseApiKeyReturn {
apiKey: string | null;
@@ -17,7 +18,7 @@ export function useApiKey(): UseApiKeyReturn {
// Load API key from localStorage
const loadApiKey = () => {
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
setApiKey(token);
} catch (error) {
console.error("Error loading API key:", error);
diff --git a/surfsense_web/hooks/use-chat.ts b/surfsense_web/hooks/use-chat.ts
index a3462203a..9d6728702 100644
--- a/surfsense_web/hooks/use-chat.ts
+++ b/surfsense_web/hooks/use-chat.ts
@@ -3,6 +3,7 @@ import { useCallback, useEffect, useState } from "react";
import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-client";
import type { ResearchMode } from "@/components/chat";
import type { Document } from "@/hooks/use-documents";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface UseChatStateProps {
search_space_id: string;
@@ -22,7 +23,7 @@ export function useChatState({ chat_id }: UseChatStateProps) {
const [topK, setTopK] = useState(5);
useEffect(() => {
- const bearerToken = localStorage.getItem("surfsense_bearer_token");
+ const bearerToken = localStorage.getItem(AUTH_TOKEN_KEY);
setToken(bearerToken);
}, []);
diff --git a/surfsense_web/hooks/use-connector-edit-page.ts b/surfsense_web/hooks/use-connector-edit-page.ts
index 870a87dcb..ef45828ce 100644
--- a/surfsense_web/hooks/use-connector-edit-page.ts
+++ b/surfsense_web/hooks/use-connector-edit-page.ts
@@ -15,6 +15,7 @@ import {
type SearchSourceConnector,
useSearchSourceConnectors,
} from "@/hooks/use-search-source-connectors";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
const normalizeListInput = (value: unknown): string[] => {
if (Array.isArray(value)) {
@@ -174,7 +175,7 @@ export function useConnectorEditPage(connectorId: number, searchSpaceId: string)
setIsFetchingRepos(true);
setFetchedRepos(null);
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) throw new Error("No auth token");
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/github/repositories`,
diff --git a/surfsense_web/hooks/use-connectors.ts b/surfsense_web/hooks/use-connectors.ts
index db0a2618e..f1d43353c 100644
--- a/surfsense_web/hooks/use-connectors.ts
+++ b/surfsense_web/hooks/use-connectors.ts
@@ -1,3 +1,5 @@
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
+
// Types for connector API
export interface ConnectorConfig {
[key: string]: string;
@@ -38,7 +40,7 @@ export const ConnectorService = {
method: "POST",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(data),
}
@@ -58,7 +60,7 @@ export const ConnectorService = {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/search-source-connectors?skip=${skip}&limit=${limit}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
@@ -77,7 +79,7 @@ export const ConnectorService = {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/search-source-connectors/${connectorId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
@@ -98,7 +100,7 @@ export const ConnectorService = {
method: "PUT",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(data),
}
@@ -119,7 +121,7 @@ export const ConnectorService = {
{
method: "DELETE",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
diff --git a/surfsense_web/hooks/use-document-by-chunk.ts b/surfsense_web/hooks/use-document-by-chunk.ts
index dd36fcab1..be84b0375 100644
--- a/surfsense_web/hooks/use-document-by-chunk.ts
+++ b/surfsense_web/hooks/use-document-by-chunk.ts
@@ -1,6 +1,7 @@
"use client";
import { useCallback, useState } from "react";
import { toast } from "sonner";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface Chunk {
id: number;
@@ -53,7 +54,7 @@ export function useDocumentByChunk() {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/by-chunk/${chunkId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
"Content-Type": "application/json",
},
method: "GET",
diff --git a/surfsense_web/hooks/use-document-types.ts b/surfsense_web/hooks/use-document-types.ts
index 415e42e90..52c873a5b 100644
--- a/surfsense_web/hooks/use-document-types.ts
+++ b/surfsense_web/hooks/use-document-types.ts
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useState } from "react";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface DocumentTypeCount {
type: string;
@@ -23,7 +24,7 @@ export const useDocumentTypes = (searchSpaceId?: number, lazy: boolean = false)
try {
setIsLoading(true);
setError(null);
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
diff --git a/surfsense_web/hooks/use-documents.ts b/surfsense_web/hooks/use-documents.ts
index 21ee959b8..53d13e10e 100644
--- a/surfsense_web/hooks/use-documents.ts
+++ b/surfsense_web/hooks/use-documents.ts
@@ -2,6 +2,7 @@
import { useCallback, useEffect, useState } from "react";
import { toast } from "sonner";
import { normalizeListResponse } from "@/lib/pagination";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface Document {
id: number;
@@ -82,7 +83,7 @@ export function useDocuments(searchSpaceId: number, options?: UseDocumentsOption
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents?${params.toString()}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -163,7 +164,7 @@ export function useDocuments(searchSpaceId: number, options?: UseDocumentsOption
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/search?${params.toString()}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -197,7 +198,7 @@ export function useDocuments(searchSpaceId: number, options?: UseDocumentsOption
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/${documentId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "DELETE",
}
@@ -232,7 +233,7 @@ export function useDocuments(searchSpaceId: number, options?: UseDocumentsOption
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/type-counts?${params.toString()}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
diff --git a/surfsense_web/hooks/use-llm-configs.ts b/surfsense_web/hooks/use-llm-configs.ts
index 0755211c4..c6ec4838e 100644
--- a/surfsense_web/hooks/use-llm-configs.ts
+++ b/surfsense_web/hooks/use-llm-configs.ts
@@ -1,6 +1,7 @@
"use client";
import { useEffect, useState } from "react";
import { toast } from "sonner";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface LLMConfig {
id: number;
@@ -65,7 +66,7 @@ export function useLLMConfigs(searchSpaceId: number | null) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/llm-configs?search_space_id=${searchSpaceId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -98,7 +99,7 @@ export function useLLMConfigs(searchSpaceId: number | null) {
method: "POST",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(config),
}
@@ -127,7 +128,7 @@ export function useLLMConfigs(searchSpaceId: number | null) {
{
method: "DELETE",
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
}
);
@@ -157,7 +158,7 @@ export function useLLMConfigs(searchSpaceId: number | null) {
method: "PUT",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(config),
}
@@ -207,7 +208,7 @@ export function useLLMPreferences(searchSpaceId: number | null) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/search-spaces/${searchSpaceId}/llm-preferences`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -245,7 +246,7 @@ export function useLLMPreferences(searchSpaceId: number | null) {
method: "PUT",
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
body: JSON.stringify(newPreferences),
}
@@ -297,7 +298,7 @@ export function useGlobalLLMConfigs() {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/global-llm-configs`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
diff --git a/surfsense_web/hooks/use-logs.ts b/surfsense_web/hooks/use-logs.ts
index 7defd8345..4823f62c6 100644
--- a/surfsense_web/hooks/use-logs.ts
+++ b/surfsense_web/hooks/use-logs.ts
@@ -1,6 +1,7 @@
"use client";
import { useCallback, useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export type LogLevel = "DEBUG" | "INFO" | "WARNING" | "ERROR" | "CRITICAL";
export type LogStatus = "IN_PROGRESS" | "SUCCESS" | "FAILED";
@@ -99,7 +100,7 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/logs?${params}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -150,7 +151,7 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
const response = await fetch(`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/logs`, {
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "POST",
body: JSON.stringify(logData),
@@ -184,7 +185,7 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
{
headers: {
"Content-Type": "application/json",
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "PUT",
body: JSON.stringify(updateData),
@@ -216,7 +217,7 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/logs/${logId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "DELETE",
}
@@ -244,7 +245,7 @@ export function useLogs(searchSpaceId?: number, filters: LogFilters = {}) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/logs/${logId}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -291,7 +292,7 @@ export function useLogsSummary(searchSpaceId: number, hours: number = 24) {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/logs/search-space/${searchSpaceId}/summary?hours=${hours}`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
diff --git a/surfsense_web/hooks/use-search-source-connectors.ts b/surfsense_web/hooks/use-search-source-connectors.ts
index 41b5f5115..22f707e39 100644
--- a/surfsense_web/hooks/use-search-source-connectors.ts
+++ b/surfsense_web/hooks/use-search-source-connectors.ts
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useState } from "react";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
export interface SearchSourceConnector {
id: number;
@@ -66,7 +67,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
try {
setIsLoading(true);
setError(null);
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
@@ -176,7 +177,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
spaceId: number
) => {
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
@@ -222,7 +223,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
>
) => {
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
@@ -262,7 +263,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
*/
const deleteConnector = async (connectorId: number) => {
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
@@ -302,7 +303,7 @@ export const useSearchSourceConnectors = (lazy: boolean = false, searchSpaceId?:
endDate?: string
) => {
try {
- const token = localStorage.getItem("surfsense_bearer_token");
+ const token = localStorage.getItem(AUTH_TOKEN_KEY);
if (!token) {
throw new Error("No authentication token found");
diff --git a/surfsense_web/hooks/use-search-spaces.ts b/surfsense_web/hooks/use-search-spaces.ts
index 43c34fbd9..daec2542c 100644
--- a/surfsense_web/hooks/use-search-spaces.ts
+++ b/surfsense_web/hooks/use-search-spaces.ts
@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import { toast } from "sonner";
+import { AUTH_TOKEN_KEY } from "@/lib/constants";
interface SearchSpace {
id: number;
@@ -24,7 +25,7 @@ export function useSearchSpaces() {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}
@@ -57,7 +58,7 @@ export function useSearchSpaces() {
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
headers: {
- Authorization: `Bearer ${localStorage.getItem("surfsense_bearer_token")}`,
+ Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN_KEY)}`,
},
method: "GET",
}