snow-flow 1.3.25 → 1.3.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.claude/config.json +33 -9
  2. package/.claude-flow/queen/queen-memory.db +0 -0
  3. package/.roo/README.md +56 -0
  4. package/.roo/workflows/basic-tdd.json +32 -0
  5. package/.roomodes +122 -0
  6. package/CLAUDE.md +140 -752
  7. package/claude-flow +30 -75
  8. package/dist/cli.js +250 -7
  9. package/dist/compliance/advanced-compliance-system.js +857 -0
  10. package/dist/compliance/index.js +8 -0
  11. package/dist/documentation/index.js +8 -0
  12. package/dist/documentation/self-documenting-system.js +1006 -0
  13. package/dist/healing/index.js +8 -0
  14. package/dist/healing/self-healing-system.js +1041 -0
  15. package/dist/intelligence/performance-recommendations-engine.js +479 -4
  16. package/dist/managers/scope-manager.js +5 -2
  17. package/dist/mcp/servicenow-deployment-mcp.js +113 -15
  18. package/dist/mcp/servicenow-flow-composer-mcp.js +4 -2
  19. package/dist/mcp/servicenow-intelligent-mcp.js +351 -0
  20. package/dist/mcp/servicenow-operations-mcp.js +2 -2
  21. package/dist/memory/memory-system.js +146 -0
  22. package/dist/monitoring/enhanced-monitoring-system.js +1085 -0
  23. package/dist/optimization/cost-optimization-engine.js +771 -0
  24. package/dist/optimization/flow-performance-optimizer.js +723 -0
  25. package/dist/optimization/index.js +10 -0
  26. package/dist/orchestration/flow-update-orchestrator.js +648 -0
  27. package/dist/rollback/smart-rollback-system.js +462 -0
  28. package/dist/templates/flow-template-system.js +625 -0
  29. package/dist/testing/flow-testing-automation.js +641 -0
  30. package/dist/testing/integration-test-suite.js +890 -0
  31. package/dist/utils/flow-structure-builder.js +1 -1
  32. package/dist/utils/servicenow-client.js +50 -2
  33. package/dist/utils/snow-oauth.js +66 -8
  34. package/dist/utils/xml-first-flow-generator.js +6 -0
  35. package/dist/version.js +13 -1
  36. package/package.json +1 -1
