Merge pull request #3 from MythosAI/feature/auth

Feature/auth
This commit is contained in:
Jason Feibelman 2025-03-27 15:22:23 -04:00 committed by GitHub
commit a9404062c0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1539 additions and 1159 deletions

8
.env.sample Normal file
View file

@ -0,0 +1,8 @@
# auth0 credentials
AUTH0_SECRET=your_auth0_secret
APP_BASE_URL=http://localhost:3000
AUTH0_DOMAIN=your_auth0_domain
AUTH0_ISSUER_BASE_URL=your_auth0_issuer_base_url
AUTH0_CLIENT_ID=your_auth0_client_id
AUTH0_CLIENT_SECRET=your_auth0_client_secret
SEARXNG_API_URL=http://localhost:8080

View file

@ -19,6 +19,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
@ -27,4 +30,4 @@ COPY --from=builder /home/perplexica/data ./data
RUN mkdir /home/perplexica/uploads
CMD ["node", "server.js"]
CMD ["node", "server.js"]

View file

@ -14,8 +14,10 @@ services:
build:
context: .
dockerfile: app.dockerfile
environment:
- SEARXNG_API_URL=http://searxng:8080
env_file:
- .env # env variables for auth0
environment
- SEARXNG_API_URL=http://localhost:8080
ports:
- 3000:3000
networks:

5
notes.md Normal file
View file

@ -0,0 +1,5 @@
### Adding auth0
* use `yard add` for new packages and the packages will be updated automatically
* auth-secret generate with `openssl rand -hex 32`
* need to no-cache if updating packages...don't need to remove `--frozen-lockfile` can be handled with `yarn`
* version 2 is using

View file

@ -12,6 +12,7 @@
"db:push": "drizzle-kit push"
},
"dependencies": {
"@auth0/nextjs-auth0": "^4",
"@headlessui/react": "^2.2.0",
"@iarna/toml": "^2.2.5",
"@icons-pack/react-simple-icons": "^12.3.0",

24
src/app/profile/page.tsx Normal file
View file

@ -0,0 +1,24 @@
import { auth0 } from '@/lib/auth0';
export default async function ProfilePage() {
const session = await auth0.getSession();
if (!session) {
return (
<main>
<h2> Not logged in</h2>
<a href="/auth/login">Log in</a>
</main>
);
}
return (
<main>
<h2> Logged in as {session.user.name}</h2>
<p>Email: {session.user.email}</p>
<img src={session.user.picture} alt="avatar" width={100} />
<br />
<a href="/auth/logout">Log out</a>
</main>
);
}

View file

@ -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"
/>
<DeleteChat redirect chatId={chatId} chats={[]} setChats={() => {}} />
<ProfileButton /> {/* 👈 Add this here */}
</div>
</div>
);

View file

@ -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<UserProfile | null>(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 (
<a href="/auth/logout" title="Log out" className="block p-2">
<img
src={user.picture}
alt="profile"
className="rounded-full w-8 h-8 border border-white/20"
/>
</a>
);
}

6
src/lib/auth0.ts Normal file
View file

@ -0,0 +1,6 @@
// lib/auth0.ts
import { Auth0Client } from '@auth0/nextjs-auth0/server';
export const auth0 = new Auth0Client();
console.log('💥 AUTH0_ISSUER_BASE_URL =', process.env.AUTH0_ISSUER_BASE_URL);

32
src/middleware.ts Normal file
View file

@ -0,0 +1,32 @@
import { NextRequest, NextResponse } from "next/server"
import { auth0 } from "@/lib/auth0"
export async function middleware(request: NextRequest) {
const authRes = await auth0.middleware(request)
if (request.nextUrl.pathname.startsWith("/auth")) {
return authRes
}
const session = await auth0.getSession(request)
if (!session) {
// user is not authenticated, redirect to login page
return NextResponse.redirect(new URL("/auth/login", request.nextUrl.origin))
}
// the headers from the auth middleware should always be returned
return authRes
}
// export const config = {
// matcher: [
// /*
// * Match all paths except:
// * - public files (_next, images, icons, etc.)
// * - auth routes like /auth/login and /auth/callback
// */
// '/((?!_next/static|_next/image|favicon.ico|auth/.*).*)',
// ],
// };

2577
yarn.lock

File diff suppressed because it is too large Load diff