UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

244 lines 32.9 kB
/** * Security Rules - Defines security patterns and checks * Based on OWASP Top 10, CWE Top 25, and DollhouseMCP-specific security requirements */ export class SecurityRules { /** * OWASP Top 10 security rules */ getOWASPRules() { return [ { id: 'OWASP-A01-001', name: 'Hardcoded Secrets', description: 'Potential hardcoded secret or API key detected', severity: 'critical', category: 'code', pattern: /(?:api[_-]?key|secret|password|token|private[_-]?key)\s*[:=]\s*["'][a-zA-Z0-9+/=_-]{10,}["']/gi, remediation: 'Use environment variables or secure key management services instead of hardcoding secrets', references: ['https://owasp.org/Top10/A01_2021-Broken_Access_Control/'], tags: ['high-confidence'] }, { id: 'OWASP-A03-001', name: 'SQL Injection', description: 'Potential SQL injection vulnerability', severity: 'critical', category: 'code', pattern: /(?:query|execute)\s*\(\s*['"`].*\$\{[^}]+\}.*['"`]|['"`].*\+\s*[a-zA-Z_]\w*\s*\+.*['"`]\s*\)/g, remediation: 'Use parameterized queries or prepared statements', references: ['https://owasp.org/Top10/A03_2021-Injection/'] }, { id: 'OWASP-A03-002', name: 'Command Injection', description: 'Potential command injection vulnerability', severity: 'critical', category: 'code', pattern: /(?:exec|spawn|execSync|spawnSync)\s*\([^)]*(?:\$\{[^}]+\}|\+\s*[a-zA-Z_]\w*)/g, remediation: 'Validate and sanitize all user input before using in system commands', references: ['https://owasp.org/Top10/A03_2021-Injection/'] }, { id: 'OWASP-A03-003', name: 'Path Traversal', description: 'Potential path traversal vulnerability', severity: 'high', category: 'code', pattern: /(?:readFile|writeFile|readdir|mkdir|rm|unlink)[^(]*\([^)]*(?:\.\.[/\\].*\+|\+.*\.\.[/\\])/g, remediation: 'Validate and sanitize file paths, use path.resolve() and check against allowed directories', references: ['https://owasp.org/Top10/A03_2021-Injection/'] }, { id: 'OWASP-A03-004', name: 'XSS - Direct HTML Injection', description: 'Potential XSS vulnerability through direct HTML injection', severity: 'high', category: 'code', pattern: /innerHTML\s*=\s*[^'"`]*\$\{|dangerouslySetInnerHTML/g, remediation: 'Use textContent or proper HTML escaping functions', references: ['https://owasp.org/Top10/A03_2021-Injection/'] }, { id: 'OWASP-A05-001', name: 'Insecure Configuration', description: 'Security-sensitive configuration detected', severity: 'medium', category: 'code', pattern: /(?:NODE_TLS_REJECT_UNAUTHORIZED|strictSSL|rejectUnauthorized)\s*[:=]\s*(?:false|0|["']false["']|["']0["'])/gi, remediation: 'Enable SSL/TLS certificate validation in production', references: ['https://owasp.org/Top10/A05_2021-Security_Misconfiguration/'] }, { id: 'OWASP-A07-001', name: 'Weak Authentication', description: 'Potential weak authentication mechanism', severity: 'high', category: 'code', pattern: /(?:md5|sha1)\s*\(/gi, remediation: 'Use strong hashing algorithms like bcrypt, scrypt, or Argon2 for passwords', references: ['https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures/'] } ]; } /** * CWE Top 25 security rules */ getCWERules() { return [ { id: 'CWE-79-001', name: 'Reflected XSS', description: 'User input reflected without encoding', severity: 'high', category: 'code', pattern: /res\.(?:send|write|end)\s*\([^)]*(?:req\.(?:query|params|body)|request\.)/g, remediation: 'Encode all user input before reflecting in responses', references: ['https://cwe.mitre.org/data/definitions/79.html'] }, { id: 'CWE-89-001', name: 'SQL String Concatenation', description: 'SQL query built using string concatenation', severity: 'critical', category: 'code', pattern: /["'`].*(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER).*["'`]\s*\+\s*\w+/gi, remediation: 'Use parameterized queries instead of string concatenation', references: ['https://cwe.mitre.org/data/definitions/89.html'] }, { id: 'CWE-22-001', name: 'Path Manipulation', description: 'File path constructed from user input', severity: 'high', category: 'code', pattern: /path\.join\s*\([^)]*(?:req\.|request\.|params|query|body)/g, remediation: 'Validate paths against a whitelist and use path.resolve()', references: ['https://cwe.mitre.org/data/definitions/22.html'] }, { id: 'CWE-798-001', name: 'Hardcoded Credentials', description: 'Credentials hardcoded in source', severity: 'critical', category: 'code', pattern: /(?:username|user|login)\s*[:=]\s*["'][^"']+["'].*(?:password|pass|pwd)\s*[:=]\s*["'][^"']+["']/gi, remediation: 'Store credentials in environment variables or secure vaults', references: ['https://cwe.mitre.org/data/definitions/798.html'] } ]; } /** * DollhouseMCP-specific security rules */ getDollhouseMCPRules() { return [ { id: 'DMCP-SEC-001', name: 'Unsafe Persona Loading', description: 'Persona loaded without validation', severity: 'high', category: 'custom', pattern: /loadPersona\s*\([^)]*\)\s*(?!.*validate)/g, remediation: 'Always validate personas before loading using PersonaValidator', references: ['DollhouseMCP Security Guidelines'] }, { id: 'DMCP-SEC-002', name: 'Token Validation Bypass', description: 'Token used without validation', severity: 'critical', category: 'custom', pattern: /(?:getToken|useToken|token\.use)\s*\([^)]*\)(?!.*(?:validate|verify|check))/gi, remediation: 'Always validate tokens using TokenManager.validateToken()', references: ['DollhouseMCP Security Guidelines'] }, { id: 'DMCP-SEC-003', name: 'Rate Limiting Missing', description: 'API endpoint without rate limiting', severity: 'medium', category: 'custom', check: (content, context) => { const findings = []; // Check for MCP tool handlers without rate limiting const toolPattern = /name:\s*["']([^"']+)["'].*handle:/gs; const hasRateLimit = /rateLimiter|checkRateLimit|tokenBucket/i.test(content); if (toolPattern.test(content) && !hasRateLimit) { findings.push({ ruleId: 'DMCP-SEC-003', severity: 'medium', message: 'MCP tool handler without rate limiting', remediation: 'Add rate limiting to prevent abuse', confidence: 'high' }); } return findings; }, remediation: 'Implement rate limiting for all MCP tools', references: ['Issue #174 - Rate Limiting Implementation'] }, { id: 'DMCP-SEC-004', name: 'Unicode Validation Missing', description: 'User input processed without Unicode normalization', severity: 'medium', category: 'custom', check: (content, context) => { const findings = []; // Check for user input processing without Unicode validation const inputPattern = /(?:req\.|request\.|params|query|body|content)/; const hasUnicodeCheck = /UnicodeValidator|normalizeUnicode/i.test(content); if (inputPattern.test(content) && !hasUnicodeCheck) { findings.push({ ruleId: 'DMCP-SEC-004', severity: 'medium', message: 'User input processed without Unicode normalization', remediation: 'Use UnicodeValidator.normalize() on all user input', confidence: 'medium' }); } return findings; }, remediation: 'Apply Unicode normalization to prevent bypass attacks', references: ['Issue #162 - Unicode Normalization'] }, { id: 'DMCP-SEC-005', name: 'Unvalidated YAML Content', description: 'YAML content parsed without security validation', severity: 'high', category: 'custom', pattern: /yaml\.load\s*\(|parse\s*\([^)]*\.ya?ml/gi, remediation: 'Use SecureYamlParser for all YAML parsing', references: ['DollhouseMCP Security Guidelines'] }, { id: 'DMCP-SEC-006', name: 'Security Event Not Logged', description: 'Security-relevant operation without logging', severity: 'low', category: 'custom', check: (content, context) => { const findings = []; // Check for security operations without logging const securityOps = /(?:authenticate|authorize|validate|sanitize|encrypt|decrypt)/i; const hasLogging = /SecurityMonitor\.log|logSecurityEvent/i.test(content); if (securityOps.test(content) && !hasLogging) { findings.push({ ruleId: 'DMCP-SEC-006', severity: 'low', message: 'Security operation without audit logging', remediation: 'Add SecurityMonitor.logSecurityEvent() for audit trail', confidence: 'medium' }); } return findings; }, remediation: 'Log all security-relevant operations for audit trail', references: ['DollhouseMCP Security Guidelines'] } ]; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2VjdXJpdHlSdWxlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9zZWN1cml0eS9hdWRpdC9ydWxlcy9TZWN1cml0eVJ1bGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUlILE1BQU0sT0FBTyxhQUFhO0lBQ3hCOztPQUVHO0lBQ0gsYUFBYTtRQUNYLE9BQU87WUFDTDtnQkFDRSxFQUFFLEVBQUUsZUFBZTtnQkFDbkIsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsV0FBVyxFQUFFLGdEQUFnRDtnQkFDN0QsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixPQUFPLEVBQUUsZ0dBQWdHO2dCQUN6RyxXQUFXLEVBQUUsMkZBQTJGO2dCQUN4RyxVQUFVLEVBQUUsQ0FBQyx5REFBeUQsQ0FBQztnQkFDdkUsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUM7YUFDMUI7WUFDRDtnQkFDRSxFQUFFLEVBQUUsZUFBZTtnQkFDbkIsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLFdBQVcsRUFBRSx1Q0FBdUM7Z0JBQ3BELFFBQVEsRUFBRSxVQUFVO2dCQUNwQixRQUFRLEVBQUUsTUFBTTtnQkFDaEIsT0FBTyxFQUFFLCtGQUErRjtnQkFDeEcsV0FBVyxFQUFFLGtEQUFrRDtnQkFDL0QsVUFBVSxFQUFFLENBQUMsNkNBQTZDLENBQUM7YUFDNUQ7WUFDRDtnQkFDRSxFQUFFLEVBQUUsZUFBZTtnQkFDbkIsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsV0FBVyxFQUFFLDJDQUEyQztnQkFDeEQsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLFFBQVEsRUFBRSxNQUFNO2dCQUNoQixPQUFPLEVBQUUsK0VBQStFO2dCQUN4RixXQUFXLEVBQUUsc0VBQXNFO2dCQUNuRixVQUFVLEVBQUUsQ0FBQyw2Q0FBNkMsQ0FBQzthQUM1RDtZQUNEO2dCQUNFLEVBQUUsRUFBRSxlQUFlO2dCQUNuQixJQUFJLEVB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Q2pEO1lBQ0Q7Z0JBQ0UsRUFBRSxFQUFFLGNBQWM7Z0JBQ2xCLElBQUksRUFBRSwyQkFBMkI7Z0JBQ2pDLFdBQVcsRUFBRSw2Q0FBNkM7Z0JBQzFELFFBQVEsRUFBRSxLQUFLO2dCQUNmLFFBQVEsRUFBRSxRQUFRO2dCQUNsQixLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUU7b0JBQzFCLE1BQU0sUUFBUSxHQUFzQixFQUFFLENBQUM7b0JBQ3ZDLGdEQUFnRDtvQkFDaEQsTUFBTSxXQUFXLEdBQUcsK0RBQStELENBQUM7b0JBQ3BGLE1BQU0sVUFBVSxHQUFHLHdDQUF3QyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFFMUUsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7d0JBQzdDLFFBQVEsQ0FBQyxJQUFJLENBQUM7NEJBQ1osTUFBTSxFQUFFLGNBQWM7NEJBQ3RCLFFBQVEsRUFBRSxLQUFjOzRCQUN4QixPQUFPLEVBQUUsMENBQTBDOzRCQUNuRCxXQUFXLEVBQUUsd0RBQXdEOzRCQUNyRSxVQUFVLEVBQUUsUUFBaUI7eUJBQzlCLENBQUMsQ0FBQztvQkFDTCxDQUFDO29CQUVELE9BQU8sUUFBUSxDQUFDO2dCQUNsQixDQUFDO2dCQUNELFdBQVcsRUFBRSxzREFBc0Q7Z0JBQ25FLFVBQVUsRUFBRSxDQUFDLGtDQUFrQyxDQUFDO2FBQ2pEO1NBQ0YsQ0FBQztJQUNKLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2VjdXJpdHkgUnVsZXMgLSBEZWZpbmVzIHNlY3VyaXR5IHBhdHRlcm5zIGFuZCBjaGVja3NcbiAqIEJhc2VkIG9uIE9XQVNQIFRvcCAxMCwgQ1dFIFRvcCAyNSwgYW5kIERvbGxob3VzZU1DUC1zcGVjaWZpYyBzZWN1cml0eSByZXF1aXJlbWVudHNcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFNlY3VyaXR5UnVsZSwgU2VjdXJpdHlGaW5kaW5nIH0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5leHBvcnQgY2xhc3MgU2VjdXJpdHlSdWxlcyB7XG4gIC8qKlxuICAgKiBPV0FTUCBUb3AgMTAgc2VjdXJpdHkgcnVsZXNcbiAgICovXG4gIGdldE9XQVNQUnVsZXMoKTogU2VjdXJpdHlSdWxlW10ge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnT1dBU1AtQTAxLTAwMScsXG4gICAgICAgIG5hbWU6ICdIYXJkY29kZWQgU2VjcmV0cycsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUG90ZW50aWFsIGhhcmRjb2RlZCBzZWNyZXQgb3IgQVBJIGtleSBkZXRlY3RlZCcsXG4gICAgICAgIHNldmVyaXR5OiAnY3JpdGljYWwnLFxuICAgICAgICBjYXRlZ29yeTogJ2NvZGUnLFxuICAgICAgICBwYXR0ZXJuOiAvKD86YXBpW18tXT9rZXl8c2VjcmV0fHBhc3N3b3JkfHRva2VufHByaXZhdGVbXy1dP2tleSlcXHMqWzo9XVxccypbXCInXVthLXpBLVowLTkrLz1fLV17MTAsfVtcIiddL2dpLFxuICAgICAgICByZW1lZGlhdGlvbjogJ1VzZSBlbnZpcm9ubWVudCB2YXJpYWJsZXMgb3Igc2VjdXJlIGtleSBtYW5hZ2VtZW50IHNlcnZpY2VzIGluc3RlYWQgb2YgaGFyZGNvZGluZyBzZWNyZXRzJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL293YXNwLm9yZy9Ub3AxMC9BMDFfMjAyMS1Ccm9rZW5fQWNjZXNzX0NvbnRyb2wvJ10sXG4gICAgICAgIHRhZ3M6IFsnaGlnaC1jb25maWRlbmNlJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnT1dBU1AtQTAzLTAwMScsXG4gICAgICAgIG5hbWU6ICdTUUwgSW5qZWN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdQb3RlbnRpYWwgU1FMIGluamVjdGlvbiB2dWxuZXJhYmlsaXR5JyxcbiAgICAgICAgc2V2ZXJpdHk6ICdjcml0aWNhbCcsXG4gICAgICAgIGNhdGVnb3J5OiAnY29kZScsXG4gICAgICAgIHBhdHRlcm46IC8oPzpxdWVyeXxleGVjdXRlKVxccypcXChcXHMqWydcImBdLipcXCRcXHtbXn1dK1xcfS4qWydcImBdfFsnXCJgXS4qXFwrXFxzKlthLXpBLVpfXVxcdypcXHMqXFwrLipbJ1wiYF1cXHMqXFwpL2csXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnVXNlIHBhcmFtZXRlcml6ZWQgcXVlcmllcyBvciBwcmVwYXJlZCBzdGF0ZW1lbnRzJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL293YXNwLm9yZy9Ub3AxMC9BMDNfMjAyMS1JbmplY3Rpb24vJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnT1dBU1AtQTAzLTAwMicsXG4gICAgICAgIG5hbWU6ICdDb21tYW5kIEluamVjdGlvbicsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUG90ZW50aWFsIGNvbW1hbmQgaW5qZWN0aW9uIHZ1bG5lcmFiaWxpdHknLFxuICAgICAgICBzZXZlcml0eTogJ2NyaXRpY2FsJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjb2RlJyxcbiAgICAgICAgcGF0dGVybjogLyg/OmV4ZWN8c3Bhd258ZXhlY1N5bmN8c3Bhd25TeW5jKVxccypcXChbXildKig/OlxcJFxce1tefV0rXFx9fFxcK1xccypbYS16QS1aX11cXHcqKS9nLFxuICAgICAgICByZW1lZGlhdGlvbjogJ1ZhbGlkYXRlIGFuZCBzYW5pdGl6ZSBhbGwgdXNlciBpbnB1dCBiZWZvcmUgdXNpbmcgaW4gc3lzdGVtIGNvbW1hbmRzJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL293YXNwLm9yZy9Ub3AxMC9BMDNfMjAyMS1JbmplY3Rpb24vJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnT1dBU1AtQTAzLTAwMycsXG4gICAgICAgIG5hbWU6ICdQYXRoIFRyYXZlcnNhbCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUG90ZW50aWFsIHBhdGggdHJhdmVyc2FsIHZ1bG5lcmFiaWxpdHknLFxuICAgICAgICBzZXZlcml0eTogJ2hpZ2gnLFxuICAgICAgICBjYXRlZ29yeTogJ2NvZGUnLFxuICAgICAgICBwYXR0ZXJuOiAvKD86cmVhZEZpbGV8d3JpdGVGaWxlfHJlYWRkaXJ8bWtkaXJ8cm18dW5saW5rKVteKF0qXFwoW14pXSooPzpcXC5cXC5bL1xcXFxdLipcXCt8XFwrLipcXC5cXC5bL1xcXFxdKS9nLFxuICAgICAgICByZW1lZGlhdGlvbjogJ1ZhbGlkYXRlIGFuZCBzYW5pdGl6ZSBmaWxlIHBhdGhzLCB1c2UgcGF0aC5yZXNvbHZlKCkgYW5kIGNoZWNrIGFnYWluc3QgYWxsb3dlZCBkaXJlY3RvcmllcycsXG4gICAgICAgIHJlZmVyZW5jZXM6IFsnaHR0cHM6Ly9vd2FzcC5vcmcvVG9wMTAvQTAzXzIwMjEtSW5qZWN0aW9uLyddXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpZDogJ09XQVNQLUEwMy0wMDQnLFxuICAgICAgICBuYW1lOiAnWFNTIC0gRGlyZWN0IEhUTUwgSW5qZWN0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdQb3RlbnRpYWwgWFNTIHZ1bG5lcmFiaWxpdHkgdGhyb3VnaCBkaXJlY3QgSFRNTCBpbmplY3Rpb24nLFxuICAgICAgICBzZXZlcml0eTogJ2hpZ2gnLFxuICAgICAgICBjYXRlZ29yeTogJ2NvZGUnLFxuICAgICAgICBwYXR0ZXJuOiAvaW5uZXJIVE1MXFxzKj1cXHMqW14nXCJgXSpcXCRcXHt8ZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwvZyxcbiAgICAgICAgcmVtZWRpYXRpb246ICdVc2UgdGV4dENvbnRlbnQgb3IgcHJvcGVyIEhUTUwgZXNjYXBpbmcgZnVuY3Rpb25zJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL293YXNwLm9yZy9Ub3AxMC9BMDNfMjAyMS1JbmplY3Rpb24vJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnT1dBU1AtQTA1LTAwMScsXG4gICAgICAgIG5hbWU6ICdJbnNlY3VyZSBDb25maWd1cmF0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdTZWN1cml0eS1zZW5zaXRpdmUgY29uZmlndXJhdGlvbiBkZXRlY3RlZCcsXG4gICAgICAgIHNldmVyaXR5OiAnbWVkaXVtJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjb2RlJyxcbiAgICAgICAgcGF0dGVybjogLyg/Ok5PREVfVExTX1JFSkVDVF9VTkFVVEhPUklaRUR8c3RyaWN0U1NMfHJlamVjdFVuYXV0aG9yaXplZClcXHMqWzo9XVxccyooPzpmYWxzZXwwfFtcIiddZmFsc2VbXCInXXxbXCInXTBbXCInXSkvZ2ksXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnRW5hYmxlIFNTTC9UTFMgY2VydGlmaWNhdGUgdmFsaWRhdGlvbiBpbiBwcm9kdWN0aW9uJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL293YXNwLm9yZy9Ub3AxMC9BMDVfMjAyMS1TZWN1cml0eV9NaXNjb25maWd1cmF0aW9uLyddXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpZDogJ09XQVNQLUEwNy0wMDEnLFxuICAgICAgICBuYW1lOiAnV2VhayBBdXRoZW50aWNhdGlvbicsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUG90ZW50aWFsIHdlYWsgYXV0aGVudGljYXRpb24gbWVjaGFuaXNtJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdoaWdoJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjb2RlJyxcbiAgICAgICAgcGF0dGVybjogLyg/Om1kNXxzaGExKVxccypcXCgvZ2ksXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnVXNlIHN0cm9uZyBoYXNoaW5nIGFsZ29yaXRobXMgbGlrZSBiY3J5cHQsIHNjcnlwdCwgb3IgQXJnb24yIGZvciBwYXNzd29yZHMnLFxuICAgICAgICByZWZlcmVuY2VzOiBbJ2h0dHBzOi8vb3dhc3Aub3JnL1RvcDEwL0EwN18yMDIxLUlkZW50aWZpY2F0aW9uX2FuZF9BdXRoZW50aWNhdGlvbl9GYWlsdXJlcy8nXVxuICAgICAgfVxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogQ1dFIFRvcCAyNSBzZWN1cml0eSBydWxlc1xuICAgKi9cbiAgZ2V0Q1dFUnVsZXMoKTogU2VjdXJpdHlSdWxlW10ge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIGlkOiAnQ1dFLTc5LTAwMScsXG4gICAgICAgIG5hbWU6ICdSZWZsZWN0ZWQgWFNTJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdVc2VyIGlucHV0IHJlZmxlY3RlZCB3aXRob3V0IGVuY29kaW5nJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdoaWdoJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjb2RlJyxcbiAgICAgICAgcGF0dGVybjogL3Jlc1xcLig/OnNlbmR8d3JpdGV8ZW5kKVxccypcXChbXildKig/OnJlcVxcLig/OnF1ZXJ5fHBhcmFtc3xib2R5KXxyZXF1ZXN0XFwuKS9nLFxuICAgICAgICByZW1lZGlhdGlvbjogJ0VuY29kZSBhbGwgdXNlciBpbnB1dCBiZWZvcmUgcmVmbGVjdGluZyBpbiByZXNwb25zZXMnLFxuICAgICAgICByZWZlcmVuY2VzOiBbJ2h0dHBzOi8vY3dlLm1pdHJlLm9yZy9kYXRhL2RlZmluaXRpb25zLzc5Lmh0bWwnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdDV0UtODktMDAxJyxcbiAgICAgICAgbmFtZTogJ1NRTCBTdHJpbmcgQ29uY2F0ZW5hdGlvbicsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnU1FMIHF1ZXJ5IGJ1aWx0IHVzaW5nIHN0cmluZyBjb25jYXRlbmF0aW9uJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdjcml0aWNhbCcsXG4gICAgICAgIGNhdGVnb3J5OiAnY29kZScsXG4gICAgICAgIHBhdHRlcm46IC9bXCInYF0uKig/OlNFTEVDVHxJTlNFUlR8VVBEQVRFfERFTEVURXxEUk9QfENSRUFURXxBTFRFUikuKltcIidgXVxccypcXCtcXHMqXFx3Ky9naSxcbiAgICAgICAgcmVtZWRpYXRpb246ICdVc2UgcGFyYW1ldGVyaXplZCBxdWVyaWVzIGluc3RlYWQgb2Ygc3RyaW5nIGNvbmNhdGVuYXRpb24nLFxuICAgICAgICByZWZlcmVuY2VzOiBbJ2h0dHBzOi8vY3dlLm1pdHJlLm9yZy9kYXRhL2RlZmluaXRpb25zLzg5Lmh0bWwnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdDV0UtMjItMDAxJyxcbiAgICAgICAgbmFtZTogJ1BhdGggTWFuaXB1bGF0aW9uJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdGaWxlIHBhdGggY29uc3RydWN0ZWQgZnJvbSB1c2VyIGlucHV0JyxcbiAgICAgICAgc2V2ZXJpdHk6ICdoaWdoJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjb2RlJyxcbiAgICAgICAgcGF0dGVybjogL3BhdGhcXC5qb2luXFxzKlxcKFteKV0qKD86cmVxXFwufHJlcXVlc3RcXC58cGFyYW1zfHF1ZXJ5fGJvZHkpL2csXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnVmFsaWRhdGUgcGF0aHMgYWdhaW5zdCBhIHdoaXRlbGlzdCBhbmQgdXNlIHBhdGgucmVzb2x2ZSgpJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydodHRwczovL2N3ZS5taXRyZS5vcmcvZGF0YS9kZWZpbml0aW9ucy8yMi5odG1sJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnQ1dFLTc5OC0wMDEnLFxuICAgICAgICBuYW1lOiAnSGFyZGNvZGVkIENyZWRlbnRpYWxzJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdDcmVkZW50aWFscyBoYXJkY29kZWQgaW4gc291cmNlJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdjcml0aWNhbCcsXG4gICAgICAgIGNhdGVnb3J5OiAnY29kZScsXG4gICAgICAgIHBhdHRlcm46IC8oPzp1c2VybmFtZXx1c2VyfGxvZ2luKVxccypbOj1dXFxzKltcIiddW15cIiddK1tcIiddLiooPzpwYXNzd29yZHxwYXNzfHB3ZClcXHMqWzo9XVxccypbXCInXVteXCInXStbXCInXS9naSxcbiAgICAgICAgcmVtZWRpYXRpb246ICdTdG9yZSBjcmVkZW50aWFscyBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMgb3Igc2VjdXJlIHZhdWx0cycsXG4gICAgICAgIHJlZmVyZW5jZXM6IFsnaHR0cHM6Ly9jd2UubWl0cmUub3JnL2RhdGEvZGVmaW5pdGlvbnMvNzk4Lmh0bWwnXVxuICAgICAgfVxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogRG9sbGhvdXNlTUNQLXNwZWNpZmljIHNlY3VyaXR5IHJ1bGVzXG4gICAqL1xuICBnZXREb2xsaG91c2VNQ1BSdWxlcygpOiBTZWN1cml0eVJ1bGVbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdETUNQLVNFQy0wMDEnLFxuICAgICAgICBuYW1lOiAnVW5zYWZlIFBlcnNvbmEgTG9hZGluZycsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnUGVyc29uYSBsb2FkZWQgd2l0aG91dCB2YWxpZGF0aW9uJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdoaWdoJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjdXN0b20nLFxuICAgICAgICBwYXR0ZXJuOiAvbG9hZFBlcnNvbmFcXHMqXFwoW14pXSpcXClcXHMqKD8hLip2YWxpZGF0ZSkvZyxcbiAgICAgICAgcmVtZWRpYXRpb246ICdBbHdheXMgdmFsaWRhdGUgcGVyc29uYXMgYmVmb3JlIGxvYWRpbmcgdXNpbmcgUGVyc29uYVZhbGlkYXRvcicsXG4gICAgICAgIHJlZmVyZW5jZXM6IFsnRG9sbGhvdXNlTUNQIFNlY3VyaXR5IEd1aWRlbGluZXMnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdETUNQLVNFQy0wMDInLFxuICAgICAgICBuYW1lOiAnVG9rZW4gVmFsaWRhdGlvbiBCeXBhc3MnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ1Rva2VuIHVzZWQgd2l0aG91dCB2YWxpZGF0aW9uJyxcbiAgICAgICAgc2V2ZXJpdHk6ICdjcml0aWNhbCcsXG4gICAgICAgIGNhdGVnb3J5OiAnY3VzdG9tJyxcbiAgICAgICAgcGF0dGVybjogLyg/OmdldFRva2VufHVzZVRva2VufHRva2VuXFwudXNlKVxccypcXChbXildKlxcKSg/IS4qKD86dmFsaWRhdGV8dmVyaWZ5fGNoZWNrKSkvZ2ksXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnQWx3YXlzIHZhbGlkYXRlIHRva2VucyB1c2luZyBUb2tlbk1hbmFnZXIudmFsaWRhdGVUb2tlbigpJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydEb2xsaG91c2VNQ1AgU2VjdXJpdHkgR3VpZGVsaW5lcyddXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBpZDogJ0RNQ1AtU0VDLTAwMycsXG4gICAgICAgIG5hbWU6ICdSYXRlIExpbWl0aW5nIE1pc3NpbmcnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJ0FQSSBlbmRwb2ludCB3aXRob3V0IHJhdGUgbGltaXRpbmcnLFxuICAgICAgICBzZXZlcml0eTogJ21lZGl1bScsXG4gICAgICAgIGNhdGVnb3J5OiAnY3VzdG9tJyxcbiAgICAgICAgY2hlY2s6IChjb250ZW50LCBjb250ZXh0KSA9PiB7XG4gICAgICAgICAgY29uc3QgZmluZGluZ3M6IFNlY3VyaXR5RmluZGluZ1tdID0gW107XG4gICAgICAgICAgLy8gQ2hlY2sgZm9yIE1DUCB0b29sIGhhbmRsZXJzIHdpdGhvdXQgcmF0ZSBsaW1pdGluZ1xuICAgICAgICAgIGNvbnN0IHRvb2xQYXR0ZXJuID0gL25hbWU6XFxzKltcIiddKFteXCInXSspW1wiJ10uKmhhbmRsZTovZ3M7XG4gICAgICAgICAgY29uc3QgaGFzUmF0ZUxpbWl0ID0gL3JhdGVMaW1pdGVyfGNoZWNrUmF0ZUxpbWl0fHRva2VuQnVja2V0L2kudGVzdChjb250ZW50KTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAodG9vbFBhdHRlcm4udGVzdChjb250ZW50KSAmJiAhaGFzUmF0ZUxpbWl0KSB7XG4gICAgICAgICAgICBmaW5kaW5ncy5wdXNoKHtcbiAgICAgICAgICAgICAgcnVsZUlkOiAnRE1DUC1TRUMtMDAzJyxcbiAgICAgICAgICAgICAgc2V2ZXJpdHk6ICdtZWRpdW0nIGFzIGNvbnN0LFxuICAgICAgICAgICAgICBtZXNzYWdlOiAnTUNQIHRvb2wgaGFuZGxlciB3aXRob3V0IHJhdGUgbGltaXRpbmcnLFxuICAgICAgICAgICAgICByZW1lZGlhdGlvbjogJ0FkZCByYXRlIGxpbWl0aW5nIHRvIHByZXZlbnQgYWJ1c2UnLFxuICAgICAgICAgICAgICBjb25maWRlbmNlOiAnaGlnaCcgYXMgY29uc3RcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICBcbiAgICAgICAgICByZXR1cm4gZmluZGluZ3M7XG4gICAgICAgIH0sXG4gICAgICAgIHJlbWVkaWF0aW9uOiAnSW1wbGVtZW50IHJhdGUgbGltaXRpbmcgZm9yIGFsbCBNQ1AgdG9vbHMnLFxuICAgICAgICByZWZlcmVuY2VzOiBbJ0lzc3VlICMxNzQgLSBSYXRlIExpbWl0aW5nIEltcGxlbWVudGF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnRE1DUC1TRUMtMDA0JyxcbiAgICAgICAgbmFtZTogJ1VuaWNvZGUgVmFsaWRhdGlvbiBNaXNzaW5nJyxcbiAgICAgICAgZGVzY3JpcHRpb246ICdVc2VyIGlucHV0IHByb2Nlc3NlZCB3aXRob3V0IFVuaWNvZGUgbm9ybWFsaXphdGlvbicsXG4gICAgICAgIHNldmVyaXR5OiAnbWVkaXVtJyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjdXN0b20nLFxuICAgICAgICBjaGVjazogKGNvbnRlbnQsIGNvbnRleHQpID0+IHtcbiAgICAgICAgICBjb25zdCBmaW5kaW5nczogU2VjdXJpdHlGaW5kaW5nW10gPSBbXTtcbiAgICAgICAgICAvLyBDaGVjayBmb3IgdXNlciBpbnB1dCBwcm9jZXNzaW5nIHdpdGhvdXQgVW5pY29kZSB2YWxpZGF0aW9uXG4gICAgICAgICAgY29uc3QgaW5wdXRQYXR0ZXJuID0gLyg/OnJlcVxcLnxyZXF1ZXN0XFwufHBhcmFtc3xxdWVyeXxib2R5fGNvbnRlbnQpLztcbiAgICAgICAgICBjb25zdCBoYXNVbmljb2RlQ2hlY2sgPSAvVW5pY29kZVZhbGlkYXRvcnxub3JtYWxpemVVbmljb2RlL2kudGVzdChjb250ZW50KTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAoaW5wdXRQYXR0ZXJuLnRlc3QoY29udGVudCkgJiYgIWhhc1VuaWNvZGVDaGVjaykge1xuICAgICAgICAgICAgZmluZGluZ3MucHVzaCh7XG4gICAgICAgICAgICAgIHJ1bGVJZDogJ0RNQ1AtU0VDLTAwNCcsXG4gICAgICAgICAgICAgIHNldmVyaXR5OiAnbWVkaXVtJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ1VzZXIgaW5wdXQgcHJvY2Vzc2VkIHdpdGhvdXQgVW5pY29kZSBub3JtYWxpemF0aW9uJyxcbiAgICAgICAgICAgICAgcmVtZWRpYXRpb246ICdVc2UgVW5pY29kZVZhbGlkYXRvci5ub3JtYWxpemUoKSBvbiBhbGwgdXNlciBpbnB1dCcsXG4gICAgICAgICAgICAgIGNvbmZpZGVuY2U6ICdtZWRpdW0nIGFzIGNvbnN0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIGZpbmRpbmdzO1xuICAgICAgICB9LFxuICAgICAgICByZW1lZGlhdGlvbjogJ0FwcGx5IFVuaWNvZGUgbm9ybWFsaXphdGlvbiB0byBwcmV2ZW50IGJ5cGFzcyBhdHRhY2tzJyxcbiAgICAgICAgcmVmZXJlbmNlczogWydJc3N1ZSAjMTYyIC0gVW5pY29kZSBOb3JtYWxpemF0aW9uJ11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGlkOiAnRE1DUC1TRUMtMDA1JyxcbiAgICAgICAgbmFtZTogJ1VudmFsaWRhdGVkIFlBTUwgQ29udGVudCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnWUFNTCBjb250ZW50IHBhcnNlZCB3aXRob3V0IHNlY3VyaXR5IHZhbGlkYXRpb24nLFxuICAgICAgICBzZXZlcml0eTogJ2hpZ2gnLFxuICAgICAgICBjYXRlZ29yeTogJ2N1c3RvbScsXG4gICAgICAgIHBhdHRlcm46IC95YW1sXFwubG9hZFxccypcXCh8cGFyc2VcXHMqXFwoW14pXSpcXC55YT9tbC9naSxcbiAgICAgICAgcmVtZWRpYXRpb246ICdVc2UgU2VjdXJlWWFtbFBhcnNlciBmb3IgYWxsIFlBTUwgcGFyc2luZycsXG4gICAgICAgIHJlZmVyZW5jZXM6IFsnRG9sbGhvdXNlTUNQIFNlY3VyaXR5IEd1aWRlbGluZXMnXVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdETUNQLVNFQy0wMDYnLFxuICAgICAgICBuYW1lOiAnU2VjdXJpdHkgRXZlbnQgTm90IExvZ2dlZCcsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnU2VjdXJpdHktcmVsZXZhbnQgb3BlcmF0aW9uIHdpdGhvdXQgbG9nZ2luZycsXG4gICAgICAgIHNldmVyaXR5OiAnbG93JyxcbiAgICAgICAgY2F0ZWdvcnk6ICdjdXN0b20nLFxuICAgICAgICBjaGVjazogKGNvbnRlbnQsIGNvbnRleHQpID0+IHtcbiAgICAgICAgICBjb25zdCBmaW5kaW5nczogU2VjdXJpdHlGaW5kaW5nW10gPSBbXTtcbiAgICAgICAgICAvLyBDaGVjayBmb3Igc2VjdXJpdHkgb3BlcmF0aW9ucyB3aXRob3V0IGxvZ2dpbmdcbiAgICAgICAgICBjb25zdCBzZWN1cml0eU9wcyA9IC8oPzphdXRoZW50aWNhdGV8YXV0aG9yaXplfHZhbGlkYXRlfHNhbml0aXplfGVuY3J5cHR8ZGVjcnlwdCkvaTtcbiAgICAgICAgICBjb25zdCBoYXNMb2dnaW5nID0gL1NlY3VyaXR5TW9uaXRvclxcLmxvZ3xsb2dTZWN1cml0eUV2ZW50L2kudGVzdChjb250ZW50KTtcbiAgICAgICAgICBcbiAgICAgICAgICBpZiAoc2VjdXJpdHlPcHMudGVzdChjb250ZW50KSAmJiAhaGFzTG9nZ2luZykge1xuICAgICAgICAgICAgZmluZGluZ3MucHVzaCh7XG4gICAgICAgICAgICAgIHJ1bGVJZDogJ0RNQ1AtU0VDLTAwNicsXG4gICAgICAgICAgICAgIHNldmVyaXR5OiAnbG93JyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogJ1NlY3VyaXR5IG9wZXJhdGlvbiB3aXRob3V0IGF1ZGl0IGxvZ2dpbmcnLFxuICAgICAgICAgICAgICByZW1lZGlhdGlvbjogJ0FkZCBTZWN1cml0eU1vbml0b3IubG9nU2VjdXJpdHlFdmVudCgpIGZvciBhdWRpdCB0cmFpbCcsXG4gICAgICAgICAgICAgIGNvbmZpZGVuY2U6ICdtZWRpdW0nIGFzIGNvbnN0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgXG4gICAgICAgICAgcmV0dXJuIGZpbmRpbmdzO1xuICAgICAgICB9LFxuICAgICAgICByZW1lZGlhdGlvbjogJ0xvZyBhbGwgc2VjdXJpdHktcmVsZXZhbnQgb3BlcmF0aW9ucyBmb3IgYXVkaXQgdHJhaWwnLFxuICAgICAgICByZWZlcmVuY2VzOiBbJ0RvbGxob3VzZU1DUCBTZWN1cml0eSBHdWlkZWxpbmVzJ11cbiAgICAgIH1cbiAgICBdO1xuICB9XG59Il19