···
createPasswordResetToken,
verifyPasswordResetToken,
consumePasswordResetToken,
···
const user = await createUser(email, password, name);
// Send verification email - MUST succeed for registration to complete
-
const { code, token } = createEmailVerificationToken(user.id);
···
user: { id: user.id, email: user.email },
email_verification_required: true,
···
{ error: "Registration failed" },
···
// Check if email is verified
if (!isEmailVerified(user.id)) {
user: { id: user.id, email: user.email },
email_verification_required: true,
···
return Response.json({ error: "Login failed" }, { status: 500 });
···
return Response.json({ message: "Verification email sent" });
return handleError(error);
···
+
getVerificationCodeSentAt,
createPasswordResetToken,
verifyPasswordResetToken,
consumePasswordResetToken,
···
const user = await createUser(email, password, name);
// Send verification email - MUST succeed for registration to complete
+
const { code, token, sentAt } = createEmailVerificationToken(user.id);
···
user: { id: user.id, email: user.email },
email_verification_required: true,
+
verification_code_sent_at: sentAt,
···
+
console.error("[Auth] Registration error:", err);
{ error: "Registration failed" },
···
// Check if email is verified
if (!isEmailVerified(user.id)) {
+
let codeSentAt = getVerificationCodeSentAt(user.id);
+
// If no verification code exists, auto-send one
+
const { code, token, sentAt } = createEmailVerificationToken(user.id);
+
subject: "Verify your email - Thistle",
+
html: verifyEmailTemplate({
+
console.error("[Email] Failed to send verification email on login:", err);
+
// Don't fail login - just return null timestamp so client can try resend
user: { id: user.id, email: user.email },
email_verification_required: true,
+
verification_code_sent_at: codeSentAt,
···
+
console.error("[Auth] Login error:", error);
return Response.json({ error: "Login failed" }, { status: 500 });
···
return Response.json({ message: "Verification email sent" });
+
return handleError(error);
+
"/api/auth/resend-verification-code": {
+
const body = await req.json();
+
const { email } = body;
+
return Response.json({ error: "Email required" }, { status: 400 });
+
// Rate limiting by email
+
const rateLimitError = enforceRateLimit(req, "resend-verification-code", {
+
account: { max: 3, windowSeconds: 5 * 60, email },
+
if (rateLimitError) return rateLimitError;
+
const user = getUserByEmail(email);
+
// Don't reveal if user exists
+
return Response.json({ message: "If an account exists with that email, a verification code has been sent" });
+
// Check if already verified
+
if (isEmailVerified(user.id)) {
+
{ error: "Email already verified" },
+
// Generate new code and send email
+
const { code, token, sentAt } = createEmailVerificationToken(user.id);
+
subject: "Verify your email - Thistle",
+
html: verifyEmailTemplate({
+
message: "Verification code sent",
+
verification_code_sent_at: sentAt,
return handleError(error);