survey-mcp-server
Version:
400 lines (399 loc) • 15.2 kB
JavaScript
/**
* Company Name Filtering Utilities
* Helper functions for filtering data based on company IMO numbers
*
* ============================================================================
* OLD IMPLEMENTATION (COMMENTED OUT - REPLACED BY OPTIMIZED VERSION)
* ============================================================================
* The old implementation has been replaced with an optimized version that includes:
* - In-memory caching with TTL (5 minutes)
* - MongoDB connection pooling
* - Set-based IMO lookups (O(1) instead of O(n))
* - Cached environment variables
* ============================================================================
*/
import { MongoClient } from "mongodb";
/**
* Check if IMO filtering should be bypassed for admin companies
*/
function shouldBypassImoFiltering(companyName) {
const adminCompanies = ['admin', 'administrator', 'superadmin', 'syia'];
return adminCompanies.some(admin => companyName.toLowerCase().includes(admin.toLowerCase()));
}
/**
* Optimized Company Filter Manager with caching and connection pooling
*/
class CompanyFilterManager {
// Cache structure: Map<"companyName:dbName", { imos: Set<string>, timestamp: number }>
imoCache = new Map();
// Connection pool: Map<"mongoUri", MongoClient>
mongoClients = new Map();
// Cache TTL: 5 minutes
CACHE_TTL = 5 * 60 * 1000;
// Cached environment variables
cachedCompanyName = null;
cachedDbConfig = null;
/**
* Get company name (cached)
*/
getCompanyName() {
if (this.cachedCompanyName === null) {
this.cachedCompanyName = process.env.COMPANY_NAME || '';
}
return this.cachedCompanyName;
}
/**
* Get database configuration (cached)
*/
getDbConfig() {
if (this.cachedDbConfig === null) {
this.cachedDbConfig = {
dbName: process.env.GROUP_DETAILS_DB_NAME || process.env.FLEET_DISTRIBUTION_DB_NAME || '',
mongoUri: process.env.GROUP_DETAILS_MONGO_URI || process.env.FLEET_DISTRIBUTION_MONGO_URI || ''
};
}
return this.cachedDbConfig;
}
/**
* Get or create MongoDB client (connection pooling)
*/
async getMongoClient(mongoUri) {
if (!this.mongoClients.has(mongoUri)) {
const client = new MongoClient(mongoUri, {
maxPoolSize: 10,
minPoolSize: 2,
maxIdleTimeMS: 30000
});
await client.connect();
this.mongoClients.set(mongoUri, client);
}
return this.mongoClients.get(mongoUri);
}
/**
* Get company IMO set with caching (returns Set for O(1) lookups)
*/
async getCompanyImoSet(companyName, dbName, mongoUri, collectionName = 'common_group_details') {
const cacheKey = `${companyName}:${dbName}`;
const cached = this.imoCache.get(cacheKey);
// Return from cache if valid
if (cached && (Date.now() - cached.timestamp) < this.CACHE_TTL) {
return cached.imos;
}
// Fetch from MongoDB
if (!dbName || !mongoUri || !companyName) {
return new Set();
}
try {
const client = await this.getMongoClient(mongoUri);
const db = client.db(dbName);
const collection = db.collection(collectionName);
// Try both companyName and groupName fields for compatibility
const result = await collection.findOne({ $or: [{ companyName: companyName }, { groupName: companyName }] }, { projection: { imoList: 1, _id: 0 } });
const imoSet = new Set(result?.imoList?.map((imo) => String(imo)) || []);
// Update cache
this.imoCache.set(cacheKey, {
imos: imoSet,
timestamp: Date.now()
});
return imoSet;
}
catch (error) {
console.error(`Error fetching IMO numbers for company ${companyName}:`, error);
return new Set();
}
}
/**
* Validate if an IMO belongs to the company (optimized)
*/
async isValidImoForCompany(imo, companyName, dbName, mongoUri) {
const finalCompanyName = companyName || this.getCompanyName();
if (!finalCompanyName) {
return true; // If no company name, allow all
}
// Bypass validation for "Synergy" company
if (finalCompanyName === "Synergy") {
return true;
}
// Bypass validation for admin companies
if (shouldBypassImoFiltering(finalCompanyName)) {
return true;
}
// Use provided dbName/mongoUri or fallback to cached environment variables
const config = this.getDbConfig();
const finalDbName = dbName || config.dbName;
const finalMongoUri = mongoUri || config.mongoUri;
if (!finalDbName || !finalMongoUri) {
return true; // Allow if config is missing
}
try {
const imoSet = await this.getCompanyImoSet(finalCompanyName, finalDbName, finalMongoUri);
// O(1) lookup using Set
return imoSet.has(String(imo));
}
catch (error) {
console.error(`Error validating IMO for company: ${error}`);
return true; // Allow on error to prevent blocking
}
}
/**
* Update Typesense filter with company IMO numbers (optimized)
*/
async updateTypesenseFilterWithCompanyImos(filter, dbName, mongoUri) {
const companyName = this.getCompanyName();
if (!companyName) {
return filter;
}
// Bypass filtering for "Synergy" company
if (companyName === "Synergy") {
return filter;
}
// Bypass filtering for admin companies
if (shouldBypassImoFiltering(companyName)) {
return filter;
}
// Use provided dbName/mongoUri or fallback to cached environment variables
const config = this.getDbConfig();
const finalDbName = dbName || config.dbName;
const finalMongoUri = mongoUri || config.mongoUri;
if (!finalDbName || !finalMongoUri) {
return filter;
}
try {
const imoSet = await this.getCompanyImoSet(companyName, finalDbName, finalMongoUri);
if (imoSet.size === 0) {
// If no company IMO numbers found, return a filter that matches nothing for security
// This prevents access to all data when company configuration is missing
return filter ? `${filter} && imo:0` : 'imo:0';
}
const imoFilter = `imo:[${Array.from(imoSet).join(",")}]`;
if (filter && filter.trim()) {
return `${filter} && ${imoFilter}`;
}
else {
return imoFilter;
}
}
catch (error) {
console.error(`Error updating Typesense filter with company IMOs: ${error}`);
return filter; // Return original filter on error
}
}
/**
* Get authorized IMO numbers for a company (for fleet filtering)
*/
async getAuthorizedImoNumbers(companyName, dbName, mongoUri) {
const finalCompanyName = companyName || this.getCompanyName();
if (!finalCompanyName) {
return [];
}
// Bypass for "Synergy" company - return empty to allow all
if (finalCompanyName === "Synergy") {
return [];
}
// Bypass for admin companies - return empty to allow all
if (shouldBypassImoFiltering(finalCompanyName)) {
return [];
}
// Use provided dbName/mongoUri or fallback to cached environment variables
const config = this.getDbConfig();
const finalDbName = dbName || config.dbName;
const finalMongoUri = mongoUri || config.mongoUri;
if (!finalDbName || !finalMongoUri) {
return [];
}
try {
const imoSet = await this.getCompanyImoSet(finalCompanyName, finalDbName, finalMongoUri);
return Array.from(imoSet);
}
catch (error) {
console.error(`Error fetching authorized IMO numbers: ${error}`);
return [];
}
}
/**
* Clear cache (useful for testing or forced refresh)
*/
clearCache() {
this.imoCache.clear();
this.cachedCompanyName = null;
this.cachedDbConfig = null;
}
/**
* Close all MongoDB connections (cleanup)
*/
async closeConnections() {
const closePromises = Array.from(this.mongoClients.values()).map(client => client.close());
await Promise.all(closePromises);
this.mongoClients.clear();
}
}
// Singleton instance
export const companyFilter = new CompanyFilterManager();
// Export functions for backward compatibility
export async function isValidImoForCompany(imo, companyName, dbName, mongoUri) {
return companyFilter.isValidImoForCompany(imo, companyName, dbName, mongoUri);
}
export async function updateTypesenseFilterWithCompanyImos(filter, dbName, mongoUri) {
return companyFilter.updateTypesenseFilterWithCompanyImos(filter, dbName, mongoUri);
}
export async function getAuthorizedImoNumbers(companyName, dbName, mongoUri) {
return companyFilter.getAuthorizedImoNumbers(companyName, dbName, mongoUri);
}
// Export shouldBypassImoFiltering for use in handlers
export { shouldBypassImoFiltering };
/**
* ============================================================================
* OLD IMPLEMENTATION (COMMENTED OUT)
* ============================================================================
*/
// /**
// * Fetch IMO numbers for a specific company from MongoDB
// */
// async function fetchCompanyImoNumbers(companyName: string, dbName: string, mongoUri: string, collectionName: string = 'common_group_details'): Promise<string[]> {
// if (!dbName || !mongoUri || !companyName) {
// return [];
// }
//
// const mongoClient = new MongoClient(mongoUri);
// await mongoClient.connect();
//
// try {
// const db = mongoClient.db(dbName);
// const collection = db.collection(collectionName);
//
// const companyDoc = await collection.findOne({ companyName: companyName });
//
// if (companyDoc && companyDoc.imoList && Array.isArray(companyDoc.imoList)) {
// return companyDoc.imoList.map((imo: any) => String(imo));
// }
//
// return [];
// } catch (error) {
// console.error(`Error fetching company IMO numbers: ${error}`);
// return [];
// } finally {
// await mongoClient.close();
// }
// }
// /**
// * Check if IMO filtering should be bypassed for admin companies
// */
// function shouldBypassImoFiltering(companyName: string): boolean {
// const adminCompanies = ['admin', 'Admin', 'ADMIN', 'SYIA', 'Syia'];
// return adminCompanies.includes(companyName);
// }
// /**
// * Validate if an IMO belongs to the company
// */
// export async function isValidImoForCompany(imo: string | number, companyName?: string, dbName?: string, mongoUri?: string): Promise<boolean> {
// const finalCompanyName = companyName || process.env.COMPANY_NAME || '';
//
// if (!finalCompanyName) {
// return true; // If no company name, allow all
// }
//
// // Bypass validation for "Synergy" company
// if (finalCompanyName === "Synergy") {
// return true;
// }
//
// // Bypass validation for admin companies
// if (shouldBypassImoFiltering(finalCompanyName)) {
// return true;
// }
//
// // Use provided dbName/mongoUri or fallback to environment variables
// const finalDbName = dbName || process.env.GROUP_DETAILS_DB_NAME || process.env.FLEET_DISTRIBUTION_DB_NAME || '';
// const finalMongoUri = mongoUri || process.env.GROUP_DETAILS_MONGO_URI || process.env.FLEET_DISTRIBUTION_MONGO_URI || '';
//
// if (!finalDbName || !finalMongoUri) {
// return true; // Allow if config is missing
// }
//
// try {
// const imoNumbers = await fetchCompanyImoNumbers(finalCompanyName, finalDbName, finalMongoUri);
// return imoNumbers.includes(String(imo));
// } catch (error) {
// console.error(`Error validating IMO for company: ${error}`);
// return true; // Allow on error to prevent blocking
// }
// }
// /**
// * Update Typesense filter with company IMO numbers for filtering
// */
// export async function updateTypesenseFilterWithCompanyImos(filter: string, dbName?: string, mongoUri?: string): Promise<string> {
// const companyName = process.env.COMPANY_NAME || '';
//
// if (!companyName) {
// return filter;
// }
//
// // Bypass filtering for "Synergy" company
// if (companyName === "Synergy") {
// return filter;
// }
//
// // Bypass filtering for admin companies
// if (shouldBypassImoFiltering(companyName)) {
// return filter;
// }
//
// // Use provided dbName/mongoUri or fallback to environment variables
// const finalDbName = dbName || process.env.GROUP_DETAILS_DB_NAME || process.env.FLEET_DISTRIBUTION_DB_NAME || '';
// const finalMongoUri = mongoUri || process.env.GROUP_DETAILS_MONGO_URI || process.env.FLEET_DISTRIBUTION_MONGO_URI || '';
//
// if (!finalDbName || !finalMongoUri) {
// return filter;
// }
//
// const companyImos = await fetchCompanyImoNumbers(companyName, finalDbName, finalMongoUri);
//
// if (companyImos.length === 0) {
// // If no company IMO numbers found, return a filter that matches nothing for security
// // This prevents access to all data when company configuration is missing
// return filter ? `${filter} && imo:0` : 'imo:0';
// }
//
// const imoFilter = `imo:[${companyImos.join(",")}]`;
//
// if (filter && filter.trim()) {
// return `${filter} && ${imoFilter}`;
// } else {
// return imoFilter;
// }
// }
// /**
// * Get authorized IMO numbers for a company
// */
// export async function getAuthorizedImoNumbers(companyName?: string, dbName?: string, mongoUri?: string): Promise<string[]> {
// const finalCompanyName = companyName || process.env.COMPANY_NAME || '';
//
// if (!finalCompanyName) {
// return []; // If no company name, return empty
// }
//
// // Bypass for "Synergy" company - return empty to allow all
// if (finalCompanyName === "Synergy") {
// return [];
// }
//
// // Bypass for admin companies - return empty to allow all
// if (shouldBypassImoFiltering(finalCompanyName)) {
// return [];
// }
//
// // Use provided dbName/mongoUri or fallback to environment variables
// const finalDbName = dbName || process.env.GROUP_DETAILS_DB_NAME || process.env.FLEET_DISTRIBUTION_DB_NAME || '';
// const finalMongoUri = mongoUri || process.env.GROUP_DETAILS_MONGO_URI || process.env.FLEET_DISTRIBUTION_MONGO_URI || '';
//
// if (!finalDbName || !finalMongoUri) {
// return [];
// }
//
// try {
// return await fetchCompanyImoNumbers(finalCompanyName, finalDbName, finalMongoUri);
// } catch (error) {
// console.error(`Error fetching authorized IMO numbers: ${error}`);
// return [];
// }
// }