forked from bradtraversy/prostore
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth.ts
165 lines (143 loc) · 4.6 KB
/
auth.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import NextAuth from 'next-auth';
import { PrismaAdapter } from '@auth/prisma-adapter';
import { prisma } from '@/db/prisma';
import CredentialsProvider from 'next-auth/providers/credentials';
import { compare } from './lib/encrypt';
import type { NextAuthConfig } from 'next-auth';
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export const config = {
pages: {
signIn: '/sign-in',
error: '/sign-in',
},
session: {
strategy: 'jwt',
maxAge: 30 * 24 * 60 * 60, // 30 days
},
adapter: PrismaAdapter(prisma),
providers: [
CredentialsProvider({
credentials: {
email: { type: 'email' },
password: { type: 'password' },
},
async authorize(credentials) {
if (credentials == null) return null;
// Find user in database
const user = await prisma.user.findFirst({
where: {
email: credentials.email as string,
},
});
// Check if user exists and if the password matches
if (user && user.password) {
const isMatch = await compare(
credentials.password as string,
user.password
);
// If password is correct, return user
if (isMatch) {
return {
id: user.id,
name: user.name,
email: user.email,
role: user.role,
};
}
}
// If user does not exist or password does not match return null
return null;
},
}),
],
callbacks: {
async session({ session, user, trigger, token }: any) {
// Set the user ID from the token
session.user.id = token.sub;
session.user.role = token.role;
session.user.name = token.name;
// If there is an update, set the user name
if (trigger === 'update') {
session.user.name = user.name;
}
return session;
},
async jwt({ token, user, trigger, session }: any) {
// Assign user fields to token
if (user) {
token.id = user.id;
token.role = user.role;
// If user has no name then use the email
if (user.name === 'NO_NAME') {
token.name = user.email!.split('@')[0];
// Update database to reflect the token name
await prisma.user.update({
where: { id: user.id },
data: { name: token.name },
});
}
if (trigger === 'signIn' || trigger === '#') {
const cookiesObject = await cookies();
const sessionCartId = cookiesObject.get('sessionCartId')?.value;
if (sessionCartId) {
const sessionCart = await prisma.cart.findFirst({
where: { sessionCartId },
});
if (sessionCart) {
// Delete current user cart
await prisma.cart.deleteMany({
where: { userId: user.id },
});
// Assign new cart
await prisma.cart.update({
where: { id: sessionCart.id },
data: { userId: user.id },
});
}
}
}
}
// Handle session updates
if (session?.user.name && trigger === 'update') {
token.name = session.user.name;
}
return token;
},
authorized({ request, auth }: any) {
// Array of regex patterns of paths we want to protect
const protectedPaths = [
/\/shipping-address/,
/\/payment-method/,
/\/place-order/,
/\/profile/,
/\/user\/(.*)/,
/\/order\/(.*)/,
/\/admin/,
];
// Get pathname from the req URL object
const { pathname } = request.nextUrl;
// Check if user is not authenticated and accessing a protected path
if (!auth && protectedPaths.some((p) => p.test(pathname))) return false;
// Check for session cart cookie
if (!request.cookies.get('sessionCartId')) {
// Generate new session cart id cookie
const sessionCartId = crypto.randomUUID();
// Clone the req headers
const newRequestHeaders = new Headers(request.headers);
// Create new response and add the new headers
const response = NextResponse.next({
request: {
headers: newRequestHeaders,
},
});
// Set newly generated sessionCartId in the response cookies
response.cookies.set('sessionCartId', sessionCartId);
return response;
} else {
return true;
}
},
},
} satisfies NextAuthConfig;
export const { handlers, auth, signIn, signOut } = NextAuth(config);