Initial commit: StreamFlow IPTV platform
This commit is contained in:
commit
73a8ae9ffd
1240 changed files with 278451 additions and 0 deletions
227
backend/utils/routeProtection.js
Normal file
227
backend/utils/routeProtection.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
/**
|
||||
* Route Protection Utility
|
||||
* Ensures all routes have proper error handling (CWE-391 compliance)
|
||||
* Wraps database callbacks and async operations with error handlers
|
||||
*/
|
||||
|
||||
const logger = require('./logger');
|
||||
const { sanitizeError } = require('./errorHandler');
|
||||
|
||||
/**
|
||||
* Wrap database callback to ensure errors are caught
|
||||
*
|
||||
* @param {Function} callback - Database callback function
|
||||
* @param {Object} res - Express response object
|
||||
* @param {string} context - Context for error logging
|
||||
* @returns {Function} Wrapped callback
|
||||
*/
|
||||
function wrapDbCallback(callback, res, context = 'Database operation') {
|
||||
return function(err, ...args) {
|
||||
if (err) {
|
||||
logger.error(`${context} error:`, {
|
||||
error: err.message,
|
||||
stack: err.stack,
|
||||
context
|
||||
});
|
||||
|
||||
const sanitized = sanitizeError(err);
|
||||
return res.status(500).json({
|
||||
error: sanitized.message,
|
||||
code: sanitized.code,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
return callback(err, ...args);
|
||||
} catch (callbackError) {
|
||||
logger.error(`${context} callback error:`, {
|
||||
error: callbackError.message,
|
||||
stack: callbackError.stack,
|
||||
context
|
||||
});
|
||||
|
||||
const sanitized = sanitizeError(callbackError);
|
||||
return res.status(500).json({
|
||||
error: sanitized.message,
|
||||
code: sanitized.code,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap sync route handler to catch any errors
|
||||
*
|
||||
* @param {Function} handler - Route handler function
|
||||
* @returns {Function} Wrapped handler
|
||||
*/
|
||||
function wrapSyncHandler(handler) {
|
||||
return function(req, res, next) {
|
||||
try {
|
||||
return handler(req, res, next);
|
||||
} catch (error) {
|
||||
logger.error('Sync route handler error:', {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
method: req.method,
|
||||
path: req.path
|
||||
});
|
||||
|
||||
next(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap async route handler to catch promise rejections
|
||||
*
|
||||
* @param {Function} handler - Async route handler function
|
||||
* @returns {Function} Wrapped handler
|
||||
*/
|
||||
function wrapAsyncHandler(handler) {
|
||||
return function(req, res, next) {
|
||||
Promise.resolve(handler(req, res, next))
|
||||
.catch((error) => {
|
||||
logger.error('Async route handler error:', {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
method: req.method,
|
||||
path: req.path
|
||||
});
|
||||
|
||||
next(error);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Smart route wrapper - automatically detects and wraps handlers
|
||||
*
|
||||
* @param {Function} handler - Route handler (sync or async)
|
||||
* @returns {Function} Wrapped handler
|
||||
*/
|
||||
function protectRoute(handler) {
|
||||
// Check if handler is async
|
||||
if (handler.constructor.name === 'AsyncFunction') {
|
||||
return wrapAsyncHandler(handler);
|
||||
}
|
||||
|
||||
return wrapSyncHandler(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Protect all routes in a router
|
||||
*
|
||||
* @param {Object} router - Express router
|
||||
* @param {Array} routes - Array of route definitions
|
||||
*/
|
||||
function protectAllRoutes(router, routes) {
|
||||
routes.forEach(({ method, path, middleware = [], handler }) => {
|
||||
const wrappedHandler = protectRoute(handler);
|
||||
router[method](path, ...middleware, wrappedHandler);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a safe database wrapper with automatic error handling
|
||||
*
|
||||
* @param {Object} db - Database connection
|
||||
* @returns {Object} Wrapped database object
|
||||
*/
|
||||
function createSafeDb(db) {
|
||||
return {
|
||||
// Wrap db.run
|
||||
run: (sql, params, callback) => {
|
||||
try {
|
||||
return db.run(sql, params, (err, ...args) => {
|
||||
if (err) {
|
||||
logger.error('Database run error:', {
|
||||
error: err.message,
|
||||
sql: sql.substring(0, 100) // Log first 100 chars only
|
||||
});
|
||||
}
|
||||
if (callback) {
|
||||
try {
|
||||
return callback(err, ...args);
|
||||
} catch (callbackError) {
|
||||
logger.error('Database run callback error:', callbackError);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Database run exception:', error);
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Wrap db.get
|
||||
get: (sql, params, callback) => {
|
||||
try {
|
||||
return db.get(sql, params, (err, ...args) => {
|
||||
if (err) {
|
||||
logger.error('Database get error:', {
|
||||
error: err.message,
|
||||
sql: sql.substring(0, 100)
|
||||
});
|
||||
}
|
||||
if (callback) {
|
||||
try {
|
||||
return callback(err, ...args);
|
||||
} catch (callbackError) {
|
||||
logger.error('Database get callback error:', callbackError);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Database get exception:', error);
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Wrap db.all
|
||||
all: (sql, params, callback) => {
|
||||
try {
|
||||
return db.all(sql, params, (err, ...args) => {
|
||||
if (err) {
|
||||
logger.error('Database all error:', {
|
||||
error: err.message,
|
||||
sql: sql.substring(0, 100)
|
||||
});
|
||||
}
|
||||
if (callback) {
|
||||
try {
|
||||
return callback(err, ...args);
|
||||
} catch (callbackError) {
|
||||
logger.error('Database all callback error:', callbackError);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Database all exception:', error);
|
||||
if (callback) {
|
||||
callback(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Pass through other methods
|
||||
close: (...args) => db.close(...args),
|
||||
serialize: (...args) => db.serialize(...args),
|
||||
parallelize: (...args) => db.parallelize(...args)
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
wrapDbCallback,
|
||||
wrapSyncHandler,
|
||||
wrapAsyncHandler,
|
||||
protectRoute,
|
||||
protectAllRoutes,
|
||||
createSafeDb
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue