Skip to content

Commit 66dc1db

Browse files
committed
implemented better next auth configuration, enchanced security, increased rate limits and fixed orders admin page display bag
1 parent 53dc05c commit 66dc1db

5 files changed

Lines changed: 75 additions & 20 deletions

File tree

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

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import NextAuth from "next-auth";
1+
import NextAuth, { NextAuthOptions } from "next-auth";
22
import { Account, User as AuthUser } from "next-auth";
33
import GithubProvider from "next-auth/providers/github";
44
import CredentialsProvider from "next-auth/providers/credentials";
@@ -7,7 +7,7 @@ import bcrypt from "bcryptjs";
77
import prisma from "@/utils/db";
88
import { nanoid } from "nanoid";
99

10-
export const authOptions: any = {
10+
export const authOptions: NextAuthOptions = {
1111
// Configure one or more authentication providers
1212
providers: [
1313
CredentialsProvider({
@@ -40,33 +40,84 @@ export const authOptions: any = {
4040
} catch (err: any) {
4141
throw new Error(err);
4242
}
43+
return null;
4344
},
44-
})
45-
// ... existing providers ...
45+
}),
46+
// Uncomment and configure these providers as needed
47+
// GithubProvider({
48+
// clientId: process.env.GITHUB_ID!,
49+
// clientSecret: process.env.GITHUB_SECRET!,
50+
// }),
51+
// GoogleProvider({
52+
// clientId: process.env.GOOGLE_CLIENT_ID!,
53+
// clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
54+
// }),
4655
],
4756
callbacks: {
4857
async signIn({ user, account }: { user: AuthUser; account: Account }) {
49-
if (account?.provider == "credentials") {
58+
if (account?.provider === "credentials") {
5059
return true;
5160
}
52-
// ... existing provider logic ...
61+
62+
// Handle OAuth providers
63+
if (account?.provider === "github" || account?.provider === "google") {
64+
try {
65+
// Check if user exists in database
66+
const existingUser = await prisma.user.findFirst({
67+
where: {
68+
email: user.email!,
69+
},
70+
});
71+
72+
if (!existingUser) {
73+
// Create new user for OAuth providers
74+
await prisma.user.create({
75+
data: {
76+
id: nanoid(),
77+
email: user.email!,
78+
role: "user",
79+
// OAuth users don't have passwords
80+
password: null,
81+
},
82+
});
83+
}
84+
return true;
85+
} catch (error) {
86+
console.error("Error in signIn callback:", error);
87+
return false;
88+
}
89+
}
90+
91+
return true;
5392
},
5493
async jwt({ token, user }) {
5594
if (user) {
5695
token.role = user.role;
96+
token.id = user.id;
5797
}
5898
return token;
5999
},
60100
async session({ session, token }) {
61101
if (token) {
62-
session.user.role = token.role;
102+
session.user.role = token.role as string;
103+
session.user.id = token.id as string;
63104
}
64105
return session;
65106
},
66107
},
67108
pages: {
68109
signIn: '/login',
110+
error: '/login', // Redirect to login page on auth errors
111+
},
112+
session: {
113+
strategy: "jwt",
114+
maxAge: 30 * 24 * 60 * 60, // 30 days
115+
},
116+
jwt: {
117+
maxAge: 30 * 24 * 60 * 60, // 30 days
69118
},
119+
secret: process.env.NEXTAUTH_SECRET,
120+
debug: process.env.NODE_ENV === "development",
70121
};
71122

72123
export const handler = NextAuth(authOptions);

