HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/LC/api/server/middleware/validateImageRequest.js
const cookies = require('cookie');
const jwt = require('jsonwebtoken');
const { logger } = require('~/config');

const OBJECT_ID_LENGTH = 24;
const OBJECT_ID_PATTERN = /^[0-9a-f]{24}$/i;

/**
 * Validates if a string is a valid MongoDB ObjectId
 * @param {string} id - String to validate
 * @returns {boolean} - Whether string is a valid ObjectId format
 */
function isValidObjectId(id) {
  if (typeof id !== 'string') {
    return false;
  }
  if (id.length !== OBJECT_ID_LENGTH) {
    return false;
  }
  return OBJECT_ID_PATTERN.test(id);
}

/**
 * Middleware to validate image request.
 * Must be set by `secureImageLinks` via custom config file.
 */
function validateImageRequest(req, res, next) {
  if (!req.app.locals.secureImageLinks) {
    return next();
  }

  const refreshToken = req.headers.cookie ? cookies.parse(req.headers.cookie).refreshToken : null;
  if (!refreshToken) {
    logger.warn('[validateImageRequest] Refresh token not provided');
    return res.status(401).send('Unauthorized');
  }

  let payload;
  try {
    payload = jwt.verify(refreshToken, process.env.JWT_REFRESH_SECRET);
  } catch (err) {
    logger.warn('[validateImageRequest]', err);
    return res.status(403).send('Access Denied');
  }

  if (!isValidObjectId(payload.id)) {
    logger.warn('[validateImageRequest] Invalid User ID');
    return res.status(403).send('Access Denied');
  }

  const currentTimeInSeconds = Math.floor(Date.now() / 1000);
  if (payload.exp < currentTimeInSeconds) {
    logger.warn('[validateImageRequest] Refresh token expired');
    return res.status(403).send('Access Denied');
  }

  const fullPath = decodeURIComponent(req.originalUrl);
  const pathPattern = new RegExp(`^/images/${payload.id}/[^/]+$`);

  if (pathPattern.test(fullPath)) {
    logger.debug('[validateImageRequest] Image request validated');
    next();
  } else {
    logger.warn('[validateImageRequest] Invalid image path');
    res.status(403).send('Access Denied');
  }
}

module.exports = validateImageRequest;