Skip to content

Commit 3ef0d28

Browse files
committed
feat: update app with RAG tracking and admin dashboard changes
1 parent bea321f commit 3ef0d28

File tree

6 files changed

+247
-88
lines changed

6 files changed

+247
-88
lines changed

app/globals.css

+46
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,49 @@ a {
4040
color-scheme: dark;
4141
}
4242
}
43+
44+
/* Mermaid diagram styling */
45+
.mermaid {
46+
text-align: center;
47+
}
48+
49+
.mermaid svg {
50+
max-width: 100%;
51+
height: auto !important;
52+
margin: 0 auto;
53+
display: block;
54+
}
55+
56+
/* Fix for mermaid dark mode issues */
57+
[data-theme="dark"] .mermaid .label {
58+
color: #FFFFFF !important;
59+
}
60+
61+
[data-theme="dark"] .mermaid .node rect,
62+
[data-theme="dark"] .mermaid .node circle,
63+
[data-theme="dark"] .mermaid .node ellipse,
64+
[data-theme="dark"] .mermaid .node polygon,
65+
[data-theme="dark"] .mermaid .node path {
66+
fill: #2D2D2D !important;
67+
stroke: #CCCCCC !important;
68+
}
69+
70+
[data-theme="dark"] .mermaid .edgePath .path {
71+
stroke: #CCCCCC !important;
72+
}
73+
74+
[data-theme="dark"] .mermaid .edgeLabel {
75+
background-color: #2D2D2D !important;
76+
color: #FFFFFF !important;
77+
}
78+
79+
/* Enhanced visibility for diagrams */
80+
.mermaid-diagram-container {
81+
padding: 16px;
82+
background-color: #F8F9FA;
83+
border-radius: 8px;
84+
border: 1px solid #E1E4E8;
85+
margin: 16px 0;
86+
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
87+
overflow: auto;
88+
}

app/layout.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '@fontsource/roboto/300.css';
99
import '@fontsource/roboto/400.css';
1010
import '@fontsource/roboto/500.css';
1111
import '@fontsource/roboto/700.css';
12+
import './globals.css';
1213

1314
const inter = Inter({ subsets: ['latin'] });
1415

app/lib/auth.js

