Skip to content

Commit 4ae5fa1

Browse files
authored
Merge pull request #37 from PMS61/main
chore: update dependencies and configuration for Next.js 16 and React 19
2 parents b052e56 + 95825f2 commit 4ae5fa1

File tree

11 files changed

+862
-442
lines changed

11 files changed

+862
-442
lines changed

.github/workflows/ci.yml

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,37 @@
1-
name: CI
2-
3-
on:
4-
push:
5-
branches: [ main, develop ]
6-
pull_request:
7-
branches: [ main, develop ]
8-
9-
jobs:
10-
build:
11-
runs-on: ubuntu-latest
12-
13-
steps:
14-
- uses: actions/checkout@v3
15-
16-
- name: Setup Node.js
17-
uses: actions/setup-node@v4
18-
with:
19-
node-version: '20'
20-
cache: 'npm'
21-
22-
- name: Install dependencies
23-
run: npm ci
24-
25-
- name: Type check
26-
run: npm run type-check
27-
28-
# - name: Run tests
29-
# run: npm run test
30-
31-
- name: Build
32-
run: npm run build
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [ main, develop ]
6+
pull_request:
7+
branches: [ main, develop ]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v3
15+
16+
- name: Setup Node.js
17+
uses: actions/setup-node@v4
18+
uses: actions/setup-node@v4
19+
with:
20+
node-version: '20'
21+
node-version: '20'
22+
cache: 'npm'
23+
24+
- name: Install dependencies
25+
run: npm ci
26+
27+
28+
- name: Type check
29+
run: npm run type-check
30+
31+
32+
# - name: Run tests
33+
# run: npm run test
34+
35+
36+
- name: Build
37+
run: npm run build -- --webpack

app/api/auth/[...nextauth]/route.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,11 @@ import { authOptions } from "@/lib/auth"
66
// should only export valid Route handlers (GET, POST, etc.). Exporting
77
// arbitrary values like `authOptions` from a Route file causes type errors
88
// during build.
9+
10+
// Note: For Cloudflare Pages compatibility, this route needs edge runtime
11+
// but NextAuth v4 has crypto dependencies. Consider upgrading to Auth.js v5
12+
// or using a different auth solution for full edge compatibility.
13+
// export const runtime = 'edge'
14+
915
const handler = NextAuth(authOptions as any)
1016
export { handler as GET, handler as POST }

app/api/resources/[domain]/route.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ export const runtime = 'edge';
77

