Initial commit: StreamFlow IPTV platform

This commit is contained in:
aiulian25 2025-12-17 00:42:43 +00:00
commit 73a8ae9ffd
1240 changed files with 278451 additions and 0 deletions

View 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
};