+44-15
Original file line numberDiff line numberDiff line change
@@ -11,35 +11,61 @@ export const authOptions = {
1111
},
1212
async authorize(credentials) {
1313
try {
14-
const { conn } = await connectToDatabase();
15-
const users = conn.connection.db.collection('users');
16-
1714
// Use environment variables for admin credentials
1815
const adminEmail = process.env.ADMIN_EMAIL || '[email protected]';
1916
const adminPassword = process.env.ADMIN_PASSWORD || 'admin123';
2017

2118
if (credentials.email === adminEmail && credentials.password === adminPassword) {
19+
console.log('Admin user authenticated successfully');
2220
return {
2321
id: '1',
2422
email: adminEmail,
2523
name: 'Admin User',
26-
isAdmin: true
24+
isAdmin: true,
25+
role: 'admin'
2726
};
2827
}
2928

30-
// In production, verify against your database
31-
const user = await users.findOne({ email: credentials.email });
32-
if (!user) return null;
29+
try {
30+
const { conn } = await connectToDatabase();
31+
const users = conn.connection.db.collection('users');
32+
33+
// In production, verify against your database
34+
const user = await users.findOne({ email: credentials.email });
35+
if (!user) {
36+
console.log(`User not found: ${credentials.email}`);
37+
return null;
38+
}
3339

34-
// In production, use proper password hashing
35-
if (user.password !== credentials.password) return null;
40+
// In production, use proper password hashing
41+
if (user.password !== credentials.password) {
42+
console.log(`Invalid password for user: ${credentials.email}`);
43+
return null;
44+
}
3645

37-
return {
38-
id: user._id.toString(),
39-
email: user.email,
40-
name: user.name,
41-
isAdmin: user.isAdmin
42-
};
46+
console.log(`User authenticated successfully: ${credentials.email}`);
47+
return {
48+
id: user._id.toString(),
49+
email: user.email,
50+
name: user.name,
51+
isAdmin: user.isAdmin || false,
52+
role: user.isAdmin ? 'admin' : 'user'
53+
};
54+
} catch (dbError) {
55+
console.error('Database error during authentication:', dbError);
56+
// Fall back to admin credentials if database connection fails
57+
if (credentials.email === adminEmail && credentials.password === adminPassword) {
58+
console.log('Using admin credentials as fallback');
59+
return {
60+
id: '1',
61+
email: adminEmail,
62+
name: 'Admin User',
63+
isAdmin: true,
64+
role: 'admin'
65+
};
66+
}
67+
return null;
68+
}
4369
} catch (error) {
4470
console.error('Auth error:', error);
4571
return null;
@@ -51,12 +77,14 @@ export const authOptions = {
5177
async jwt({ token, user }) {
5278
if (user) {
5379
token.isAdmin = user.isAdmin;
80+
token.role = user.role;
5481
}
5582
return token;
5683
},
5784
async session({ session, token }) {
5885
if (token) {
5986
session.user.isAdmin = token.isAdmin;
87+
session.user.role = token.role;
6088
}
6189
return session;
6290
}
@@ -67,4 +95,5 @@ export const authOptions = {
6795
session: {
6896
strategy: 'jwt',
6997
},
98+
debug: process.env.NODE_ENV === 'development',
7099
};

app/models/UnansweredQuestion.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ const unansweredQuestionSchema = new mongoose.Schema({
55
user_id: { type: String, required: true },
66
user_name: { type: String, required: true },
77
question: { type: String, required: true },
8-
answer: { type: String, required: true },
8+
answer: { type: String },
99
module: { type: String },
1010
question_embedding: {
1111
type: [Number],
12-
required: true,
1312
index: {
1413
type: 'vectorSearch',
1514
dimensions: 1536,

middleware.js

+58-17
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,70 @@ import { getToken } from 'next-auth/jwt';
44
export async function middleware(request) {
55
// Get the pathname of the request
66
const path = request.nextUrl.pathname;
7+
8+
// Define public paths that don't require authentication
9+
const isPublicPath =
10+
path === '/auth/signin' ||
11+
path === '/auth/signup' ||
12+
path === '/api/auth/signin' ||
13+
path === '/api/auth/signup' ||
14+
path === '/api/auth/callback' ||
15+
path === '/api/auth/session' ||
16+
path === '/api/auth/csrf' ||
17+
path === '/api/auth/providers' ||
18+
path.startsWith('/_next') ||
19+
path.startsWith('/static') ||
20+
path === '/favicon.ico';
21+
22+
// Check if the path is public
23+
if (isPublicPath) {
24+
return NextResponse.next();
25+
}
26+
27+
// Check if the path is an API route
28+
const isApiRoute = path.startsWith('/api/');
729

8-
// If the path starts with /admin, check authentication
9-
if (path.startsWith('/admin')) {
10-
const session = await getToken({
11-
req: request,
12-
secret: process.env.NEXTAUTH_SECRET
13-
});
14-
15-
// If there is no session or the user is not an admin, redirect to signin
16-
if (!session || !session.isAdmin) {
17-
const url = new URL('/auth/signin', request.url);
18-
url.searchParams.set('callbackUrl', encodeURI(request.url));
19-
return NextResponse.redirect(url);
30+
// For API routes, check for authentication
31+
if (isApiRoute) {
32+
try {
33+
const token = await getToken({ req: request });
34+
35+
// If no token is found and it's not a public API route, return unauthorized
36+
if (!token) {
37+
console.log(`Unauthorized API access attempt: ${path}`);
38+
return NextResponse.json(
39+
{ error: 'Unauthorized' },
40+
{ status: 401 }
41+
);
42+
}
43+
44+
// For admin-only API routes, check if the user is an admin
45+
if (path.startsWith('/api/admin/') && !token.isAdmin) {
46+
console.log(`Forbidden API access attempt: ${path}`);
47+
return NextResponse.json(
48+
{ error: 'Forbidden' },
49+
{ status: 403 }
50+
);
51+
}
52+
} catch (error) {
53+
console.error('Middleware error:', error);
54+
// Continue to the next middleware or route handler
2055
}
2156
}
22-
57+
58+
// Continue to the next middleware or route handler
2359
return NextResponse.next();
2460
}
2561

26-
// Configure which paths middleware should run on
62+
// Configure the middleware to run on specific paths
2763
export const config = {
2864
matcher: [
29-
// Match all paths starting with /admin
30-
'/admin/:path*'
31-
]
65+
/*
66+
* Match all request paths except for the ones starting with:
67+
* - _next/static (static files)
68+
* - _next/image (image optimization files)
69+
* - favicon.ico (favicon file)
70+
*/
71+
'/((?!_next/static|_next/image|favicon.ico).*)',
72+
],
3273
};

0 commit comments

Comments
 (0)