-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsend-email-reset-password.ts
More file actions
86 lines (77 loc) · 2.48 KB
/
Copy pathsend-email-reset-password.ts
File metadata and controls
86 lines (77 loc) · 2.48 KB
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
import z from 'zod/v4'
import type { ApiRouteHandler, ApiRouteSchema, Context } from '../../core'
import { createEndpoint } from '../../core/endpoint'
import { type AuthContext } from '../context'
export function sendEmailResetPassword<
const TAuthContext extends AuthContext,
const TContext extends Context,
>(authContext: TAuthContext) {
const { authConfig, internalHandlers } = authContext
const schema = {
method: 'POST',
path: '/api/auth/send-otp-forgot-password',
body: z.object({
email: z.string(),
}),
responses: {
200: z.object({
status: z.string(),
}),
400: z.object({
status: z.string(),
}),
},
} as const satisfies ApiRouteSchema
const handler: ApiRouteHandler<TContext, typeof schema> = async (args) => {
console.log('sendEmailResetPassword called with args:', args)
if (!authConfig.resetPassword?.enabled) {
// TODO: Log not enabled
return {
status: 400,
body: { status: 'reset password not enabled' },
}
}
let user
try {
console.log('Finding user by email:', args.body.email)
user = await internalHandlers.user.findByEmail(args.body.email)
} catch {
return {
status: 400,
body: { status: 'user not found' },
}
}
// Generate a secure random token
const token = crypto.randomUUID()
const identifier = `reset-password:${token}`
await internalHandlers.verification.deleteByUserIdAndIdentifierPrefix(
user.id,
'reset-password:'
)
await internalHandlers.verification.create({
identifier,
value: user.id,
expiresAt: new Date(
Date.now() + (authConfig.resetPassword?.expiresInMs ?? 1000 * 60 * 60 * 24) // TODO; make config always set default
),
})
// TODO: change this to domain config websiteURL
const resetPasswordLink = `${authConfig.resetPassword?.resetPasswordUrl ?? 'http://localhost:3000/admin/auth/reset-password'}?token=${token}`
// Send email
if (authConfig.resetPassword?.sendEmailResetPassword) {
await authConfig.resetPassword.sendEmailResetPassword(user.email, resetPasswordLink)
} else {
// Fallback to console log for development
console.warn(
'No "auth.resetPassword.sendEmailResetPassword" function provided, using console.log for development purposes.'
)
}
return {
status: 200,
body: {
status: 'ok',
},
}
}
return createEndpoint(schema, handler)
}