commit
ab6040f083
11 changed files with 1534 additions and 1156 deletions
8
.env.sample
Normal file
8
.env.sample
Normal 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
|
||||
|
|
@ -30,6 +30,7 @@ COPY --from=builder /home/perplexica /home/perplexica
|
|||
# COPY --from=builder /home/perplexica/.next/standalone ./
|
||||
# COPY --from=builder /home/perplexica/data ./data
|
||||
|
||||
|
||||
RUN mkdir -p /home/perplexica/uploads
|
||||
|
||||
# CMD ["node", "server.js"]
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ services:
|
|||
build:
|
||||
context: .
|
||||
dockerfile: app.dockerfile
|
||||
env_file:
|
||||
- .env # env variables for auth0
|
||||
environment:
|
||||
- SEARXNG_API_URL=http://searxng:8080
|
||||
- CHOKIDAR_USEPOLLING=true
|
||||
|
|
|
|||
5
notes.md
Normal file
5
notes.md
Normal 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
|
||||
|
|
@ -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
24
src/app/profile/page.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
32
src/components/ProfileButton.tsx
Normal file
32
src/components/ProfileButton.tsx
Normal 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
6
src/lib/auth0.ts
Normal 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
32
src/middleware.ts
Normal 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/.*).*)',
|
||||
// ],
|
||||
// };
|
||||
Loading…
Add table
Add a link
Reference in a new issue