multibridge
Version:
A multi-database connection framework with centralized configuration
71 lines (70 loc) • 2.32 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeMongoQuery = executeMongoQuery;
const loggers_1 = __importDefault(require("../utils/loggers"));
const errors_1 = require("../utils/errors");
// Whitelist of allowed MongoDB collection methods for security
const ALLOWED_MONGODB_METHODS = new Set([
"find",
"findOne",
"findOneAndUpdate",
"findOneAndReplace",
"findOneAndDelete",
"insertOne",
"insertMany",
"updateOne",
"updateMany",
"deleteOne",
"deleteMany",
"countDocuments",
"estimatedDocumentCount",
"distinct",
"aggregate",
"bulkWrite",
"createIndex",
"createIndexes",
"dropIndex",
"dropIndexes",
"listIndexes",
"indexExists",
"indexInformation",
]);
async function executeMongoQuery(connection, query) {
const { collection, method, args } = query;
if (!collection || !method) {
throw new errors_1.ValidationError("Invalid MongoDB query structure. Expected { collection, method, args }.", {
query,
});
}
// Validate method is in whitelist
if (!ALLOWED_MONGODB_METHODS.has(method)) {
throw new errors_1.ValidationError(`Method '${method}' is not allowed. Allowed methods: ${Array.from(ALLOWED_MONGODB_METHODS).join(", ")}`, { collection, method });
}
const dbCollection = connection.collection(collection);
const fn = dbCollection[method];
if (typeof fn !== "function") {
throw new errors_1.QueryError(`Method ${method} does not exist on MongoDB collection ${collection}`, {
collection,
method,
});
}
try {
// call the function with the collection as `this` to maintain context
return await fn.apply(dbCollection, args);
}
catch (error) {
loggers_1.default.error(`Error executing MongoDB query: ${error.message}`, {
collection,
method,
error: error.stack,
});
throw new errors_1.QueryError(`MongoDB query execution failed: ${error.message}`, {
collection,
method,
originalError: error,
});
}
}