import type { NextFunction, Request, Response } from 'express';
import config from '@/shared/config';
import { UNSAFE_HTTP_METHODS } from '@/shared/constants/auth';
import ForbiddenError from '@/shared/errors/forbidden';

function getOriginFromHeader(value: string | undefined): string | null {
  if (!value) {
    return null;
  }

  try {
    return new URL(value).origin;
  } catch {
    return null;
  }
}

function csrfOrigin(req: Request, _res: Response, next: NextFunction): void {
  if (!UNSAFE_HTTP_METHODS.includes(req.method)) {
    next();
    return;
  }

  const sourceOrigin =
    getOriginFromHeader(req.headers.origin) ||
    getOriginFromHeader(req.headers.referer);

  if (config.auth.allowAllOrigins && sourceOrigin) {
    next();
    return;
  }

  if (sourceOrigin && config.auth.allowedOrigins.includes(sourceOrigin)) {
    next();
    return;
  }

  next(new ForbiddenError());
}

export default csrfOrigin;
