15d5333cf6
* Init Maizzle * Initial template JSX conversion and testing * WIP * WIP * WIP * WIP * WIP * Migrated AttendeeRescheduledEmail * WIP * WIP * DRY * Cleanup * Cleanup * Cleanup * Migrate feedback email * Migrates ForgotPasswordEmail * Migrates OrganizerCancelledEmail * Migrated OrganizerLocationChangeEmail * Formatting * Migrated AttendeeRequestRescheduledEmail * Migrates OrganizerPaymentRefundFailedEmail * Migrates OrganizerRequestEmail * Migrates OrganizerRequestReminderEmail * Fixes type-check * Moved email-manager to package * Import fixes * Removed duplicate email code from vital app * Removed duplicate email code from wipemycal * Build/type fixes * Fixes web email imports * Fixes build * Embed build fixes * Update AttendeeAwaitingPaymentEmail.tsx * Update default-cookies.ts * Revert "Embed build fixes" This reverts commit 8d693e99aca6dfe92d5cbb27ffa962545c3e9389. * Embed build fixes # Conflicts: # packages/embeds/embed-core/package.json * dep and email date fixes * Update attendee-scheduled-email.ts * Update package.json * Update [...nextauth].tsx * Update email.ts * Prevents /api/email on production builds Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
import { ResetPasswordRequest } from "@prisma/client";
|
|
import dayjs from "dayjs";
|
|
import { NextApiRequest, NextApiResponse } from "next";
|
|
|
|
import { sendPasswordResetEmail } from "@calcom/emails";
|
|
import { PASSWORD_RESET_EXPIRY_HOURS } from "@calcom/emails/templates/forgot-password-email";
|
|
|
|
import prisma from "@lib/prisma";
|
|
|
|
import { getTranslation } from "@server/lib/i18n";
|
|
|
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
const t = await getTranslation(req.body.language ?? "en", "common");
|
|
|
|
if (req.method !== "POST") {
|
|
return res.status(405).end();
|
|
}
|
|
|
|
try {
|
|
const maybeUser = await prisma.user.findUnique({
|
|
where: {
|
|
email: req.body?.email?.toLowerCase(),
|
|
},
|
|
select: {
|
|
name: true,
|
|
identityProvider: true,
|
|
email: true,
|
|
},
|
|
});
|
|
|
|
if (!maybeUser) {
|
|
return res.status(400).json({ message: "Couldn't find an account for this email" });
|
|
}
|
|
|
|
const maybePreviousRequest = await prisma.resetPasswordRequest.findMany({
|
|
where: {
|
|
email: maybeUser.email,
|
|
expires: {
|
|
gt: new Date(),
|
|
},
|
|
},
|
|
});
|
|
|
|
let passwordRequest: ResetPasswordRequest;
|
|
|
|
if (maybePreviousRequest && maybePreviousRequest?.length >= 1) {
|
|
passwordRequest = maybePreviousRequest[0];
|
|
} else {
|
|
const expiry = dayjs().add(PASSWORD_RESET_EXPIRY_HOURS, "hours").toDate();
|
|
const createdResetPasswordRequest = await prisma.resetPasswordRequest.create({
|
|
data: {
|
|
email: maybeUser.email,
|
|
expires: expiry,
|
|
},
|
|
});
|
|
passwordRequest = createdResetPasswordRequest;
|
|
}
|
|
|
|
const resetLink = `${process.env.NEXT_PUBLIC_WEBAPP_URL}/auth/forgot-password/${passwordRequest.id}`;
|
|
await sendPasswordResetEmail({
|
|
language: t,
|
|
user: maybeUser,
|
|
resetLink,
|
|
});
|
|
|
|
/** So we can test the password reset flow on CI */
|
|
if (process.env.NEXT_PUBLIC_IS_E2E) {
|
|
return res.status(201).json({ message: "Reset Requested", resetLink });
|
|
} else {
|
|
return res.status(201).json({ message: "Reset Requested" });
|
|
}
|
|
} catch (reason) {
|
|
// console.error(reason);
|
|
return res.status(500).json({ message: "Unable to create password reset request" });
|
|
}
|
|
}
|