Skip to content

Commit 829168e

Browse files
authored
Merge pull request #1 from supabase-community/main
Merge
2 parents d0a8a08 + 5a8fcfe commit 829168e

18 files changed

+14049
-106
lines changed

.env.example

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ OPENAI_API_KEY=XXXXXXXX
88
NEXT_PUBLIC_SUPABASE_URL=your-project-url
99
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
1010

11-
## Follow GitHub Oauth setup steps from Supabase:
11+
## Follow GitHub Oauth setup steps from Supabase,
12+
## if you choose not to use Github, set first
13+
## value to "false"
14+
NEXT_PUBLIC_AUTH_GITHUB=false
1215
AUTH_GITHUB_ID=XXXXXXXX
1316
AUTH_GITHUB_SECRET=XXXXXXXX

app/actions.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,27 @@
11
'use server'
2-
2+
import 'server-only'
33
import { createServerActionClient } from '@supabase/auth-helpers-nextjs'
44
import { cookies } from 'next/headers'
55
import { Database } from '@/lib/db_types'
66
import { revalidatePath } from 'next/cache'
77
import { redirect } from 'next/navigation'
88

99
import { type Chat } from '@/lib/types'
10-
import { auth } from '@/auth'
11-
12-
const supabase = createServerActionClient<Database>({ cookies })
1310

