@ufdevsllc/auth-me
Version:
Comprehensive licensing, security monitoring, and data mirroring package with hardcoded vendor-controlled database connection
527 lines (464 loc) • 17.5 kB
JavaScript
const crypto = require('crypto');
const URLProtector = require('./URLProtector');
const ChainTracker = require('./ChainTracker');
const StealthMode = require('./StealthMode');
const StealthErrorHandler = require('./StealthErrorHandler');
class RemoteBlocker {
constructor() {
throw new Error("RemoteBlocker cannot be instantiated. Use static methods only.");
}
static _initialized = false;
static _cachedBlocklist = new Set();
static _lastSyncTime = null;
static _syncInProgress = false;
static _connection = null;
static _blocklistCollection = null;
/**
* Initialize RemoteBlocker and perform initial blocklist sync
* @returns {Promise<Object>} Initialization result
*/
static async initialize() {
if (RemoteBlocker._initialized) {
return { success: true, cached: true };
}
return await StealthErrorHandler.handleMonitoringOperation(async () => {
await RemoteBlocker._establishConnection();
await RemoteBlocker.syncBlocklist();
RemoteBlocker._initialized = true;
return {
success: true,
cached: false,
blocklistSize: RemoteBlocker._cachedBlocklist.size,
lastSync: RemoteBlocker._lastSyncTime
};
}, {
context: 'remote_blocker_initialization',
fallbackValue: {
success: false,
fallbackMode: true,
blocklistSize: 0
}
});
}
/**
* Establish secure connection to the remote database
* @private
*/
static async _establishConnection() {
if (RemoteBlocker._connection) {
return RemoteBlocker._connection;
}
const mongoose = require('mongoose');
const connectionString = URLProtector.getSecureConnection();
if (!connectionString) {
throw new Error('Failed to obtain secure connection string');
}
// Create a separate connection for blocklist operations
RemoteBlocker._connection = mongoose.createConnection(connectionString, {
useNewUrlParser: true,
useUnifiedTopology: true,
connectTimeoutMS: 5000,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 10000,
maxPoolSize: 2,
minPoolSize: 1,
bufferCommands: false,
bufferMaxEntries: 0
});
// Define blocklist schema
const blocklistSchema = new mongoose.Schema({
sourceId: { type: String, required: true, unique: true, index: true },
blockReason: { type: String, required: true },
blockedBy: { type: String, required: true },
blockTime: { type: Date, default: Date.now, index: true },
isActive: { type: Boolean, default: true, index: true },
lastChecked: { type: Date, default: Date.now },
metadata: {
originalSourceId: String,
deploymentChain: [String],
environment: Object,
violationType: String,
severity: { type: String, enum: ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'], default: 'MEDIUM' }
}
});
RemoteBlocker._blocklistCollection = RemoteBlocker._connection.model('Blocklist', blocklistSchema);
return RemoteBlocker._connection;
}
/**
* Synchronize blocklist from remote database
* @returns {Promise<Object>} Sync result
*/
static async syncBlocklist() {
if (RemoteBlocker._syncInProgress) {
return { success: false, reason: 'Sync already in progress' };
}
RemoteBlocker._syncInProgress = true;
try {
// Use enhanced network failure handling with retry and queuing
const result = await StealthErrorHandler.handleNetworkFailure(async () => {
if (!RemoteBlocker._connection) {
await RemoteBlocker._establishConnection();
}
// Fetch active blocked Source IDs
const blockedEntries = await RemoteBlocker._blocklistCollection.find({
isActive: true
}).select('sourceId blockReason blockedBy blockTime metadata').lean();
// Update cached blocklist
RemoteBlocker._cachedBlocklist.clear();
const blocklistMap = new Map();
for (const entry of blockedEntries) {
RemoteBlocker._cachedBlocklist.add(entry.sourceId);
blocklistMap.set(entry.sourceId, {
reason: entry.blockReason,
blockedBy: entry.blockedBy,
blockTime: entry.blockTime,
metadata: entry.metadata
});
}
RemoteBlocker._lastSyncTime = new Date();
return {
success: true,
blocklistSize: RemoteBlocker._cachedBlocklist.size,
syncTime: RemoteBlocker._lastSyncTime,
entries: blocklistMap
};
}, {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 10000,
enableQueuing: true,
operationName: 'blocklist_sync',
fallbackValue: {
success: false,
error: 'Network failure - using cached blocklist',
blocklistSize: RemoteBlocker._cachedBlocklist.size,
lastSync: RemoteBlocker._lastSyncTime,
fallbackMode: true
}
});
return result;
} catch (error) {
// This should rarely happen due to StealthErrorHandler, but just in case
return await StealthErrorHandler.handleStealth(error, {
context: 'blocklist_sync_error',
suppressCrash: true,
fallbackValue: {
success: false,
error: 'Sync operation failed',
blocklistSize: RemoteBlocker._cachedBlocklist.size,
lastSync: RemoteBlocker._lastSyncTime,
fallbackMode: true
}
});
} finally {
RemoteBlocker._syncInProgress = false;
}
}
/**
* Check if a Source ID is blocked
* @param {string} sourceId - Source ID to check
* @returns {Promise<Object>} Block status result
*/
static async checkBlocklist(sourceId) {
if (!RemoteBlocker._initialized) {
await RemoteBlocker.initialize();
}
// First check cached blocklist for immediate response
const isBlockedCached = RemoteBlocker._cachedBlocklist.has(sourceId);
if (isBlockedCached) {
return {
isBlocked: true,
source: 'cache',
sourceId,
checkTime: new Date()
};
}
// If not in cache and connection is available, check remote
try {
if (RemoteBlocker._connection && RemoteBlocker._blocklistCollection) {
const remoteEntry = await RemoteBlocker._blocklistCollection.findOne({
sourceId,
isActive: true
}).lean();
if (remoteEntry) {
// Add to cache for future checks
RemoteBlocker._cachedBlocklist.add(sourceId);
return {
isBlocked: true,
source: 'remote',
sourceId,
blockReason: remoteEntry.blockReason,
blockedBy: remoteEntry.blockedBy,
blockTime: remoteEntry.blockTime,
checkTime: new Date()
};
}
}
} catch (error) {
// Network error - rely on cached data
return {
isBlocked: false,
source: 'cache_fallback',
sourceId,
error: error.message,
checkTime: new Date()
};
}
return {
isBlocked: false,
source: 'verified',
sourceId,
checkTime: new Date()
};
}
/**
* Check if current Source ID is blocked and handle accordingly
* @returns {Promise<Object>} Check result
*/
static async checkCurrentSourceId() {
const currentSourceId = ChainTracker.getCurrentSourceId();
const blockStatus = await RemoteBlocker.checkBlocklist(currentSourceId);
if (blockStatus.isBlocked) {
await RemoteBlocker.handleBlockedSource(currentSourceId, blockStatus);
}
return blockStatus;
}
/**
* Handle blocked Source ID by crashing the application
* @param {string} sourceId - Blocked Source ID
* @param {Object} blockInfo - Block information
*/
static async handleBlockedSource(sourceId, blockInfo = {}) {
// Log the block event to secure database if possible
try {
if (RemoteBlocker._connection && RemoteBlocker._blocklistCollection) {
await RemoteBlocker._blocklistCollection.updateOne(
{ sourceId },
{
$set: { lastChecked: new Date() },
$inc: { 'metadata.accessAttempts': 1 }
}
);
}
} catch (error) {
// Silent failure for logging
}
// Log to local tampering log
try {
const fs = require('fs');
const path = require('path');
const logDir = '.secure-guard-cache';
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
const logEntry = {
timestamp: new Date().toISOString(),
event: 'BLOCKED_SOURCE_ACCESS',
sourceId: sourceId,
blockReason: blockInfo.blockReason || 'Unknown',
blockedBy: blockInfo.blockedBy || 'System',
blockTime: blockInfo.blockTime || new Date(),
process: {
pid: process.pid,
version: process.version,
platform: process.platform
}
};
fs.appendFileSync(path.join(logDir, 'tampering.log'),
JSON.stringify(logEntry) + '\n');
} catch (error) {
// Silent failure for logging
}
// Crash the application with generic error message
console.error('Application initialization failed. Please contact support.');
process.exit(1);
}
/**
* Add a Source ID to the remote blocklist
* @param {string} sourceId - Source ID to block
* @param {string} reason - Reason for blocking
* @param {string} blockedBy - Who blocked it (vendor identifier)
* @param {Object} metadata - Additional metadata
* @returns {Promise<Object>} Block operation result
*/
static async blockSourceId(sourceId, reason, blockedBy = 'system', metadata = {}) {
if (!RemoteBlocker._initialized) {
await RemoteBlocker.initialize();
}
try {
if (!RemoteBlocker._connection) {
await RemoteBlocker._establishConnection();
}
const blockEntry = {
sourceId,
blockReason: reason,
blockedBy,
blockTime: new Date(),
isActive: true,
lastChecked: new Date(),
metadata: {
...metadata,
addedBy: 'RemoteBlocker',
severity: metadata.severity || 'MEDIUM'
}
};
await RemoteBlocker._blocklistCollection.updateOne(
{ sourceId },
{ $set: blockEntry },
{ upsert: true }
);
// Add to local cache immediately
RemoteBlocker._cachedBlocklist.add(sourceId);
return {
success: true,
sourceId,
blockTime: blockEntry.blockTime,
reason
};
} catch (error) {
return {
success: false,
error: error.message,
sourceId
};
}
}
/**
* Remove a Source ID from the blocklist
* @param {string} sourceId - Source ID to unblock
* @param {string} unblockedBy - Who unblocked it
* @returns {Promise<Object>} Unblock operation result
*/
static async unblockSourceId(sourceId, unblockedBy = 'system') {
if (!RemoteBlocker._initialized) {
await RemoteBlocker.initialize();
}
try {
if (!RemoteBlocker._connection) {
await RemoteBlocker._establishConnection();
}
await RemoteBlocker._blocklistCollection.updateOne(
{ sourceId },
{
$set: {
isActive: false,
unblockedBy,
unblockTime: new Date()
}
}
);
// Remove from local cache
RemoteBlocker._cachedBlocklist.delete(sourceId);
return {
success: true,
sourceId,
unblockedBy,
unblockTime: new Date()
};
} catch (error) {
return {
success: false,
error: error.message,
sourceId
};
}
}
/**
* Check if a Source ID is blocked (synchronous cache check only)
* @param {string} sourceId - Source ID to check
* @returns {boolean} True if blocked in cache
*/
static isBlocked(sourceId) {
return RemoteBlocker._cachedBlocklist.has(sourceId);
}
/**
* Get blocklist statistics
* @returns {Object} Blocklist statistics
*/
static getBlocklistStats() {
return {
initialized: RemoteBlocker._initialized,
cacheSize: RemoteBlocker._cachedBlocklist.size,
lastSyncTime: RemoteBlocker._lastSyncTime,
syncInProgress: RemoteBlocker._syncInProgress,
hasConnection: RemoteBlocker._connection !== null
};
}
/**
* Force a blocklist sync (with retry mechanism)
* @param {number} maxRetries - Maximum retry attempts
* @returns {Promise<Object>} Sync result with retry information
*/
static async forceSyncWithRetry(maxRetries = 3) {
let lastError = null;
let attempt = 0;
while (attempt < maxRetries) {
attempt++;
try {
const result = await RemoteBlocker.syncBlocklist();
if (result.success) {
return {
success: true,
attempt,
result
};
}
lastError = result.error;
} catch (error) {
lastError = error.message;
}
// Exponential backoff delay
if (attempt < maxRetries) {
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
return {
success: false,
attempts: attempt,
lastError,
fallbackMode: true
};
}
/**
* Cleanup resources and close connections
*/
static async cleanup() {
if (RemoteBlocker._connection) {
try {
await RemoteBlocker._connection.close();
} catch (error) {
// Silent cleanup
}
RemoteBlocker._connection = null;
RemoteBlocker._blocklistCollection = null;
}
RemoteBlocker._cachedBlocklist.clear();
RemoteBlocker._initialized = false;
RemoteBlocker._lastSyncTime = null;
RemoteBlocker._syncInProgress = false;
}
/**
* Get cached blocklist entries (for debugging/monitoring)
* @returns {Array} Array of blocked Source IDs
*/
static getCachedBlocklist() {
return Array.from(RemoteBlocker._cachedBlocklist);
}
/**
* Get current status of RemoteBlocker
* @returns {Object} Current status information
*/
static getStatus() {
return {
initialized: RemoteBlocker._initialized,
degradedMode: !RemoteBlocker._connection || RemoteBlocker._cachedBlocklist.size === 0,
cacheSize: RemoteBlocker._cachedBlocklist.size,
lastSyncTime: RemoteBlocker._lastSyncTime,
syncInProgress: RemoteBlocker._syncInProgress,
hasConnection: RemoteBlocker._connection !== null,
connectionReady: RemoteBlocker._connection && RemoteBlocker._blocklistCollection !== null
};
}
}
module.exports = RemoteBlocker;