← back to Norma

app/api/drafts/[id]/send-test/route.ts

111 lines

import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { requireRole } from '@/lib/require-role';
import { auditLog } from '@/lib/audit';
import { getOrgId } from '@/lib/orgId';
import { htmlToText } from '@/lib/export';
import nodemailer from 'nodemailer';

type RouteContext = { params: Promise<{ id: string }> };

/**
 * POST /api/drafts/[id]/send-test
 * Send a test email using nodemailer + SMTP config from environment.
 * Body (optional): { to?: string }
 */
export async function POST(request: NextRequest, context: RouteContext) {
  const auth = requireRole(request, 'admin', 'staff');
  if (auth instanceof NextResponse) return auth;

  const orgId = auth.role === 'admin' ? getOrgId(request) : auth.orgId;
  if (!orgId) {
    return NextResponse.json({ error: 'Missing org context' }, { status: 400 });
  }

  const { id } = await context.params;

  // Check SMTP configuration
  const smtpHost = process.env.SMTP_HOST;
  const smtpPort = process.env.SMTP_PORT;
  const smtpUser = process.env.SMTP_USER;
  const smtpPass = process.env.SMTP_PASS;

  if (!smtpHost || !smtpPort || !smtpUser || !smtpPass) {
    return NextResponse.json(
      {
        error: 'SMTP not configured. Set SMTP_HOST, SMTP_PORT, SMTP_USER, and SMTP_PASS environment variables to enable test sending.',
      },
      { status: 400 }
    );
  }

  try {
    const body = await request.json().catch(() => ({}));

    // Determine recipient
    const recipientEmail = body.to || process.env.TEST_SEND_TO;
    if (!recipientEmail) {
      return NextResponse.json(
        { error: 'No recipient specified. Provide "to" in the request body or set TEST_SEND_TO environment variable.' },
        { status: 400 }
      );
    }

    // Fetch the draft
    const draftResult = await query(`SELECT * FROM drafts WHERE id = $1 AND org_id = $2`, [id, orgId]);
    if (draftResult.rowCount === 0) {
      return NextResponse.json({ error: 'Draft not found' }, { status: 404 });
    }

    const draft = draftResult.rows[0];

    // Create transporter
    const transporter = nodemailer.createTransport({
      host: smtpHost,
      port: parseInt(smtpPort, 10),
      secure: parseInt(smtpPort, 10) === 465,
      auth: {
        user: smtpUser,
        pass: smtpPass,
      },
    });

    // Build and send the email
    const plainText = draft.body_text || htmlToText(draft.body_html);

    await transporter.sendMail({
      from: `"${draft.from_name}" <${draft.from_email}>`,
      replyTo: draft.reply_to || undefined,
      to: recipientEmail,
      subject: `[TEST] ${draft.subject}`,
      text: plainText,
      html: draft.body_html,
    });

    // Update draft with test send info
    const now = new Date().toISOString();
    await query(
      `UPDATE drafts SET test_sent_at = $1, test_sent_to = $2 WHERE id = $3 AND org_id = $4`,
      [now, recipientEmail, id, orgId]
    );

    const ip = request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip') || undefined;
    await auditLog(
      'draft.test_sent',
      'draft',
      id,
      { sent_to: recipientEmail, subject: draft.subject },
      ip
    );

    return NextResponse.json({
      success: true,
      sentTo: recipientEmail,
      sentAt: now,
    });
  } catch (err) {
    console.error('[api/drafts/[id]/send-test] POST error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to send test email' }, { status: 500 });
  }
}