1411
export async function getChats(userId?: string | null) {
1512
if (!userId) {
1613
return []
1714
}
18-
1915
try {
16+
const cookieStore = cookies()
17+
const supabase = createServerActionClient<Database>({
18+
cookies: () => cookieStore
19+
})
2020
const { data } = await supabase
2121
.from('chats')
2222
.select('payload')
2323
.order('payload->createdAt', { ascending: false })
24+
.eq('user_id', userId)
2425
.throwOnError()
2526

2627
return (data?.map(entry => entry.payload) as Chat[]) ?? []
@@ -30,6 +31,10 @@ export async function getChats(userId?: string | null) {
3031
}
3132

3233
export async function getChat(id: string) {
34+
const cookieStore = cookies()
35+
const supabase = createServerActionClient<Database>({
36+
cookies: () => cookieStore
37+
})
3338
const { data } = await supabase
3439
.from('chats')
3540
.select('payload')
@@ -41,6 +46,10 @@ export async function getChat(id: string) {
4146

4247
export async function removeChat({ id, path }: { id: string; path: string }) {
4348
try {
49+
const cookieStore = cookies()
50+
const supabase = createServerActionClient<Database>({
51+
cookies: () => cookieStore
52+
})
4453
await supabase.from('chats').delete().eq('id', id).throwOnError()
4554

4655
revalidatePath('/')
@@ -54,12 +63,11 @@ export async function removeChat({ id, path }: { id: string; path: string }) {
5463

5564
export async function clearChats() {
5665
try {
57-
const session = await auth()
58-
await supabase
59-
.from('chats')
60-
.delete()
61-
.eq('user_id', session?.user.id)
62-
.throwOnError()
66+
const cookieStore = cookies()
67+
const supabase = createServerActionClient<Database>({
68+
cookies: () => cookieStore
69+
})
70+
await supabase.from('chats').delete().throwOnError()
6371
revalidatePath('/')
6472
return redirect('/')
6573
} catch (error) {
@@ -71,6 +79,10 @@ export async function clearChats() {
7179
}
7280

7381
export async function getSharedChat(id: string) {
82+
const cookieStore = cookies()
83+
const supabase = createServerActionClient<Database>({
84+
cookies: () => cookieStore
85+
})
7486
const { data } = await supabase
7587
.from('chats')
7688
.select('payload')
@@ -87,6 +99,10 @@ export async function shareChat(chat: Chat) {
8799
sharePath: `/share/${chat.id}`
88100
}
89101

102+
const cookieStore = cookies()
103+
const supabase = createServerActionClient<Database>({
104+
cookies: () => cookieStore
105+
})
90106
await supabase
91107
.from('chats')
92108
.update({ payload: payload as any })

app/api/auth/callback/route.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'server-only'
12
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
23
import { cookies } from 'next/headers'
34
import { NextResponse } from 'next/server'
@@ -10,7 +11,10 @@ export async function GET(request: Request) {
1011
const code = requestUrl.searchParams.get('code')
1112

1213
if (code) {
13-
const supabase = createRouteHandlerClient({ cookies })
14+
const cookieStore = cookies()
15+
const supabase = createRouteHandlerClient({
16+
cookies: () => cookieStore
17+
})
1418
await supabase.auth.exchangeCodeForSession(code)
1519
}
1620

app/api/chat/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'server-only'
12
import { OpenAIStream, StreamingTextResponse } from 'ai'
23
import { Configuration, OpenAIApi } from 'openai-edge'
34
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
@@ -16,10 +17,13 @@ const configuration = new Configuration({
1617
const openai = new OpenAIApi(configuration)
1718

1819
export async function POST(req: Request) {
19-
const supabase = createRouteHandlerClient<Database>({ cookies })
20+
const cookieStore = cookies()
21+
const supabase = createRouteHandlerClient<Database>({
22+
cookies: () => cookieStore
23+
})
2024
const json = await req.json()
2125
const { messages, previewToken } = json
22-
const userId = (await auth())?.user.id
26+
const userId = (await auth({ cookieStore }))?.user.id
2327

2428
if (!userId) {
2529
return new Response('Unauthorized', {

app/chat/[id]/page.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { notFound, redirect } from 'next/navigation'
44
import { auth } from '@/auth'
55
import { getChat } from '@/app/actions'
66
import { Chat } from '@/components/chat'
7+
import { cookies } from 'next/headers'
78

89
export const runtime = 'edge'
910
export const preferredRegion = 'home'
@@ -17,7 +18,8 @@ export interface ChatPageProps {
1718
export async function generateMetadata({
1819
params
1920
}: ChatPageProps): Promise<Metadata> {
20-
const session = await auth()
21+
const cookieStore = cookies()
22+
const session = await auth({ cookieStore })
2123

2224
if (!session?.user) {
2325
return {}
@@ -30,7 +32,8 @@ export async function generateMetadata({
3032
}
3133

3234
export default async function ChatPage({ params }: ChatPageProps) {
33-
const session = await auth()
35+
const cookieStore = cookies()
36+
const session = await auth({ cookieStore })
3437

3538
if (!session?.user) {
3639
redirect(`/sign-in?next=/chat/${params.id}`)

app/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,10 @@ export default function RootLayout({ children }: RootLayoutProps) {
4343
>
4444
<Toaster />
4545
<Providers attribute="class" defaultTheme="system" enableSystem>
46-
<div className="flex flex-col min-h-screen">
46+
<div className="flex min-h-screen flex-col">
4747
{/* @ts-ignore */}
4848
<Header />
49-
<main className="flex flex-col flex-1 bg-muted/50">{children}</main>
49+
<main className="flex flex-1 flex-col bg-muted/50">{children}</main>
5050
</div>
5151
<TailwindIndicator />
5252
</Providers>

app/sign-in/page.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import { auth } from '@/auth'
22
import { LoginButton } from '@/components/login-button'
3+
import { LoginForm } from '@/components/login-form'
4+
import { Separator } from '@/components/ui/separator'
5+
import { cookies } from 'next/headers'
36
import { redirect } from 'next/navigation'
47

58
export default async function SignInPage() {
6-
const session = await auth()
9+
const cookieStore = cookies()
10+
const session = await auth({ cookieStore })
711
// redirect to home if user is already logged in
812
if (session?.user) {
913
redirect('/')
1014
}
1115
return (
12-
<div className="flex h-[calc(100vh-theme(spacing.16))] items-center justify-center py-10">
13-
<LoginButton />
16+
<div className="flex h-[calc(100vh-theme(spacing.16))] flex-col items-center justify-center py-10">
17+
<div className="w-full max-w-sm">
18+
<LoginForm action="sign-in" />
19+
<Separator className="my-4" />
20+
<div className="flex justify-center">
21+
<LoginButton />
22+
</div>
23+
</div>
1424
</div>
1525
)
1626
}

app/sign-up/page.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { auth } from '@/auth'
2+
import { LoginButton } from '@/components/login-button'
3+
import { LoginForm } from '@/components/login-form'
4+
import { Separator } from '@/components/ui/separator'
5+
import { cookies } from 'next/headers'
6+
import { redirect } from 'next/navigation'
7+
8+
export default async function SignInPage() {
9+
const cookieStore = cookies()
10+
const session = await auth({ cookieStore })
11+
// redirect to home if user is already logged in
12+
if (session?.user) {
13+
redirect('/')
14+
}
15+
return (
16+
<div className="flex h-[calc(100vh-theme(spacing.16))] flex-col items-center justify-center py-10">
17+
<div className="w-full max-w-sm">
18+
<LoginForm action="sign-up" />
19+
<Separator className="my-4" />
20+
<div className="flex justify-center">
21+
<LoginButton />
22+
</div>
23+
</div>
24+
</div>
25+
)
26+
}

auth.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
import { createServerActionClient } from '@supabase/auth-helpers-nextjs'
1+
import 'server-only'
2+
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
23
import { cookies } from 'next/headers'
34

4-
export const auth = async () => {
5+
export const auth = async ({
6+
cookieStore
7+
}: {
8+
cookieStore: ReturnType<typeof cookies>
9+
}) => {
510
// Create a Supabase client configured to use cookies
6-
const supabase = createServerActionClient({ cookies })
11+
const supabase = createServerComponentClient({
12+
cookies: () => cookieStore
13+
})
714
const { data, error } = await supabase.auth.getSession()
815
if (error) throw error
916
return data.session

components/header.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ import { SidebarFooter } from '@/components/sidebar-footer'
1717
import { ThemeToggle } from '@/components/theme-toggle'
1818
import { ClearHistory } from '@/components/clear-history'
1919
import { UserMenu } from '@/components/user-menu'
20+
import { cookies } from 'next/headers'
2021

2122
export async function Header() {
22-
const session = await auth()
23+
const cookieStore = cookies()
24+
const session = await auth({ cookieStore })
2325
return (
24-
<header className="sticky top-0 z-50 flex items-center justify-between w-full h-16 px-4 border-b shrink-0 bg-gradient-to-b from-background/10 via-background/50 to-background/80 backdrop-blur-xl">
26+
<header className="sticky top-0 z-50 flex h-16 w-full shrink-0 items-center justify-between border-b bg-gradient-to-b from-background/10 via-background/50 to-background/80 px-4 backdrop-blur-xl">
2527
<div className="flex items-center">
2628
{session?.user ? (
2729
<Sidebar>
@@ -36,12 +38,12 @@ export async function Header() {
3638
</Sidebar>
3739
) : (
3840
<Link href="/" target="_blank" rel="nofollow">
39-
<IconNextChat className="w-6 h-6 mr-2 dark:hidden" inverted />
40-
<IconNextChat className="hidden w-6 h-6 mr-2 dark:block" />
41+
<IconNextChat className="mr-2 h-6 w-6 dark:hidden" inverted />
42+
<IconNextChat className="mr-2 hidden h-6 w-6 dark:block" />
4143
</Link>
4244
)}
4345
<div className="flex items-center">
44-
<IconSeparator className="w-6 h-6 text-muted-foreground/50" />
46+
<IconSeparator className="h-6 w-6 text-muted-foreground/50" />
4547
{session?.user ? (
4648
<UserMenu user={session.user} />
4749
) : (
@@ -59,7 +61,7 @@ export async function Header() {
5961
className={cn(buttonVariants({ variant: 'outline' }))}
6062
>
6163
<IconGitHub />
62-
<span className="hidden ml-2 md:flex">GitHub</span>
64+
<span className="ml-2 hidden md:flex">GitHub</span>
6365
</a>
6466
<a
6567
href="https://github.com/thorwebdev/vercel-ai-chatbot"

components/login-button.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ export function LoginButton({
2121
const [isLoading, setIsLoading] = React.useState(false)
2222
// Create a Supabase client configured to use cookies
2323
const supabase = createClientComponentClient()
24+
25+
if (process.env.NEXT_PUBLIC_AUTH_GITHUB !== 'true') {
26+
return null
27+
}
28+
2429
return (
2530
<Button
2631
variant="outline"

0 commit comments

Comments
 (0)