diff --git a/app/actions.ts b/app/actions.ts
index 3c6967c..cab6259 100644
--- a/app/actions.ts
+++ b/app/actions.ts
@@ -1,11 +1,11 @@
"use server";
+import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";
-import { getServerSession } from "@/lib/session/get-server-session";
import { revalidatePath } from "next/cache";
export async function removeChat({ id, path }: { id: string; path: string }) {
- const session = await getServerSession();
+ const session = await auth();
const userId = session?.user?.email;
if (!userId || !id) {
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..e47b0fd
--- /dev/null
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,2 @@
+export { GET, POST } from "@/auth";
+export const runtime = "edge";
diff --git a/app/api/auth/callback/route.ts b/app/api/auth/callback/route.ts
deleted file mode 100644
index a235634..0000000
--- a/app/api/auth/callback/route.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import { NextRequest, NextResponse } from 'next/server';
-import { serialize } from 'cookie';
-import { createSession } from '@/lib/session/create';
-import { encryptJWECookie } from '@/lib/cookies/encrypt-jwe';
-import ms from 'ms';
-import { userSessionCookieName } from '@/lib/session/constants';
-
-export const runtime = 'edge';
-
-const sharedTokenSecret = process.env.SHARE_TOKEN_ENDPOINT_SECRET;
-const cookieTTL = ms('1y');
-
-export async function GET(req: NextRequest) {
- const { origin, searchParams } = req.nextUrl;
- const shareableToken = searchParams.get('shareableToken');
-
- if (!sharedTokenSecret || !shareableToken) {
- // TODO: Make an error page
- return NextResponse.json({ error: 'Invalid request' }, { status: 500 });
- }
-
- const query = new URLSearchParams({
- sharedTokenSecret,
- });
-
- const response = await fetch(
- `https://api.vercel.com/user/tokens/shared/${shareableToken}?${query.toString()}`
- );
-
- const { token } = (await response.json()) as { token: string };
-
- const session = await createSession(token);
-
- const cookieValue = await encryptJWECookie(session, '1y');
- const next = req.cookies.get('auth-next')?.value;
-
- return NextResponse.redirect(new URL(next ?? '/', origin), {
- headers: [
- [
- 'set-cookie',
- serialize(userSessionCookieName, cookieValue, {
- path: '/',
- maxAge: cookieTTL / 1000,
- expires: new Date(Date.now() + cookieTTL),
- httpOnly: true,
- secure: process.env.NODE_ENV !== 'development',
- }),
- ],
- // There's currently an issue with adding more than one cookie to a response: https://github.com/vercel/next.js/issues/46579
- // the `auth-next` cookie will expire in 10 min anyway
- // [
- // 'set-cookie',
- // serialize('auth-next', '', {
- // path: '/api/auth/callback',
- // maxAge: 0,
- // expires: new Date(),
- // httpOnly: true,
- // })
- // ]
- ],
- });
-}
diff --git a/app/api/auth/login/route.ts b/app/api/auth/login/route.ts
deleted file mode 100644
index 1bd23cc..0000000
--- a/app/api/auth/login/route.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { NextRequest, NextResponse } from 'next/server';
-import { serialize } from 'cookie';
-
-export const runtime = 'edge';
-
-export async function GET(req: NextRequest) {
- const { origin } = req.nextUrl;
-
- const next = req.nextUrl.searchParams.get('next');
-
- const params = new URLSearchParams({
- redirectUrl: new URL('/api/auth/callback', origin).toString(),
- });
-
- return NextResponse.redirect(
- `https://vercel.com/api/vercel-auth?${params.toString()}`,
- {
- headers: next
- ? {
- 'Set-Cookie': serialize('auth-next', next, {
- path: '/api/auth/callback',
- maxAge: 60 * 60 * 10,
- httpOnly: true,
- }),
- }
- : undefined,
- }
- );
-}
diff --git a/app/api/auth/logout/route.ts b/app/api/auth/logout/route.ts
deleted file mode 100644
index a8b2768..0000000
--- a/app/api/auth/logout/route.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { userSessionCookieName } from '@/lib/session/constants';
-import { serialize } from 'cookie';
-import { NextRequest, NextResponse } from 'next/server';
-
-export const runtime = 'edge';
-
-export async function GET(req: NextRequest) {
- const { origin, searchParams } = req.nextUrl;
- const next = searchParams.get('next');
-
- return NextResponse.redirect(new URL(next ?? '/', origin), {
- headers: [
- [
- 'set-cookie',
- serialize(userSessionCookieName, '', {
- path: '/',
- maxAge: 0,
- expires: new Date(),
- httpOnly: true,
- secure: process.env.NODE_ENV !== 'development',
- }),
- ],
- ],
- });
-}
diff --git a/app/api/generate/route.ts b/app/api/generate/route.ts
index 7d34526..5d73c5a 100644
--- a/app/api/generate/route.ts
+++ b/app/api/generate/route.ts
@@ -1,10 +1,11 @@
+import { auth } from "@/auth";
import { OpenAIStream, openai } from "@/lib/openai";
-import { getServerSession } from "@/lib/session/get-server-session";
import { prisma } from "@/lib/prisma";
-export async function POST(req: Request) {
+export const POST = auth(async function POST(req: Request) {
const json = await req.json();
- const session = await getServerSession();
+ // @ts-ignore
+ console.log(req.auth); // todo fix types
const res = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
@@ -41,4 +42,4 @@ export async function POST(req: Request) {
status: 200,
headers: { "Content-Type": "text/event-stream" },
});
-}
+});
diff --git a/app/chat/[id]/page.tsx b/app/chat/[id]/page.tsx
index 4129e8c..f4e6f06 100644
--- a/app/chat/[id]/page.tsx
+++ b/app/chat/[id]/page.tsx
@@ -3,7 +3,7 @@ import { prisma } from "@/lib/prisma";
import { Chat } from "../../chat";
import { type Metadata } from "next";
-import { getServerSession } from "@/lib/session/get-server-session";
+import { auth } from "@/auth";
export interface ChatPageProps {
params: {
@@ -29,7 +29,7 @@ export const runtime = "nodejs"; // default
export const preferredRegion = "home";
export const dynamic = "force-dynamic";
export default async function ChatPage({ params }: ChatPageProps) {
- const session = await getServerSession();
+ const session = await auth();
const chat = await prisma.chat.findFirst({
where: {
id: params.id,
diff --git a/app/page.tsx b/app/page.tsx
index a3ca75a..7dec5b3 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,6 +1,6 @@
-import { getServerSession } from "@/lib/session/get-server-session";
import { Chat } from "./chat";
import { Sidebar } from "./sidebar";
+import { auth } from "@/auth";
// Prisma does not support Edge without the Data Proxy currently
export const runtime = "nodejs"; // default
@@ -8,7 +8,7 @@ export const preferredRegion = "home";
export const dynamic = "force-dynamic";
export default async function IndexPage() {
- const session = await getServerSession();
+ const session = await auth();
return (
diff --git a/app/sidebar.tsx b/app/sidebar.tsx
index e2379f3..d43cd82 100644
--- a/app/sidebar.tsx
+++ b/app/sidebar.tsx
@@ -2,7 +2,7 @@ import { NextChatLogo } from "@/components/ui/nextchat-logo";
import { Login } from "@/components/ui/login";
import { UserMenu } from "@/components/ui/user-menu";
import { prisma } from "@/lib/prisma";
-import { type Session } from "@/lib/session/types";
+import { type Session } from "@auth/nextjs/types";
import { cn } from "@/lib/utils";
import { Plus } from "lucide-react";
import Link from "next/link";
@@ -70,7 +70,8 @@ async function SidebarList({ session }: { session?: Session }) {
updatedAt: "desc",
},
}),
- [session?.user.id || ""],
+ // @ts-ignore
+ [session?.user?.id || ""],
{
revalidate: 3600,
}
diff --git a/auth.ts b/auth.ts
new file mode 100644
index 0000000..100244e
--- /dev/null
+++ b/auth.ts
@@ -0,0 +1,26 @@
+import NextAuth from "@auth/nextjs";
+import GitHub from "@auth/nextjs/providers/github";
+import { NextResponse } from "next/server";
+export const {
+ handlers: { GET, POST },
+ auth,
+ CSRF_experimental,
+} = NextAuth({
+ // @ts-ignore
+ providers: [GitHub],
+ session: { strategy: "jwt" },
+ async authorized({ request, auth }: any) {
+ const url = request.nextUrl;
+
+ if (request.method === "POST") {
+ const { authToken } = (await request.json()) ?? {};
+ // If the request has a valid auth token, it is authorized
+ const valid = true;
+ if (valid) return true;
+ return NextResponse.json("Invalid auth token", { status: 401 });
+ }
+
+ // Logged in users are authenticated, otherwise redirect to login page
+ return !!auth;
+ },
+});
diff --git a/components/ui/login.tsx b/components/ui/login.tsx
index f0c37f4..07edb90 100644
--- a/components/ui/login.tsx
+++ b/components/ui/login.tsx
@@ -1,14 +1,13 @@
"use client";
-
-import Link from "next/link";
+import { signIn } from "@auth/nextjs/client";
export function Login() {
return (
- signIn("github")}
>
Login
-
+
);
}
diff --git a/components/ui/user-menu.tsx b/components/ui/user-menu.tsx
index 97ff9b4..fb32743 100644
--- a/components/ui/user-menu.tsx
+++ b/components/ui/user-menu.tsx
@@ -1,7 +1,9 @@
"use client";
import { ThemeToggle } from "@/components/theme-toggle";
-import { type Session } from "@/lib/session/types";
+import { type Session } from "@auth/nextjs/types";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
+import { signOut } from "@auth/nextjs/client";
+
import Image from "next/image";
export interface UserMenuProps {
@@ -14,12 +16,12 @@ export function UserMenu({ session }: UserMenuProps) {