!C99Shell v. 2.5 [PHP 8 Update] [24.05.2025]!

Software: Apache. PHP/8.1.30 

uname -a: Linux server1.tuhinhossain.com 5.15.0-163-generic #173-Ubuntu SMP Tue Oct 14 17:51:00 UTC
2025 x86_64
 

uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root)  

Safe-mode: OFF (not secure)

/home/picotech/domains/note.picotech.app/public_html/src/middleware/   drwxr-xr-x
Free 25.88 GB of 117.98 GB (21.93%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Self remove    Logout    


Viewing file:     errorHandler.js (9.36 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
const config = require('../config/config');

// Sanitize error messages to prevent information disclosure
const sanitizeErrorMessage = (message) => {
  if (!message) return 'An error occurred';

  // Remove file paths, stack traces, and sensitive information
  return message
    .replace(/\/[^\s]+/g, '/[REDACTED]') // Remove file paths
    .replace(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g, '[REDACTED_IP]') // Remove IPs
    .replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '[REDACTED_EMAIL]') // Remove emails
    .replace(/\b[A-Z]{2,}\b/g, '[REDACTED_TOKEN]') // Remove potential tokens/keys
    .replace(/password|token|key|secret/gi, '[REDACTED]') // Remove sensitive keywords
    .substring(0, 200); // Limit length
};

// Custom error class
class AppError extends Error {
  constructor(message, statusCode, code = null, details = null) {
    super(message);
    this.statusCode = statusCode;
    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
    this.isOperational = true;
    this.code = code;
    this.details = details;

    Error.captureStackTrace(this, this.constructor);
  }
}

// Handle Sequelize validation errors
const handleSequelizeValidationError = (err) => {
  const errors = err.errors.map(error => ({
    field: error.path,
    message: error.message,
    value: error.value,
  }));

  return new AppError('Validation failed', 400, 'VALIDATION_ERROR', errors);
};

// Handle Sequelize unique constraint errors
const handleSequelizeUniqueConstraintError = (err) => {
  const field = err.errors[0]?.path || 'field';
  const message = `${field} already exists`;
  
  return new AppError(message, 409, 'DUPLICATE_ENTRY');
};

// Handle Sequelize foreign key constraint errors
const handleSequelizeForeignKeyConstraintError = (err) => {
  return new AppError('Referenced resource not found', 400, 'FOREIGN_KEY_CONSTRAINT');
};

// Handle JWT errors
const handleJWTError = () => {
  return new AppError('Invalid token. Please log in again', 401, 'INVALID_TOKEN');
};

const handleJWTExpiredError = () => {
  return new AppError('Your token has expired. Please log in again', 401, 'TOKEN_EXPIRED');
};

// Handle Multer errors
const handleMulterError = (err) => {
  if (err.code === 'LIMIT_FILE_SIZE') {
    return new AppError('File too large', 400, 'FILE_TOO_LARGE');
  }
  if (err.code === 'LIMIT_FILE_COUNT') {
    return new AppError('Too many files', 400, 'TOO_MANY_FILES');
  }
  if (err.code === 'LIMIT_UNEXPECTED_FILE') {
    return new AppError('Unexpected file field', 400, 'UNEXPECTED_FILE');
  }
  
  return new AppError('File upload error', 400, 'UPLOAD_ERROR');
};

// Send error response in development
const sendErrorDev = (err, res) => {
  res.status(err.statusCode).json({
    success: false,
    error: {
      status: err.status,
      message: err.message,
      code: err.code,
      stack: err.stack,
      details: err.details || null,
    },
  });
};

// Send error response in development with validation details
const sendValidationErrorDev = (err, res) => {
  res.status(err.statusCode).json({
    success: false,
    error: {
      status: err.status,
      message: err.message,
      code: err.code,
      details: err.details || null,
      stack: err.stack,
    },
  });
};

// Send error response in production
const sendErrorProd = (err, res) => {
  // Operational, trusted error: send message to client
  if (err.isOperational) {
    res.status(err.statusCode).json({
      success: false,
      error: {
        status: err.status,
        message: err.message,
        code: err.code,
        stack: undefined, // Never include stack in production
        details: err.details || null,
      },
    });
  } else {
    // Programming or other unknown error: don't leak error details
    // Log full error details for debugging but sanitize response
    console.error('ERROR 💥', {
      message: sanitizeErrorMessage(err.message),
      stack: undefined, // Never log stack traces in production
      name: err.name,
      // Don't log sensitive information like file paths, internal data
    });

    res.status(500).json({
      success: false,
      error: {
        status: 'error',
        message: 'Something went wrong!',
        code: 'INTERNAL_SERVER_ERROR',
        stack: undefined,
        details: null,
      },
    });
  }
};

// Main error handling middleware
const globalErrorHandler = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';

  if (config.nodeEnv === 'development') {
    sendErrorDev(err, res);
  } else {
    let error = { ...err };
    error.message = err.message;

    // Handle specific error types
    if (err.name === 'SequelizeValidationError') {
      error = handleSequelizeValidationError(error);
    }

    if (err.name === 'SequelizeUniqueConstraintError') {
      error = handleSequelizeUniqueConstraintError(error);
    }

    if (err.name === 'SequelizeForeignKeyConstraintError') {
      error = handleSequelizeForeignKeyConstraintError(error);
    }

    if (err.name === 'JsonWebTokenError') {
      error = handleJWTError();
    }

    if (err.name === 'TokenExpiredError') {
      error = handleJWTExpiredError();
    }

    if (err.name === 'MulterError') {
      error = handleMulterError(err);
    }

    // Handle Sequelize database errors (like constraint violations)
    if (err.name === 'SequelizeDatabaseError' || err.original?.code) {
      // Handle specific database constraint errors
      if (err.original?.code === 'ER_DUP_ENTRY') {
        // Check if it's an email validation error (email format)
        if (err.original?.sqlMessage?.includes('email')) {
          error = new AppError('Invalid email address', 400, 'VALIDATION_ERROR', [{
            field: 'email',
            message: 'Invalid email address',
            value: err.original?.sqlMessage?.match(/'([^']+)'/)?.[1] || 'invalid'
          }]);
        } else {
          error = new AppError('A database constraint was violated. Please check your input.', 400, 'DATABASE_CONSTRAINT_ERROR');
        }
      } else {
        error = new AppError('A database error occurred. Please try again.', 500, 'DATABASE_ERROR');
      }
    }

    // Always send validation errors in development mode with details
    if (err.code === 'VALIDATION_ERROR' && config.nodeEnv === 'development') {
      sendValidationErrorDev(err, res);
    } else {
      sendErrorProd(error, res);
    }
  }
};

