Source: middleware/checkBlocked.ts

import { PrismaClient, Role } from '@prisma/client';
import { Request, Response, NextFunction } from 'express';
import dayjs from 'dayjs';

const prisma = new PrismaClient();

interface CustomRequest extends Request {
  user?: {
    id: string;
    role: Role;
  };
}

/**
 * Middleware to check if the user is blocked by the author or banned from the site.
 *
 * This middleware checks if the current user is blocked by the author (based on `authorId` from the request body) or if the user is banned (temporarily or permanently) from the platform. If the user is blocked or banned, a 403 Forbidden response is returned. Otherwise, the request proceeds to the next middleware.
 *
 * @param {CustomRequest} req - Express request object, extended to include the user property.
 * @param {Response} res - Express response object.
 * @param {NextFunction} next - Express next middleware function.
 * @returns {Promise<void>} - Calls `next()` if the user is not blocked or banned, otherwise returns a 403 Forbidden response.
 *
 * @example
 * // Use checkBlocked middleware in a route
 * app.post('/messages', checkBlocked, sendMessage);
 */
const checkBlocked = async (
  req: CustomRequest,
  res: Response,
  next: NextFunction
): Promise<void> => {
  const { authorId } = req.body;
  const userId = Number(req.user?.id);

  if (!userId) {
    res.status(401).json({ message: 'Unauthorized' });
    return;
  }

  try {
    // Check if the user is blocked by the author
    const isBlocked = await prisma.block.findFirst({
      where: {
        blockedById: authorId,
        blockedUserId: userId,
      },
    });

    if (isBlocked) {
      res.status(403).json({ message: 'You are blocked by this user' });
      return;
    }

    // Check if the user is banned
    const user = await prisma.user.findUnique({
      where: { id: userId },
    });

    // If the user is banned, check if it's temporary or permanent
    if (user?.banned) {
      if (user.banExpiry && dayjs(user.banExpiry).isAfter(dayjs())) {
        res.status(403).json({
          message: `You are temporarily banned until ${dayjs(user.banExpiry).format('YYYY-MM-DD HH:mm:ss')}`,
        });
        return;
      }

      // Permanently banned users
      res.status(403).json({ message: 'You are permanently banned from the site' });
      return;
    }

    next();
  } catch (error) {
    res.status(500).json({ message: 'Internal server error', error: (error as any).message });
  }
};

export default checkBlocked;