components/AdminOrders.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const AdminOrders = () => {
2121
const fetchOrders = async () => {
2222
const response = await apiClient.get("/api/orders");
2323
const data = await response.json();
24-
setOrders(data);
24+
25+
setOrders(data?.orders);
2526
};
2627
fetchOrders();
2728
}, []);
@@ -49,7 +50,7 @@ const AdminOrders = () => {
4950
</thead>
5051
<tbody>
5152
{/* row 1 */}
52-
{orders &&
53+
{orders && orders.length > 0 &&
5354
orders.map((order) => (
5455
<tr key={order?.id}>
5556
<th>

server/middleware/advancedRateLimiter.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const rateLimit = require('express-rate-limit');
33
// Rate limiter for password reset attempts
44
const passwordResetLimiter = rateLimit({
55
windowMs: 60 * 60 * 1000, // 1 hour
6-
max: 3, // Limit to 3 password reset attempts per hour per IP
6+
max: 6, // Limit to 3 password reset attempts per hour per IP
77
message: {
88
error: 'Too many password reset attempts, please try again later.',
99
retryAfter: '1 hour'
@@ -21,7 +21,7 @@ const passwordResetLimiter = rateLimit({
2121
// Rate limiter for admin operations
2222
const adminLimiter = rateLimit({
2323
windowMs: 15 * 60 * 1000, // 15 minutes
24-
max: 50, // Higher limit for admin operations
24+
max: 100, // Higher limit for admin operations
2525
message: {
2626
error: 'Too many admin operations, please try again later.',
2727
retryAfter: '15 minutes'
@@ -39,7 +39,7 @@ const adminLimiter = rateLimit({
3939
// Rate limiter for wishlist operations
4040
const wishlistLimiter = rateLimit({
4141
windowMs: 5 * 60 * 1000, // 5 minutes
42-
max: 20, // Limit wishlist operations
42+
max: 40, // Limit wishlist operations
4343
message: {
4444
error: 'Too many wishlist operations, please try again later.',
4545
retryAfter: '5 minutes'
@@ -57,7 +57,7 @@ const wishlistLimiter = rateLimit({
5757
// Rate limiter for product operations (viewing, etc.)
5858
const productLimiter = rateLimit({
5959
windowMs: 1 * 60 * 1000, // 1 minute
60-
max: 60, // Allow more requests for product viewing
60+
max: 120, // Allow more requests for product viewing
6161
message: {
6262
error: 'Too many product requests, please try again later.',
6363
retryAfter: '1 minute'

server/middleware/rateLimiter.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const rateLimit = require('express-rate-limit');
33
// General API rate limiter - applies to all API routes
44
const generalLimiter = rateLimit({
55
windowMs: 15 * 60 * 1000, // 15 minutes
6-
max: 100, // Limit each IP to 100 requests per windowMs
6+
max: 200, // Limit each IP to 100 requests per windowMs
77
message: {
88
error: 'Too many requests from this IP, please try again later.',
99
retryAfter: '15 minutes'
@@ -21,7 +21,7 @@ const generalLimiter = rateLimit({
2121
// Strict rate limiter for authentication endpoints
2222
const authLimiter = rateLimit({
2323
windowMs: 15 * 60 * 1000, // 15 minutes
24-
max: 5, // Limit each IP to 5 login attempts per windowMs
24+
max: 10, // Limit each IP to 5 login attempts per windowMs
2525
message: {
2626
error: 'Too many authentication attempts, please try again later.',
2727
retryAfter: '15 minutes'
@@ -40,7 +40,7 @@ const authLimiter = rateLimit({
4040
// Strict rate limiter for user registration
4141
const registerLimiter = rateLimit({
4242
windowMs: 60 * 60 * 1000, // 1 hour
43-
max: 3, // Limit each IP to 3 registration attempts per hour
43+
max: 6, // Limit each IP to 3 registration attempts per hour
4444
message: {
4545
error: 'Too many registration attempts, please try again later.',
4646
retryAfter: '1 hour'
@@ -58,7 +58,7 @@ const registerLimiter = rateLimit({
5858
// Moderate rate limiter for user management endpoints
5959
const userManagementLimiter = rateLimit({
6060
windowMs: 15 * 60 * 1000, // 15 minutes
61-
max: 20, // Limit each IP to 20 requests per windowMs
61+
max: 40, // Limit each IP to 20 requests per windowMs
6262
message: {
6363
error: 'Too many user management requests, please try again later.',
6464
retryAfter: '15 minutes'
@@ -76,7 +76,7 @@ const userManagementLimiter = rateLimit({
7676
// Rate limiter for file uploads
7777
const uploadLimiter = rateLimit({
7878
windowMs: 15 * 60 * 1000, // 15 minutes
79-
max: 10, // Limit each IP to 10 uploads per windowMs
79+
max: 20, // Limit each IP to 10 uploads per windowMs
8080
message: {
8181
error: 'Too many file uploads, please try again later.',
8282
retryAfter: '15 minutes'
@@ -94,7 +94,7 @@ const uploadLimiter = rateLimit({
9494
// Rate limiter for search endpoints
9595
const searchLimiter = rateLimit({
9696
windowMs: 1 * 60 * 1000, // 1 minute
97-
max: 30, // Limit each IP to 30 search requests per minute
97+
max: 60, // Limit each IP to 30 search requests per minute
9898
message: {
9999
error: 'Too many search requests, please try again later.',
100100
retryAfter: '1 minute'
@@ -112,7 +112,7 @@ const searchLimiter = rateLimit({
112112
// Rate limiter for order operations
113113
const orderLimiter = rateLimit({
114114
windowMs: 15 * 60 * 1000, // 15 minutes
115-
max: 15, // Limit each IP to 15 order operations per windowMs
115+
max: 20, // Limit each IP to 15 order operations per windowMs
116116
message: {
117117
error: 'Too many order operations, please try again later.',
118118
retryAfter: '15 minutes'

typings.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ interface WishListItem {
8686
declare module "next-auth" {
8787
interface Session {
8888
user: {
89+
id: string;
8990
name: string;
9091
email: string;
9192
image: string;
@@ -94,12 +95,14 @@ declare module "next-auth" {
9495
}
9596

9697
interface User {
98+
id: string;
9799
role: string;
98100
}
99101
}
100102

101103
declare module "next-auth/jwt" {
102104
interface JWT {
105+
id: string;
103106
role: string;
104107
}
105108
}

0 commit comments

Comments
 (0)