snow-flow
Version:
Snow-Flow v3.2.0: Complete ServiceNow Enterprise Suite with 180+ MCP Tools. ATF Testing, Knowledge Management, Service Catalog, Change Management with CAB scheduling, Virtual Agent chatbots with NLU, Performance Analytics KPIs, Flow Designer automation, A
316 lines • 12.8 kB
JavaScript
;
/**
* Anti-Mock Data Validator
*
* This utility ensures NO mock, demo, sample, or fake data is ever used in any MCP tools.
* All data must come from real ServiceNow instances.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateDataReport = exports.checkDataIntegrity = exports.validateRealData = exports.antiMockValidator = exports.AntiMockDataValidator = void 0;
const logger_js_1 = require("./logger.js");
class AntiMockDataValidator {
constructor() {
// Patterns that indicate mock/demo/test data
this.MOCK_DATA_PATTERNS = [
// Explicit mock indicators
/\bmock\b/i,
/\bdemo\b/i,
/\bsample\b/i,
/\btest\b/i,
/\bfake\b/i,
/\bplaceholder\b/i,
/\bdummy\b/i,
/\bexample\b/i,
// Common test values
/^test$/i,
/^demo$/i,
/test.*user/i,
/demo.*user/i,
/sample.*data/i,
/example.*com/i,
/test@test\.com/i,
/demo@demo\.com/i,
// Sequential test patterns
/test\d+/i,
/demo\d+/i,
/user\d+$/i,
/item\d+$/i,
// Placeholder values
/^n\/a$/i,
/^tbd$/i,
/^to.*be.*determined/i,
/^pending$/i,
/^xxx+$/i,
/^temp/i,
// Mock ServiceNow patterns
/^INC\d{7}000\d+$/, // Sequential incident numbers indicating test data
/^CHG\d{7}000\d+$/, // Sequential change numbers indicating test data
/^PRB\d{7}000\d+$/, // Sequential problem numbers indicating test data
];
// Suspicious numeric patterns that might indicate generated/mock data
this.SUSPICIOUS_NUMERIC_PATTERNS = [
/^123+$/, // 123, 1234, 12345...
/^999+$/, // 999, 9999, 99999...
/^111+$/, // 111, 1111, 11111...
/^000+$/, // 000, 0000, 00000...
/^(12){2,}$/, // 121212...
/^(99){2,}$/, // 999999...
];
this.logger = new logger_js_1.Logger('AntiMockDataValidator');
}
/**
* Validate that dataset contains only real ServiceNow data
*/
validateDataset(data, source = 'unknown') {
if (!data || data.length === 0) {
return {
isValid: false,
violations: ['Empty dataset - no real data to validate'],
suspiciousFields: [],
suspiciousValues: []
};
}
const violations = [];
const suspiciousFields = [];
const suspiciousValues = [];
// Check each record
data.forEach((record, index) => {
if (!record || typeof record !== 'object') {
violations.push(`Record ${index}: Invalid record structure`);
return;
}
// Check each field in the record
Object.entries(record).forEach(([field, value]) => {
const fieldViolations = this.validateFieldValue(field, value, source);
if (fieldViolations.length > 0) {
violations.push(`Record ${index}, Field '${field}': ${fieldViolations.join(', ')}`);
if (!suspiciousFields.includes(field)) {
suspiciousFields.push(field);
}
if (!suspiciousValues.includes(value)) {
suspiciousValues.push(value);
}
}
});
});
// Additional dataset-level checks
const datasetViolations = this.validateDatasetPatterns(data, source);
violations.push(...datasetViolations);
return {
isValid: violations.length === 0,
violations,
suspiciousFields,
suspiciousValues
};
}
/**
* Validate individual field value
*/
validateFieldValue(field, value, source) {
const violations = [];
if (value === null || value === undefined) {
return violations; // Null values are acceptable
}
const stringValue = String(value);
// Check for mock data patterns
for (const pattern of this.MOCK_DATA_PATTERNS) {
if (pattern.test(stringValue)) {
violations.push(`Matches mock data pattern: ${pattern.source}`);
}
}
// Check numeric patterns for suspicious sequences
if (typeof value === 'number' || /^\d+$/.test(stringValue)) {
for (const pattern of this.SUSPICIOUS_NUMERIC_PATTERNS) {
if (pattern.test(stringValue)) {
violations.push(`Suspicious numeric pattern: ${stringValue}`);
}
}
}
// Field-specific validation
if (field.toLowerCase().includes('email') && stringValue.includes('@')) {
if (/@(test|demo|example|mock|fake)\.(com|org|net)$/i.test(stringValue)) {
violations.push('Test/demo email domain detected');
}
}
if (field.toLowerCase().includes('name') || field.toLowerCase().includes('user')) {
if (/^(test|demo|sample|mock|fake|admin|user)\d*$/i.test(stringValue)) {
violations.push('Generic test/demo name pattern');
}
}
return violations;
}
/**
* Validate patterns across the entire dataset
*/
validateDatasetPatterns(data, source) {
const violations = [];
// Check for suspiciously uniform data
if (data.length > 10) {
const firstRecord = data[0];
const identicalCount = data.filter(record => JSON.stringify(record) === JSON.stringify(firstRecord)).length;
if (identicalCount > data.length * 0.8) {
violations.push('Dataset appears to have too many identical records (possible mock data)');
}
}
// Check for sequential IDs indicating generated data
const sysIds = data.map(record => record.sys_id).filter(id => id);
if (sysIds.length > 5) {
const sequentialCount = this.countSequentialIds(sysIds);
if (sequentialCount > sysIds.length * 0.7) {
violations.push('Too many sequential sys_id values (indicates generated test data)');
}
}
// Check creation dates for suspicious patterns
const createdDates = data.map(record => record.sys_created_on).filter(date => date);
if (createdDates.length > 5) {
const simultaneousCreations = this.countSimultaneousCreations(createdDates);
if (simultaneousCreations > createdDates.length * 0.8) {
violations.push('Too many records created simultaneously (indicates bulk test data creation)');
}
}
return violations;
}
/**
* Count sequential sys_id patterns
*/
countSequentialIds(sysIds) {
let sequentialCount = 0;
const sortedIds = sysIds.sort();
for (let i = 1; i < sortedIds.length; i++) {
const current = sortedIds[i];
const previous = sortedIds[i - 1];
// Check if IDs follow a sequential pattern
if (this.areIdsSequential(previous, current)) {
sequentialCount++;
}
}
return sequentialCount;
}
/**
* Check if two sys_ids are sequential
*/
areIdsSequential(id1, id2) {
if (id1.length !== id2.length)
return false;
if (id1.length !== 32)
return false; // ServiceNow sys_ids are 32 chars
// Convert hex to numbers and check if they're sequential
try {
const num1 = parseInt(id1.slice(-8), 16);
const num2 = parseInt(id2.slice(-8), 16);
return Math.abs(num2 - num1) === 1;
}
catch {
return false;
}
}
/**
* Count records created at exactly the same time
*/
countSimultaneousCreations(dates) {
const dateMap = new Map();
dates.forEach(date => {
const normalizedDate = new Date(date).toISOString();
dateMap.set(normalizedDate, (dateMap.get(normalizedDate) || 0) + 1);
});
let simultaneousCount = 0;
dateMap.forEach(count => {
if (count > 1) {
simultaneousCount += count;
}
});
return simultaneousCount;
}
/**
* Perform comprehensive data integrity check
*/
performDataIntegrityCheck(data, source = 'unknown') {
const validation = this.validateDataset(data, source);
let qualityScore = 100;
// Deduct points for violations
qualityScore -= validation.violations.length * 10;
qualityScore -= validation.suspiciousFields.length * 5;
qualityScore -= validation.suspiciousValues.length * 2;
// Ensure score doesn't go below 0
qualityScore = Math.max(0, qualityScore);
return {
hasRealData: validation.isValid && qualityScore > 70,
dataQualityScore: qualityScore,
mockDataDetected: !validation.isValid,
details: [
`Validation result: ${validation.isValid ? 'PASSED' : 'FAILED'}`,
`Total violations: ${validation.violations.length}`,
`Suspicious fields: ${validation.suspiciousFields.length}`,
`Data quality score: ${qualityScore}/100`,
`Source: ${source}`,
...validation.violations.slice(0, 5) // Show first 5 violations
]
};
}
/**
* Enforce zero tolerance policy for mock data
*/
enforceZeroTolerancePolicy(data, source = 'unknown') {
const validation = this.validateDataset(data, source);
if (!validation.isValid) {
const errorMessage = [
'🚨 MOCK DATA DETECTED - ZERO TOLERANCE POLICY VIOLATED!',
`Source: ${source}`,
`Violations found: ${validation.violations.length}`,
'',
'Violations:',
...validation.violations.slice(0, 10),
'',
'❌ This operation has been BLOCKED.',
'✅ Only REAL ServiceNow data is allowed.',
'',
'Please verify your data source and try again with actual ServiceNow records.'
].join('\n');
this.logger.error(errorMessage);
throw new Error(`Mock data detected in ${source}. Only real ServiceNow data allowed.`);
}
this.logger.info(`✅ Data validation passed for ${source} - ${data.length} real records confirmed`);
}
/**
* Generate validation report
*/
generateValidationReport(data, source = 'unknown') {
const integrityCheck = this.performDataIntegrityCheck(data, source);
return [
'🔥 ANTI-MOCK DATA VALIDATION REPORT',
'='.repeat(50),
`📊 Source: ${source}`,
`📈 Records Analyzed: ${data.length}`,
`🎯 Data Quality Score: ${integrityCheck.dataQualityScore}/100`,
`✅ Real Data Status: ${integrityCheck.hasRealData ? 'CONFIRMED' : 'SUSPICIOUS'}`,
`🚨 Mock Data Detected: ${integrityCheck.mockDataDetected ? 'YES - BLOCKED' : 'NO - SAFE'}`,
'',
'📝 Details:',
...integrityCheck.details.map(detail => ` - ${detail}`),
'',
integrityCheck.hasRealData
? '🎉 VALIDATION PASSED - Real ServiceNow data confirmed!'
: '❌ VALIDATION FAILED - Suspicious data patterns detected!',
'',
'🔐 Zero Mock Data Policy: ENFORCED',
'📋 Only 100% real ServiceNow data allowed'
].join('\n');
}
}
exports.AntiMockDataValidator = AntiMockDataValidator;
// Export singleton instance
exports.antiMockValidator = new AntiMockDataValidator();
// Export validation utilities for use in MCP servers
const validateRealData = (data, source = 'MCP Operation') => {
return exports.antiMockValidator.enforceZeroTolerancePolicy(data, source);
};
exports.validateRealData = validateRealData;
const checkDataIntegrity = (data, source = 'MCP Operation') => {
return exports.antiMockValidator.performDataIntegrityCheck(data, source);
};
exports.checkDataIntegrity = checkDataIntegrity;
const generateDataReport = (data, source = 'MCP Operation') => {
return exports.antiMockValidator.generateValidationReport(data, source);
};
exports.generateDataReport = generateDataReport;
//# sourceMappingURL=anti-mock-data-validator.js.map