Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to @supabase/ssr from @supabase/auth-helpers-nextjs #23

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,19 @@ npm install supabase --save-dev
npx supabase start
```

Run migration script to create the tables

```bash
psql -h db.your-supabase-instance.supabase.co -U your_supabase_user -d your_supabase_database -f supabase/migrations/20230707053030_init.sql
```

Create the table in Supabase UI

```
Table name: chats
Columns: id (default Supabase), convo_id (text, primary, unique), payload (jsonb), user_id (uuid)
```

Install the local dependencies and start dev mode:

```bash
Expand Down
126 changes: 103 additions & 23 deletions app/actions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use server'
import 'server-only'
import { createServerActionClient } from '@supabase/auth-helpers-nextjs'
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { Database } from '@/lib/db_types'
import { revalidatePath } from 'next/cache'
Expand All @@ -14,9 +14,24 @@ export async function getChats(userId?: string | null) {
}
try {
const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});

const { data } = await supabase
.from('chats')
.select('payload')
Expand All @@ -32,13 +47,26 @@ export async function getChats(userId?: string | null) {

export async function getChat(id: string) {
const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});
const { data } = await supabase
.from('chats')
.select('payload')
.eq('id', id)
.eq('convo_id', id)
.maybeSingle()

return (data?.payload as Chat) ?? null
Expand All @@ -47,10 +75,23 @@ export async function getChat(id: string) {
export async function removeChat({ id, path }: { id: string; path: string }) {
try {
const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})
await supabase.from('chats').delete().eq('id', id).throwOnError()
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});
await supabase.from('chats').delete().eq('convo_id', id).throwOnError()

revalidatePath('/')
return revalidatePath(path)
Expand All @@ -64,9 +105,22 @@ export async function removeChat({ id, path }: { id: string; path: string }) {
export async function clearChats() {
try {
const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});
await supabase.from('chats').delete().throwOnError()
revalidatePath('/')
return redirect('/')
Expand All @@ -80,13 +134,26 @@ export async function clearChats() {

export async function getSharedChat(id: string) {
const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});
const { data } = await supabase
.from('chats')
.select('payload')
.eq('id', id)
.eq('convo_id', id)
.not('payload->sharePath', 'is', null)
.maybeSingle()

Expand All @@ -100,13 +167,26 @@ export async function shareChat(chat: Chat) {
}

const cookieStore = cookies()
const supabase = createServerActionClient<Database>({
cookies: () => cookieStore
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
});
await supabase
.from('chats')
.update({ payload: payload as any })
.eq('id', chat.id)
.eq('convo_id', chat.id)
.throwOnError()

return payload
Expand Down
22 changes: 18 additions & 4 deletions app/api/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'server-only'
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'

Expand All @@ -12,9 +12,23 @@ export async function GET(request: Request) {

if (code) {
const cookieStore = cookies()
const supabase = createRouteHandlerClient({
cookies: () => cookieStore
})
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
}
)
await supabase.auth.exchangeCodeForSession(code)
}

Expand Down
28 changes: 21 additions & 7 deletions app/api/chat/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import 'server-only'
import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs'
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { Database } from '@/lib/db_types'

Expand All @@ -18,12 +18,25 @@ const openai = new OpenAIApi(configuration)

export async function POST(req: Request) {
const cookieStore = cookies()
const supabase = createRouteHandlerClient<Database>({
cookies: () => cookieStore
})
const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.set({ name, value: '', ...options })
},
},
})
const json = await req.json()
const { messages, previewToken } = json
const userId = (await auth({ cookieStore }))?.user.id
const userId = (await auth({ cookieStore }))?.id

if (!userId) {
return new Response('Unauthorized', {
Expand Down Expand Up @@ -62,8 +75,9 @@ export async function POST(req: Request) {
}
]
}
// Insert chat into database.
await supabase.from('chats').upsert({ id, payload }).throwOnError()

// @ts-expect-error upsert doesn't like convo_id somehow
await supabase.from('chats').upsert({ convo_id: id, payload }, { onConflict: 'convo_id' }).throwOnError()
}
})

Expand Down
10 changes: 5 additions & 5 deletions app/chat/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export async function generateMetadata({
params
}: ChatPageProps): Promise<Metadata> {
const cookieStore = cookies()
const session = await auth({ cookieStore })
const user = await auth({ cookieStore })

if (!session?.user) {
if (!user.id) {
return {}
}

Expand All @@ -33,9 +33,9 @@ export async function generateMetadata({

export default async function ChatPage({ params }: ChatPageProps) {
const cookieStore = cookies()
const session = await auth({ cookieStore })
const user = await auth({ cookieStore })

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

Expand All @@ -45,7 +45,7 @@ export default async function ChatPage({ params }: ChatPageProps) {
notFound()
}

if (chat?.userId !== session?.user?.id) {
if (chat?.userId !== user?.id) {
notFound()
}

Expand Down
4 changes: 2 additions & 2 deletions app/sign-in/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { redirect } from 'next/navigation'

export default async function SignInPage() {
const cookieStore = cookies()
const session = await auth({ cookieStore })
const user = await auth({ cookieStore })
// redirect to home if user is already logged in
if (session?.user) {
if (user) {
redirect('/')
}
return (
Expand Down
4 changes: 2 additions & 2 deletions app/sign-up/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { redirect } from 'next/navigation'

export default async function SignInPage() {
const cookieStore = cookies()
const session = await auth({ cookieStore })
const user = await auth({ cookieStore })
// redirect to home if user is already logged in
if (session?.user) {
if (user) {
redirect('/')
}
return (
Expand Down
21 changes: 15 additions & 6 deletions auth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import 'server-only'
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
import { createServerClient, type CookieOptions } from '@supabase/ssr'
import { cookies } from 'next/headers'

export const auth = async ({
Expand All @@ -8,10 +8,19 @@ export const auth = async ({
cookieStore: ReturnType<typeof cookies>
}) => {
// Create a Supabase client configured to use cookies
const supabase = createServerComponentClient({
cookies: () => cookieStore
})
const { data, error } = await supabase.auth.getSession()

const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
},
}
)
const { data, error } = await supabase.auth.getUser()
if (error) throw error
return data.session
return data.user
}
Loading