UNPKG

create-auth-js-boiler

Version:
283 lines (262 loc) 18.7 kB
import nodemailer from "nodemailer"; export const sendVerificationEmail = async (email: string, token: string) => { const confirmLink = `${process.env.NEXTAUTH_URL}/auth/new-verification?token=${token}`; const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, auth: { user: process.env.EMAIL, pass: process.env.EMAIL_PASS_KEY, }, }); // HTML email template with inline styles for maximum compatibility const htmlContent = ` <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Verify your email</title> </head> <body style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; font-size: 16px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%; background-color: #f6f6f6;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; display: block; max-width: 580px; padding: 10px; width: 580px; margin: 0 auto;"> <div style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 580px; padding: 10px;"> <!-- HEADER --> <div style="text-align: center; margin-bottom: 30px; margin-top: 30px;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 20px; text-align: center;"> <h1 style="color: #03045e; font-size: 24px; font-weight: bold; margin: 0; margin-bottom: 8px;">Auth JS Boiler</h1> <span style="color: #90a4ae; font-size: 14px;">Complete Authentication Solution</span> </td> </tr> </table> </div> <!-- MAIN CONTENT --> <div style="background: #ffffff; border-radius: 8px; padding: 30px; box-shadow: 0 2px 5px rgba(0,0,0,0.05);"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;"> <h2 style="color: #2b3a4a; font-size: 20px; font-weight: bold; margin: 0 0 20px;">Verify Your Email Address</h2> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px; color: #4a5568;">Thank you for registering. To complete your registration and access all features, please verify your email address.</p> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 24px; color: #4a5568;">This link will expire in 10 minutes.</p> <table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; width: 100%; box-sizing: border-box;"> <tr> <td align="center" style="font-family: sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 16px;"> <a href="${confirmLink}" target="_blank" style="display: inline-block; color: #ffffff; background-color: #03045e; border-radius: 4px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: bold; margin: 0; padding: 12px 24px; border: none;"> Verify Email Address </a> </td> </tr> </table> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; color: #718096;">If the button doesn't work, copy and paste this link into your browser:</p> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; color: #718096;"><a href="${confirmLink}" style="color: #03045e; text-decoration: underline;">${confirmLink}</a></p> </td> </tr> </table> </div> <!-- FOOTER --> <div style="clear: both; margin-top: 24px; text-align: center; width: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #9ca3af; font-size: 12px; text-align: center;"> <p style="margin: 0; margin-bottom: 5px;">This email was sent to ${email}</p> <p style="margin: 0; margin-bottom: 5px;">If you didn't create an account, you can safely ignore this email.</p> <p style="margin: 0; margin-bottom: 5px;">&copy; ${new Date().getFullYear()} Auth JS Boiler. All rights reserved.</p> </td> </tr> </table> </div> </div> </td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> </tr> </table> </body> </html> `; // Send mail with defined transport object await transporter.sendMail({ from: `"Auth JS Boiler" <${process.env.EMAIL}>`, // Formatted sender to: email, subject: "Verify Your Email Address", text: `Thanks for signing up! Please verify your email by clicking this link: ${confirmLink}`, html: htmlContent, }); }; export const sendPasswordResetEmail = async (email: string, token: string) => { const resetLink = `${process.env.NEXTAUTH_URL}/auth/new-password?token=${token}`; const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, auth: { user: process.env.EMAIL, pass: process.env.EMAIL_PASS_KEY, }, }); // HTML email template with inline styles for maximum compatibility const htmlContent = ` <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Reset your password</title> </head> <body style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; font-size: 16px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%; background-color: #f6f6f6;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; display: block; max-width: 580px; padding: 10px; width: 580px; margin: 0 auto;"> <div style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 580px; padding: 10px;"> <!-- HEADER --> <div style="text-align: center; margin-bottom: 30px; margin-top: 30px;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 20px; text-align: center;"> <h1 style="color: #03045e; font-size: 24px; font-weight: bold; margin: 0; margin-bottom: 8px;">Auth JS Boiler</h1> <span style="color: #90a4ae; font-size: 14px;">Complete Authentication Solution</span> </td> </tr> </table> </div> <!-- MAIN CONTENT --> <div style="background: #ffffff; border-radius: 8px; padding: 30px; box-shadow: 0 2px 5px rgba(0,0,0,0.05);"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;"> <h2 style="color: #2b3a4a; font-size: 20px; font-weight: bold; margin: 0 0 20px;">Reset Your Password</h2> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px; color: #4a5568;">You recently requested to reset your password for your account. Click the button below to create a new password.</p> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 24px; color: #4a5568;">This link will expire in 10 minutes for security reasons.</p> <table role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; width: 100%; box-sizing: border-box;"> <tr> <td align="center" style="font-family: sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 16px;"> <a href="${resetLink}" target="_blank" style="display: inline-block; color: #ffffff; background-color: #03045e; border-radius: 4px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: bold; margin: 0; padding: 12px 24px; border: none;"> Reset Password </a> </td> </tr> </table> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; color: #718096;">If the button doesn't work, copy and paste this link into your browser:</p> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; color: #718096;"><a href="${resetLink}" style="color: #03045e; text-decoration: underline;">${resetLink}</a></p> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-bottom: 15px; color: #718096;">If you did not request a password reset, please ignore this email or contact support if you have concerns about your account.</p> </td> </tr> </table> </div> <!-- FOOTER --> <div style="clear: both; margin-top: 24px; text-align: center; width: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #9ca3af; font-size: 12px; text-align: center;"> <p style="margin: 0; margin-bottom: 5px;">This email was sent to ${email}</p> <p style="margin: 0; margin-bottom: 5px;">If you didn't request a password reset, you can safely ignore this email.</p> <p style="margin: 0; margin-bottom: 5px;">&copy; ${new Date().getFullYear()} Auth JS Boiler. All rights reserved.</p> </td> </tr> </table> </div> </div> </td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> </tr> </table> </body> </html> `; // Send mail with defined transport object await transporter.sendMail({ from: `"Auth JS Boiler" <${process.env.EMAIL}>`, // Formatted sender to: email, subject: "Reset Your Password", text: `You recently requested a password reset for your account. Please reset your password by clicking this link: ${resetLink} (This link will expire in 10 minutes)`, html: htmlContent, }); }; export const sendTwoFactorTokenEmail = async (email: string, token: string) => { const transporter = nodemailer.createTransport({ host: "smtp.gmail.com", port: 587, secure: false, auth: { user: process.env.EMAIL, pass: process.env.EMAIL_PASS_KEY, }, }); // HTML email template with inline styles for maximum compatibility const htmlContent = ` <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Your Authentication Code</title> </head> <body style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; font-size: 16px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%; background-color: #f6f6f6;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; display: block; max-width: 580px; padding: 10px; width: 580px; margin: 0 auto;"> <div style="box-sizing: border-box; display: block; margin: 0 auto; max-width: 580px; padding: 10px;"> <!-- HEADER --> <div style="text-align: center; margin-bottom: 30px; margin-top: 30px;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top; padding-bottom: 20px; text-align: center;"> <h1 style="color: #03045e; font-size: 24px; font-weight: bold; margin: 0; margin-bottom: 8px;">Auth JS Boiler</h1> <span style="color: #90a4ae; font-size: 14px;">Complete Authentication Solution</span> </td> </tr> </table> </div> <!-- MAIN CONTENT --> <div style="background: #ffffff; border-radius: 8px; padding: 30px; box-shadow: 0 2px 5px rgba(0,0,0,0.05);"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;"> <h2 style="color: #2b3a4a; font-size: 20px; font-weight: bold; margin: 0 0 20px;">Your Authentication Code</h2> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px; color: #4a5568;">To complete the sign-in process, please use the following verification code:</p> <!-- CODE DISPLAY --> <div style="background-color: #f8fafc; border: 1px solid #e2e8f0; border-radius: 6px; margin: 24px 0; padding: 16px; text-align: center;"> <p style="font-family: monospace; font-size: 32px; font-weight: bold; letter-spacing: 4px; margin: 0; color: #03045e;">${token}</p> </div> <p style="font-family: sans-serif; font-size: 16px; font-weight: normal; margin: 0; margin-bottom: 16px; color: #4a5568;">This code will expire in 10 minutes for security purposes.</p> <p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; margin-top: 24px; color: #718096;">If you did not request this code, please ignore this email and ensure your account is secure.</p> </td> </tr> </table> </div> <!-- FOOTER --> <div style="clear: both; margin-top: 24px; text-align: center; width: 100%;"> <table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: separate; width: 100%;"> <tr> <td style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #9ca3af; font-size: 12px; text-align: center;"> <p style="margin: 0; margin-bottom: 5px;">This email was sent to ${email}</p> <p style="margin: 0; margin-bottom: 5px;">If you didn't attempt to sign in, you can safely ignore this email.</p> <p style="margin: 0; margin-bottom: 5px;">&copy; ${new Date().getFullYear()} Auth JS Boiler. All rights reserved.</p> </td> </tr> </table> </div> </div> </td> <td style="font-family: sans-serif; font-size: 16px; vertical-align: top;">&nbsp;</td> </tr> </table> </body> </html> `; // Send mail with defined transport object await transporter.sendMail({ from: `"Auth JS Boiler" <${process.env.EMAIL}>`, // Formatted sender to: email, subject: "Your Two-Factor Authentication Code", text: `Your verification code is: ${token}\n\nThis code will expire in 10 minutes.\n\nIf you didn't request this code, please ignore this email.`, html: htmlContent, }); };