UNPKG

nextjs-auth-starter

Version:

CLI tool to set up Next.js authentication with better-auth, PostgreSQL, and Drizzle ORM. Usage: npx nextjs-auth-starter init

161 lines (142 loc) 5.18 kB
import { env } from "../env.mjs"; interface EmailOptions { to: string; subject: string; html: string; text?: string; } export class MailjetService { private apiKey: string; private secretKey: string; private fromEmail: string; private fromName: string; constructor() { this.apiKey = env.MAILJET_API_KEY; this.secretKey = env.MAILJET_SECRET_KEY; this.fromEmail = env.MAILJET_FROM_EMAIL; this.fromName = env.MAILJET_FROM_NAME; if (!this.apiKey || !this.secretKey || !this.fromEmail) { throw new Error( "Mailjet configuration is missing. Please set MAILJET_API_KEY, MAILJET_SECRET_KEY, and MAILJET_FROM_EMAIL in your environment variables." ); } } async sendEmail({ to, subject, html, text }: EmailOptions): Promise<boolean> { try { if (!to || to.trim() === "") { console.error("Empty email address provided to sendEmail"); return false; } const response = await fetch("https://api.mailjet.com/v3.1/send", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Basic ${Buffer.from( `${this.apiKey}:${this.secretKey}` ).toString("base64")}`, }, body: JSON.stringify({ Messages: [ { From: { Email: this.fromEmail, Name: this.fromName, }, To: [ { Email: to, }, ], Subject: subject, TextPart: text || "", HTMLPart: html, }, ], }), }); if (!response.ok) { const error = await response.text(); console.error("Mailjet API error:", error); return false; } return true; } catch (error) { console.error("Error sending email:", error); return false; } } async sendVerificationEmail( to: string, verificationUrl: string ): Promise<boolean> { if (!to || to.trim() === "") { console.error("Empty email address provided to sendVerificationEmail"); return false; } const subject = "Verify your email address"; const html = ` <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"> <h1 style="color: #333; text-align: center;">Email Verification</h1> <p style="color: #666; font-size: 16px;"> Thank you for signing up! Please click the button below to verify your email address. </p> <div style="text-align: center; margin: 30px 0;"> <a href="${verificationUrl}" style="background-color: #007cba; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;"> Verify Email </a> </div> <p style="color: #999; font-size: 14px;"> If the button doesn't work, copy and paste this link into your browser: <br> <a href="${verificationUrl}">${verificationUrl}</a> </p> <p style="color: #999; font-size: 12px;"> If you didn't create an account, you can safely ignore this email. </p> </div> `; const text = ` Email Verification Thank you for signing up! Please visit the following link to verify your email address: ${verificationUrl} If you didn't create an account, you can safely ignore this email. `; return this.sendEmail({ to, subject, html, text }); } async sendPasswordResetEmail(to: string, resetUrl: string): Promise<boolean> { const subject = "Reset your password"; const html = ` <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;"> <h1 style="color: #333; text-align: center;">Password Reset</h1> <p style="color: #666; font-size: 16px;"> You requested to reset your password. Click the button below to create a new password. </p> <div style="text-align: center; margin: 30px 0;"> <a href="${resetUrl}" style="background-color: #dc3545; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; display: inline-block;"> Reset Password </a> </div> <p style="color: #999; font-size: 14px;"> If the button doesn't work, copy and paste this link into your browser: <br> <a href="${resetUrl}">${resetUrl}</a> </p> <p style="color: #999; font-size: 12px;"> If you didn't request a password reset, you can safely ignore this email. This link will expire in 1 hour. </p> </div> `; const text = ` Password Reset You requested to reset your password. Please visit the following link to create a new password: ${resetUrl} If you didn't request a password reset, you can safely ignore this email. This link will expire in 1 hour. `; return this.sendEmail({ to, subject, html, text }); } } export const mailjetService = new MailjetService();