Skip to content

Instantly share code, notes, and snippets.

@kiliman
Last active July 15, 2022 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiliman/42d68d74ee6fefde18ce18731ec1480e to your computer and use it in GitHub Desktop.
Save kiliman/42d68d74ee6fefde18ce18731ec1480e to your computer and use it in GitHub Desktop.
Send email from Remix using `nodemailer`
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)
}
// 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