cal.pub0.org/apps/web/pages/api/auth/forgot-password.ts

53 lines
1.6 KiB
TypeScript

import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import { passwordResetRequest } from "@calcom/features/auth/lib/passwordResetRequest";
import { checkRateLimitAndThrowError } from "@calcom/lib/checkRateLimitAndThrowError";
import { defaultHandler } from "@calcom/lib/server";
import prisma from "@calcom/prisma";
async function handler(req: NextApiRequest, res: NextApiResponse) {
const email = z
.string()
.email()
.transform((val) => val.toLowerCase())
.safeParse(req.body?.email);
if (!email.success) {
return res.status(400).json({ message: "email is required" });
}
// fallback to email if ip is not present
let ip = (req.headers["x-real-ip"] as string) ?? email.data;
const forwardedFor = req.headers["x-forwarded-for"] as string;
if (!ip && forwardedFor) {
ip = forwardedFor?.split(",").at(0) ?? email.data;
}
// 10 requests per minute
await checkRateLimitAndThrowError({
rateLimitingType: "core",
identifier: ip,
});
try {
const user = await prisma.user.findUnique({
where: { email: email.data },
select: { name: true, email: true, locale: true },
});
// Don't leak info about whether the user exists
if (!user) return res.status(201).json({ message: "password_reset_email_sent" });
await passwordResetRequest(user);
return res.status(201).json({ message: "password_reset_email_sent" });
} catch (reason) {
console.error(reason);
return res.status(500).json({ message: "Unable to create password reset request" });
}
}
export default defaultHandler({
POST: Promise.resolve({ default: handler }),
});