import type { EmailConfig, EmailUserConfig } from '@auth/core/providers/email'; import { generateRandomString, RandomReader } from '@oslojs/crypto/random'; import { alphabet } from 'oslo/crypto'; import { UseSend } from 'usesend-js'; export default function UseSendProvider(config: EmailUserConfig): EmailConfig { return { id: 'usesend', type: 'email', name: 'UseSend', from: process.env.USESEND_FROM_EMAIL ?? 'noreply@example.com', 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, token } = params; // Derive a display name from the site URL, fallback to 'App' const siteUrl = process.env.USESEND_FROM_EMAIL ?? ''; const appName = siteUrl.split('@')[1]?.split('.')[0] ?? 'App'; const useSend = new UseSend( process.env.USESEND_API_KEY!, process.env.USESEND_URL!, ); // 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 - ${appName}` : `Sign in to ${appName}`, text: isPasswordReset ? `Your password reset code is ${token}` : `Your sign in code is ${token}`, html: isPasswordReset ? `
You requested a password reset. Your reset code is:
This code expires in 1 hour.
If you didn't request this, please ignore this email.
Your verification code is:
This code expires in 24 hours.