88
export async function GET(
99
request: NextRequest,
10-
{ params }: { params: { domain: string } }
10+
{ params }: { params: Promise<{ domain: string }> }
1111
) {
1212
try {
13-
const domain = params.domain;
13+
const { domain } = await params;
1414
const domainResources = resources[domain as keyof typeof resources] || [];
1515

1616
return NextResponse.json(domainResources);

lib/auth.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,11 @@ export const authOptions: NextAuthOptions = {
7272
}
7373
return false;
7474
},
75-
async jwt({ token, user, trigger }) {
76-
// Fetch user's admin status from Supabase on sign in or session update
77-
if (token.email) {
75+
async jwt({ token, user, trigger, session }) {
76+
// Fetch user's admin status from Supabase only on initial sign in
77+
// Subsequent requests will use the cached value in the JWT token
78+
if (user) {
79+
// Initial sign in - fetch admin status
7880
try {
7981
const { data: userData } = await supabaseAdmin
8082
.from('users')
@@ -87,8 +89,15 @@ export const authOptions: NextAuthOptions = {
8789
}
8890
} catch (error) {
8991
console.error('Error fetching user admin status:', error);
92+
token.isAdmin = false;
9093
}
9194
}
95+
96+
// Handle session updates (e.g., when admin status changes)
97+
if (session && trigger === 'update') {
98+
token.isAdmin = session.isAdmin;
99+
}
100+
92101
return token;
93102
},
94103
async session({ session, token }) {

middleware.ts

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { getToken } from "next-auth/jwt";
22
import { NextResponse } from "next/server";
33
import type { NextRequest } from "next/server";
4-
import { createClient } from "@supabase/supabase-js";
54

65
export async function middleware(request: NextRequest) {
7-
const token = await getToken({
6+
const token = await getToken({
87
req: request,
98
secret: process.env.NEXTAUTH_SECRET
109
});
11-
10+
1211
const isAdminRoute = request.nextUrl.pathname.startsWith("/admin-dashboard");
1312
const isDashboardRoute = request.nextUrl.pathname.startsWith("/dashboard");
14-
13+
1514
// Protect dashboard and admin routes
1615
if (isDashboardRoute || isAdminRoute) {
1716
// Redirect to sign in if not authenticated
@@ -26,48 +25,21 @@ export async function middleware(request: NextRequest) {
2625
return NextResponse.redirect(new URL("/auth/error", request.url));
2726
}
2827

29-
// Check admin status directly from Supabase
30-
if (token.email) {
31-
try {
32-
const supabase = createClient(
33-
process.env.NEXT_PUBLIC_SUPABASE_URL!,
34-
process.env.SUPABASE_SERVICE_ROLE_KEY!,
35-
{
36-
auth: {
37-
autoRefreshToken: false,
38-
persistSession: false
39-
}
40-
}
41-
);
42-
43-
const { data: userData, error } = await supabase
44-
.from('users')
45-
.select('is_admin')
46-
.eq('email', token.email)
47-
.single();
48-
49-
const isAdmin = userData?.is_admin === 1;
50-
51-
// Admin-only routes protection
52-
if (isAdminRoute) {
53-
if (!isAdmin) {
54-
// Non-admin users trying to access admin dashboard - redirect to regular dashboard
55-
return NextResponse.redirect(new URL("/dashboard", request.url));
56-
}
57-
}
58-
59-
// Allow admins to access both /dashboard and /admin-dashboard
60-
// No redirect needed for admins accessing regular dashboard
61-
} catch (error) {
62-
console.error('Error checking admin status in middleware:', error);
63-
// If there's an error, allow regular dashboard access but not admin
64-
if (isAdminRoute) {
65-
return NextResponse.redirect(new URL("/dashboard", request.url));
66-
}
28+
// Admin-only routes protection
29+
if (isAdminRoute) {
30+
// For Cloudflare Pages compatibility, admin check is done client-side
31+
// Middleware only protects the route with authentication
32+
// The page itself will check admin status from the JWT token
33+
if (!token.isAdmin) {
34+
// Non-admin users trying to access admin dashboard - redirect to regular dashboard
35+
return NextResponse.redirect(new URL("/dashboard", request.url));
6736
}
6837
}
38+
39+
// Allow admins to access both /dashboard and /admin-dashboard
40+
// No redirect needed for admins accessing regular dashboard
6941
}
70-
42+
7143
return NextResponse.next();
7244
}
7345

next.config.mjs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ const nextConfig = {
66
// Use standalone output only for Docker deployments
77
// Cloudflare Pages uses its own build process
88
output: process.env.NEXT_OUTPUT_STANDALONE === 'true' ? 'standalone' : undefined,
9-
eslint: {
10-
// Prevent lint errors from failing the production build. Team can fix lint issues separately.
11-
ignoreDuringBuilds: true,
12-
},
139
images: {
1410
remotePatterns: [
1511
{
@@ -26,11 +22,10 @@ const nextConfig = {
2622
},
2723
],
2824
},
29-
experimental: {
30-
serverActions: {
31-
bodySizeLimit: '2mb',
32-
},
33-
},
25+
// Turbopack configuration (Next.js 16+)
26+
// Empty object to silence warning - webpack config is used for this project
27+
turbopack: {},
28+
// Webpack configuration (for backwards compatibility)
3429
webpack: (config, { isServer }) => {
3530
if (!isServer) {
3631
config.resolve.fallback = {

0 commit comments

Comments
 (0)