// Handle unhandled routes
const handleNotFound = (req, res, next) => {
  const err = new AppError(`Can't find ${req.originalUrl} on this server!`, 404, 'ROUTE_NOT_FOUND');
  next(err);
};

// Async error wrapper
const catchAsync = (fn) => {
  return (req, res, next) => {
    fn(req, res, next).catch(next);
  };
};

// Handle unhandled promise rejections
const handleUnhandledRejection = () => {
  process.on('unhandledRejection', (err, promise) => {
    console.log('UNHANDLED REJECTION! 💥 Shutting down...');
    console.log(err.name, err.message);
    
    // Close server gracefully
    process.exit(1);
  });
};

// Handle uncaught exceptions
const handleUncaughtException = () => {
  process.on('uncaughtException', (err) => {
    console.log('UNCAUGHT EXCEPTION! 💥 Shutting down...');
    console.log(err.name, err.message);
    
    process.exit(1);
  });
};

// Graceful shutdown handler
const handleGracefulShutdown = (server) => {
  const shutdown = (signal) => {
    console.log(`${signal} received. Shutting down gracefully...`);
    
    server.close(() => {
      console.log('Process terminated');
      process.exit(0);
    });
    
    // Force close after 10 seconds
    setTimeout(() => {
      console.log('Forcing shutdown...');
      process.exit(1);
    }, 10000);
  };

  process.on('SIGTERM', () => shutdown('SIGTERM'));
  process.on('SIGINT', () => shutdown('SIGINT'));
};

// Log error details
const logError = (err, req = null) => {
  const errorInfo = {
    timestamp: new Date().toISOString(),
    message: config.nodeEnv === 'production' ? sanitizeErrorMessage(err.message) : err.message,
    // Don't log stack traces in production to avoid information disclosure
    stack: config.nodeEnv === 'development' ? err.stack : undefined,
    statusCode: err.statusCode,
    code: err.code,
  };

  if (req) {
    errorInfo.request = {
      method: req.method,
      url: req.originalUrl,
      // Sanitize IP address for privacy
      ip: req.ip ? req.ip.replace(/\.\d+$/, '.***') : undefined,
      userAgent: req.get('User-Agent') ? req.get('User-Agent').substring(0, 100) : undefined, // Limit user agent length
      userId: req.user?.id || null,
    };
  }

  console.error('Error Details:', JSON.stringify(errorInfo, null, 2));
};

// Validation error formatter
const formatValidationErrors = (errors) => {
  return errors.map(error => ({
    field: error.path || error.param,
    message: error.msg || error.message,
    value: error.value,
    location: error.location,
  }));
};

// Rate limit error handler
const handleRateLimitError = (req, res) => {
  res.status(429).json({
    success: false,
    error: {
      status: 'fail',
      message: 'Too many requests from this IP, please try again later',
      code: 'RATE_LIMIT_EXCEEDED',
      stack: undefined,
      details: { retryAfter: req.rateLimit?.resetTime || 900 },
    },
  });
};

module.exports = {
  AppError,
  globalErrorHandler,
  handleNotFound,
  catchAsync,
  handleUnhandledRejection,
  handleUncaughtException,
  handleGracefulShutdown,
  logError,
  formatValidationErrors,
  handleRateLimitError,
};

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0058 ]--