import { NextRequest, NextResponse } from 'next/server' import { supabase } from '@/lib/supabase' import crypto from 'crypto' import nodemailer from 'nodemailer' // Initialize nodemailer transporter const createTransporter = () => { const smtpHost = process.env.SMTP_HOST const smtpPort = process.env.SMTP_PORT ? parseInt(process.env.SMTP_PORT) : 587 const smtpUser = process.env.SMTP_USER const smtpPassword = process.env.SMTP_PASSWORD const smtpFromEmail = process.env.SMTP_FROM_EMAIL || 'BUILDMATE ' const smtpFromName = process.env.SMTP_FROM_NAME || 'BUILDMATE' if (!smtpHost || !smtpUser || !smtpPassword) return null return nodemailer.createTransport({ host: smtpHost, port: smtpPort, secure: smtpPort === 465, auth: { user: smtpUser, pass: smtpPassword }, }) } export async function POST(request: NextRequest) { try { const { email } = await request.json() if (!email) return NextResponse.json({ error: 'Email is required' }, { status: 400 }) // Validate email format const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ if (!emailRegex.test(email)) return NextResponse.json({ error: 'Invalid email format' }, { status: 400 }) // Validate email domain const emailDomain = email.trim().toLowerCase().split('@')[1] const realEmailProviders = [ 'gmail.com', 'googlemail.com', 'yahoo.com', 'yahoo.co.uk', 'yahoo.co.jp', 'ymail.com', 'rocketmail.com', 'outlook.com', 'hotmail.com', 'live.com', 'msn.com', 'icloud.com', 'me.com', 'mac.com', 'protonmail.com', 'proton.me', 'aol.com', 'mail.com', 'email.com' ] if (!realEmailProviders.some(provider => emailDomain === provider || emailDomain.endsWith('.' + provider))) { return NextResponse.json({ error: 'Please use a verified email address from a real email provider (Gmail, Yahoo, Outlook, etc.)', details: 'We only send verification codes to verified email addresses for security' }, { status: 400 }) } // Check if email already exists in users table const { data: existingUser } = await supabase .from('users') .select('email') .eq('email', email.trim().toLowerCase()) .single() if (existingUser) { return NextResponse.json({ error: 'Email already registered. Please use a different email or login.' }, { status: 400 }) } // Check if there's an existing unexpired code in signup_verification_codes const { data: existingCode } = await supabase .from('signup_verification_codes') .select('*') .eq('email', email.trim().toLowerCase()) .eq('verified', false) .order('expires_at', { ascending: false }) .limit(1) .maybeSingle() if (existingCode && existingCode.expires_at > Date.now()) { const timeRemaining = Math.ceil((existingCode.expires_at - Date.now()) / 1000 / 60) return NextResponse.json({ success: true, message: `A verification code was already sent. Please check your email. The code expires in ${timeRemaining} minute(s).`, codeAlreadySent: true }) } // Generate new 6-digit verification code const code = Math.floor(100000 + Math.random() * 900000).toString() const expiresAt = Date.now() + 5 * 60 * 1000 // 5 minutes const token = crypto.randomBytes(32).toString('hex') // Insert code into Supabase table const { error: insertError } = await supabase .from('signup_verification_codes') .insert({ email: email.trim().toLowerCase(), code, expires_at: expiresAt, token, token_expires_at: expiresAt, }) if (insertError) { console.error('Error inserting verification code:', insertError) return NextResponse.json({ error: insertError.message }, { status: 500 }) } // Send email via SMTP let transporter try { transporter = createTransporter() } catch (placeholderError: any) { console.error('SMTP configuration error:', placeholderError.message) if (process.env.NODE_ENV === 'development') { console.log('🔐 Verification code for', email, ':', code) return NextResponse.json({ success: true, code, message: 'Code generated (SMTP not configured, check console)' }) } return NextResponse.json({ error: placeholderError.message }, { status: 400 }) } if (!transporter && process.env.NODE_ENV === 'development') { console.log('🔐 Verification code for', email, ':', code) return NextResponse.json({ success: true, code, message: 'Code generated (SMTP not configured, check console)' }) } const fromEmailRaw = process.env.SMTP_FROM_EMAIL || 'noreply@buildmate.com' const fromName = process.env.SMTP_FROM_NAME || 'BUILDMATE' const fromEmail = fromEmailRaw.includes('<') ? fromEmailRaw.match(/<(.+)>/)?.[1] || fromEmailRaw : fromEmailRaw const mailOptions = { from: `${fromName} <${fromEmail}>`, to: email.trim().toLowerCase(), subject: 'BUILDMATE - Email Verification Code', html: ` Email Verification

BUILDMATE

Email Verification

Hello,

Thank you for signing up for BUILDMATE! Please use the verification code below to complete your registration:

Your verification code is:

${code}

This code will expire in 5 minutes. If you didn't request this code, please ignore this email.

Security Notice: Never share this code with anyone. BUILDMATE will never ask for your verification code.

This is an automated email from BUILDMATE. Please do not reply to this email.

© ${new Date().getFullYear()} BUILDMATE. All rights reserved.

`, } await transporter.sendMail(mailOptions) console.log('✅ Verification email sent to', email) return NextResponse.json({ success: true, message: 'Verification code sent to your email' }) } catch (error: any) { console.error('Send verification code error:', error) return NextResponse.json({ error: error.message || 'Internal server error' }, { status: 500 }) } }