← back to Norma

app/api/social/connect/route.ts

78 lines

import { NextRequest, NextResponse } from 'next/server';
import { requireRole } from '@/lib/require-role';
import { storeSocialCredentials, disconnectSocial, PLATFORM_FIELDS } from '@/lib/credentials';
import { auditLog } from '@/lib/audit';

const VALID_PLATFORMS = ['twitter', 'bluesky', 'facebook', 'instagram'];

/**
 * POST /api/social/connect
 * Store credentials for a social platform.
 * Body: { platform: string, credentials: Record<string, string> }
 */
export async function POST(request: NextRequest) {
  const auth = requireRole(request, 'admin');
  if (auth instanceof NextResponse) return auth;

  const body = await request.json().catch(() => ({}));
  const { platform, credentials } = body;

  if (!platform || !VALID_PLATFORMS.includes(platform)) {
    return NextResponse.json(
      { error: `Invalid platform. Must be one of: ${VALID_PLATFORMS.join(', ')}` },
      { status: 400 },
    );
  }

  if (!credentials || typeof credentials !== 'object') {
    return NextResponse.json({ error: 'credentials object is required' }, { status: 400 });
  }

  // Validate that at least one credential field is provided
  const fields = PLATFORM_FIELDS[platform] || [];
  const providedKeys = fields.map((f) => f.key).filter((k) => credentials[k]);
  if (providedKeys.length === 0) {
    return NextResponse.json(
      { error: `At least one credential field required for ${platform}` },
      { status: 400 },
    );
  }

  await storeSocialCredentials(platform, credentials);

  await auditLog('social.connected', 'social_account', platform, {
    connectedBy: auth.username,
    fieldsProvided: providedKeys,
  });

  return NextResponse.json({ success: true, platform, status: 'connected' });
}

/**
 * DELETE /api/social/connect
 * Disconnect a social platform — clears tokens.
 * Body: { platform: string }
 */
export async function DELETE(request: NextRequest) {
  const auth = requireRole(request, 'admin');
  if (auth instanceof NextResponse) return auth;

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

  if (!platform || !VALID_PLATFORMS.includes(platform)) {
    return NextResponse.json(
      { error: `Invalid platform. Must be one of: ${VALID_PLATFORMS.join(', ')}` },
      { status: 400 },
    );
  }

  await disconnectSocial(platform);

  await auditLog('social.disconnected', 'social_account', platform, {
    disconnectedBy: auth.username,
  });

  return NextResponse.json({ success: true, platform, status: 'disconnected' });
}