Last active
July 15, 2022 17:45
-
-
Save kiliman/42d68d74ee6fefde18ce18731ec1480e to your computer and use it in GitHub Desktop.
Send email from Remix using `nodemailer`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Transporter } from 'nodemailer' | |
import nodemailer from 'nodemailer' | |
import Mail from 'nodemailer/lib/mailer' | |
declare global { | |
var transport: Transporter | |
} | |
const transporter: Transporter = | |
global.transport ?? (global.transport = getTransport()) | |
function getTransport() { | |
const transporter = nodemailer.createTransport({ | |
pool: true, | |
host: process.env.SMTP_HOST, | |
port: Number(process.env.SMTP_PORT), | |
secure: true, | |
auth: { | |
user: process.env.SMTP_USERNAME, | |
pass: process.env.SMTP_PASSWORD, | |
}, | |
tls: { | |
ciphers: 'SSLv3', | |
rejectUnauthorized: false, | |
}, | |
}) | |
return transporter | |
} | |
export async function sendMail(mailOptions: Mail.Options) { | |
return transporter.sendMail(mailOptions) | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// routes/forgot-password.tsx | |
export const action = async ({ request }: ActionArgs) => { | |
const formData = await request.formData() | |
const email = String(formData.get('email')) | |
const user = await getUserByEmail(email) | |
if (!user) { | |
// say it's sent even if we don't have a user to prevent harvesting | |
return redirect('/forgot-password/sent') | |
} | |
user.resetToken = getResetToken() | |
// token expires in 3 days | |
user.resetTokenExpires = new Date(Date.now() + 1000 * 60 * 60 * 24 * 3) | |
await updateUser(user) | |
const url = new URL(`${process.env.SERVER_URL}/reset-password`) | |
url.searchParams.set('email', email) | |
url.searchParams.set('token', user.resetToken) | |
const link = url.toString() | |
const html = renderToString( | |
<EmailTemplate | |
url={process.env.SERVER_URL} | |
email={email} | |
link={link} | |
/>, | |
) | |
const result = await sendMail({ | |
from: process.env.EMAIL_SENDER, | |
to: email, | |
subject: 'Password Reset', | |
html, | |
}) | |
return redirect('/forgot-password/sent') | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment