import { Body, Button, Container, Head, Heading, Hr, Html, Img, Link, Preview, pixelBasedPreset, Section, Tailwind, Text } from "@react-email/components" import type { ReactNode } from "react" import { cn } from "../../../lib/utils" import { type EmailClassNames, type EmailColors, EmailStyles } from "./email-styles" const passwordChangedEmailLocalization = { YOUR_PASSWORD_HAS_BEEN_CHANGED: "Your password has been changed", LOGO: "Logo", PASSWORD_CHANGED_SUCCESSFULLY: "Password changed successfully", PASSWORD_FOR_YOUR_ACCOUNT_CHANGED: "The password for your {appName} account {userEmail} has been changed successfully.", CHANGED_AT: "Changed at", IF_YOU_MADE_THIS_CHANGE: "If you made this change, you can safely ignore this email. Your account is secure.", I_DIDNT_MAKE_THIS_CHANGE: "I didn't make this change", EMAIL_SENT_BY: "Email sent by {appName}.", IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE: "If you didn't authorize this change, please contact support immediately {supportEmail} to secure your account.", POWERED_BY_BETTER_AUTH: "Powered by {betterAuth}" } /** * Localization strings for the PasswordChangedEmail component. * * Contains all text content used in the password changed notification email template. */ export type PasswordChangedEmailLocalization = typeof passwordChangedEmailLocalization /** * Props for the PasswordChangedEmail component. */ export interface PasswordChangedEmailProps { /** Email address of the user account */ email?: string /** Timestamp when the password was changed */ timestamp?: string /** URL to secure the account if unauthorized change occurred */ secureAccountURL?: string /** Name of the application sending the email */ appName?: string /** Support email address for security concerns */ supportEmail?: string /** Logo URL(s) - a single string or light/dark variants. If omitted, no logo is shown. */ logoURL?: string | { light: string; dark: string } /** Custom CSS class names for styling specific parts of the email */ classNames?: EmailClassNames /** Custom color scheme for light and dark modes */ colors?: EmailColors /** Whether to show the "Powered by better-auth" footer */ poweredBy?: boolean /** Whether to enable dark mode support */ darkMode?: boolean /** Additional React nodes to inject into the email head */ head?: ReactNode /** * Localization overrides for customizing email text * @remarks `PasswordChangedEmailLocalization` */ localization?: Partial } /** * Email template component that notifies users when their password has been changed. * * This email includes: * - Password change confirmation message * - Timestamp of the change * - Secure account action button if unauthorized change occurred * - Security warnings and support contact information * - Customizable branding and styling * - Support for light/dark mode themes * * @example * ```tsx * * ``` */ export const PasswordChangedEmail = ({ email, timestamp, secureAccountURL, appName, supportEmail, logoURL, colors, classNames, darkMode = true, poweredBy, head, ...props }: PasswordChangedEmailProps) => { const localization = { ...PasswordChangedEmail.localization, ...props.localization } const previewText = localization.YOUR_PASSWORD_HAS_BEEN_CHANGED return ( {head} {previewText}
{logoURL && (typeof logoURL === "string" ? ( {appName ) : ( <> {appName {appName ))} {localization.PASSWORD_CHANGED_SUCCESSFULLY} {(() => { const textWithAppName = localization.PASSWORD_FOR_YOUR_ACCOUNT_CHANGED.replace( "{appName}", appName || "" ) .replace(/\s{2,}/g, " ") .replace(" .", ".") const [beforeUserEmail, afterUserEmail] = textWithAppName.split("{userEmail}") return email ? ( <> {beforeUserEmail} {email} {afterUserEmail} ) : ( textWithAppName .replace("{userEmail}", "") .replace(/\s{2,}/g, " ") .replace(" .", ".") ) })()} {timestamp && (
{localization.CHANGED_AT}: {timestamp}
)} {localization.IF_YOU_MADE_THIS_CHANGE} {secureAccountURL && (
)}
{appName && ( {localization.EMAIL_SENT_BY.replace("{appName}", appName)} )} {(() => { const [beforeSupportEmail, afterSupportEmail] = localization.IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE.split( "{supportEmail}" ) return supportEmail ? ( <> {beforeSupportEmail} {supportEmail} {afterSupportEmail} ) : ( localization.IF_YOU_DIDNT_AUTHORIZE_THIS_CHANGE.replace( "{supportEmail}", "" ) .replace(/\s{2,}/g, " ") .replace(" .", ".") ) })()} {poweredBy && ( {(() => { const [beforeBetterAuth, afterBetterAuth] = localization.POWERED_BY_BETTER_AUTH.split("{betterAuth}") return ( <> {beforeBetterAuth} better-auth {afterBetterAuth} ) })()} )}
) } PasswordChangedEmail.localization = passwordChangedEmailLocalization PasswordChangedEmail.PreviewProps = { email: "m@example.com", timestamp: "February 10, 2025 at 4:20 PM UTC", secureAccountURL: "https://better-auth-ui.com/settings/security", appName: "Better Auth", supportEmail: "support@example.com", darkMode: true } as PasswordChangedEmailProps export default PasswordChangedEmail