diff --git a/apps/web/components/forgot-password.tsx b/apps/web/components/forgot-password.tsx index 2f4250c05..cd7e4a99c 100644 --- a/apps/web/components/forgot-password.tsx +++ b/apps/web/components/forgot-password.tsx @@ -27,7 +27,7 @@ export default function ForgotPassword() { }), { loading: "Sending...", - success: `Reset link sent. `, + success: "Reset link sent.", error: "Could not send reset link :/", } ); diff --git a/apps/web/components/reset-password.tsx b/apps/web/components/reset-password.tsx index 7cc38ce42..3bf4dcbcf 100644 --- a/apps/web/components/reset-password.tsx +++ b/apps/web/components/reset-password.tsx @@ -40,20 +40,8 @@ export default function ResetPassword(props: any) { if (!response.ok) { toast.dismiss(); - - if (response.status == 404) { - toast.error("Invalid Token"); - } - - if (response.status == 400) { - toast.error("New password must be different"); - } - - if (response.status == 500) { - toast.error("Something went wrong."); - } - - return; + const error = await response.json(); + toast.error(error.message); } if (response.ok) { diff --git a/apps/web/pages/api/auth/forgot-password.ts b/apps/web/pages/api/auth/forgot-password.ts index 7edab5aca..1c77c6df6 100644 --- a/apps/web/pages/api/auth/forgot-password.ts +++ b/apps/web/pages/api/auth/forgot-password.ts @@ -20,7 +20,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) { }); if (!user) { - return res.status(404).json({ message: "No user found with this email." }); + return res.status(404).json({ message: "No user found with this email" }); } const existingToken = await prisma.passwordResetToken.findFirst({ @@ -33,23 +33,24 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) { }); if (existingToken) { - return res - .status(400) - .json({ message: "A password reset has already been requested. Please check your email." }); + return res.status(400).json({ message: "Password reset requested." }); } const token = crypto.randomBytes(64).toString("hex"); + const expiry = new Date(); + expiry.setHours(expiry.getHours() + 1); // Set expiry to one hour from now let passwordResetToken; try { passwordResetToken = await prisma.passwordResetToken.create({ data: { token, + expiry, userId: user.id, }, }); } catch (error) { - return res.status(500).json({ message: "Error saving token." }); + return res.status(500).json({ message: "Something went wrong" }); } await sendResetPassword(user, passwordResetToken.token); diff --git a/apps/web/pages/api/auth/reset-password.ts b/apps/web/pages/api/auth/reset-password.ts index c98de4809..89ed6108c 100644 --- a/apps/web/pages/api/auth/reset-password.ts +++ b/apps/web/pages/api/auth/reset-password.ts @@ -25,12 +25,16 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) { return res.status(404).json({ message: "Invalid token." }); } + const now = new Date(); + + if (now > foundToken.expiry) { + return res.status(400).json({ message: "Token has expired" }); + } + const isSamePassword = await verifyPassword(password, foundToken.User.password!); if (isSamePassword) { - return res - .status(400) - .json({ message: "New password must be different from the current password." }); + return res.status(400).json({ message: "New password must be different" }); } const hashedPassword = await hashPassword(password); diff --git a/packages/prisma/migrations/20230605164015_expire_password_reset_token/migration.sql b/packages/prisma/migrations/20230605164015_expire_password_reset_token/migration.sql new file mode 100644 index 000000000..a3a70e575 --- /dev/null +++ b/packages/prisma/migrations/20230605164015_expire_password_reset_token/migration.sql @@ -0,0 +1,8 @@ +/* + Warnings: + + - Added the required column `expiry` to the `PasswordResetToken` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "PasswordResetToken" ADD COLUMN "expiry" TIMESTAMP(3) NOT NULL; diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index c702f244f..fc8463c9b 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -164,6 +164,7 @@ model PasswordResetToken { id Int @id @default(autoincrement()) token String @unique createdAt DateTime @default(now()) + expiry DateTime userId Int User User @relation(fields: [userId], references: [id]) }