import type { EmailConfig, EmailUserConfig } from '@auth/core/providers/email'; import { alphabet } from 'oslo/crypto'; import { generateRandomString, RandomReader } from '@oslojs/crypto/random'; import { UseSend } from 'usesend-js'; export default function UseSendProvider(config: EmailUserConfig): EmailConfig { return { id: 'usesend', type: 'email', name: 'UseSend', from: 'TechTracker ', maxAge: 24 * 60 * 60, // 24 hours async generateVerificationToken() { const random: RandomReader = { read(bytes) { crypto.getRandomValues(bytes); }, }; return generateRandomString(random, alphabet('0-9'), 6); }, async sendVerificationRequest(params) { const { identifier: to, provider, url, theme, token } = params; //const { host } = new URL(url); const host = 'TechTracker'; const useSend = new UseSend( process.env.AUTH_USESEND_API_KEY!, 'https://usesend.gbrown.org', ); // For password reset, we want to send the code, not the magic link const isPasswordReset = url.includes('reset') || provider.id?.includes('reset'); const result = await useSend.emails.send({ from: provider.from!, to: [to], subject: isPasswordReset ? `Reset your password - ${host}` : `Sign in to ${host}`, text: isPasswordReset ? `Your password reset code is ${token}` : `Your sign in code is ${token}`, html: isPasswordReset ? `

Password Reset Request

You requested a password reset. Your reset code is:

${token}

This code expires in 1 hour.

If you didn't request this, please ignore this email.

` : `

Your Sign In Code

Your verification code is:

${token}

This code expires in 24 hours.

`, }); if (result.error) { throw new Error('UseSend error: ' + JSON.stringify(result.error)); } }, options: config, }; } // Create specific instances for password reset and email verification export const UseSendOTPPasswordReset = UseSendProvider({ id: 'usesend-otp-password-reset', apiKey: process.env.AUTH_USESEND_API_KEY, maxAge: 60 * 60, // 1 hour }); export const UseSendOTP = UseSendProvider({ id: 'usesend-otp', apiKey: process.env.AUTH_USESEND_API_KEY, maxAge: 60 * 20, // 20 minutes });