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.
- package/.claude/settings.local.json +10 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +278 -6
- package/dist/index.js.map +1 -1
- package/index.js +204 -94
- package/package.json +1 -1
- package/src/index.ts +312 -12
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
463
|
+
resolve(result || { return: "Success" });
|
|
192
464
|
}
|
|
193
|
-
},
|
|
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
|
|
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
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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
|
-
|
|
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
|
-
|
|
181
|
-
|
|
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
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
501
|
+
resolve(result || { return: "Success" });
|
|
202
502
|
}
|
|
203
503
|
},
|
|
204
|
-
|
|
504
|
+
nsContext,
|
|
205
505
|
customRequestHeader
|
|
206
506
|
);
|
|
207
507
|
});
|