@@ -64,7 +64,7 @@ function generateFlowComponents(flowDefinition, flowSysId) {
64
64
  type: 'flow',
65
65
  status: 'published',
66
66
  active: true,
67
- run_as: 'system',
67
+ run_as: 'user', // 🔒 SEC-001 FIX: Default to 'user' to prevent privilege escalation
68
68
  sys_class_name: 'sys_hub_flow',
69
69
  table: flowDefinition.table,
70
70
  category: 'custom',
@@ -10,6 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.ServiceNowClient = void 0;
12
12
  const axios_1 = __importDefault(require("axios"));
13
+ const https_1 = __importDefault(require("https"));
13
14
  const snow_oauth_1 = require("./snow-oauth");
14
15
  const action_type_cache_1 = require("./action-type-cache");
15
16
  const snow_flow_config_js_1 = require("../config/snow-flow-config.js");
@@ -25,12 +26,59 @@ class ServiceNowClient {
25
26
  this.lastTokenRefresh = 0;
26
27
  this.logger = new logger_1.Logger('ServiceNowClient');
27
28
  this.oauth = new snow_oauth_1.ServiceNowOAuth();
29
+ // 🔒 SSL/TLS Certificate Validation Fix: Add proper HTTPS agent with certificate validation
30
+ const httpsAgent = new https_1.default.Agent({
31
+ rejectUnauthorized: true, // Enforce certificate validation
32
+ checkServerIdentity: (hostname, cert) => {
33
+ // Custom certificate validation for ServiceNow instances
34
+ // Allow *.service-now.com and user-configured instances
35
+ const validHosts = [
36
+ /.*\.service-now\.com$/,
37
+ /.*\.servicenow\.com$/
38
+ ];
39
+ // Get configured instance hostname
40
+ const instanceUrl = process.env.SNOW_INSTANCE;
41
+ if (instanceUrl) {
42
+ try {
43
+ const instanceHostname = new URL(instanceUrl.startsWith('http') ? instanceUrl : `https://${instanceUrl}`).hostname;
44
+ validHosts.push(new RegExp(`^${instanceHostname.replace(/\./g, '\\.')}$`));
45
+ }
46
+ catch (error) {
47
+ // Invalid URL format, rely on default validation
48
+ }
49
+ }
50
+ // Check if hostname matches allowed patterns
51
+ if (validHosts.some(pattern => pattern.test(hostname))) {
52
+ return undefined; // Valid hostname
53
+ }
54
+ // For development/testing environments, allow localhost/127.0.0.1
55
+ if (process.env.NODE_ENV === 'development' &&
56
+ (hostname === 'localhost' || hostname === '127.0.0.1' || hostname.startsWith('192.168.'))) {
57
+ return undefined;
58
+ }
59
+ return new Error(`Certificate hostname mismatch: ${hostname} not allowed`);
60
+ },
61
+ // secureProtocol removed to avoid conflict with minVersion/maxVersion
62
+ ciphers: [
63
+ 'ECDHE-RSA-AES128-GCM-SHA256',
64
+ 'ECDHE-RSA-AES256-GCM-SHA384',
65
+ 'ECDHE-RSA-AES128-SHA256',
66
+ 'ECDHE-RSA-AES256-SHA384'
67
+ ].join(':'), // Only allow secure ciphers
68
+ honorCipherOrder: true,
69
+ maxVersion: 'TLSv1.3',
70
+ minVersion: 'TLSv1.2'
71
+ });
28
72
  this.client = axios_1.default.create({
29
73
  timeout: snow_flow_config_js_1.snowFlowConfig.servicenow.timeout,
30
74
  headers: {
31
75
  'Content-Type': 'application/json',
32
76
  'Accept': 'application/json'
33
- }
77
+ },
78
+ httpsAgent, // Use secure HTTPS agent with certificate validation
79
+ // Additional security headers
80
+ maxRedirects: 5,
81
+ validateStatus: (status) => status < 400 // Reject 4xx and 5xx by default
34
82
  });
35
83
  // 🔧 CRITICAL FIX: Add makeRequest method to Axios instance to fix phantom calls
36
84
  // Some code expects makeRequest to exist on this.client (the Axios instance)
@@ -1328,7 +1376,7 @@ snow_create_flow({
1328
1376
  active: true, // Always create as active
1329
1377
  internal_name: this.sanitizeInternalName(flow.name),
1330
1378
  category: flow.category || 'custom',
1331
- run_as: flow.run_as || 'system', // 🔧 FIX: Default to 'system' for proper execution
1379
+ run_as: flow.run_as || 'user', // 🔒 SEC-001 FIX: Default to 'user' to prevent privilege escalation
1332
1380
  status: 'published', // 🔧 FIX: Ensure flow is published, not draft
1333
1381
  validated: true, // 🔧 FIX: Mark as validated to allow activation
1334
1382
  // Include complete flow definition to prevent corruption
@@ -21,10 +21,33 @@ const snow_flow_config_js_1 = require("../config/snow-flow-config.js");
21
21
  const unified_auth_store_js_1 = require("./unified-auth-store.js");
22
22
  class ServiceNowOAuth {
23
23
  constructor() {
24
+ // 🔒 SEC-002 FIX: Add rate limiting to prevent authentication bypass attacks
25
+ this.lastTokenRequest = 0;
26
+ this.tokenRequestCount = 0;
27
+ this.TOKEN_REQUEST_WINDOW_MS = 60000; // 1 minute window
28
+ this.MAX_TOKEN_REQUESTS_PER_WINDOW = 10; // Max 10 token requests per minute
24
29
  // Store tokens in user's home directory
25
30
  const configDir = process.env.SNOW_FLOW_HOME || (0, path_1.join)(os_1.default.homedir(), '.snow-flow');
26
31
  this.tokenPath = (0, path_1.join)(configDir, 'auth.json');
27
32
  }
33
+ /**
34
+ * 🔒 SEC-002 FIX: Check rate limiting for token requests to prevent brute force attacks
35
+ */
36
+ checkTokenRequestRateLimit() {
37
+ const now = Date.now();
38
+ // Reset counter if window has passed
39
+ if (now - this.lastTokenRequest > this.TOKEN_REQUEST_WINDOW_MS) {
40
+ this.tokenRequestCount = 0;
41
+ this.lastTokenRequest = now;
42
+ }
43
+ // Check if within rate limit
44
+ if (this.tokenRequestCount >= this.MAX_TOKEN_REQUESTS_PER_WINDOW) {
45
+ console.warn('🔒 Rate limit exceeded: Too many token requests. Please wait before retrying.');
46
+ return false;
47
+ }
48
+ this.tokenRequestCount++;
49
+ return true;
50
+ }
28
51
  /**
29
52
  * Generate a random state parameter for CSRF protection
30
53
  */
@@ -62,8 +85,27 @@ class ServiceNowOAuth {
62
85
  /**
63
86
  * Initialize OAuth flow - opens browser and handles callback
64
87
  */
88
+ /**
89
+ * 🔧 CRIT-002 FIX: Normalize instance URL to prevent trailing slash 400 errors
90
+ */
91
+ normalizeInstanceUrl(instance) {
92
+ // Remove any trailing slashes that cause 400 errors
93
+ let normalized = instance.replace(/\/+$/, '');
94
+ // Add https:// if missing
95
+ if (!normalized.startsWith('http://') && !normalized.startsWith('https://')) {
96
+ normalized = `https://${normalized}`;
97
+ }
98
+ // Ensure .service-now.com suffix if it's just the instance name
99
+ if (!normalized.includes('.service-now.com') && !normalized.includes('localhost') && !normalized.includes('127.0.0.1')) {
100
+ const instanceName = normalized.replace('https://', '').replace('http://', '');
101
+ normalized = `https://${instanceName}.service-now.com`;
102
+ }
103
+ return normalized;
104
+ }
65
105
  async authenticate(instance, clientId, clientSecret) {
66
106
  try {
107
+ // 🔧 CRIT-002 FIX: Apply URL normalization
108
+ const normalizedInstance = this.normalizeInstanceUrl(instance);
67
109
  // Validate client secret format
68
110
  const secretValidation = this.validateClientSecret(clientSecret);
69
111
  if (!secretValidation.valid) {
@@ -94,15 +136,15 @@ class ServiceNowOAuth {
94
136
  error: `Port ${port} is already in use. Please free up the port and try again.`
95
137
  };
96
138
  }
97
- // Store credentials temporarily (remove trailing slash from instance)
139
+ // Store credentials temporarily with normalized instance
98
140
  this.credentials = {
99
- instance: instance.replace(/\/$/, ''),
141
+ instance: normalizedInstance.replace('https://', '').replace('http://', ''),
100
142
  clientId,
101
143
  clientSecret,
102
144
  redirectUri
103
145
  };
104
146
  console.log('🚀 Starting ServiceNow OAuth flow...');
105
- console.log(`📋 Instance: ${instance}`);
147
+ console.log(`📋 Instance: ${normalizedInstance}`);
106
148
  console.log(`🔐 Client ID: ${clientId}`);
107
149
  console.log(`🔗 Redirect URI: ${redirectUri}`);
108
150
  // Generate state parameter for CSRF protection
@@ -110,18 +152,18 @@ class ServiceNowOAuth {
110
152
  // Generate PKCE parameters
111
153
  this.generatePKCE();
112
154
  // Generate authorization URL
113
- const authUrl = this.generateAuthUrl(instance, clientId, redirectUri);
155
+ const authUrl = this.generateAuthUrl(this.credentials.instance, clientId, redirectUri);
114
156
  console.log('\n🌐 Authorization URL generated:');
115
157
  console.log(`${authUrl}\n`);
116
158
  // Start local server to handle callback
117
159
  const authResult = await this.startCallbackServer(redirectUri, port);
118
160
  if (authResult.success && authResult.accessToken) {
119
- // Save tokens
161
+ // Save tokens with normalized instance
120
162
  await this.saveTokens({
121
163
  accessToken: authResult.accessToken,
122
164
  refreshToken: authResult.refreshToken || '',
123
165
  expiresIn: authResult.expiresIn || 3600,
124
- instance: instance.replace(/\/$/, ''),
166
+ instance: this.credentials.instance,
125
167
  clientId,
126
168
  clientSecret
127
169
  });
@@ -303,6 +345,13 @@ class ServiceNowOAuth {
303
345
  */
304
346
  async exchangeCodeForTokens(code) {
305
347
  try {
348
+ // 🔒 SEC-002 FIX: Apply rate limiting to prevent authentication bypass attacks
349
+ if (!this.checkTokenRequestRateLimit()) {
350
+ return {
351
+ success: false,
352
+ error: 'Rate limit exceeded. Too many token requests. Please wait 1 minute before retrying.'
353
+ };
354
+ }
306
355
  const tokenUrl = `https://${this.credentials.instance}/oauth_token.do`;
307
356
  const response = await axios_1.default.post(tokenUrl, new URLSearchParams({
308
357
  grant_type: 'authorization_code',
@@ -314,7 +363,8 @@ class ServiceNowOAuth {
314
363
  }), {
315
364
  headers: {
316
365
  'Content-Type': 'application/x-www-form-urlencoded'
317
- }
366
+ },
367
+ timeout: 15000 // 🔒 SEC-002 FIX: 15 second timeout to prevent hanging requests
318
368
  });
319
369
  const data = response.data;
320
370
  if (data.access_token) {
@@ -434,6 +484,13 @@ class ServiceNowOAuth {
434
484
  */
435
485
  async refreshAccessToken(tokens) {
436
486
  try {
487
+ // 🔒 SEC-002 FIX: Apply rate limiting to prevent authentication bypass attacks
488
+ if (!this.checkTokenRequestRateLimit()) {
489
+ return {
490
+ success: false,
491
+ error: 'Rate limit exceeded. Too many token requests. Please wait 1 minute before retrying.'
492
+ };
493
+ }
437
494
  // If no tokens provided, load from file
438
495
  if (!tokens) {
439
496
  tokens = await this.loadTokens();
@@ -453,7 +510,8 @@ class ServiceNowOAuth {
453
510
  }), {
454
511
  headers: {
455
512
  'Content-Type': 'application/x-www-form-urlencoded'
456
- }
513
+ },
514
+ timeout: 15000 // 🔒 SEC-002 FIX: 15 second timeout to prevent hanging requests
457
515
  });
458
516
  const data = response.data;
459
517
  if (data.access_token) {
@@ -453,6 +453,12 @@ class XMLFirstFlowGenerator {
453
453
  getActionTypeId(actionType) {
454
454
  return exports.ACTION_TYPE_SYS_IDS[actionType] || exports.ACTION_TYPE_SYS_IDS['script'];
455
455
  }
456
+ /**
457
+ * Generate complete Flow XML - alias for backward compatibility
458
+ */
459
+ generateCompleteFlowXML(flowDef) {
460
+ return this.generateFlowUpdateSetXML(flowDef);
461
+ }
456
462
  /**
457
463
  * Save XML to file
458
464
  */
package/dist/version.js CHANGED
@@ -7,12 +7,24 @@ exports.VERSION_INFO = exports.VERSION = void 0;
7
7
  exports.getVersionString = getVersionString;
8
8
  exports.getLatestFeatures = getLatestFeatures;
9
9
  exports.isLatestVersion = isLatestVersion;
10
- exports.VERSION = '1.3.23';
10
+ exports.VERSION = '1.3.27';
11
11
  exports.VERSION_INFO = {
12
12
  version: exports.VERSION,
13
13
  name: 'Snow-Flow',
14
14
  description: 'ServiceNow Queen Agent - Hive-Mind Intelligence for ServiceNow Development',
15
15
  features: {
16
+ '1.3.27': [
17
+ '🤖 AUTONOMOUS SYSTEMS: All 4 autonomous systems now ENABLED BY DEFAULT in swarm command!',
18
+ '✅ SELF-DOCUMENTING: Automatic documentation generation and updates (default: enabled)',
19
+ '💰 COST OPTIMIZATION: AI-driven cost management with auto-optimization (default: enabled)',
20
+ '🔐 COMPLIANCE MONITORING: Multi-framework compliance with auto-remediation (default: enabled)',
21
+ 'đŸĨ SELF-HEALING: Predictive failure detection with automatic recovery (default: enabled)',
22
+ 'âš™ī¸ FLEXIBLE CONTROL: Use --no-autonomous-* flags to disable specific systems',
23
+ 'đŸšĢ GLOBAL DISABLE: Use --no-autonomous-all to disable all autonomous systems',
24
+ 'đŸ’Ē FORCE OVERRIDE: Use --autonomous-all to force enable all (overrides --no- flags)',
25
+ 'đŸŽ¯ PERFECT ORCHESTRATOR: True "ÊÊn command voor alles" - zero manual intervention needed!',
26
+ 'Based on user request: "oke maar kunnen we het niet als standaard aanzetten dat al deze dingen beschikbaar zijn?"'
27
+ ],
16
28
  '1.3.16': [
17
29
  '🔄 VERSION BUMP: Clean version update for npm publish',
18
30
  '✨ INCLUDES: All improvements from v1.3.15',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snow-flow",
3
- "version": "1.3.25",
3
+ "version": "1.3.28",
4
4
  "description": "ServiceNow Queen Agent - Hive-Mind Intelligence for ServiceNow Development inspired by claude-flow. Transform complex workflows into elegant one-command orchestration.",
5
5
  "main": "dist/index.js",
6
6
  "type": "commonjs",