import { NextRequest, NextResponse } from "next/server"; import { supabase } from "@/lib/supabase"; import nodemailer from "nodemailer"; export const dynamic = "force-dynamic"; export const runtime = "nodejs"; 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) { throw new Error("SMTP credentials are missing in environment variables."); } return nodemailer.createTransport({ host: smtpHost, port: smtpPort, secure: smtpPort === 465, auth: { user: smtpUser, pass: smtpPassword, }, }); }; export async function POST(request: NextRequest) { try { const { userId } = await request.json(); if (!userId) { return NextResponse.json({ error: "User ID is required" }, { status: 400 }); } // Get user info from Supabase const { data: user, error: userError } = await supabase .from("users") .select("user_name, email") .eq("user_id", userId) .single(); if (userError || !user) { return NextResponse.json({ error: "User not found" }, { status: 404 }); } // Check if an unexpired unverified code already exists const { data: existingCode } = await supabase .from("password_change_verification_codes") .select("*") .eq("user_id", userId) .eq("verified", false) .gt("expires_at", new Date().toISOString()) // only unexpired codes .single(); if (existingCode) { return NextResponse.json({ success: true, message: "A verification code was already sent. Please check your email.", }); } // Generate 6-digit code const code = Math.floor(100000 + Math.random() * 900000).toString(); const expiresAt = new Date(Date.now() + 5 * 60 * 1000).toISOString(); // store as UTC // Insert into Supabase await supabase.from("password_change_verification_codes").insert({ user_id: userId, code, expires_at: expiresAt, }); // Send email const transporter = createTransporter(); 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 emailHtml = ` Password Change Verification Code

BUILDMATE

Password Change Verification Code

Hello ${user.user_name},

You requested to change the password for your BUILDMATE account. Please use the verification code below to confirm this change:

${code}

This code will expire in 5 minutes

Security Notice: If you didn't request this password change, please ignore this message or contact support immediately if you're concerned about your account security.

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

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

`; await transporter.verify(); await transporter.sendMail({ from: `${fromName} <${fromEmail}>`, to: user.email, subject: `BUILDMATE Password Change Verification Code`, html: emailHtml, }); return NextResponse.json({ success: true, message: "Verification code sent to your email" }); } catch (error: any) { console.error("Send password change code error:", error); return NextResponse.json({ error: error.message || "Internal server error" }, { status: 500 }); } }