@driveflux/auth 4.0.60 → 4.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AuthProvider.js +76 -59
- package/dist/authorization/constants.js +45 -24
- package/dist/authorization/define.js +57 -28
- package/dist/authorization/fields/index.js +4 -7
- package/dist/authorization/helpers.js +10 -8
- package/dist/authorization/index.js +6 -6
- package/dist/authorization/permissions-list.js +5 -7
- package/dist/authorization/quick.js +1 -1
- package/dist/authorization/roles/admin/business-development-executive.js +20 -7
- package/dist/authorization/roles/admin/ceo.js +4 -2
- package/dist/authorization/roles/admin/common.js +4 -2
- package/dist/authorization/roles/admin/concierge.js +35 -10
- package/dist/authorization/roles/admin/customer-success-executive.js +40 -10
- package/dist/authorization/roles/admin/data-analyst.js +7 -4
- package/dist/authorization/roles/admin/designer.js +7 -4
- package/dist/authorization/roles/admin/engineer.js +7 -4
- package/dist/authorization/roles/admin/finance-executive.js +11 -4
- package/dist/authorization/roles/admin/head-of-business-development.js +14 -4
- package/dist/authorization/roles/admin/head-of-data-analytics.js +14 -4
- package/dist/authorization/roles/admin/head-of-engineering.js +17 -6
- package/dist/authorization/roles/admin/head-of-finance.js +8 -3
- package/dist/authorization/roles/admin/head-of-human-resources.js +13 -5
- package/dist/authorization/roles/admin/head-of-marketing.js +17 -5
- package/dist/authorization/roles/admin/head-of-operations.js +8 -3
- package/dist/authorization/roles/admin/head-of-product.js +17 -6
- package/dist/authorization/roles/admin/head-of-sales.js +17 -5
- package/dist/authorization/roles/admin/human-resources-executive.js +12 -5
- package/dist/authorization/roles/admin/marketing-executive.js +7 -4
- package/dist/authorization/roles/admin/product-manager.js +7 -4
- package/dist/authorization/roles/admin/sales-executive.js +24 -8
- package/dist/authorization/roles/consumer/business-admin.js +19 -6
- package/dist/authorization/roles/consumer/business-user.js +18 -6
- package/dist/authorization/roles/consumer/member.js +16 -6
- package/dist/authorization/types.js +1 -1
- package/dist/authorization/update-user-permissions.js +22 -15
- package/dist/authorization/utils.js +26 -11
- package/dist/context.js +8 -9
- package/dist/default.js +1 -1
- package/dist/server/authenticate-user.js +11 -7
- package/dist/server/cors.js +23 -12
- package/dist/server/credentials-provider.js +2 -2
- package/dist/server/next-auth.js +104 -109
- package/dist/server/prisma-adapter.js +88 -52
- package/dist/server/verfiy-token.js +39 -24
- package/dist/translations.js +4 -4
- package/dist/use-auth.js +1 -1
- package/dist/use-session.js +1 -1
- package/package.json +2 -2
package/dist/server/next-auth.js
CHANGED
|
@@ -8,7 +8,7 @@ import { nanoid } from 'nanoid';
|
|
|
8
8
|
import CredentialsProvider from 'next-auth/providers/credentials';
|
|
9
9
|
import FacebookProvider from 'next-auth/providers/facebook';
|
|
10
10
|
import GoogleProvider from 'next-auth/providers/google';
|
|
11
|
-
import { AUTH_COOKIE_CALLBACK_URL, AUTH_COOKIE_CSRF_TOKEN, AUTH_COOKIE_NONCE, AUTH_COOKIE_PKCE_CODE_VERIFIER, AUTH_COOKIE_SESSION_TOKEN, AUTH_COOKIE_STATE
|
|
11
|
+
import { AUTH_COOKIE_CALLBACK_URL, AUTH_COOKIE_CSRF_TOKEN, AUTH_COOKIE_NONCE, AUTH_COOKIE_PKCE_CODE_VERIFIER, AUTH_COOKIE_SESSION_TOKEN, AUTH_COOKIE_STATE } from '../constants.js';
|
|
12
12
|
import { extractDefault } from '../default.js';
|
|
13
13
|
import { translations } from '../translations.js';
|
|
14
14
|
import { authenticateUser } from './authenticate-user.js';
|
|
@@ -21,80 +21,79 @@ const nextAuthUrl = process.env.NEXTAUTH_URL;
|
|
|
21
21
|
if (!nextAuthUrl) {
|
|
22
22
|
throw new Error('NEXTAUTH_URL is not set');
|
|
23
23
|
}
|
|
24
|
-
export const generateSessionToken = async (user)
|
|
24
|
+
export const generateSessionToken = async (user)=>{
|
|
25
25
|
const secret = new TextEncoder().encode(config.auth.jwtSecret);
|
|
26
26
|
const alg = 'HS256';
|
|
27
27
|
const token = await new SignJWT({
|
|
28
|
-
roles: user.groups
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
.setSubject(user.id)
|
|
33
|
-
.setIssuer('flux.website')
|
|
34
|
-
.setAudience('flux.website')
|
|
35
|
-
.sign(secret);
|
|
28
|
+
roles: user.groups
|
|
29
|
+
}).setProtectedHeader({
|
|
30
|
+
alg
|
|
31
|
+
}).setIssuedAt().setSubject(user.id).setIssuer('flux.website').setAudience('flux.website').sign(secret);
|
|
36
32
|
return token.toString();
|
|
37
33
|
};
|
|
38
|
-
export const getCredentialsOptions = ()
|
|
34
|
+
export const getCredentialsOptions = ()=>{
|
|
39
35
|
return {
|
|
40
36
|
name: 'Credentials',
|
|
41
37
|
credentials: {
|
|
42
|
-
login: {
|
|
43
|
-
|
|
38
|
+
login: {
|
|
39
|
+
label: translations.email,
|
|
40
|
+
type: 'text'
|
|
41
|
+
},
|
|
42
|
+
password: {
|
|
43
|
+
label: translations.password,
|
|
44
|
+
type: 'password'
|
|
45
|
+
}
|
|
44
46
|
},
|
|
45
|
-
async authorize(credentials) {
|
|
47
|
+
async authorize (credentials) {
|
|
46
48
|
if (!credentials) {
|
|
47
49
|
return null;
|
|
48
50
|
}
|
|
49
51
|
const authResult = await authenticateUser(credentials);
|
|
50
52
|
return authResult.ok ? authResult.val : null;
|
|
51
|
-
}
|
|
53
|
+
}
|
|
52
54
|
};
|
|
53
55
|
};
|
|
54
56
|
export const authOptions = {
|
|
55
57
|
adapter,
|
|
56
58
|
providers: [
|
|
57
|
-
...
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}),
|
|
71
|
-
]
|
|
72
|
-
: []),
|
|
73
|
-
extractDefault(CredentialsProvider)(getCredentialsOptions()),
|
|
59
|
+
...config.auth.google ? [
|
|
60
|
+
extractDefault(GoogleProvider)({
|
|
61
|
+
...config.auth.google,
|
|
62
|
+
allowDangerousEmailAccountLinking: true
|
|
63
|
+
})
|
|
64
|
+
] : [],
|
|
65
|
+
...config.auth.facebook ? [
|
|
66
|
+
extractDefault(FacebookProvider)({
|
|
67
|
+
...config.auth.facebook,
|
|
68
|
+
allowDangerousEmailAccountLinking: true
|
|
69
|
+
})
|
|
70
|
+
] : [],
|
|
71
|
+
extractDefault(CredentialsProvider)(getCredentialsOptions())
|
|
74
72
|
],
|
|
75
73
|
callbacks: {
|
|
76
|
-
async signIn({ account, profile }) {
|
|
77
|
-
const processName = (profile)
|
|
74
|
+
async signIn ({ account, profile }) {
|
|
75
|
+
const processName = (profile)=>{
|
|
78
76
|
if (profile?.given_name || profile?.family_name) {
|
|
79
77
|
return {
|
|
80
78
|
firstName: profile?.given_name || '',
|
|
81
|
-
lastName: profile?.family_name || ''
|
|
79
|
+
lastName: profile?.family_name || ''
|
|
82
80
|
};
|
|
83
81
|
}
|
|
84
82
|
if (!profile?.name) {
|
|
85
83
|
return {
|
|
86
84
|
firstName: '',
|
|
87
|
-
lastName: ''
|
|
85
|
+
lastName: ''
|
|
88
86
|
};
|
|
89
87
|
}
|
|
90
|
-
const r = (str)
|
|
88
|
+
const r = (str)=>str.replace(/\s+/g, ' ').trim();
|
|
91
89
|
const names = profile?.name.trim();
|
|
92
90
|
const nameSegments = names.split(' ');
|
|
93
|
-
const firstName = r(nameSegments
|
|
94
|
-
.filter((_s, i) => i !== nameSegments?.length - 1)
|
|
95
|
-
.join(' '));
|
|
91
|
+
const firstName = r(nameSegments.filter((_s, i)=>i !== nameSegments?.length - 1).join(' '));
|
|
96
92
|
const lastName = r(nameSegments?.[nameSegments?.length - 1]);
|
|
97
|
-
return {
|
|
93
|
+
return {
|
|
94
|
+
firstName,
|
|
95
|
+
lastName
|
|
96
|
+
};
|
|
98
97
|
};
|
|
99
98
|
if (account?.provider === 'google') {
|
|
100
99
|
if (!profile?.email) {
|
|
@@ -105,7 +104,7 @@ export const authOptions = {
|
|
|
105
104
|
// const password = await bcrypt.hash(nanoid(), nanoid())
|
|
106
105
|
await prisma.user.upsert({
|
|
107
106
|
where: {
|
|
108
|
-
email: profile.email
|
|
107
|
+
email: profile.email
|
|
109
108
|
},
|
|
110
109
|
create: {
|
|
111
110
|
id: generateId('User'),
|
|
@@ -115,13 +114,12 @@ export const authOptions = {
|
|
|
115
114
|
password,
|
|
116
115
|
registrationComplete: false,
|
|
117
116
|
metadata: {
|
|
118
|
-
signupProvider: 'google'
|
|
119
|
-
}
|
|
117
|
+
signupProvider: 'google'
|
|
118
|
+
}
|
|
120
119
|
},
|
|
121
|
-
update: {}
|
|
120
|
+
update: {}
|
|
122
121
|
});
|
|
123
|
-
}
|
|
124
|
-
else if (account?.provider === 'facebook') {
|
|
122
|
+
} else if (account?.provider === 'facebook') {
|
|
125
123
|
if (!profile?.email) {
|
|
126
124
|
throw new Error('Unauthenticated');
|
|
127
125
|
}
|
|
@@ -129,7 +127,7 @@ export const authOptions = {
|
|
|
129
127
|
const password = `${nanoid()}-${nanoid()}`;
|
|
130
128
|
await prisma.user.upsert({
|
|
131
129
|
where: {
|
|
132
|
-
email: profile.email
|
|
130
|
+
email: profile.email
|
|
133
131
|
},
|
|
134
132
|
create: {
|
|
135
133
|
id: generateId('User'),
|
|
@@ -139,46 +137,43 @@ export const authOptions = {
|
|
|
139
137
|
password,
|
|
140
138
|
registrationComplete: false,
|
|
141
139
|
metadata: {
|
|
142
|
-
signupProvider: 'facebook'
|
|
143
|
-
}
|
|
140
|
+
signupProvider: 'facebook'
|
|
141
|
+
}
|
|
144
142
|
},
|
|
145
|
-
update: {}
|
|
143
|
+
update: {}
|
|
146
144
|
});
|
|
147
145
|
}
|
|
148
146
|
return true;
|
|
149
147
|
},
|
|
150
|
-
async session({ session, user, trigger }) {
|
|
151
|
-
const { password, permissions, stripeCustomerId, ...newUser } = {
|
|
148
|
+
async session ({ session, user, trigger }) {
|
|
149
|
+
const { password, permissions, stripeCustomerId, ...newUser } = {
|
|
150
|
+
...user
|
|
151
|
+
};
|
|
152
152
|
const finalSession = {
|
|
153
153
|
user: newUser,
|
|
154
154
|
expires: new Date(session.expires).toISOString(),
|
|
155
155
|
id: session.id,
|
|
156
|
-
sessionToken: session.sessionToken
|
|
156
|
+
sessionToken: session.sessionToken
|
|
157
157
|
};
|
|
158
|
-
const decodedToken = session.sessionToken
|
|
159
|
-
? decodeJwt(session.sessionToken)
|
|
160
|
-
: null;
|
|
158
|
+
const decodedToken = session.sessionToken ? decodeJwt(session.sessionToken) : null;
|
|
161
159
|
const tokenRoles = decodedToken?.roles;
|
|
162
160
|
if (session.sessionToken) {
|
|
163
|
-
if (trigger === 'update' ||
|
|
164
|
-
!tokenRoles ||
|
|
165
|
-
!areArraysSimilar(tokenRoles, user.groups)) {
|
|
161
|
+
if (trigger === 'update' || !tokenRoles || !areArraysSimilar(tokenRoles, user.groups)) {
|
|
166
162
|
const newSessionToken = await generateSessionToken(user);
|
|
167
163
|
// We can't call the update session from the patch because it searches by sessionToken and not by ID
|
|
168
164
|
try {
|
|
169
165
|
await prisma.session.update({
|
|
170
166
|
where: {
|
|
171
|
-
sessionToken: session.sessionToken
|
|
167
|
+
sessionToken: session.sessionToken
|
|
172
168
|
},
|
|
173
169
|
data: {
|
|
174
|
-
sessionToken: newSessionToken
|
|
175
|
-
}
|
|
170
|
+
sessionToken: newSessionToken
|
|
171
|
+
}
|
|
176
172
|
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// Nothing to do in this case
|
|
173
|
+
} catch (_e) {
|
|
174
|
+
// Sometimes, concurrent requests can happen and one would update
|
|
175
|
+
// before the other, so prisma won't find it based on sessionToken and throw
|
|
176
|
+
// Nothing to do in this case
|
|
182
177
|
}
|
|
183
178
|
// @ts-expect-error dirty property to be removed in the patch
|
|
184
179
|
finalSession.newSessionToken = newSessionToken;
|
|
@@ -193,18 +188,26 @@ export const authOptions = {
|
|
|
193
188
|
await prisma.session.update({
|
|
194
189
|
where: {
|
|
195
190
|
id: session.id,
|
|
196
|
-
OR: [
|
|
191
|
+
OR: [
|
|
192
|
+
{
|
|
193
|
+
lastActiveAt: null
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
lastActiveAt: {
|
|
197
|
+
lt: threshold
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
]
|
|
197
201
|
},
|
|
198
202
|
data: {
|
|
199
|
-
lastActiveAt: new Date()
|
|
200
|
-
}
|
|
203
|
+
lastActiveAt: new Date()
|
|
204
|
+
}
|
|
201
205
|
});
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Silently fail
|
|
206
|
+
} catch (_e) {
|
|
207
|
+
// Silently fail
|
|
205
208
|
}
|
|
206
209
|
return finalSession;
|
|
207
|
-
}
|
|
210
|
+
}
|
|
208
211
|
},
|
|
209
212
|
cookies: {
|
|
210
213
|
sessionToken: {
|
|
@@ -214,12 +217,8 @@ export const authOptions = {
|
|
|
214
217
|
sameSite: 'lax',
|
|
215
218
|
path: '/',
|
|
216
219
|
secure: useSecureCookies,
|
|
217
|
-
domain: process.env.NO_COOKIE_DOMAIN === 'true'
|
|
218
|
-
|
|
219
|
-
: nextAuthUrl === 'localhost'
|
|
220
|
-
? `.${nextAuthUrl}`
|
|
221
|
-
: `.${new URL(nextAuthUrl).hostname}`,
|
|
222
|
-
},
|
|
220
|
+
domain: process.env.NO_COOKIE_DOMAIN === 'true' ? undefined : nextAuthUrl === 'localhost' ? `.${nextAuthUrl}` : `.${new URL(nextAuthUrl).hostname}`
|
|
221
|
+
}
|
|
223
222
|
},
|
|
224
223
|
callbackUrl: {
|
|
225
224
|
name: AUTH_COOKIE_CALLBACK_URL,
|
|
@@ -227,8 +226,8 @@ export const authOptions = {
|
|
|
227
226
|
httpOnly: true,
|
|
228
227
|
sameSite: 'lax',
|
|
229
228
|
path: '/',
|
|
230
|
-
secure: useSecureCookies
|
|
231
|
-
}
|
|
229
|
+
secure: useSecureCookies
|
|
230
|
+
}
|
|
232
231
|
},
|
|
233
232
|
csrfToken: {
|
|
234
233
|
name: `${useSecureCookies ? '__Host-' : ''}${AUTH_COOKIE_CSRF_TOKEN}`,
|
|
@@ -236,8 +235,8 @@ export const authOptions = {
|
|
|
236
235
|
httpOnly: true,
|
|
237
236
|
sameSite: 'lax',
|
|
238
237
|
path: '/',
|
|
239
|
-
secure: useSecureCookies
|
|
240
|
-
}
|
|
238
|
+
secure: useSecureCookies
|
|
239
|
+
}
|
|
241
240
|
},
|
|
242
241
|
pkceCodeVerifier: {
|
|
243
242
|
name: AUTH_COOKIE_PKCE_CODE_VERIFIER,
|
|
@@ -246,8 +245,8 @@ export const authOptions = {
|
|
|
246
245
|
sameSite: 'lax',
|
|
247
246
|
path: '/',
|
|
248
247
|
secure: useSecureCookies,
|
|
249
|
-
maxAge: 900
|
|
250
|
-
}
|
|
248
|
+
maxAge: 900
|
|
249
|
+
}
|
|
251
250
|
},
|
|
252
251
|
state: {
|
|
253
252
|
name: AUTH_COOKIE_STATE,
|
|
@@ -256,8 +255,8 @@ export const authOptions = {
|
|
|
256
255
|
sameSite: 'lax',
|
|
257
256
|
path: '/',
|
|
258
257
|
secure: useSecureCookies,
|
|
259
|
-
maxAge: 900
|
|
260
|
-
}
|
|
258
|
+
maxAge: 900
|
|
259
|
+
}
|
|
261
260
|
},
|
|
262
261
|
nonce: {
|
|
263
262
|
name: AUTH_COOKIE_NONCE,
|
|
@@ -265,13 +264,13 @@ export const authOptions = {
|
|
|
265
264
|
httpOnly: true,
|
|
266
265
|
sameSite: 'lax',
|
|
267
266
|
path: '/',
|
|
268
|
-
secure: useSecureCookies
|
|
269
|
-
}
|
|
270
|
-
}
|
|
267
|
+
secure: useSecureCookies
|
|
268
|
+
}
|
|
269
|
+
}
|
|
271
270
|
},
|
|
272
271
|
useSecureCookies,
|
|
273
272
|
jwt: {
|
|
274
|
-
async encode(params) {
|
|
273
|
+
async encode (params) {
|
|
275
274
|
const secret = new TextEncoder().encode(config.auth.jwtSecret);
|
|
276
275
|
const alg = 'HS256';
|
|
277
276
|
const tokenId = params.token?.sub;
|
|
@@ -280,40 +279,36 @@ export const authOptions = {
|
|
|
280
279
|
}
|
|
281
280
|
const user = await prisma.user.findUnique({
|
|
282
281
|
where: {
|
|
283
|
-
id: tokenId
|
|
284
|
-
}
|
|
282
|
+
id: tokenId
|
|
283
|
+
}
|
|
285
284
|
});
|
|
286
285
|
if (!user) {
|
|
287
286
|
throw new Error('No user found');
|
|
288
287
|
}
|
|
289
288
|
const token = await new SignJWT({
|
|
290
289
|
...params.token,
|
|
291
|
-
roles: user.groups
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
.setSubject(user.id)
|
|
296
|
-
.setIssuer('flux.website')
|
|
297
|
-
.setAudience('flux.website')
|
|
298
|
-
.sign(secret);
|
|
290
|
+
roles: user.groups
|
|
291
|
+
}).setProtectedHeader({
|
|
292
|
+
alg
|
|
293
|
+
}).setIssuedAt().setSubject(user.id).setIssuer('flux.website').setAudience('flux.website').sign(secret);
|
|
299
294
|
if (adapter.createSession) {
|
|
300
295
|
await adapter.createSession({
|
|
301
296
|
sessionToken: token,
|
|
302
297
|
userId: user.id,
|
|
303
|
-
expires: new Date(Date.now() + (params.maxAge ?? MAX_AGE) * 1000)
|
|
298
|
+
expires: new Date(Date.now() + (params.maxAge ?? MAX_AGE) * 1000)
|
|
304
299
|
});
|
|
305
300
|
}
|
|
306
301
|
return token;
|
|
307
|
-
}
|
|
302
|
+
}
|
|
308
303
|
},
|
|
309
304
|
session: {
|
|
310
305
|
strategy: 'database',
|
|
311
306
|
maxAge: MAX_AGE,
|
|
312
|
-
generateSessionToken: async (user)
|
|
307
|
+
generateSessionToken: async (user)=>{
|
|
313
308
|
return await generateSessionToken(user);
|
|
314
|
-
}
|
|
309
|
+
}
|
|
315
310
|
},
|
|
316
311
|
pages: {
|
|
317
|
-
signIn: '/signin'
|
|
318
|
-
}
|
|
312
|
+
signIn: '/signin'
|
|
313
|
+
}
|
|
319
314
|
};
|
|
@@ -4,136 +4,172 @@ export function PrismaAdapter() {
|
|
|
4
4
|
return {
|
|
5
5
|
// TODO
|
|
6
6
|
// @ts-expect-error TypeScript is not working here
|
|
7
|
-
createUser: async ({ id, groups, permissions, emailVerified, ...data })
|
|
7
|
+
createUser: async ({ id, groups, permissions, emailVerified, ...data })=>{
|
|
8
8
|
// @ts-expect-error
|
|
9
9
|
const userData = {
|
|
10
10
|
id: id || generateId('User'),
|
|
11
|
-
groups: groups || [
|
|
11
|
+
groups: groups || [
|
|
12
|
+
'member'
|
|
13
|
+
],
|
|
12
14
|
permissions: permissions || {},
|
|
13
15
|
emailVerified: Boolean(emailVerified),
|
|
14
16
|
email: data.email.toLowerCase().trim(),
|
|
15
|
-
...data
|
|
17
|
+
...data
|
|
16
18
|
};
|
|
17
19
|
const user = await prisma.user.create({
|
|
18
20
|
data: {
|
|
19
|
-
...userData
|
|
20
|
-
}
|
|
21
|
+
...userData
|
|
22
|
+
}
|
|
21
23
|
});
|
|
22
24
|
return user;
|
|
23
25
|
},
|
|
24
26
|
// TODO
|
|
25
27
|
// @ts-expect-error
|
|
26
|
-
getUser: (id)
|
|
28
|
+
getUser: (id)=>prisma.user.findUnique({
|
|
29
|
+
where: {
|
|
30
|
+
id
|
|
31
|
+
}
|
|
32
|
+
}),
|
|
27
33
|
// TODO
|
|
28
34
|
// @ts-expect-error
|
|
29
|
-
getUserByEmail: (email)
|
|
35
|
+
getUserByEmail: (email)=>prisma.user.findUnique({
|
|
36
|
+
where: {
|
|
37
|
+
email: email.toLowerCase().trim()
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
30
40
|
// TODO
|
|
31
41
|
// @ts-expect-error
|
|
32
|
-
async getUserByAccount(provider_providerAccountId) {
|
|
42
|
+
async getUserByAccount (provider_providerAccountId) {
|
|
33
43
|
const account = await prisma.account.findUnique({
|
|
34
|
-
where: {
|
|
35
|
-
|
|
44
|
+
where: {
|
|
45
|
+
provider_providerAccountId
|
|
46
|
+
},
|
|
47
|
+
select: {
|
|
48
|
+
user: true
|
|
49
|
+
}
|
|
36
50
|
});
|
|
37
51
|
return account?.user ?? null;
|
|
38
52
|
},
|
|
39
53
|
// TODO
|
|
40
54
|
// @ts-expect-error
|
|
41
|
-
updateUser: ({ id, ...data })
|
|
55
|
+
updateUser: ({ id, ...data })=>{
|
|
42
56
|
// @ts-expect-error
|
|
43
57
|
const userData = {
|
|
44
58
|
email: data.email?.toLowerCase().trim(),
|
|
45
|
-
...data
|
|
59
|
+
...data
|
|
46
60
|
};
|
|
47
|
-
return prisma.user.update({
|
|
61
|
+
return prisma.user.update({
|
|
62
|
+
where: {
|
|
63
|
+
id
|
|
64
|
+
},
|
|
65
|
+
data: {
|
|
66
|
+
...userData
|
|
67
|
+
}
|
|
68
|
+
});
|
|
48
69
|
},
|
|
49
70
|
// TODO
|
|
50
71
|
// @ts-expect-error
|
|
51
|
-
deleteUser: (id)
|
|
72
|
+
deleteUser: (id)=>prisma.user.delete({
|
|
73
|
+
where: {
|
|
74
|
+
id
|
|
75
|
+
}
|
|
76
|
+
}),
|
|
52
77
|
// @ts-expect-error
|
|
53
|
-
linkAccount: ({ id, ...data })
|
|
78
|
+
linkAccount: ({ id, ...data })=>{
|
|
54
79
|
return prisma.account.create({
|
|
55
80
|
// @ts-expect-error
|
|
56
81
|
data: {
|
|
57
82
|
id: id || generateId('Account'),
|
|
58
|
-
...data
|
|
59
|
-
}
|
|
83
|
+
...data
|
|
84
|
+
}
|
|
60
85
|
});
|
|
61
86
|
},
|
|
62
87
|
// @ts-expect-error
|
|
63
|
-
unlinkAccount: (provider_providerAccountId)
|
|
64
|
-
|
|
65
|
-
|
|
88
|
+
unlinkAccount: (provider_providerAccountId)=>prisma.account.delete({
|
|
89
|
+
where: {
|
|
90
|
+
provider_providerAccountId
|
|
91
|
+
}
|
|
92
|
+
}),
|
|
66
93
|
// TODO
|
|
67
94
|
// @ts-expect-error
|
|
68
|
-
async getSessionAndUser(sessionToken) {
|
|
95
|
+
async getSessionAndUser (sessionToken) {
|
|
69
96
|
const userAndSession = await prisma.session.findUnique({
|
|
70
|
-
where: {
|
|
71
|
-
|
|
97
|
+
where: {
|
|
98
|
+
sessionToken
|
|
99
|
+
},
|
|
100
|
+
include: {
|
|
101
|
+
user: true
|
|
102
|
+
}
|
|
72
103
|
});
|
|
73
|
-
if (!userAndSession)
|
|
74
|
-
return null;
|
|
104
|
+
if (!userAndSession) return null;
|
|
75
105
|
const { user, ...session } = userAndSession;
|
|
76
|
-
return {
|
|
106
|
+
return {
|
|
107
|
+
user,
|
|
108
|
+
session
|
|
109
|
+
};
|
|
77
110
|
},
|
|
78
111
|
// TODO
|
|
79
112
|
// @ts-expect-error
|
|
80
|
-
async createSession({ id, ...data }) {
|
|
113
|
+
async createSession ({ id, ...data }) {
|
|
81
114
|
const session = await prisma.session.create({
|
|
82
115
|
data: {
|
|
83
116
|
id: id || generateId('Session'),
|
|
84
|
-
...data
|
|
85
|
-
}
|
|
117
|
+
...data
|
|
118
|
+
}
|
|
86
119
|
});
|
|
87
120
|
return session;
|
|
88
121
|
},
|
|
89
|
-
updateSession: (data)
|
|
122
|
+
updateSession: (data)=>{
|
|
90
123
|
return prisma.session.update({
|
|
91
|
-
where: {
|
|
92
|
-
|
|
124
|
+
where: {
|
|
125
|
+
sessionToken: data.sessionToken
|
|
126
|
+
},
|
|
127
|
+
data
|
|
93
128
|
});
|
|
94
129
|
},
|
|
95
|
-
deleteSession: async (sessionToken)
|
|
130
|
+
deleteSession: async (sessionToken)=>{
|
|
96
131
|
try {
|
|
97
|
-
await prisma.session.delete({
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
132
|
+
await prisma.session.delete({
|
|
133
|
+
where: {
|
|
134
|
+
sessionToken
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
} catch (_e) {
|
|
138
|
+
// TODO
|
|
139
|
+
// DO nothing for now
|
|
102
140
|
}
|
|
103
141
|
},
|
|
104
142
|
// TODO
|
|
105
143
|
// @ts-expect-error
|
|
106
|
-
async createVerificationToken({ id, ...data }) {
|
|
144
|
+
async createVerificationToken ({ id, ...data }) {
|
|
107
145
|
const verificationToken = await prisma.verificationToken.create({
|
|
108
146
|
data: {
|
|
109
147
|
id: id || generateId('VerificationToken'),
|
|
110
|
-
...data
|
|
111
|
-
}
|
|
148
|
+
...data
|
|
149
|
+
}
|
|
112
150
|
});
|
|
113
151
|
// TODO
|
|
114
152
|
// @ts-expect-errors // MongoDB needs an ID, but we don't
|
|
115
|
-
if (verificationToken.id)
|
|
116
|
-
verificationToken.id = undefined;
|
|
153
|
+
if (verificationToken.id) verificationToken.id = undefined;
|
|
117
154
|
return verificationToken;
|
|
118
155
|
},
|
|
119
|
-
async useVerificationToken(identifier_token) {
|
|
156
|
+
async useVerificationToken (identifier_token) {
|
|
120
157
|
try {
|
|
121
158
|
const verificationToken = await prisma.verificationToken.delete({
|
|
122
|
-
where: {
|
|
159
|
+
where: {
|
|
160
|
+
identifier_token
|
|
161
|
+
}
|
|
123
162
|
});
|
|
124
163
|
// TODO
|
|
125
164
|
// @ts-expect-errors // MongoDB needs an ID, but we don't
|
|
126
|
-
if (verificationToken.id)
|
|
127
|
-
verificationToken.id = undefined;
|
|
165
|
+
if (verificationToken.id) verificationToken.id = undefined;
|
|
128
166
|
return verificationToken;
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
167
|
+
} catch (error) {
|
|
131
168
|
// If token already used/deleted, just return null
|
|
132
169
|
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2025
|
|
133
|
-
if (error.code === 'P2025')
|
|
134
|
-
return null;
|
|
170
|
+
if (error.code === 'P2025') return null;
|
|
135
171
|
throw error;
|
|
136
172
|
}
|
|
137
|
-
}
|
|
173
|
+
}
|
|
138
174
|
};
|
|
139
175
|
}
|