diff --git a/app.dockerfile b/app.dockerfile index 3433288..68d5f5a 100644 --- a/app.dockerfile +++ b/app.dockerfile @@ -16,6 +16,9 @@ FROM node:20.18.0-slim WORKDIR /home/perplexica +# 🐧 Install curl + netstat (from net-tools) +RUN apt-get update && apt-get install -y curl net-tools && apt-get clean + COPY --from=builder /home/perplexica/public ./public COPY --from=builder /home/perplexica/.next/static ./public/_next/static @@ -24,4 +27,4 @@ COPY --from=builder /home/perplexica/data ./data RUN mkdir /home/perplexica/uploads -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] diff --git a/src/app/[auth0]/route.ts b/src/app/[auth0]/route.ts new file mode 100644 index 0000000..1097b3a --- /dev/null +++ b/src/app/[auth0]/route.ts @@ -0,0 +1,4 @@ +import { handleAuth } from '@auth0/nextjs-auth0'; + +export const GET = handleAuth(); +export const POST = handleAuth(); \ No newline at end of file diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 13f2da3..b0c8a16 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -3,6 +3,7 @@ import { Message } from './ChatWindow'; import { useEffect, useState } from 'react'; import { formatTimeDifference } from '@/lib/utils'; import DeleteChat from './DeleteChat'; +import ProfileButton from './ProfileButton'; // adjust path if needed const Navbar = ({ chatId, @@ -64,6 +65,7 @@ const Navbar = ({ className="active:scale-95 transition duration-100 cursor-pointer" /> {}} /> + {/* 👈 Add this here */} ); diff --git a/src/components/ProfileButton.tsx b/src/components/ProfileButton.tsx new file mode 100644 index 0000000..f3a1423 --- /dev/null +++ b/src/components/ProfileButton.tsx @@ -0,0 +1,32 @@ +'use client'; + +import { useEffect, useState } from 'react'; + +interface UserProfile { + name?: string; + email?: string; + picture?: string; +} + +export default function ProfileButton() { + const [user, setUser] = useState(null); + + useEffect(() => { + fetch('/auth/profile') + .then((res) => (res.ok ? res.json() : null)) + .then((data) => setUser(data?.user)) + .catch(() => setUser(null)); + }, []); + + if (!user) return null; + + return ( + + profile + + ); +} diff --git a/src/middleware.ts b/src/middleware.ts index 67158ef..8081c35 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,19 +1,29 @@ -import type { NextRequest } from "next/server" +import { auth0 } from './lib/auth0'; +import { NextResponse } from 'next/server'; +import type { NextRequest } from 'next/server'; -import { auth0 } from "./lib/auth0" export async function middleware(request: NextRequest) { - return await auth0.middleware(request) + const res = await auth0.getSession(request); + + if (!res) { + // not logged in, redirect to Auth0 login + return Response.redirect( + new URL('/auth/login', request.url), + 302 + ); + } + + return NextResponse.next(); } export const config = { matcher: [ /* - * Match all request paths except for the ones starting with: - * - _next/static (static files) - * - _next/image (image optimization files) - * - favicon.ico, sitemap.xml, robots.txt (metadata files) + * Match all paths except: + * - public files (_next, images, icons, etc.) + * - auth routes like /auth/login and /auth/callback */ - "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)", + '/((?!_next/static|_next/image|favicon.ico|auth/.*).*)', ], -} \ No newline at end of file +}; \ No newline at end of file