cisco-axl 1.3.1 → 1.4.0

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.
@@ -0,0 +1,10 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(git add:*)",
5
+ "Bash(npm run build:*)",
6
+ "Bash(git push:*)"
7
+ ],
8
+ "deny": []
9
+ }
10
+ }
package/dist/index.d.ts CHANGED
@@ -20,6 +20,18 @@ declare class axlService {
20
20
  * @memberof axlService
21
21
  */
22
22
  constructor(host: string, username: string, password: string, version: string);
23
+ /**
24
+ * Test authentication credentials against the AXL endpoint
25
+ * @returns {Promise<boolean>} - Resolves to true if authentication is successful
26
+ * @memberof axlService
27
+ */
28
+ testAuthentication(): Promise<boolean>;
29
+ /**
30
+ * Private method to test authentication using a simple GET request to the AXL endpoint
31
+ * @returns {Promise<boolean>} - Resolves with true if authentication successful, false otherwise
32
+ * @private
33
+ */
34
+ private _testAuthenticationDirectly;
23
35
  /**
24
36
  * Returns a list of available AXL operations
25
37
  * @param {string} [filter] - Optional filter to narrow down operations
package/dist/index.js CHANGED
@@ -34,11 +34,33 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  const soap = __importStar(require("strong-soap"));
36
36
  const path = __importStar(require("path"));
37
+ const https = __importStar(require("https"));
38
+ const url_1 = require("url");
37
39
  const WSDL = soap.soap.WSDL;
38
40
  const wsdlOptions = {
39
41
  attributesKey: "attributes",
40
42
  valueKey: "value",
41
43
  };
44
+ /**
45
+ * Helper function to log debug messages only when DEBUG environment variable is set
46
+ * @param {string} message - The message to log
47
+ * @param {any} [data] - Optional data to log
48
+ */
49
+ const debugLog = (message, data) => {
50
+ // Get the DEBUG value, handling case-insensitivity
51
+ const debug = process.env.DEBUG;
52
+ // Check if DEBUG is set and is a truthy value (not 'false', 'no', '0', etc.)
53
+ const isDebugEnabled = debug &&
54
+ !['false', 'no', '0', 'off', 'n'].includes(debug.toLowerCase());
55
+ if (isDebugEnabled) {
56
+ if (data) {
57
+ console.log(`[AXL DEBUG] ${message}`, data);
58
+ }
59
+ else {
60
+ console.log(`[AXL DEBUG] ${message}`);
61
+ }
62
+ }
63
+ };
42
64
  /**
43
65
  * Cisco axlService Service
44
66
  * This is a service class that uses fetch and promises to pull AXL data from Cisco CUCM
@@ -65,6 +87,85 @@ class axlService {
65
87
  version: version,
66
88
  };
67
89
  }
90
+ /**
91
+ * Test authentication credentials against the AXL endpoint
92
+ * @returns {Promise<boolean>} - Resolves to true if authentication is successful
93
+ * @memberof axlService
94
+ */
95
+ async testAuthentication() {
96
+ try {
97
+ const authSuccess = await this._testAuthenticationDirectly();
98
+ if (!authSuccess) {
99
+ throw new Error("Authentication failed. Check username and password.");
100
+ }
101
+ return true;
102
+ }
103
+ catch (error) {
104
+ throw new Error(`Authentication test failed: ${error.message}`);
105
+ }
106
+ }
107
+ /**
108
+ * Private method to test authentication using a simple GET request to the AXL endpoint
109
+ * @returns {Promise<boolean>} - Resolves with true if authentication successful, false otherwise
110
+ * @private
111
+ */
112
+ async _testAuthenticationDirectly() {
113
+ const options = this._OPTIONS;
114
+ const url = new url_1.URL(options.endpoint);
115
+ return new Promise((resolve) => {
116
+ const authHeader = 'Basic ' + Buffer.from(`${options.username}:${options.password}`).toString('base64');
117
+ const reqOptions = {
118
+ hostname: url.hostname,
119
+ port: url.port || 8443,
120
+ path: url.pathname,
121
+ method: 'GET', // Simply use GET instead of POST
122
+ headers: {
123
+ 'Authorization': authHeader,
124
+ 'Connection': 'keep-alive'
125
+ },
126
+ rejectUnauthorized: false // For self-signed certificates
127
+ };
128
+ debugLog(`Testing authentication to ${url.hostname}:${url.port || 8443}${url.pathname}`);
129
+ const req = https.request(reqOptions, (res) => {
130
+ debugLog(`Authentication test response status: ${res.statusCode}`);
131
+ // Check status code for authentication failures
132
+ if (res.statusCode === 401 || res.statusCode === 403) {
133
+ debugLog('Authentication failed: Unauthorized status code');
134
+ resolve(false); // Authentication failed
135
+ return;
136
+ }
137
+ let responseData = '';
138
+ res.on('data', (chunk) => {
139
+ responseData += chunk;
140
+ });
141
+ res.on('end', () => {
142
+ // Check for the expected success message
143
+ const successIndicator = "Cisco CallManager: AXL Web Service";
144
+ if (responseData.includes(successIndicator)) {
145
+ debugLog('Authentication succeeded: Found success message');
146
+ resolve(true); // Authentication succeeded
147
+ }
148
+ else if (responseData.includes('Authentication failed') ||
149
+ responseData.includes('401 Unauthorized') ||
150
+ responseData.includes('403 Forbidden')) {
151
+ debugLog('Authentication failed: Found failure message in response');
152
+ resolve(false); // Authentication failed
153
+ }
154
+ else {
155
+ debugLog('Authentication status uncertain, response did not contain expected messages');
156
+ // If we're not sure, assume it failed to be safe
157
+ resolve(false);
158
+ }
159
+ });
160
+ });
161
+ req.on('error', (error) => {
162
+ console.error('Authentication test error:', error.message);
163
+ resolve(false);
164
+ });
165
+ // Since it's a GET request, we just end it without writing any data
166
+ req.end();
167
+ });
168
+ }
68
169
  /**
69
170
  * Returns a list of available AXL operations
70
171
  * @param {string} [filter] - Optional filter to narrow down operations
@@ -151,9 +252,16 @@ class axlService {
151
252
  * @returns {Promise<any>} - Result of the operation
152
253
  * @memberof axlService
153
254
  */
154
- executeOperation(operation, tags, opts) {
255
+ async executeOperation(operation, tags, opts) {
155
256
  var _a, _b, _c;
156
257
  const options = this._OPTIONS;
258
+ // First test authentication
259
+ debugLog(`Testing authentication before executing operation: ${operation}`);
260
+ const authSuccess = await this._testAuthenticationDirectly();
261
+ if (!authSuccess) {
262
+ throw new Error("Authentication failed. Check username and password.");
263
+ }
264
+ debugLog('Authentication successful, proceeding with operation');
157
265
  const clean = (_a = opts === null || opts === void 0 ? void 0 : opts.clean) !== null && _a !== void 0 ? _a : false;
158
266
  const dataContainerIdentifierTails = (_b = opts === null || opts === void 0 ? void 0 : opts.dataContainerIdentifierTails) !== null && _b !== void 0 ? _b : "_data";
159
267
  const removeAttributes = (_c = opts === null || opts === void 0 ? void 0 : opts.removeAttributes) !== null && _c !== void 0 ? _c : false;
@@ -161,22 +269,186 @@ class axlService {
161
269
  Object.keys(tags).forEach((k) => (tags[k] === "" || k.includes(dataContainerIdentifierTails)) && delete tags[k]);
162
270
  return new Promise((resolve, reject) => {
163
271
  soap.soap.createClient(options.url, wsdlOptions, function (err, client) {
164
- const customRequestHeader = { connection: "keep-alive" };
165
272
  if (err) {
166
273
  reject(err);
167
274
  return;
168
275
  }
276
+ // Get the properly versioned namespace URL
277
+ const namespaceUrl = `http://www.cisco.com/AXL/API/${options.version}`;
278
+ // 1. Set envelope key
279
+ client.wsdl.options = {
280
+ ...client.wsdl.options,
281
+ envelopeKey: "soapenv", // Change default 'soap' to 'soapenv'
282
+ };
283
+ // 2. Define namespaces with the correct version
284
+ client.wsdl.definitions.xmlns.ns = namespaceUrl;
285
+ // Remove ns1 if it exists
286
+ if (client.wsdl.definitions.xmlns.ns1) {
287
+ delete client.wsdl.definitions.xmlns.ns1;
288
+ }
289
+ const customRequestHeader = {
290
+ connection: "keep-alive",
291
+ SOAPAction: `"CUCM:DB ver=${options.version} ${operation}"`,
292
+ };
169
293
  client.setSecurity(new soap.soap.BasicAuthSecurity(options.username, options.password));
170
294
  client.setEndpoint(options.endpoint);
171
295
  client.on("soapError", function (err) {
172
- reject(err.root.Envelope.Body.Fault);
296
+ var _a, _b, _c;
297
+ // Check if this is an authentication error
298
+ if ((_c = (_b = (_a = err.root) === null || _a === void 0 ? void 0 : _a.Envelope) === null || _b === void 0 ? void 0 : _b.Body) === null || _c === void 0 ? void 0 : _c.Fault) {
299
+ const fault = err.root.Envelope.Body.Fault;
300
+ const faultString = fault.faultstring || fault.faultString || '';
301
+ if (typeof faultString === 'string' &&
302
+ (faultString.includes('Authentication failed') ||
303
+ faultString.includes('credentials') ||
304
+ faultString.includes('authorize'))) {
305
+ reject(new Error("Authentication failed. Check username and password."));
306
+ }
307
+ else {
308
+ reject(fault);
309
+ }
310
+ }
311
+ else {
312
+ reject(err);
313
+ }
173
314
  });
315
+ // Check if the operation function exists
316
+ if (!client.AXLAPIService || !client.AXLAPIService.AXLPort || typeof client.AXLAPIService.AXLPort[operation] !== "function") {
317
+ // For operations that aren't found, try a manual approach
318
+ if (operation.startsWith("apply") || operation.startsWith("reset")) {
319
+ // Determine which parameter to use (name or uuid)
320
+ const operationObj = tags[operation] || tags;
321
+ // Check if uuid or name is provided
322
+ let paramTag, paramValue;
323
+ if (operationObj.uuid) {
324
+ paramTag = "uuid";
325
+ paramValue = operationObj.uuid;
326
+ }
327
+ else {
328
+ paramTag = "name";
329
+ paramValue = operationObj.name;
330
+ }
331
+ const rawXml = `<?xml version="1.0" encoding="UTF-8"?>
332
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="${namespaceUrl}">
333
+ <soapenv:Header/>
334
+ <soapenv:Body>
335
+ <ns:${operation}>
336
+ <${paramTag}>${paramValue}</${paramTag}>
337
+ </ns:${operation}>
338
+ </soapenv:Body>
339
+ </soapenv:Envelope>`;
340
+ debugLog(`Executing manual XML request for operation: ${operation}`);
341
+ // Use client.request for direct XML request
342
+ client._request(options.endpoint, rawXml, function (err, body, response) {
343
+ if (err) {
344
+ reject(err);
345
+ return;
346
+ }
347
+ // Check for authentication failures in the response
348
+ if (response && (response.statusCode === 401 || response.statusCode === 403)) {
349
+ reject(new Error("Authentication failed. Check username and password."));
350
+ return;
351
+ }
352
+ if (body && typeof body === 'string' &&
353
+ (body.includes('Authentication failed') ||
354
+ body.includes('401 Unauthorized') ||
355
+ body.includes('403 Forbidden'))) {
356
+ reject(new Error("Authentication failed. Check username and password."));
357
+ return;
358
+ }
359
+ // Parse the response
360
+ try {
361
+ // Don't automatically assume success
362
+ if (body && body.includes('Fault')) {
363
+ // Try to extract the fault message
364
+ const faultMatch = /<faultstring>(.*?)<\/faultstring>/;
365
+ const match = body.match(faultMatch);
366
+ if (match && match[1]) {
367
+ const faultString = match[1];
368
+ if (faultString.includes('Authentication failed') ||
369
+ faultString.includes('credentials') ||
370
+ faultString.includes('authorize')) {
371
+ reject(new Error("Authentication failed. Check username and password."));
372
+ }
373
+ else {
374
+ reject(new Error(faultString));
375
+ }
376
+ }
377
+ else {
378
+ reject(new Error('Unknown SOAP fault occurred'));
379
+ }
380
+ }
381
+ else {
382
+ const result = { return: "Success" }; // Only report success if no errors found
383
+ resolve(result);
384
+ }
385
+ }
386
+ catch (parseError) {
387
+ reject(parseError);
388
+ }
389
+ }, customRequestHeader);
390
+ return;
391
+ }
392
+ else {
393
+ reject(new Error(`Operation "${operation}" not found`));
394
+ return;
395
+ }
396
+ }
397
+ // Get the operation function - confirmed to exist at this point
174
398
  const axlFunc = client.AXLAPIService.AXLPort[operation];
175
- axlFunc(tags, function (err, result) {
399
+ // Define namespace context with the correct version
400
+ const nsContext = {
401
+ ns: namespaceUrl,
402
+ };
403
+ // Prepare message for specific operations
404
+ let message = tags;
405
+ // Handle operations that start with "apply" or "reset"
406
+ if (operation.startsWith("apply") || operation.startsWith("reset")) {
407
+ const operationKey = operation;
408
+ // If there's a nested structure, flatten it
409
+ if (tags[operationKey]) {
410
+ // Check if uuid or name is provided in the nested structure
411
+ if (tags[operationKey].uuid) {
412
+ message = { uuid: tags[operationKey].uuid };
413
+ }
414
+ else if (tags[operationKey].name) {
415
+ message = { name: tags[operationKey].name };
416
+ }
417
+ // If neither uuid nor name is provided, try to use any available
418
+ else {
419
+ // Try to use uuid or name from the top level as fallback
420
+ message = tags.uuid ? { uuid: tags.uuid } : { name: tags.name };
421
+ }
422
+ }
423
+ }
424
+ debugLog(`Executing operation: ${operation}`);
425
+ // Execute the operation
426
+ axlFunc(message, function (err, result, rawResponse) {
176
427
  if (err) {
428
+ // Check if this is an authentication error
429
+ if (err.message && (err.message.includes('Authentication failed') ||
430
+ err.message.includes('401 Unauthorized') ||
431
+ err.message.includes('403 Forbidden') ||
432
+ err.message.includes('credentials'))) {
433
+ reject(new Error("Authentication failed. Check username and password."));
434
+ return;
435
+ }
436
+ // Check if the error response indicates authentication failure
437
+ if (err.response && (err.response.statusCode === 401 || err.response.statusCode === 403)) {
438
+ reject(new Error("Authentication failed. Check username and password."));
439
+ return;
440
+ }
177
441
  reject(err);
178
442
  return;
179
443
  }
444
+ // Check the raw response for auth failures (belt and suspenders approach)
445
+ if (rawResponse && typeof rawResponse === 'string' &&
446
+ (rawResponse.includes('Authentication failed') ||
447
+ rawResponse.includes('401 Unauthorized') ||
448
+ rawResponse.includes('403 Forbidden'))) {
449
+ reject(new Error("Authentication failed. Check username and password."));
450
+ return;
451
+ }
180
452
  if (result === null || result === void 0 ? void 0 : result.hasOwnProperty("return")) {
181
453
  const output = result.return;
182
454
  if (clean) {
@@ -188,9 +460,9 @@ class axlService {
188
460
  resolve(output);
189
461
  }
190
462
  else {
191
- reject("No return results");
463
+ resolve(result || { return: "Success" });
192
464
  }
193
- }, null, customRequestHeader);
465
+ }, nsContext, customRequestHeader);
194
466
  });
195
467
  });
196
468
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/index.js CHANGED
@@ -1,22 +1,45 @@
1
1
  const soap = require("strong-soap").soap;
2
2
  const WSDL = soap.WSDL;
3
3
  const path = require("path");
4
+ const https = require("https");
5
+ const { URL } = require("url");
6
+
4
7
  const wsdlOptions = {
5
8
  attributesKey: "attributes",
6
9
  valueKey: "value",
7
10
  ns1: "ns",
8
11
  };
9
12
 
13
+ /**
14
+ * Helper function to log debug messages only when DEBUG environment variable is set
15
+ * @param {string} message - The message to log
16
+ * @param {any} [data] - Optional data to log
17
+ */
18
+ const debugLog = (message, data) => {
19
+ // Get the DEBUG value, handling case-insensitivity
20
+ const debug = process.env.DEBUG;
21
+
22
+ // Check if DEBUG is set and is a truthy value (not 'false', 'no', '0', etc.)
23
+ const isDebugEnabled = debug && !["false", "no", "0", "off", "n"].includes(debug.toLowerCase());
24
+
25
+ if (isDebugEnabled) {
26
+ if (data) {
27
+ console.log(`[AXL DEBUG] ${message}`, data);
28
+ } else {
29
+ console.log(`[AXL DEBUG] ${message}`);
30
+ }
31
+ }
32
+ };
33
+
10
34
  /**
11
35
  * Cisco axlService Service
12
36
  * This is a service class that uses fetch and promises to pull AXL data from Cisco CUCM
13
37
  *
14
- *
15
38
  * @class axlService
16
39
  */
17
40
  class axlService {
18
41
  constructor(host, username, password, version) {
19
- if (!host | !username | !password | !version) throw new TypeError("missing parameters");
42
+ if (!host || !username || !password || !version) throw new TypeError("missing parameters");
20
43
  this._OPTIONS = {
21
44
  username: username,
22
45
  password: password,
@@ -25,10 +48,100 @@ class axlService {
25
48
  version: version,
26
49
  };
27
50
  }
51
+
52
+ /**
53
+ * Test authentication credentials against the AXL endpoint
54
+ * @returns {Promise<boolean>} - Resolves to true if authentication is successful
55
+ */
56
+ async testAuthentication() {
57
+ try {
58
+ const authSuccess = await this._testAuthenticationDirectly();
59
+ if (!authSuccess) {
60
+ throw new Error("Authentication failed. Check username and password.");
61
+ }
62
+ return true;
63
+ } catch (error) {
64
+ throw new Error(`Authentication test failed: ${error.message}`);
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Private method to test authentication using a simple GET request to the AXL endpoint
70
+ * @returns {Promise<boolean>} - Resolves with true if authentication successful, false otherwise
71
+ * @private
72
+ */
73
+ async _testAuthenticationDirectly() {
74
+ const options = this._OPTIONS;
75
+ const url = new URL(options.endpoint);
76
+
77
+ return new Promise((resolve) => {
78
+ const authHeader = "Basic " + Buffer.from(`${options.username}:${options.password}`).toString("base64");
79
+
80
+ const reqOptions = {
81
+ hostname: url.hostname,
82
+ port: url.port || 8443,
83
+ path: url.pathname,
84
+ method: "GET", // Simply use GET instead of POST
85
+ headers: {
86
+ Authorization: authHeader,
87
+ Connection: "keep-alive",
88
+ },
89
+ rejectUnauthorized: false, // For self-signed certificates
90
+ };
91
+
92
+ debugLog(`Testing authentication to ${url.hostname}:${url.port || 8443}${url.pathname}`);
93
+
94
+ const req = https.request(reqOptions, (res) => {
95
+ debugLog(`Authentication test response status: ${res.statusCode}`);
96
+
97
+ // Check status code for authentication failures
98
+ if (res.statusCode === 401 || res.statusCode === 403) {
99
+ debugLog("Authentication failed: Unauthorized status code");
100
+ resolve(false); // Authentication failed
101
+ return;
102
+ }
103
+
104
+ let responseData = "";
105
+
106
+ res.on("data", (chunk) => {
107
+ responseData += chunk;
108
+ });
109
+
110
+ res.on("end", () => {
111
+ // Check for the expected success message
112
+ const successIndicator = "Cisco CallManager: AXL Web Service";
113
+ if (responseData.includes(successIndicator)) {
114
+ debugLog("Authentication succeeded: Found success message");
115
+ resolve(true); // Authentication succeeded
116
+ } else if (responseData.includes("Authentication failed") || responseData.includes("401 Unauthorized") || responseData.includes("403 Forbidden")) {
117
+ debugLog("Authentication failed: Found failure message in response");
118
+ resolve(false); // Authentication failed
119
+ } else {
120
+ debugLog("Authentication status uncertain, response did not contain expected messages");
121
+ // If we're not sure, assume it failed to be safe
122
+ resolve(false);
123
+ }
124
+ });
125
+ });
126
+
127
+ req.on("error", (error) => {
128
+ console.error("Authentication test error:", error.message);
129
+ resolve(false);
130
+ });
131
+
132
+ // Since it's a GET request, we just end it without writing any data
133
+ req.end();
134
+ });
135
+ }
136
+
28
137
  returnOperations(filter) {
29
138
  var options = this._OPTIONS;
30
139
  return new Promise((resolve, reject) => {
31
140
  soap.createClient(options.url, wsdlOptions, function (err, client) {
141
+ if (err) {
142
+ reject(err);
143
+ return;
144
+ }
32
145
  client.setSecurity(new soap.BasicAuthSecurity(options.username, options.password));
33
146
  client.setEndpoint(options.endpoint);
34
147
 
@@ -60,6 +173,7 @@ class axlService {
60
173
  });
61
174
  });
62
175
  }
176
+
63
177
  getOperationTags(operation) {
64
178
  var options = this._OPTIONS;
65
179
  return new Promise((resolve, reject) => {
@@ -91,12 +205,28 @@ class axlService {
91
205
  });
92
206
  });
93
207
  }
94
- executeOperation(operation, tags, opts) {
95
- var options = this._OPTIONS;
96
208
 
97
- var clean = opts?.clean ? opts.clean : false;
98
- var dataContainerIdentifierTails = opts?.dataContainerIdentifierTails ? opts.dataContainerIdentifierTails : "_data";
99
- var removeAttributes = opts?.removeAttributes ? opts.removeAttributes : false;
209
+ /**
210
+ * Executes an AXL operation against the CUCM
211
+ * @param {string} operation - The AXL operation to execute
212
+ * @param {Object} tags - The tags required for the operation
213
+ * @param {Object} [opts] - Optional parameters for customizing the operation
214
+ * @returns {Promise<any>} - Result of the operation
215
+ */
216
+ async executeOperation(operation, tags, opts) {
217
+ const options = this._OPTIONS;
218
+
219
+ // First test authentication
220
+ debugLog(`Testing authentication before executing operation: ${operation}`);
221
+ const authSuccess = await this._testAuthenticationDirectly();
222
+ if (!authSuccess) {
223
+ throw new Error("Authentication failed. Check username and password.");
224
+ }
225
+ debugLog("Authentication successful, proceeding with operation");
226
+
227
+ const clean = opts?.clean ?? false;
228
+ const dataContainerIdentifierTails = opts?.dataContainerIdentifierTails ?? "_data";
229
+ const removeAttributes = opts?.removeAttributes ?? false;
100
230
 
101
231
  // Let's remove empty top level strings. Also filter out json-variables
102
232
  Object.keys(tags).forEach((k) => (tags[k] == "" || k.includes(dataContainerIdentifierTails)) && delete tags[k]);
@@ -134,7 +264,19 @@ class axlService {
134
264
  client.setEndpoint(options.endpoint);
135
265
 
136
266
  client.on("soapError", function (err) {
137
- reject(err.root.Envelope.Body.Fault);
267
+ // Check if this is an authentication error
268
+ if (err.root?.Envelope?.Body?.Fault) {
269
+ const fault = err.root.Envelope.Body.Fault;
270
+ const faultString = fault.faultstring || fault.faultString || "";
271
+
272
+ if (typeof faultString === "string" && (faultString.includes("Authentication failed") || faultString.includes("credentials") || faultString.includes("authorize"))) {
273
+ reject(new Error("Authentication failed. Check username and password."));
274
+ } else {
275
+ reject(fault);
276
+ }
277
+ } else {
278
+ reject(err);
279
+ }
138
280
  });
139
281
 
140
282
  // Check if the operation function exists
@@ -143,7 +285,6 @@ class axlService {
143
285
  if (operation.startsWith("apply") || operation.startsWith("reset")) {
144
286
  // Determine which parameter to use (name or uuid)
145
287
  const operationObj = tags[operation] || tags;
146
-
147
288
  // Check if uuid or name is provided
148
289
  let paramTag, paramValue;
149
290
 
@@ -165,6 +306,8 @@ class axlService {
165
306
  </soapenv:Body>
166
307
  </soapenv:Envelope>`;
167
308
 
309
+ debugLog(`Executing manual XML request for operation: ${operation}`);
310
+
168
311
  // Use client.request for direct XML request
169
312
  client._request(
170
313
  options.endpoint,
@@ -175,10 +318,38 @@ class axlService {
175
318
  return;
176
319
  }
177
320
 
321
+ // Check for authentication failures in the response
322
+ if (response && (response.statusCode === 401 || response.statusCode === 403)) {
323
+ reject(new Error("Authentication failed. Check username and password."));
324
+ return;
325
+ }
326
+
327
+ if (body && typeof body === "string" && (body.includes("Authentication failed") || body.includes("401 Unauthorized") || body.includes("403 Forbidden"))) {
328
+ reject(new Error("Authentication failed. Check username and password."));
329
+ return;
330
+ }
331
+
178
332
  // Parse the response
179
333
  try {
180
- const result = { return: "Success" }; // Default success response
181
- resolve(result);
334
+ // Don't automatically assume success
335
+ if (body && body.includes("Fault")) {
336
+ // Try to extract the fault message
337
+ const faultMatch = /<faultstring>(.*?)<\/faultstring>/;
338
+ const match = body.match(faultMatch);
339
+ if (match && match[1]) {
340
+ const faultString = match[1];
341
+ if (faultString.includes("Authentication failed") || faultString.includes("credentials") || faultString.includes("authorize")) {
342
+ reject(new Error("Authentication failed. Check username and password."));
343
+ } else {
344
+ reject(new Error(faultString));
345
+ }
346
+ } else {
347
+ reject(new Error("Unknown SOAP fault occurred"));
348
+ }
349
+ } else {
350
+ const result = { return: "Success" }; // Only report success if no errors found
351
+ resolve(result);
352
+ }
182
353
  } catch (parseError) {
183
354
  reject(parseError);
184
355
  }
@@ -224,14 +395,35 @@ class axlService {
224
395
  }
225
396
  }
226
397
 
398
+ debugLog(`Executing operation: ${operation}`);
399
+
227
400
  // Execute the operation
228
401
  axlFunc(
229
402
  message,
230
- function (err, result) {
403
+ function (err, result, rawResponse, soapHeader, rawRequest) {
231
404
  if (err) {
405
+ // Check if this is an authentication error
406
+ if (err.message && (err.message.includes("Authentication failed") || err.message.includes("401 Unauthorized") || err.message.includes("403 Forbidden") || err.message.includes("credentials"))) {
407
+ reject(new Error("Authentication failed. Check username and password."));
408
+ return;
409
+ }
410
+
411
+ // Check if the error response indicates authentication failure
412
+ if (err.response && (err.response.statusCode === 401 || err.response.statusCode === 403)) {
413
+ reject(new Error("Authentication failed. Check username and password."));
414
+ return;
415
+ }
416
+
232
417
  reject(err);
233
418
  return;
234
419
  }
420
+
421
+ // Check the raw response for auth failures (belt and suspenders approach)
422
+ if (rawResponse && typeof rawResponse === "string" && (rawResponse.includes("Authentication failed") || rawResponse.includes("401 Unauthorized") || rawResponse.includes("403 Forbidden"))) {
423
+ reject(new Error("Authentication failed. Check username and password."));
424
+ return;
425
+ }
426
+
235
427
  if (result?.hasOwnProperty("return")) {
236
428
  var output = result.return;
237
429
  if (clean) {
@@ -251,88 +443,6 @@ class axlService {
251
443
  });
252
444
  });
253
445
  }
254
- // executeOperation(operation, tags, opts) {
255
- // var options = this._OPTIONS;
256
-
257
- // var clean = opts?.clean ? opts.clean : false;
258
- // var dataContainerIdentifierTails = opts?.dataContainerIdentifierTails ? opts.dataContainerIdentifierTails : "_data";
259
- // var removeAttributes = opts?.removeAttributes ? opts.removeAttributes : false;
260
-
261
- // // Let's remove empty top level strings. Also filter out json-variables
262
- // Object.keys(tags).forEach((k) => (tags[k] == "" || k.includes(dataContainerIdentifierTails)) && delete tags[k]);
263
-
264
- // return new Promise((resolve, reject) => {
265
- // soap.createClient(options.url, wsdlOptions, function (err, client) {
266
- // // Key changes to fix the namespace issue
267
-
268
- // // 1. Define the namespace prefix mapping
269
- // client.wsdl.definitions.xmlns.ns = "http://www.cisco.com/AXL/API/15.0";
270
-
271
- // // 2. Remove any ns1 namespace mapping if it exists
272
- // if (client.wsdl.definitions.xmlns.ns1) {
273
- // delete client.wsdl.definitions.xmlns.ns1;
274
- // }
275
-
276
- // // 3. Set the envelope key
277
- // client.wsdl.options = {
278
- // ...client.wsdl.options,
279
- // envelopeKey: "soapenv", // Change default 'soap' to 'soapenv'
280
- // };
281
-
282
- // // 4. Important: Fix the structure of the tags object
283
- // // Instead of having nested applyRoutePartition, simplify the structure
284
- // if (operation === "applyRoutePartition" && tags.applyRoutePartition) {
285
- // tags = { name: tags.applyRoutePartition.name };
286
- // }
287
-
288
- // var customRequestHeader = {
289
- // connection: "keep-alive",
290
- // SOAPAction: `"CUCM:DB ver=${options.version} ${operation}"`,
291
- // };
292
-
293
- // if (err) {
294
- // reject(err);
295
- // }
296
- // client.setSecurity(new soap.BasicAuthSecurity(options.username, options.password));
297
- // client.setEndpoint(options.endpoint);
298
-
299
- // client.on("soapError", function (err) {
300
- // reject(err.root.Envelope.Body.Fault);
301
- // });
302
-
303
- // var axlFunc = client.AXLAPIService.AXLPort[operation];
304
-
305
- // // 5. Add the correct namespace to the operation call
306
- // const nsContext = {
307
- // ns: `http://www.cisco.com/AXL/API/${options.version}`,
308
- // };
309
-
310
- // axlFunc(
311
- // tags,
312
- // function (err, result) {
313
- // if (err) {
314
- // reject(err);
315
- // }
316
- // if (result?.hasOwnProperty("return")) {
317
- // var output = result.return;
318
- // if (clean) {
319
- // cleanObj(output);
320
- // }
321
- // if (removeAttributes) {
322
- // cleanAttributes(output);
323
- // }
324
- // resolve(output);
325
- // } else {
326
- // reject("No return results");
327
- // }
328
- // },
329
- // // Add namespace mapping for the operation call
330
- // nsContext,
331
- // customRequestHeader
332
- // );
333
- // });
334
- // });
335
- // }
336
446
  }
337
447
 
338
448
  const nestedObj = (object) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cisco-axl",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "A library to make Cisco AXL a lot easier",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as soap from 'strong-soap';
2
2
  import * as path from 'path';
3
+ import * as https from 'https';
4
+ import { URL } from 'url';
3
5
 
4
6
  const WSDL = soap.soap.WSDL;
5
7
 
@@ -22,6 +24,28 @@ interface OperationOptions {
22
24
  removeAttributes?: boolean;
23
25
  }
24
26
 
27
+ /**
28
+ * Helper function to log debug messages only when DEBUG environment variable is set
29
+ * @param {string} message - The message to log
30
+ * @param {any} [data] - Optional data to log
31
+ */
32
+ const debugLog = (message: string, data?: any): void => {
33
+ // Get the DEBUG value, handling case-insensitivity
34
+ const debug = process.env.DEBUG;
35
+
36
+ // Check if DEBUG is set and is a truthy value (not 'false', 'no', '0', etc.)
37
+ const isDebugEnabled = debug &&
38
+ !['false', 'no', '0', 'off', 'n'].includes(debug.toLowerCase());
39
+
40
+ if (isDebugEnabled) {
41
+ if (data) {
42
+ console.log(`[AXL DEBUG] ${message}`, data);
43
+ } else {
44
+ console.log(`[AXL DEBUG] ${message}`);
45
+ }
46
+ }
47
+ };
48
+
25
49
  /**
26
50
  * Cisco axlService Service
27
51
  * This is a service class that uses fetch and promises to pull AXL data from Cisco CUCM
@@ -50,6 +74,94 @@ class axlService {
50
74
  };
51
75
  }
52
76
 
77
+ /**
78
+ * Test authentication credentials against the AXL endpoint
79
+ * @returns {Promise<boolean>} - Resolves to true if authentication is successful
80
+ * @memberof axlService
81
+ */
82
+ async testAuthentication(): Promise<boolean> {
83
+ try {
84
+ const authSuccess = await this._testAuthenticationDirectly();
85
+ if (!authSuccess) {
86
+ throw new Error("Authentication failed. Check username and password.");
87
+ }
88
+ return true;
89
+ } catch (error) {
90
+ throw new Error(`Authentication test failed: ${(error as Error).message}`);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Private method to test authentication using a simple GET request to the AXL endpoint
96
+ * @returns {Promise<boolean>} - Resolves with true if authentication successful, false otherwise
97
+ * @private
98
+ */
99
+ private async _testAuthenticationDirectly(): Promise<boolean> {
100
+ const options = this._OPTIONS;
101
+ const url = new URL(options.endpoint);
102
+
103
+ return new Promise<boolean>((resolve) => {
104
+ const authHeader = 'Basic ' + Buffer.from(`${options.username}:${options.password}`).toString('base64');
105
+
106
+ const reqOptions = {
107
+ hostname: url.hostname,
108
+ port: url.port || 8443,
109
+ path: url.pathname,
110
+ method: 'GET', // Simply use GET instead of POST
111
+ headers: {
112
+ 'Authorization': authHeader,
113
+ 'Connection': 'keep-alive'
114
+ },
115
+ rejectUnauthorized: false // For self-signed certificates
116
+ };
117
+
118
+ debugLog(`Testing authentication to ${url.hostname}:${url.port || 8443}${url.pathname}`);
119
+
120
+ const req = https.request(reqOptions, (res) => {
121
+ debugLog(`Authentication test response status: ${res.statusCode}`);
122
+
123
+ // Check status code for authentication failures
124
+ if (res.statusCode === 401 || res.statusCode === 403) {
125
+ debugLog('Authentication failed: Unauthorized status code');
126
+ resolve(false); // Authentication failed
127
+ return;
128
+ }
129
+
130
+ let responseData = '';
131
+
132
+ res.on('data', (chunk) => {
133
+ responseData += chunk;
134
+ });
135
+
136
+ res.on('end', () => {
137
+ // Check for the expected success message
138
+ const successIndicator = "Cisco CallManager: AXL Web Service";
139
+ if (responseData.includes(successIndicator)) {
140
+ debugLog('Authentication succeeded: Found success message');
141
+ resolve(true); // Authentication succeeded
142
+ } else if (responseData.includes('Authentication failed') ||
143
+ responseData.includes('401 Unauthorized') ||
144
+ responseData.includes('403 Forbidden')) {
145
+ debugLog('Authentication failed: Found failure message in response');
146
+ resolve(false); // Authentication failed
147
+ } else {
148
+ debugLog('Authentication status uncertain, response did not contain expected messages');
149
+ // If we're not sure, assume it failed to be safe
150
+ resolve(false);
151
+ }
152
+ });
153
+ });
154
+
155
+ req.on('error', (error) => {
156
+ console.error('Authentication test error:', error.message);
157
+ resolve(false);
158
+ });
159
+
160
+ // Since it's a GET request, we just end it without writing any data
161
+ req.end();
162
+ });
163
+ }
164
+
53
165
  /**
54
166
  * Returns a list of available AXL operations
55
167
  * @param {string} [filter] - Optional filter to narrow down operations
@@ -149,9 +261,17 @@ class axlService {
149
261
  * @returns {Promise<any>} - Result of the operation
150
262
  * @memberof axlService
151
263
  */
152
- executeOperation(operation: string, tags: any, opts?: OperationOptions): Promise<any> {
264
+ async executeOperation(operation: string, tags: any, opts?: OperationOptions): Promise<any> {
153
265
  const options = this._OPTIONS;
154
266
 
267
+ // First test authentication
268
+ debugLog(`Testing authentication before executing operation: ${operation}`);
269
+ const authSuccess = await this._testAuthenticationDirectly();
270
+ if (!authSuccess) {
271
+ throw new Error("Authentication failed. Check username and password.");
272
+ }
273
+ debugLog('Authentication successful, proceeding with operation');
274
+
155
275
  const clean = opts?.clean ?? false;
156
276
  const dataContainerIdentifierTails = opts?.dataContainerIdentifierTails ?? "_data";
157
277
  const removeAttributes = opts?.removeAttributes ?? false;
@@ -161,47 +281,227 @@ class axlService {
161
281
 
162
282
  return new Promise((resolve, reject) => {
163
283
  soap.soap.createClient(options.url, wsdlOptions, function (err: any, client: any) {
164
- const customRequestHeader = { connection: "keep-alive" };
165
-
166
284
  if (err) {
167
285
  reject(err);
168
286
  return;
169
287
  }
170
-
288
+
289
+ // Get the properly versioned namespace URL
290
+ const namespaceUrl = `http://www.cisco.com/AXL/API/${options.version}`;
291
+
292
+ // 1. Set envelope key
293
+ client.wsdl.options = {
294
+ ...client.wsdl.options,
295
+ envelopeKey: "soapenv", // Change default 'soap' to 'soapenv'
296
+ };
297
+
298
+ // 2. Define namespaces with the correct version
299
+ client.wsdl.definitions.xmlns.ns = namespaceUrl;
300
+
301
+ // Remove ns1 if it exists
302
+ if (client.wsdl.definitions.xmlns.ns1) {
303
+ delete client.wsdl.definitions.xmlns.ns1;
304
+ }
305
+
306
+ const customRequestHeader = {
307
+ connection: "keep-alive",
308
+ SOAPAction: `"CUCM:DB ver=${options.version} ${operation}"`,
309
+ };
310
+
171
311
  client.setSecurity(new soap.soap.BasicAuthSecurity(options.username, options.password));
172
312
  client.setEndpoint(options.endpoint);
173
313
 
174
314
  client.on("soapError", function (err: any) {
175
- reject(err.root.Envelope.Body.Fault);
315
+ // Check if this is an authentication error
316
+ if (err.root?.Envelope?.Body?.Fault) {
317
+ const fault = err.root.Envelope.Body.Fault;
318
+ const faultString = fault.faultstring || fault.faultString || '';
319
+
320
+ if (typeof faultString === 'string' &&
321
+ (faultString.includes('Authentication failed') ||
322
+ faultString.includes('credentials') ||
323
+ faultString.includes('authorize'))) {
324
+ reject(new Error("Authentication failed. Check username and password."));
325
+ } else {
326
+ reject(fault);
327
+ }
328
+ } else {
329
+ reject(err);
330
+ }
176
331
  });
177
332
 
333
+ // Check if the operation function exists
334
+ if (!client.AXLAPIService || !client.AXLAPIService.AXLPort || typeof client.AXLAPIService.AXLPort[operation] !== "function") {
335
+ // For operations that aren't found, try a manual approach
336
+ if (operation.startsWith("apply") || operation.startsWith("reset")) {
337
+ // Determine which parameter to use (name or uuid)
338
+ const operationObj = tags[operation] || tags;
339
+
340
+ // Check if uuid or name is provided
341
+ let paramTag, paramValue;
342
+
343
+ if (operationObj.uuid) {
344
+ paramTag = "uuid";
345
+ paramValue = operationObj.uuid;
346
+ } else {
347
+ paramTag = "name";
348
+ paramValue = operationObj.name;
349
+ }
350
+
351
+ const rawXml = `<?xml version="1.0" encoding="UTF-8"?>
352
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="${namespaceUrl}">
353
+ <soapenv:Header/>
354
+ <soapenv:Body>
355
+ <ns:${operation}>
356
+ <${paramTag}>${paramValue}</${paramTag}>
357
+ </ns:${operation}>
358
+ </soapenv:Body>
359
+ </soapenv:Envelope>`;
360
+
361
+ debugLog(`Executing manual XML request for operation: ${operation}`);
362
+
363
+ // Use client.request for direct XML request
364
+ (client as any)._request(
365
+ options.endpoint,
366
+ rawXml,
367
+ function (err: any, body: any, response: any) {
368
+ if (err) {
369
+ reject(err);
370
+ return;
371
+ }
372
+
373
+ // Check for authentication failures in the response
374
+ if (response && (response.statusCode === 401 || response.statusCode === 403)) {
375
+ reject(new Error("Authentication failed. Check username and password."));
376
+ return;
377
+ }
378
+
379
+ if (body && typeof body === 'string' &&
380
+ (body.includes('Authentication failed') ||
381
+ body.includes('401 Unauthorized') ||
382
+ body.includes('403 Forbidden'))) {
383
+ reject(new Error("Authentication failed. Check username and password."));
384
+ return;
385
+ }
386
+
387
+ // Parse the response
388
+ try {
389
+ // Don't automatically assume success
390
+ if (body && body.includes('Fault')) {
391
+ // Try to extract the fault message
392
+ const faultMatch = /<faultstring>(.*?)<\/faultstring>/;
393
+ const match = body.match(faultMatch);
394
+ if (match && match[1]) {
395
+ const faultString = match[1];
396
+ if (faultString.includes('Authentication failed') ||
397
+ faultString.includes('credentials') ||
398
+ faultString.includes('authorize')) {
399
+ reject(new Error("Authentication failed. Check username and password."));
400
+ } else {
401
+ reject(new Error(faultString));
402
+ }
403
+ } else {
404
+ reject(new Error('Unknown SOAP fault occurred'));
405
+ }
406
+ } else {
407
+ const result = { return: "Success" }; // Only report success if no errors found
408
+ resolve(result);
409
+ }
410
+ } catch (parseError) {
411
+ reject(parseError);
412
+ }
413
+ },
414
+ customRequestHeader
415
+ );
416
+
417
+ return;
418
+ } else {
419
+ reject(new Error(`Operation "${operation}" not found`));
420
+ return;
421
+ }
422
+ }
423
+
424
+ // Get the operation function - confirmed to exist at this point
178
425
  const axlFunc = client.AXLAPIService.AXLPort[operation];
179
426
 
427
+ // Define namespace context with the correct version
428
+ const nsContext = {
429
+ ns: namespaceUrl,
430
+ };
431
+
432
+ // Prepare message for specific operations
433
+ let message = tags;
434
+
435
+ // Handle operations that start with "apply" or "reset"
436
+ if (operation.startsWith("apply") || operation.startsWith("reset")) {
437
+ const operationKey = operation;
438
+
439
+ // If there's a nested structure, flatten it
440
+ if (tags[operationKey]) {
441
+ // Check if uuid or name is provided in the nested structure
442
+ if (tags[operationKey].uuid) {
443
+ message = { uuid: tags[operationKey].uuid };
444
+ } else if (tags[operationKey].name) {
445
+ message = { name: tags[operationKey].name };
446
+ }
447
+ // If neither uuid nor name is provided, try to use any available
448
+ else {
449
+ // Try to use uuid or name from the top level as fallback
450
+ message = tags.uuid ? { uuid: tags.uuid } : { name: tags.name };
451
+ }
452
+ }
453
+ }
454
+
455
+ debugLog(`Executing operation: ${operation}`);
456
+
457
+ // Execute the operation
180
458
  axlFunc(
181
- tags,
182
- function (err: any, result: any) {
459
+ message,
460
+ function (err: any, result: any, rawResponse: any) {
183
461
  if (err) {
462
+ // Check if this is an authentication error
463
+ if (err.message && (
464
+ err.message.includes('Authentication failed') ||
465
+ err.message.includes('401 Unauthorized') ||
466
+ err.message.includes('403 Forbidden') ||
467
+ err.message.includes('credentials'))) {
468
+ reject(new Error("Authentication failed. Check username and password."));
469
+ return;
470
+ }
471
+
472
+ // Check if the error response indicates authentication failure
473
+ if (err.response && (err.response.statusCode === 401 || err.response.statusCode === 403)) {
474
+ reject(new Error("Authentication failed. Check username and password."));
475
+ return;
476
+ }
477
+
184
478
  reject(err);
185
479
  return;
186
480
  }
187
481
 
482
+ // Check the raw response for auth failures (belt and suspenders approach)
483
+ if (rawResponse && typeof rawResponse === 'string' &&
484
+ (rawResponse.includes('Authentication failed') ||
485
+ rawResponse.includes('401 Unauthorized') ||
486
+ rawResponse.includes('403 Forbidden'))) {
487
+ reject(new Error("Authentication failed. Check username and password."));
488
+ return;
489
+ }
490
+
188
491
  if (result?.hasOwnProperty("return")) {
189
492
  const output = result.return;
190
-
191
493
  if (clean) {
192
494
  cleanObj(output);
193
495
  }
194
-
195
496
  if (removeAttributes) {
196
497
  cleanAttributes(output);
197
498
  }
198
-
199
499
  resolve(output);
200
500
  } else {
201
- reject("No return results");
501
+ resolve(result || { return: "Success" });
202
502
  }
203
503
  },
204
- null,
504
+ nsContext,
205
505
  customRequestHeader
206
506
  );
207
507
  });