diff --git a/server/emails/templates/NotifyResetPassword.tsx b/server/emails/templates/NotifyResetPassword.tsx
new file mode 100644
index 00000000..05ff1f50
--- /dev/null
+++ b/server/emails/templates/NotifyResetPassword.tsx
@@ -0,0 +1,70 @@
+import {
+ Body,
+ Container,
+ Head,
+ Heading,
+ Html,
+ Preview,
+ Section,
+ Text,
+ Tailwind
+} from "@react-email/components";
+import * as React from "react";
+
+interface Props {
+ email: string;
+}
+
+export const ConfirmPasswordReset = ({ email }: Props) => {
+ const previewText = `Your password has been reset`;
+
+ return (
+
+
+ {previewText}
+
+
+
+
+ Your password has been successfully reset
+
+
+ Hi {email || "there"},
+
+
+ This email confirms that your password has just been
+ reset. If you made this change, no further action is
+ required.
+
+
+
+ If you did not request this change, please
+ contact our support team immediately.
+
+
+
+ Thank you for keeping your account secure.
+
+
+ Best regards,
+
+ Fossorial
+
+
+
+
+
+ );
+};
+
+export default ConfirmPasswordReset;
diff --git a/server/emails/templates/ResetPasswordCode.tsx b/server/emails/templates/ResetPasswordCode.tsx
index 60c2f0bb..eb2ec7fb 100644
--- a/server/emails/templates/ResetPasswordCode.tsx
+++ b/server/emails/templates/ResetPasswordCode.tsx
@@ -48,8 +48,8 @@ export const ResetPasswordCode = ({ email, code, link }: Props) => {
click here
{" "}
- and follow the instructions to reset your
- password, or manually enter the following code:
+ and follow the instructions to reset your password,
+ or manually enter the following code:
@@ -60,6 +60,11 @@ export const ResetPasswordCode = ({ email, code, link }: Props) => {
If you didn’t request this, you can safely ignore
this email.
+
+ Best regards,
+
+ Fossorial
+
diff --git a/server/emails/templates/ResourceOTPCode.tsx b/server/emails/templates/ResourceOTPCode.tsx
index 20356160..7744400c 100644
--- a/server/emails/templates/ResourceOTPCode.tsx
+++ b/server/emails/templates/ResourceOTPCode.tsx
@@ -61,6 +61,12 @@ export const ResourceOTPCode = ({
{otp}
+
+
+ Best regards,
+
+ Fossorial
+
diff --git a/server/emails/templates/SendInviteLink.tsx b/server/emails/templates/SendInviteLink.tsx
index 9612f5d9..d7a4228d 100644
--- a/server/emails/templates/SendInviteLink.tsx
+++ b/server/emails/templates/SendInviteLink.tsx
@@ -8,7 +8,7 @@ import {
Section,
Text,
Tailwind,
- Button,
+ Button
} from "@react-email/components";
import * as React from "react";
@@ -25,7 +25,7 @@ export const SendInviteLink = ({
inviteLink,
orgName,
inviterName,
- expiresInDays,
+ expiresInDays
}: SendInviteLinkProps) => {
const previewText = `${inviterName} invited to join ${orgName}`;
@@ -33,15 +33,17 @@ export const SendInviteLink = ({
{previewText}
-
+ }}
+ >
@@ -71,6 +73,12 @@ export const SendInviteLink = ({
Accept invitation to {orgName}
+
+
+ Best regards,
+
+ Fossorial
+
diff --git a/server/emails/templates/VerifyEmailCode.tsx b/server/emails/templates/VerifyEmailCode.tsx
index 4a1d07ce..fc8978ed 100644
--- a/server/emails/templates/VerifyEmailCode.tsx
+++ b/server/emails/templates/VerifyEmailCode.tsx
@@ -63,6 +63,11 @@ export const VerifyEmail = ({
If you didn’t request this, you can safely ignore
this email.
+
+ Best regards,
+
+ Fossorial
+
diff --git a/server/routers/auth/resetPassword.ts b/server/routers/auth/resetPassword.ts
index 366d8d26..1c358e39 100644
--- a/server/routers/auth/resetPassword.ts
+++ b/server/routers/auth/resetPassword.ts
@@ -1,3 +1,4 @@
+import config from "@server/config";
import { Request, Response, NextFunction } from "express";
import createHttpError from "http-errors";
import { z } from "zod";
@@ -15,6 +16,8 @@ import { encodeHex } from "oslo/encoding";
import { isWithinExpirationDate } from "oslo";
import { invalidateAllSessions } from "@server/auth";
import logger from "@server/logger";
+import ConfirmPasswordReset from "@server/emails/templates/NotifyResetPassword";
+import { sendEmail } from "@server/emails";
export const resetPasswordBody = z
.object({
@@ -141,7 +144,11 @@ export async function resetPassword(
.delete(passwordResetTokens)
.where(eq(passwordResetTokens.email, email));
- // TODO: send email to user confirming password reset
+ await sendEmail(ConfirmPasswordReset({ email }), {
+ from: config.email?.no_reply,
+ to: email,
+ subject: "Password Reset Confirmation"
+ })
return response(res, {
data: null,
diff --git a/src/components/LoginForm.tsx b/src/components/LoginForm.tsx
index 37387b85..d0dddd29 100644
--- a/src/components/LoginForm.tsx
+++ b/src/components/LoginForm.tsx
@@ -62,7 +62,7 @@ export default function LoginForm({ redirect, onLogin }: LoginFormProps) {
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);
- const [mfaRequested, setMfaRequested] = useState(true);
+ const [mfaRequested, setMfaRequested] = useState(false);
const form = useForm>({
resolver: zodResolver(formSchema),