diff --git a/src/app/page.tsx b/src/app/page.tsx index b72d2c37..e205eff3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -4,22 +4,33 @@ import { useEffect } from "react"; import { addAssistantIdToUser } from "@/lib/supabase/add_assistant_id_to_user"; import { CanvasLoading } from "@/components/CanvasLoading"; import { useUser } from "@/hooks/useUser"; +import { isAuthEnabled } from "@/lib/auth-config"; export default function Home() { const { user, getUser } = useUser(); useEffect(() => { - getUser(); + if (isAuthEnabled()) { + getUser(); + } }, []); useEffect(() => { if (typeof window === "undefined" || !user) return; - addAssistantIdToUser(); + if (isAuthEnabled()) { + addAssistantIdToUser(); + } }, [user]); + // If auth is disabled, render Canvas directly with mock user + if (!isAuthEnabled()) { + return ; + } + + // Otherwise, show loading until user is loaded if (!user) { return ; } return ; -} +} \ No newline at end of file diff --git a/src/components/Canvas.tsx b/src/components/Canvas.tsx index da86a947..1afc3d64 100644 --- a/src/components/Canvas.tsx +++ b/src/components/Canvas.tsx @@ -16,6 +16,7 @@ import { } from "@/types"; import { User } from "@supabase/supabase-js"; import { useEffect, useState } from "react"; +import { isAuthEnabled } from "@/lib/auth-config"; interface CanvasProps { user: User; @@ -23,6 +24,7 @@ interface CanvasProps { export function Canvas(props: CanvasProps) { const { toast } = useToast(); + const effectiveUserId = isAuthEnabled() ? props.user.id : 'anonymous'; const { threadId, assistantId, @@ -35,7 +37,7 @@ export function Canvas(props: CanvasProps) { setThreadId, getOrCreateAssistant, clearThreadsWithNoValues, - } = useThread(props.user.id); + } = useThread(effectiveUserId); const [chatStarted, setChatStarted] = useState(false); const [isEditing, setIsEditing] = useState(false); const { @@ -56,7 +58,7 @@ export function Canvas(props: CanvasProps) { firstTokenReceived, selectedBlocks, } = useGraph({ - userId: props.user.id, + userId: effectiveUserId, threadId, assistantId, }); @@ -67,14 +69,14 @@ export function Canvas(props: CanvasProps) { isLoadingReflections, } = useStore({ assistantId, - userId: props.user.id, + userId: effectiveUserId, }); useEffect(() => { if (typeof window === "undefined") return; if (!threadId) { - searchOrCreateThread(props.user.id); + searchOrCreateThread(effectiveUserId); } if (!assistantId) { @@ -85,14 +87,14 @@ export function Canvas(props: CanvasProps) { useEffect(() => { if (!threadId) return; // Clear threads with no values - clearThreadsWithNoValues(props.user.id); + clearThreadsWithNoValues(effectiveUserId); }, [threadId]); useEffect(() => { - if (typeof window == "undefined" || !props.user.id || userThreads.length) + if (typeof window == "undefined" || !effectiveUserId || userThreads.length) return; - getUserThreads(props.user.id); - }, [props.user.id]); + getUserThreads(effectiveUserId); + }, [effectiveUserId]); useEffect(() => { if (!assistantId || typeof window === "undefined") return; @@ -109,7 +111,7 @@ export function Canvas(props: CanvasProps) { const createThreadWithChatStarted = async () => { setChatStarted(false); clearState(); - return createThread(props.user.id); + return createThread(effectiveUserId); }; const handleQuickStart = ( @@ -165,7 +167,7 @@ export function Canvas(props: CanvasProps) { )} > (); @@ -19,10 +20,13 @@ export function useThread(userId: string) { ): Promise => { const client = createClient(); try { + // For non-auth mode, we still need to pass some identifier + const metadata = isAuthEnabled() + ? { supabase_user_id: supabaseUserId } + : { anonymous_user_id: 'anonymous' }; + const thread = await client.threads.create({ - metadata: { - supabase_user_id: supabaseUserId, - }, + metadata, }); setThreadId(thread.thread_id); setCookie(THREAD_ID_COOKIE_NAME, thread.thread_id); @@ -55,11 +59,14 @@ export function useThread(userId: string) { setIsUserThreadsLoading(true); try { const client = createClient(); + + // Adjust the search criteria based on auth status + const searchMetadata = isAuthEnabled() + ? { supabase_user_id: id } + : { anonymous_user_id: 'anonymous' }; const userThreads = await client.threads.search({ - metadata: { - supabase_user_id: id, - }, + metadata: searchMetadata, limit: 100, }); diff --git a/src/hooks/useUser.tsx b/src/hooks/useUser.tsx index c4fc8263..5ba9a8db 100644 --- a/src/hooks/useUser.tsx +++ b/src/hooks/useUser.tsx @@ -1,13 +1,29 @@ import { useState } from "react"; import { createSupabaseClient } from "@/lib/supabase/client"; import { User } from "@supabase/supabase-js"; +import { isAuthEnabled } from "@/lib/auth-config"; export function useUser() { const [user, setUser] = useState(); const [loading, setLoading] = useState(true); async function getUser() { + if (!isAuthEnabled()) { + const mockUser = { + id: 'anonymous', + email: 'anonymous@example.com', + // Add other required User properties + } as User; + setUser(mockUser); + setLoading(false); + return; + } + const supabase = createSupabaseClient(); + if (!supabase) { + setLoading(false); + return; + } const { data: { user }, @@ -21,4 +37,4 @@ export function useUser() { user, loading, }; -} +} \ No newline at end of file diff --git a/src/lib/auth-config.ts b/src/lib/auth-config.ts new file mode 100644 index 00000000..35359f75 --- /dev/null +++ b/src/lib/auth-config.ts @@ -0,0 +1,4 @@ +export const isAuthEnabled = () => { + return !!(process.env.NEXT_PUBLIC_SUPABASE_URL && + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY); + }; \ No newline at end of file diff --git a/src/lib/supabase/client.ts b/src/lib/supabase/client.ts index 0f2fb747..441397b0 100644 --- a/src/lib/supabase/client.ts +++ b/src/lib/supabase/client.ts @@ -1,6 +1,10 @@ import { createBrowserClient } from "@supabase/ssr"; +import { isAuthEnabled } from "../auth-config"; export function createSupabaseClient() { + if (!isAuthEnabled()) { + return null; + } if (!process.env.NEXT_PUBLIC_SUPABASE_URL) { throw new Error("NEXT_PUBLIC_SUPABASE_URL is not defined"); } diff --git a/src/lib/supabase/server.ts b/src/lib/supabase/server.ts index 9624233b..46d10a28 100644 --- a/src/lib/supabase/server.ts +++ b/src/lib/supabase/server.ts @@ -1,7 +1,12 @@ import { createServerClient } from "@supabase/ssr"; import { cookies } from "next/headers"; +import { isAuthEnabled } from "../auth-config"; export function createClient() { + if (!isAuthEnabled()) { + return null; + } + if (!process.env.NEXT_PUBLIC_SUPABASE_URL) { throw new Error("NEXT_PUBLIC_SUPABASE_URL is not defined"); } diff --git a/src/lib/supabase/verify_user_server.ts b/src/lib/supabase/verify_user_server.ts index 799520f4..a29815c9 100644 --- a/src/lib/supabase/verify_user_server.ts +++ b/src/lib/supabase/verify_user_server.ts @@ -1,10 +1,22 @@ import { User } from "@supabase/supabase-js"; import { createClient } from "./server"; +import { isAuthEnabled } from "../auth-config"; export async function verifyUserAuthenticated(): Promise { + if (!isAuthEnabled()) { + // Return a mock user when auth is disabled + return { + id: 'anonymous', + email: 'anonymous@example.com', + // Add other required User properties + } as User; + } + const supabase = createClient(); + if (!supabase) return undefined; + const { data: { user }, } = await supabase.auth.getUser(); return user || undefined; -} +} \ No newline at end of file diff --git a/src/middleware.ts b/src/middleware.ts index ae308f79..29aab273 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -2,6 +2,14 @@ import { type NextRequest } from "next/server"; import { updateSession } from "@/lib/supabase/middleware"; export async function middleware(request: NextRequest) { + // Check if Supabase credentials are configured + const isAuthEnabled = process.env.NEXT_PUBLIC_SUPABASE_URL && + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; + + if (!isAuthEnabled) { + return; // Skip auth middleware if Supabase is not configured + } + return await updateSession(request); }