kutt/server/mail/mail.js
2025-01-21 09:38:14 +01:00

145 lines
4.3 KiB
JavaScript

const nodemailer = require("nodemailer");
const path = require("node:path");
const fs = require("node:fs");
const { resetMailText, verifyMailText, changeEmailText } = require("./text");
const { CustomError } = require("../utils");
const env = require("../env");
const mailConfig = {
host: env.MAIL_HOST,
port: env.MAIL_PORT,
secure: env.MAIL_SECURE,
auth: env.MAIL_USER
? {
user: env.MAIL_USER,
pass: env.MAIL_PASSWORD
}
: undefined
};
const transporter = nodemailer.createTransport(mailConfig);
// Read email templates
const resetEmailTemplatePath = path.join(__dirname, "template-reset.html");
const verifyEmailTemplatePath = path.join(__dirname, "template-verify.html");
const changeEmailTemplatePath = path.join(__dirname,"template-change-email.html");
let resetEmailTemplate,
verifyEmailTemplate,
changeEmailTemplate;
// only read email templates if email is enabled
if (env.MAIL_ENABLED) {
resetEmailTemplate = fs
.readFileSync(resetEmailTemplatePath, { encoding: "utf-8" })
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME);
verifyEmailTemplate = fs
.readFileSync(verifyEmailTemplatePath, { encoding: "utf-8" })
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME);
changeEmailTemplate = fs
.readFileSync(changeEmailTemplatePath, { encoding: "utf-8" })
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME);
}
async function verification(user) {
if (!env.MAIL_ENABLED) {
throw new Error("Attempting to send verification email but email is not enabled.");
};
const mail = await transporter.sendMail({
from: env.MAIL_FROM || env.MAIL_USER,
to: user.email,
subject: "Verify your account",
text: verifyMailText
.replace(/{{verification}}/gim, user.verification_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME),
html: verifyEmailTemplate
.replace(/{{verification}}/gim, user.verification_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME)
});
if (!mail.accepted.length) {
throw new CustomError("Couldn't send verification email. Try again later.");
}
}
async function changeEmail(user) {
if (!env.MAIL_ENABLED) {
throw new Error("Attempting to send change email token but email is not enabled.");
};
const mail = await transporter.sendMail({
from: env.MAIL_FROM || env.MAIL_USER,
to: user.change_email_address,
subject: "Verify your new email address",
text: changeEmailText
.replace(/{{verification}}/gim, user.change_email_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME),
html: changeEmailTemplate
.replace(/{{verification}}/gim, user.change_email_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
.replace(/{{site_name}}/gm, env.SITE_NAME)
});
if (!mail.accepted.length) {
throw new CustomError("Couldn't send verification email. Try again later.");
}
}
async function resetPasswordToken(user) {
if (!env.MAIL_ENABLED) {
throw new Error("Attempting to send reset password email but email is not enabled.");
};
const mail = await transporter.sendMail({
from: env.MAIL_FROM || env.MAIL_USER,
to: user.email,
subject: "Reset your password",
text: resetMailText
.replace(/{{resetpassword}}/gm, user.reset_password_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN),
html: resetEmailTemplate
.replace(/{{resetpassword}}/gm, user.reset_password_token)
.replace(/{{domain}}/gm, env.DEFAULT_DOMAIN)
});
if (!mail.accepted.length) {
throw new CustomError(
"Couldn't send reset password email. Try again later."
);
}
}
async function sendReportEmail(link) {
if (!env.MAIL_ENABLED) {
throw new Error("Attempting to send report email but email is not enabled.");
};
const mail = await transporter.sendMail({
from: env.MAIL_FROM || env.MAIL_USER,
to: env.REPORT_EMAIL,
subject: "[REPORT]",
text: link,
html: link
});
if (!mail.accepted.length) {
throw new CustomError("Couldn't submit the report. Try again later.");
}
}
module.exports = {
changeEmail,
verification,
resetPasswordToken,
sendReportEmail,
}