import { PrismaClient as PrismaClientAuth } from '../node_modules/.prisma/client-auth'; import { Resend } from 'resend'; import * as dotenv from 'dotenv'; import crypto from 'crypto'; dotenv.config(); const prismaAuth = new PrismaClientAuth({ datasourceUrl: process.env.DATABASE_URL_AUTH, }); const resend = new Resend(process.env.RESEND_API_KEY); async function checkAndResend() { try { console.log('š Checking users in database...\n'); // Find users that are not verified const unverifiedUsers = await prismaAuth.user.findMany({ where: { emailVerified: false, }, select: { id: true, email: true, name: true, emailConfirmationToken: true, emailConfirmationTokenExpiry: true, createdAt: true, }, orderBy: { createdAt: 'desc', }, }); if (unverifiedUsers.length === 0) { console.log('ā No unverified users found.'); console.log('\nš All users:'); const allUsers = await prismaAuth.user.findMany({ select: { id: true, email: true, name: true, emailVerified: true, createdAt: true, }, orderBy: { createdAt: 'desc', }, }); allUsers.forEach(user => { console.log(` - ${user.email} (${user.name}) - Verified: ${user.emailVerified}`); }); return; } console.log(`Found ${unverifiedUsers.length} unverified user(s):\n`); for (const user of unverifiedUsers) { console.log(`š§ User: ${user.email} (${user.name})`); console.log(` Created: ${user.createdAt}`); console.log(` Has token: ${user.emailConfirmationToken ? 'Yes' : 'No'}`); if (user.emailConfirmationTokenExpiry) { const isExpired = user.emailConfirmationTokenExpiry < new Date(); console.log(` Token expires: ${user.emailConfirmationTokenExpiry} ${isExpired ? '(EXPIRED)' : ''}`); } console.log(''); } // Get the most recent unverified user const latestUser = unverifiedUsers[0]; console.log(`\nš¤ Attempting to resend confirmation email to: ${latestUser.email}\n`); // Generate new token if needed let token = latestUser.emailConfirmationToken; if (!token || (latestUser.emailConfirmationTokenExpiry && latestUser.emailConfirmationTokenExpiry < new Date())) { console.log('š Generating new confirmation token...'); token = crypto.randomBytes(32).toString('hex'); const tokenExpiry = new Date(); tokenExpiry.setHours(tokenExpiry.getHours() + 24); await prismaAuth.user.update({ where: { id: latestUser.id }, data: { emailConfirmationToken: token, emailConfirmationTokenExpiry: tokenExpiry, }, }); console.log('ā New token generated'); } // Send email const baseUrl = process.env.NEXTAUTH_URL || process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3001'; const confirmationUrl = `${baseUrl}/api/auth/verify-email?token=${token}`; const fromEmail = process.env.RESEND_FROM_EMAIL?.trim().replace(/^["']|["']$/g, '') || 'onboarding@resend.dev'; console.log(`š§ Sending email from: ${fromEmail}`); console.log(`š§ Sending email to: ${latestUser.email}`); console.log(`š Confirmation URL: ${confirmationUrl}\n`); try { const result = await resend.emails.send({ from: fromEmail, to: latestUser.email, subject: 'Confirm your email address', html: `
Hi ${latestUser.name},
You requested a new confirmation email. Please confirm your email address by clicking the button below:
Or copy and paste this link into your browser:
${confirmationUrl}
This link will expire in 24 hours. If you didn't request this email, you can safely ignore it.