@manyos/smileconnect-api 1.69.1 → 1.71.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/app.js +16 -3
- package/conf/clients.json +154 -140
- package/conf/mapping.json +1 -1
- package/controller/cmdbobjectController.js +40 -14
- package/controller/relatedObjectsController.js +130 -126
- package/controller/scriptController.js +35 -8
- package/controller/scriptEndpointController.js +25 -0
- package/docs/_sidebar.md +1 -0
- package/docs/configuration/scriptEndpoints.md +64 -0
- package/docs/releases.md +15 -0
- package/package.json +1 -1
- package/routes/appConfigRoutes.js +25 -1
- package/routes/scriptEndpointRoutes.js +57 -0
- package/util/config.js +93 -4
- package/util/responsehandler.js +2 -2
package/app.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
const app = require('express')();
|
|
3
3
|
|
|
4
|
+
require('dotenv').config();
|
|
5
|
+
|
|
4
6
|
const path = require('path');
|
|
5
7
|
const log = require('@manyos/logger').setupLog('SMILEconnect', path.basename(__filename));
|
|
6
8
|
|
|
@@ -33,6 +35,7 @@ const ciRelationRoutes = require('./routes/ciRelationRoutes');
|
|
|
33
35
|
const peopleRelationRoutes = require('./routes/peopleRelationRoutes');
|
|
34
36
|
const appConfigRoutes = require('./routes/appConfigRoutes');
|
|
35
37
|
const scriptRoutes = require('./routes/scriptRoutes');
|
|
38
|
+
const scriptEndpointRoutes = require('./routes/scriptEndpointRoutes');
|
|
36
39
|
const customFormRoutes = require('./routes/customFormRoutes');
|
|
37
40
|
const relatedObjectsController = require('./controller/relatedObjectsController');
|
|
38
41
|
const addRequestId = require('express-request-id')();
|
|
@@ -57,8 +60,6 @@ https.globalAgent.maxSockets = maxHTTPSockets;
|
|
|
57
60
|
|
|
58
61
|
log.info('Set max HTTP(S) Sockets to', maxHTTPSockets);
|
|
59
62
|
|
|
60
|
-
require('dotenv').config();
|
|
61
|
-
|
|
62
63
|
// The signals we want to handle
|
|
63
64
|
// NOTE: although it is tempting, the SIGKILL signal (9) cannot be intercepted and handled
|
|
64
65
|
var signals = {
|
|
@@ -345,6 +346,18 @@ app.use('/v1/customForms/:formAlias', async function(req, res, next) {
|
|
|
345
346
|
next();
|
|
346
347
|
}, customFormRoutes);
|
|
347
348
|
|
|
349
|
+
app.use('/v1/scriptEndpoints/:endpointName', async function(req, res, next) {
|
|
350
|
+
const endpointName = req.params.endpointName
|
|
351
|
+
req.formConfig = {
|
|
352
|
+
formName: endpointName,
|
|
353
|
+
endpointName,
|
|
354
|
+
configName: endpointName,
|
|
355
|
+
}
|
|
356
|
+
req.globalScriptParams.formConfig = req.formConfig
|
|
357
|
+
req.parentEventBase = 'scriptEndoint'
|
|
358
|
+
next();
|
|
359
|
+
}, scriptEndpointRoutes);
|
|
360
|
+
|
|
348
361
|
//tickethandling worklogs
|
|
349
362
|
app.use('/v1/:ticketType/:parentId/worklogs', function(req, res, next) {
|
|
350
363
|
log.debug('params1', req.params);
|
|
@@ -418,4 +431,4 @@ server.timeout = 6000000;
|
|
|
418
431
|
//check config on startuo
|
|
419
432
|
config.checkConfig();
|
|
420
433
|
//for testing only
|
|
421
|
-
module.exports = app;
|
|
434
|
+
module.exports = app;
|
package/conf/clients.json
CHANGED
|
@@ -462,7 +462,8 @@
|
|
|
462
462
|
"fields": [],
|
|
463
463
|
"constants": [],
|
|
464
464
|
"scripts": {}
|
|
465
|
-
}
|
|
465
|
+
},
|
|
466
|
+
"scriptEndpoints": {}
|
|
466
467
|
}
|
|
467
468
|
},
|
|
468
469
|
{
|
|
@@ -923,7 +924,8 @@
|
|
|
923
924
|
"fields": [],
|
|
924
925
|
"constants": [],
|
|
925
926
|
"scripts": {}
|
|
926
|
-
}
|
|
927
|
+
},
|
|
928
|
+
"scriptEndpoints": {}
|
|
927
929
|
}
|
|
928
930
|
},
|
|
929
931
|
{
|
|
@@ -1383,7 +1385,144 @@
|
|
|
1383
1385
|
"fields": [],
|
|
1384
1386
|
"constants": [],
|
|
1385
1387
|
"scripts": {}
|
|
1386
|
-
}
|
|
1388
|
+
},
|
|
1389
|
+
"scriptEndpoints": {}
|
|
1390
|
+
}
|
|
1391
|
+
},
|
|
1392
|
+
{
|
|
1393
|
+
"name": "horsti",
|
|
1394
|
+
"config": {
|
|
1395
|
+
"cmdbobject": {
|
|
1396
|
+
"fields": [],
|
|
1397
|
+
"constants": [],
|
|
1398
|
+
"scripts": {},
|
|
1399
|
+
"basequery": ""
|
|
1400
|
+
},
|
|
1401
|
+
"change": {
|
|
1402
|
+
"basequery": "1=2",
|
|
1403
|
+
"fields": [],
|
|
1404
|
+
"constants": [],
|
|
1405
|
+
"scripts": {}
|
|
1406
|
+
},
|
|
1407
|
+
"changeWorklog": {
|
|
1408
|
+
"basequery": "1=2",
|
|
1409
|
+
"fields": [],
|
|
1410
|
+
"constants": [],
|
|
1411
|
+
"scripts": {},
|
|
1412
|
+
"attachmentScripts": {}
|
|
1413
|
+
},
|
|
1414
|
+
"incident": {
|
|
1415
|
+
"basequery": "1=1",
|
|
1416
|
+
"fields": [
|
|
1417
|
+
"Description"
|
|
1418
|
+
],
|
|
1419
|
+
"constants": [],
|
|
1420
|
+
"scripts": {}
|
|
1421
|
+
},
|
|
1422
|
+
"incidentWorklog": {
|
|
1423
|
+
"basequery": "1=2",
|
|
1424
|
+
"fields": [],
|
|
1425
|
+
"constants": [],
|
|
1426
|
+
"scripts": {},
|
|
1427
|
+
"attachmentScripts": {}
|
|
1428
|
+
},
|
|
1429
|
+
"person": {
|
|
1430
|
+
"basequery": "1=2",
|
|
1431
|
+
"fields": [],
|
|
1432
|
+
"constants": [],
|
|
1433
|
+
"scripts": {}
|
|
1434
|
+
},
|
|
1435
|
+
"problem": {
|
|
1436
|
+
"basequery": "1=2",
|
|
1437
|
+
"fields": [],
|
|
1438
|
+
"constants": [],
|
|
1439
|
+
"scripts": {}
|
|
1440
|
+
},
|
|
1441
|
+
"problemWorklog": {
|
|
1442
|
+
"basequery": "1=2",
|
|
1443
|
+
"fields": [],
|
|
1444
|
+
"constants": [],
|
|
1445
|
+
"scripts": {},
|
|
1446
|
+
"attachmentScripts": {}
|
|
1447
|
+
},
|
|
1448
|
+
"supportGroup": {
|
|
1449
|
+
"basequery": "1=2",
|
|
1450
|
+
"fields": [],
|
|
1451
|
+
"constants": [],
|
|
1452
|
+
"scripts": {}
|
|
1453
|
+
},
|
|
1454
|
+
"organisation": {
|
|
1455
|
+
"basequery": "1=2",
|
|
1456
|
+
"fields": [],
|
|
1457
|
+
"constants": [],
|
|
1458
|
+
"scripts": {}
|
|
1459
|
+
},
|
|
1460
|
+
"workOrder": {
|
|
1461
|
+
"basequery": "1=2",
|
|
1462
|
+
"fields": [],
|
|
1463
|
+
"constants": [],
|
|
1464
|
+
"scripts": {}
|
|
1465
|
+
},
|
|
1466
|
+
"workOrderWorklog": {
|
|
1467
|
+
"basequery": "1=2",
|
|
1468
|
+
"fields": [],
|
|
1469
|
+
"constants": [],
|
|
1470
|
+
"scripts": {},
|
|
1471
|
+
"attachmentScripts": {}
|
|
1472
|
+
},
|
|
1473
|
+
"task": {
|
|
1474
|
+
"basequery": "1=2",
|
|
1475
|
+
"fields": [],
|
|
1476
|
+
"constants": [],
|
|
1477
|
+
"scripts": {}
|
|
1478
|
+
},
|
|
1479
|
+
"taskWorklog": {
|
|
1480
|
+
"basequery": "1=2",
|
|
1481
|
+
"fields": [],
|
|
1482
|
+
"constants": [],
|
|
1483
|
+
"scripts": {},
|
|
1484
|
+
"attachmentScripts": {}
|
|
1485
|
+
},
|
|
1486
|
+
"flowBuilder": {
|
|
1487
|
+
"basequery": "1=2",
|
|
1488
|
+
"fields": [],
|
|
1489
|
+
"constants": [],
|
|
1490
|
+
"scripts": {}
|
|
1491
|
+
},
|
|
1492
|
+
"changeTemplate": {
|
|
1493
|
+
"basequery": "1=2",
|
|
1494
|
+
"fields": [],
|
|
1495
|
+
"constants": [],
|
|
1496
|
+
"scripts": {}
|
|
1497
|
+
},
|
|
1498
|
+
"incidentTemplate": {
|
|
1499
|
+
"basequery": "1=2",
|
|
1500
|
+
"fields": [],
|
|
1501
|
+
"constants": [],
|
|
1502
|
+
"scripts": {}
|
|
1503
|
+
},
|
|
1504
|
+
"problemTemplate": {
|
|
1505
|
+
"basequery": "1=2",
|
|
1506
|
+
"fields": [],
|
|
1507
|
+
"constants": [],
|
|
1508
|
+
"scripts": {}
|
|
1509
|
+
},
|
|
1510
|
+
"workOrderTemplate": {
|
|
1511
|
+
"basequery": "1=2",
|
|
1512
|
+
"fields": [],
|
|
1513
|
+
"constants": [],
|
|
1514
|
+
"scripts": {}
|
|
1515
|
+
},
|
|
1516
|
+
"taskTemplate": {
|
|
1517
|
+
"basequery": "1=2",
|
|
1518
|
+
"fields": [],
|
|
1519
|
+
"constants": [],
|
|
1520
|
+
"scripts": {}
|
|
1521
|
+
},
|
|
1522
|
+
"options": {
|
|
1523
|
+
"translateSelectionFields": true
|
|
1524
|
+
},
|
|
1525
|
+
"scriptEndpoints": {}
|
|
1387
1526
|
}
|
|
1388
1527
|
},
|
|
1389
1528
|
{
|
|
@@ -1843,7 +1982,8 @@
|
|
|
1843
1982
|
"fields": [],
|
|
1844
1983
|
"constants": [],
|
|
1845
1984
|
"scripts": {}
|
|
1846
|
-
}
|
|
1985
|
+
},
|
|
1986
|
+
"scriptEndpoints": {}
|
|
1847
1987
|
}
|
|
1848
1988
|
},
|
|
1849
1989
|
{
|
|
@@ -1854,7 +1994,8 @@
|
|
|
1854
1994
|
"clientLimit": 100000,
|
|
1855
1995
|
"impersonateUser": "rhannemann",
|
|
1856
1996
|
"allowDynamicImpersonate": true,
|
|
1857
|
-
"translateSelectionFields": true
|
|
1997
|
+
"translateSelectionFields": true,
|
|
1998
|
+
"openAPIDescription": "Custom text to be included in customer documentation."
|
|
1858
1999
|
},
|
|
1859
2000
|
"custom_Sample:Enrollments": {
|
|
1860
2001
|
"basequery": "1=1",
|
|
@@ -2548,142 +2689,15 @@
|
|
|
2548
2689
|
],
|
|
2549
2690
|
"constants": [],
|
|
2550
2691
|
"scripts": {}
|
|
2551
|
-
}
|
|
2552
|
-
}
|
|
2553
|
-
},
|
|
2554
|
-
{
|
|
2555
|
-
"name": "horsti",
|
|
2556
|
-
"config": {
|
|
2557
|
-
"cmdbobject": {
|
|
2558
|
-
"fields": [],
|
|
2559
|
-
"constants": [],
|
|
2560
|
-
"scripts": {},
|
|
2561
|
-
"basequery": ""
|
|
2562
|
-
},
|
|
2563
|
-
"change": {
|
|
2564
|
-
"basequery": "1=2",
|
|
2565
|
-
"fields": [],
|
|
2566
|
-
"constants": [],
|
|
2567
|
-
"scripts": {}
|
|
2568
|
-
},
|
|
2569
|
-
"changeWorklog": {
|
|
2570
|
-
"basequery": "1=2",
|
|
2571
|
-
"fields": [],
|
|
2572
|
-
"constants": [],
|
|
2573
|
-
"scripts": {},
|
|
2574
|
-
"attachmentScripts": {}
|
|
2575
|
-
},
|
|
2576
|
-
"incident": {
|
|
2577
|
-
"basequery": "1=1",
|
|
2578
|
-
"fields": [
|
|
2579
|
-
"Description"
|
|
2580
|
-
],
|
|
2581
|
-
"constants": [],
|
|
2582
|
-
"scripts": {}
|
|
2583
|
-
},
|
|
2584
|
-
"incidentWorklog": {
|
|
2585
|
-
"basequery": "1=2",
|
|
2586
|
-
"fields": [],
|
|
2587
|
-
"constants": [],
|
|
2588
|
-
"scripts": {},
|
|
2589
|
-
"attachmentScripts": {}
|
|
2590
|
-
},
|
|
2591
|
-
"person": {
|
|
2592
|
-
"basequery": "1=2",
|
|
2593
|
-
"fields": [],
|
|
2594
|
-
"constants": [],
|
|
2595
|
-
"scripts": {}
|
|
2596
2692
|
},
|
|
2597
|
-
"
|
|
2598
|
-
"
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
"basequery": "1=2",
|
|
2605
|
-
"fields": [],
|
|
2606
|
-
"constants": [],
|
|
2607
|
-
"scripts": {},
|
|
2608
|
-
"attachmentScripts": {}
|
|
2609
|
-
},
|
|
2610
|
-
"supportGroup": {
|
|
2611
|
-
"basequery": "1=2",
|
|
2612
|
-
"fields": [],
|
|
2613
|
-
"constants": [],
|
|
2614
|
-
"scripts": {}
|
|
2615
|
-
},
|
|
2616
|
-
"organisation": {
|
|
2617
|
-
"basequery": "1=2",
|
|
2618
|
-
"fields": [],
|
|
2619
|
-
"constants": [],
|
|
2620
|
-
"scripts": {}
|
|
2621
|
-
},
|
|
2622
|
-
"workOrder": {
|
|
2623
|
-
"basequery": "1=2",
|
|
2624
|
-
"fields": [],
|
|
2625
|
-
"constants": [],
|
|
2626
|
-
"scripts": {}
|
|
2627
|
-
},
|
|
2628
|
-
"workOrderWorklog": {
|
|
2629
|
-
"basequery": "1=2",
|
|
2630
|
-
"fields": [],
|
|
2631
|
-
"constants": [],
|
|
2632
|
-
"scripts": {},
|
|
2633
|
-
"attachmentScripts": {}
|
|
2634
|
-
},
|
|
2635
|
-
"task": {
|
|
2636
|
-
"basequery": "1=2",
|
|
2637
|
-
"fields": [],
|
|
2638
|
-
"constants": [],
|
|
2639
|
-
"scripts": {}
|
|
2640
|
-
},
|
|
2641
|
-
"taskWorklog": {
|
|
2642
|
-
"basequery": "1=2",
|
|
2643
|
-
"fields": [],
|
|
2644
|
-
"constants": [],
|
|
2645
|
-
"scripts": {},
|
|
2646
|
-
"attachmentScripts": {}
|
|
2647
|
-
},
|
|
2648
|
-
"flowBuilder": {
|
|
2649
|
-
"basequery": "1=2",
|
|
2650
|
-
"fields": [],
|
|
2651
|
-
"constants": [],
|
|
2652
|
-
"scripts": {}
|
|
2653
|
-
},
|
|
2654
|
-
"changeTemplate": {
|
|
2655
|
-
"basequery": "1=2",
|
|
2656
|
-
"fields": [],
|
|
2657
|
-
"constants": [],
|
|
2658
|
-
"scripts": {}
|
|
2659
|
-
},
|
|
2660
|
-
"incidentTemplate": {
|
|
2661
|
-
"basequery": "1=2",
|
|
2662
|
-
"fields": [],
|
|
2663
|
-
"constants": [],
|
|
2664
|
-
"scripts": {}
|
|
2665
|
-
},
|
|
2666
|
-
"problemTemplate": {
|
|
2667
|
-
"basequery": "1=2",
|
|
2668
|
-
"fields": [],
|
|
2669
|
-
"constants": [],
|
|
2670
|
-
"scripts": {}
|
|
2671
|
-
},
|
|
2672
|
-
"workOrderTemplate": {
|
|
2673
|
-
"basequery": "1=2",
|
|
2674
|
-
"fields": [],
|
|
2675
|
-
"constants": [],
|
|
2676
|
-
"scripts": {}
|
|
2677
|
-
},
|
|
2678
|
-
"taskTemplate": {
|
|
2679
|
-
"basequery": "1=2",
|
|
2680
|
-
"fields": [],
|
|
2681
|
-
"constants": [],
|
|
2682
|
-
"scripts": {}
|
|
2683
|
-
},
|
|
2684
|
-
"options": {
|
|
2685
|
-
"translateSelectionFields": true
|
|
2693
|
+
"scriptEndpoints": {
|
|
2694
|
+
"personData": {
|
|
2695
|
+
"options": {},
|
|
2696
|
+
"scripts": [
|
|
2697
|
+
"script1"
|
|
2698
|
+
]
|
|
2699
|
+
}
|
|
2686
2700
|
}
|
|
2687
2701
|
}
|
|
2688
2702
|
}
|
|
2689
|
-
]
|
|
2703
|
+
]
|
package/conf/mapping.json
CHANGED
|
@@ -41,6 +41,7 @@ function getCmdbObjects(config, category, ciIds, includeString, options, globalS
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
function getCIRelations(clientConfig, id) {
|
|
44
|
+
log.error('Search relations with', id);
|
|
44
45
|
const query = `('Source.InstanceId'=\"${id}\" OR 'Destination.InstanceId'=\"${id}\")AND('MarkAsDeleted'=$NULL$ OR 'MarkAsDeleted'=\"No\")`;
|
|
45
46
|
return cmdbCache.get(query, function () {
|
|
46
47
|
return new Promise((resolve, reject) => {
|
|
@@ -131,11 +132,35 @@ function queryCMDBObject(clientConfig, query, customFields, customOptions, inclu
|
|
|
131
132
|
fields = customFields;
|
|
132
133
|
}
|
|
133
134
|
|
|
135
|
+
const deleteFields = [];
|
|
136
|
+
|
|
137
|
+
const internalFieldsRequired = ['Class Id', 'Instance Id', 'Reconciliation Identity'];
|
|
138
|
+
|
|
139
|
+
internalFieldsRequired.forEach(internalRequiredField => {
|
|
140
|
+
if (!fields.includes(internalRequiredField)) {
|
|
141
|
+
fields.push(internalRequiredField);
|
|
142
|
+
deleteFields.push(internalRequiredField);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
/*
|
|
134
147
|
if (!fields.includes('Class Id') && includeArray.includes('classAttributes')) {
|
|
135
148
|
fields.push('Class Id');
|
|
136
149
|
deleteClassId = true;
|
|
137
150
|
log.debug('Add classId');
|
|
151
|
+
deleteFields.push('Class Id');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (!fields.includes('Instance Id')) {
|
|
155
|
+
fields.push('Instance Id');
|
|
156
|
+
deleteFields.push('Instance Id');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!fields.includes('Reconciliation Identity')) {
|
|
160
|
+
fields.push('Reconciliation Identity');
|
|
161
|
+
deleteFields.push('Reconciliation Identity');
|
|
138
162
|
}
|
|
163
|
+
*/
|
|
139
164
|
|
|
140
165
|
const options = {
|
|
141
166
|
...clientConfig.options, ...customOptions
|
|
@@ -158,7 +183,7 @@ function queryCMDBObject(clientConfig, query, customFields, customOptions, inclu
|
|
|
158
183
|
if (result && result.data && result.data.length) {
|
|
159
184
|
let x = 0;
|
|
160
185
|
for (x=0; x< result.data.length; x++) {
|
|
161
|
-
const cmdbObject = await handleCMDBObjectResult(result.data[x], mapping, clientConfig, includeArray, globalRelationObjects,
|
|
186
|
+
const cmdbObject = await handleCMDBObjectResult(result.data[x], mapping, clientConfig, includeArray, globalRelationObjects, deleteFields, globalScriptParams);
|
|
162
187
|
cmdbObjects.push(cmdbObject);
|
|
163
188
|
}
|
|
164
189
|
}
|
|
@@ -170,12 +195,13 @@ function queryCMDBObject(clientConfig, query, customFields, customOptions, inclu
|
|
|
170
195
|
});
|
|
171
196
|
}
|
|
172
197
|
|
|
173
|
-
async function handleCMDBObjectResult(cmdbObject, mapping, clientConfig, includeArray, globalRelationObjects,
|
|
174
|
-
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
198
|
+
async function handleCMDBObjectResult(cmdbObject, mapping, clientConfig, includeArray, globalRelationObjects, deleteFields, globalScriptParams) {
|
|
199
|
+
const internalReconId = cmdbObject['Reconciliation Identity'];
|
|
200
|
+
const internalId = cmdbObject['Instance Id'];
|
|
201
|
+
|
|
202
|
+
deleteFields.forEach(internalRequiredField => {
|
|
203
|
+
delete cmdbObject[internalRequiredField];
|
|
204
|
+
});
|
|
179
205
|
|
|
180
206
|
const scripts = clientConfig[CMDBOBJECT].scripts.GET;
|
|
181
207
|
//const fields = clientConfig[ticketConfig.requestType].fields
|
|
@@ -203,30 +229,30 @@ async function handleCMDBObjectResult(cmdbObject, mapping, clientConfig, include
|
|
|
203
229
|
cmdbObject.relations = {};
|
|
204
230
|
|
|
205
231
|
if (includeArray.includes('ciRelations')) {
|
|
206
|
-
const relations = await getCIRelations(clientConfig,
|
|
232
|
+
const relations = await getCIRelations(clientConfig, internalId);
|
|
207
233
|
cmdbObject.relations.ciRelations = relations;
|
|
208
234
|
}
|
|
209
235
|
if (includeArray.includes('ticketRelations')) {
|
|
210
|
-
const relations = await ticketCIRelationController.getCITicketRelations(
|
|
236
|
+
const relations = await ticketCIRelationController.getCITicketRelations(internalId, undefined, log);
|
|
211
237
|
cmdbObject.relations.ticketRelations = relations;
|
|
212
238
|
}
|
|
213
239
|
if (includeArray.includes('personRelations')) {
|
|
214
|
-
const relations = await getPeopleRelations(clientConfig,
|
|
240
|
+
const relations = await getPeopleRelations(clientConfig, internalReconId, 'People');
|
|
215
241
|
cmdbObject.relations.personRelations = relations;
|
|
216
242
|
}
|
|
217
243
|
|
|
218
244
|
if (includeArray.includes('supportGroupRelations')) {
|
|
219
|
-
const relations = await getPeopleRelations(clientConfig,
|
|
245
|
+
const relations = await getPeopleRelations(clientConfig, internalReconId, 'Support Group');
|
|
220
246
|
cmdbObject.relations.supportGroupRelations = relations;
|
|
221
247
|
}
|
|
222
248
|
|
|
223
249
|
if (includeArray.includes('organisationRelations')) {
|
|
224
|
-
const relations = await getPeopleRelations(clientConfig,
|
|
250
|
+
const relations = await getPeopleRelations(clientConfig, internalReconId, 'People Organization');
|
|
225
251
|
cmdbObject.relations.organisationRelations = relations;
|
|
226
252
|
}
|
|
227
253
|
|
|
228
254
|
if (includeArray.includes('classAttributes')) {
|
|
229
|
-
const classAttributes = await getCMDBObjectClassAttributes(
|
|
255
|
+
const classAttributes = await getCMDBObjectClassAttributes(internalId, classId, clientConfig);
|
|
230
256
|
cmdbObject = {
|
|
231
257
|
...cmdbObject, ...classAttributes
|
|
232
258
|
}
|
|
@@ -450,4 +476,4 @@ module.exports = {
|
|
|
450
476
|
applyMapping,
|
|
451
477
|
updateCmdbObject,
|
|
452
478
|
createCmdbObject
|
|
453
|
-
};
|
|
479
|
+
};
|
|
@@ -9,157 +9,161 @@ const config = require('../util/config');
|
|
|
9
9
|
const {getEventLog} = require("../util/eventLog");
|
|
10
10
|
|
|
11
11
|
async function getRelatedObjects(req, res, next) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
12
|
+
if (req.noInclude === true) {
|
|
13
|
+
next();
|
|
14
|
+
} else {
|
|
15
|
+
const log = getEventLog(req.log, path.basename(__filename));
|
|
16
|
+
log.debug('include Data', req.includeArray);
|
|
17
|
+
log.debug('include Objects', req.includeObjectsList);
|
|
18
|
+
|
|
19
|
+
if (req.result && req.includeObjectsList && req.includeArray) {
|
|
20
|
+
let result = {};
|
|
21
|
+
const includedObjects = req.includeObjectsList;
|
|
22
|
+
const clientConfig = req.user.config;
|
|
23
|
+
|
|
24
|
+
if (req.includeArray.includes('persons') && includedObjects.persons) {
|
|
25
|
+
const persons = [];
|
|
26
|
+
const personArray = Array.from(includedObjects.persons);
|
|
27
|
+
let x=0;
|
|
28
|
+
for (x=0; x < personArray.length; x++) {
|
|
29
|
+
const personId = personArray[x];
|
|
30
|
+
log.debug('searchPeople', personId);
|
|
31
|
+
const result = await orgdata.getPerson(clientConfig, personId);
|
|
32
|
+
const person = result.data;
|
|
33
|
+
log.debug('pers', person);
|
|
34
|
+
if (person) {
|
|
35
|
+
persons.push(person);
|
|
36
|
+
}
|
|
33
37
|
}
|
|
38
|
+
result.persons = persons;
|
|
34
39
|
}
|
|
35
|
-
result.persons = persons;
|
|
36
|
-
}
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
41
|
+
if (req.includeArray.includes('organisations') && includedObjects.organisations) {
|
|
42
|
+
const organisations = [];
|
|
43
|
+
const organisationArray = Array.from(includedObjects.organisations);
|
|
44
|
+
let x=0;
|
|
45
|
+
for (x=0; x < organisationArray.length; x++) {
|
|
46
|
+
const orgId = organisationArray[x];
|
|
47
|
+
log.debug('searchOrganisation', orgId);
|
|
48
|
+
const result = await orgdata.getOrganisation(clientConfig, orgId);
|
|
49
|
+
const org = result.data;
|
|
50
|
+
if (org) {
|
|
51
|
+
organisations.push(org);
|
|
52
|
+
}
|
|
49
53
|
}
|
|
54
|
+
result.organisations = organisations;
|
|
50
55
|
}
|
|
51
|
-
result.organisations = organisations;
|
|
52
|
-
}
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
if (req.includeArray.includes('supportGroups') && includedObjects.supportgroups) {
|
|
58
|
+
const supportGroups = [];
|
|
59
|
+
const supportGroupArray = Array.from(includedObjects.supportgroups);
|
|
60
|
+
let x=0;
|
|
61
|
+
for (x=0; x < supportGroupArray.length; x++) {
|
|
62
|
+
const groupId = supportGroupArray[x];
|
|
63
|
+
log.debug('searchSupportGroup', groupId);
|
|
64
|
+
const result = await orgdata.getSupportGroup(clientConfig, groupId);
|
|
65
|
+
const supportGroup = result.data;
|
|
66
|
+
if (supportGroup) {
|
|
67
|
+
supportGroups.push(supportGroup);
|
|
68
|
+
}
|
|
65
69
|
}
|
|
70
|
+
result.supportgroups = supportGroups;
|
|
66
71
|
}
|
|
67
|
-
result.supportgroups = supportGroups;
|
|
68
|
-
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
if (req.includeArray.includes('cmdbObjects') && includedObjects.cmdbObjects) {
|
|
74
|
+
const cmdbObjects = [];
|
|
75
|
+
let x=0;
|
|
76
|
+
const cmdbObjectArray = Array.from(includedObjects.cmdbObjects);
|
|
77
|
+
log.debug(cmdbObjectArray);
|
|
78
|
+
for (x=0; x < cmdbObjectArray.length; x++) {
|
|
79
|
+
const ciId = cmdbObjectArray[x];
|
|
80
|
+
log.debug('searchCMDBObject', ciId);
|
|
81
|
+
const cmdbObject = await cmdbObjectController.getCmdbObject(clientConfig, ciId, undefined, undefined, req.globalScriptParams);
|
|
82
|
+
if (cmdbObjects !== null && cmdbObjects !== undefined && cmdbObject && cmdbObject.data) {
|
|
83
|
+
cmdbObjects.push(cmdbObject.data);
|
|
84
|
+
}
|
|
81
85
|
}
|
|
86
|
+
result.cmdbObjects = cmdbObjects;
|
|
82
87
|
}
|
|
83
|
-
result.cmdbObjects = cmdbObjects;
|
|
84
|
-
}
|
|
85
88
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
if (req.includeArray.includes('incidents') && includedObjects.incidents) {
|
|
90
|
+
const incidents = [];
|
|
91
|
+
const incidentArray = Array.from(includedObjects.incidents);
|
|
92
|
+
let x=0;
|
|
93
|
+
for (x=0; x < incidentArray.length; x++) {
|
|
94
|
+
const id = incidentArray[x];
|
|
95
|
+
log.debug('searchIncident', id);
|
|
96
|
+
const ticketConfig = config.ticketConfig["incidents"];
|
|
97
|
+
const result = await ticketController.getTicket(ticketConfig, clientConfig, id, undefined, undefined, req.globalScriptParams);
|
|
98
|
+
if (result && result.data) {
|
|
99
|
+
incidents.push(result.data);
|
|
100
|
+
}
|
|
97
101
|
}
|
|
102
|
+
result.incidents = incidents;
|
|
98
103
|
}
|
|
99
|
-
result.incidents = incidents;
|
|
100
|
-
}
|
|
101
104
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
105
|
+
if (req.includeArray.includes('workOrders') && includedObjects.workOrders) {
|
|
106
|
+
const tickets = [];
|
|
107
|
+
const ticketIdArray = Array.from(includedObjects.workOrders);
|
|
108
|
+
let x=0;
|
|
109
|
+
for (x=0; x < ticketIdArray.length; x++) {
|
|
110
|
+
const id = ticketIdArray[x];
|
|
111
|
+
log.debug('searchWorkOrder', id);
|
|
112
|
+
const ticketConfig = config.ticketConfig["workorders"];
|
|
113
|
+
const result = await ticketController.getTicket(ticketConfig, clientConfig, id, undefined, undefined, req.globalScriptParams)
|
|
114
|
+
if (result && result.data) {
|
|
115
|
+
tickets.push(result.data);
|
|
116
|
+
}
|
|
113
117
|
}
|
|
118
|
+
result.workOrders = tickets;
|
|
114
119
|
}
|
|
115
|
-
result.workOrders = tickets;
|
|
116
|
-
}
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
121
|
+
if (req.includeArray.includes('problems') && includedObjects.problems) {
|
|
122
|
+
const tickets = [];
|
|
123
|
+
const ticketIdArray = Array.from(includedObjects.problems);
|
|
124
|
+
let x=0;
|
|
125
|
+
for (x=0; x < ticketIdArray.length; x++) {
|
|
126
|
+
const id = ticketIdArray[x];
|
|
127
|
+
log.debug('searchProblem', id);
|
|
128
|
+
const ticketConfig = config.ticketConfig["problems"];
|
|
129
|
+
const result = await ticketController.getTicket(ticketConfig, clientConfig, id, undefined, undefined, req.globalScriptParams)
|
|
130
|
+
if (result && result.data) {
|
|
131
|
+
tickets.push(result.data);
|
|
132
|
+
}
|
|
129
133
|
}
|
|
134
|
+
result.problems = tickets;
|
|
130
135
|
}
|
|
131
|
-
result.problems = tickets;
|
|
132
|
-
}
|
|
133
136
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
if (req.includeArray.includes('changes') && includedObjects.changes) {
|
|
138
|
+
const tickets = [];
|
|
139
|
+
const ticketIdArray = Array.from(includedObjects.changes);
|
|
140
|
+
let x=0;
|
|
141
|
+
for (x=0; x < ticketIdArray.length; x++) {
|
|
142
|
+
const id = ticketIdArray[x];
|
|
143
|
+
log.debug('searchChange', id);
|
|
144
|
+
const ticketConfig = config.ticketConfig["changes"];
|
|
145
|
+
const result = await ticketController.getTicket(ticketConfig, clientConfig, id, undefined, undefined, req.globalScriptParams)
|
|
146
|
+
if (result && result.data) {
|
|
147
|
+
tickets.push(result.data);
|
|
148
|
+
}
|
|
145
149
|
}
|
|
150
|
+
result.changes = tickets;
|
|
146
151
|
}
|
|
147
|
-
result.changes = tickets;
|
|
148
|
-
}
|
|
149
152
|
|
|
150
|
-
|
|
153
|
+
log.debug('done');
|
|
151
154
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
//backward compatibility
|
|
156
|
+
if (req.includeObjects || (req.body && req.body.getRelations)) {
|
|
157
|
+
replaceAllKeys(req.result.data);
|
|
158
|
+
}
|
|
159
|
+
req.result.included = result || {};
|
|
160
|
+
next();
|
|
161
|
+
} else {
|
|
162
|
+
if (req.result) {
|
|
163
|
+
req.result.included = {};
|
|
164
|
+
}
|
|
165
|
+
next();
|
|
161
166
|
}
|
|
162
|
-
next();
|
|
163
167
|
}
|
|
164
168
|
}
|
|
165
169
|
|
|
@@ -223,4 +227,4 @@ async function addLinks(req, res, next) {
|
|
|
223
227
|
|
|
224
228
|
module.exports = {
|
|
225
229
|
getRelatedObjects, addLinks
|
|
226
|
-
}
|
|
230
|
+
}
|
|
@@ -56,7 +56,7 @@ function recFindByExt(base,ext,files,result) {
|
|
|
56
56
|
return result
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
async function executeScriptInternal(scriptId, requestData, params, executedByScript, clientId, globalScriptParams) {
|
|
59
|
+
async function executeScriptInternal(scriptId, requestData, params, executedByScript, clientId, globalScriptParams, customResponse) {
|
|
60
60
|
|
|
61
61
|
const code = await getGlobalScript(scriptId);
|
|
62
62
|
|
|
@@ -64,14 +64,14 @@ async function executeScriptInternal(scriptId, requestData, params, executedBySc
|
|
|
64
64
|
throw (`Script ${scriptId} does not exist!`);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
return executeCode(code, requestData, params, null, executedByScript, clientId, scriptId, globalScriptParams);
|
|
67
|
+
return executeCode(code, requestData, params, null, executedByScript, clientId, scriptId, globalScriptParams, customResponse);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
async function executeScript(scriptId, requestData, params, clientId, globalScriptParams) {
|
|
71
|
-
return executeScriptInternal(scriptId, requestData, params, false, clientId, globalScriptParams)
|
|
70
|
+
async function executeScript(scriptId, requestData, params, clientId, globalScriptParams, customResponse) {
|
|
71
|
+
return executeScriptInternal(scriptId, requestData, params, false, clientId, globalScriptParams, customResponse)
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
async function executeCode(code, requestData, params, logStream, executedByScript, clientId, scriptId, globalScriptParams) {
|
|
74
|
+
async function executeCode(code, requestData, params, logStream, executedByScript, clientId, scriptId, globalScriptParams, customResponse) {
|
|
75
75
|
const log = require('@manyos/logger').setupLog('SMILEconnect_Script_' + scriptId);
|
|
76
76
|
//todo should only be added once
|
|
77
77
|
/*if (logStream) {
|
|
@@ -81,7 +81,7 @@ async function executeCode(code, requestData, params, logStream, executedByScrip
|
|
|
81
81
|
//try to set user data for sandbox
|
|
82
82
|
|
|
83
83
|
async function executeScriptByScript(scriptId, requestData, params) {
|
|
84
|
-
return executeScriptInternal(scriptId, requestData, params, true, clientId, globalScriptParams)
|
|
84
|
+
return executeScriptInternal(scriptId, requestData, params, true, clientId, globalScriptParams, customResponse)
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
const sandbox = {
|
|
@@ -98,7 +98,8 @@ async function executeCode(code, requestData, params, logStream, executedByScrip
|
|
|
98
98
|
globalScriptParams,
|
|
99
99
|
env: process.env,
|
|
100
100
|
fetch:fetch,
|
|
101
|
-
uid:v4
|
|
101
|
+
uid:v4,
|
|
102
|
+
customResponse
|
|
102
103
|
};
|
|
103
104
|
|
|
104
105
|
sandbox.executedByScript = executedByScript === true;
|
|
@@ -255,6 +256,29 @@ async function getUsage(scriptId) {
|
|
|
255
256
|
})
|
|
256
257
|
}
|
|
257
258
|
})
|
|
259
|
+
//log.debug("ScriptEndpoints: ", client.config.scriptEndpoints);
|
|
260
|
+
if (client.config && client.config.scriptEndpoints) {
|
|
261
|
+
//log.debug("ScriptEndpoints: ", client.config.scriptEndpoints);
|
|
262
|
+
Object.keys(client.config.scriptEndpoints).forEach(scriptEndpoint => {
|
|
263
|
+
const endpointScripts = client.config.scriptEndpoints[scriptEndpoint].scripts;
|
|
264
|
+
log.debug("EndpointScripts", scriptEndpoint, endpointScripts);
|
|
265
|
+
if (endpointScripts && Array.isArray(endpointScripts)) {
|
|
266
|
+
endpointScripts.forEach(script => {
|
|
267
|
+
if (script === scriptId) {
|
|
268
|
+
const usage = {
|
|
269
|
+
client: client.name,
|
|
270
|
+
key: scriptEndpoint,
|
|
271
|
+
operation: "POST",
|
|
272
|
+
scriptType: "SCRIPTENDPOINT",
|
|
273
|
+
script
|
|
274
|
+
}
|
|
275
|
+
log.debug('script found', usage);
|
|
276
|
+
usages.push(usage);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
258
282
|
});
|
|
259
283
|
return usages;
|
|
260
284
|
}
|
|
@@ -288,13 +312,16 @@ async function getGlobalScripts() {
|
|
|
288
312
|
}
|
|
289
313
|
|
|
290
314
|
async function runScripts(scripts, data, clientId, globalScriptParams) {
|
|
315
|
+
let customResponse = {};
|
|
291
316
|
try {
|
|
292
317
|
for (let x = 0; x < scripts.length; x++) {
|
|
293
|
-
await executeScript(scripts[x], data, undefined, clientId, globalScriptParams);
|
|
318
|
+
await executeScript(scripts[x], data, undefined, clientId, globalScriptParams, customResponse);
|
|
294
319
|
}
|
|
295
320
|
} catch (error) {
|
|
296
321
|
throw error;
|
|
297
322
|
}
|
|
323
|
+
log.debug("customResponse:", customResponse);
|
|
324
|
+
return customResponse;
|
|
298
325
|
}
|
|
299
326
|
|
|
300
327
|
module.exports = {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require('dotenv').config();
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const log = require('@manyos/logger').setupLog('SMILEconnect', path.basename(__filename));
|
|
4
|
+
const config = require('../util/config');
|
|
5
|
+
const CONSTANTS = require('../util/constants');
|
|
6
|
+
const scriptController = require('./scriptController');
|
|
7
|
+
|
|
8
|
+
async function executeScripts(clientConfig, endpointName, data, globalScriptParams) {
|
|
9
|
+
if (!clientConfig.scriptEndpoints || !clientConfig.scriptEndpoints[endpointName]) {
|
|
10
|
+
throw new Error("No Endpoint config found for endpoint " + endpointName);
|
|
11
|
+
}
|
|
12
|
+
const scripts = clientConfig.scriptEndpoints[endpointName].scripts;
|
|
13
|
+
if (!scripts || !Array.isArray(scripts)) {
|
|
14
|
+
throw new Error("No Scripts defined for endpoint " + endpointName);
|
|
15
|
+
} else if (scripts.length === 0) {
|
|
16
|
+
return {message: "No scripts defined. Nothing to do."}
|
|
17
|
+
} else {
|
|
18
|
+
log.debug(`Run scripts for endpoint ${exports} -> ${scripts}`);
|
|
19
|
+
return await scriptController.runScripts(scripts, data, clientConfig.clientId, globalScriptParams);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
executeScripts
|
|
25
|
+
};
|
package/docs/_sidebar.md
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ScriptEnpoints
|
|
2
|
+
|
|
3
|
+
Script Endpoints in SMILEconnect enable you to define custom API endpoints that execute JavaScript logic directly upon invocation. This allows you to automate complex processes, integrate external systems, and respond with dynamic results — all without external middleware.
|
|
4
|
+
|
|
5
|
+
They are accessible at the url: */v1/scriptEndpoints/endpointName* via POST Action.
|
|
6
|
+
|
|
7
|
+
Sample Script:
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Access incoming request data
|
|
11
|
+
let userInput = requestData.name;
|
|
12
|
+
|
|
13
|
+
// Process data (example logic)
|
|
14
|
+
let greeting = "Hello, " + userInput + "!";
|
|
15
|
+
|
|
16
|
+
// Define custom response
|
|
17
|
+
customResponse.data = {
|
|
18
|
+
"message": greeting,
|
|
19
|
+
"timestamp": new Date().toISOString()
|
|
20
|
+
}
|
|
21
|
+
customResponse.code = 200;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The incoming request payload is automatically available via the variable requestData.
|
|
25
|
+
|
|
26
|
+
Data can be used for validation, processing, or triggering actions within BMC ITSM.
|
|
27
|
+
|
|
28
|
+
Use the global customResponse object to return results:
|
|
29
|
+
|
|
30
|
+
* customResponse.data -> JSON object returned in the HTTP response body.
|
|
31
|
+
* customResponse.code -> HTTP status code to return (e.g., 200, 400, 500). Defaults to 200.
|
|
32
|
+
|
|
33
|
+
Advanced Sample Script:
|
|
34
|
+
|
|
35
|
+
```javascript
|
|
36
|
+
//Advanced script example
|
|
37
|
+
|
|
38
|
+
const persons = await adapter.remedy.search('CTM:People', `1=1`, "Full Name, Organization", {limit:1000});
|
|
39
|
+
const organisations = await adapter.remedy.search('CTM:People Organization', `1=1`, "Full Name, Organization", {limit:1000});
|
|
40
|
+
|
|
41
|
+
function lookupOrgId(orgName) {
|
|
42
|
+
for (let y = 0; y < organisations.data.length; y++) {
|
|
43
|
+
const organisation = organisations.data[y];
|
|
44
|
+
if (organisation['Organization'] === orgName) {
|
|
45
|
+
return organisation['People Organization ID'];
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return "not found";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
//loop als Persons and lookup org id
|
|
52
|
+
for (let x = 0; x < persons.data.length; x++) {
|
|
53
|
+
const person = persons.data[x];
|
|
54
|
+
person.orgId = lookupOrgId(person.Organization);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
customResponse.data = {
|
|
58
|
+
"dataReceived": requestData,
|
|
59
|
+
organisations: organisations.data,
|
|
60
|
+
"persons": persons.data
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
customResponse.code = 203
|
|
64
|
+
```
|
package/docs/releases.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
3
|
## API
|
|
4
|
+
### 1.71.0 - 25.03.25
|
|
5
|
+
Add Script Endpoints
|
|
6
|
+
Add openAPIDescription attribute to client config
|
|
7
|
+
|
|
8
|
+
### 1.70.0 - 07.01.25
|
|
9
|
+
Fixed mapping in CI Classes for Attributes Instance ID and Reconciliation ID no longer required.
|
|
10
|
+
|
|
4
11
|
### 1.69.0 - 23.07.24
|
|
5
12
|
Remove unnecessary writes during config checks on startup.
|
|
6
13
|
|
|
@@ -210,6 +217,9 @@ e.g.
|
|
|
210
217
|
*/v1/incidents?impersonateUser=abc123
|
|
211
218
|
|
|
212
219
|
## Event Manager
|
|
220
|
+
### 1.37.0 - 15.01.25
|
|
221
|
+
Add instanceid to eventdata.
|
|
222
|
+
|
|
213
223
|
### 1.35.0 - 29.04.24
|
|
214
224
|
Add attachment support for outbound mappings
|
|
215
225
|
|
|
@@ -268,6 +278,11 @@ Update Record added to [Remedy Adapter](adapter#remedy).
|
|
|
268
278
|
The eventmanager will check all outbound webhooks for an event. If one fails, the whole Event will be set to error and the details will be added to the error message.
|
|
269
279
|
|
|
270
280
|
## GUI
|
|
281
|
+
### 1.13.4 - 20.02.25
|
|
282
|
+
Fixed: Custom mapping upload in Code viewer is not working
|
|
283
|
+
|
|
284
|
+
### 1.13.1 - 30.01.25
|
|
285
|
+
Feat: Update modules & improvments to monitor config.
|
|
271
286
|
|
|
272
287
|
### 1.11.0 - 05.04.23
|
|
273
288
|
Feat: Add REACT_APP_CLIENT_SECRET Parameter to allow confidential SSO clients
|
package/package.json
CHANGED
|
@@ -383,6 +383,30 @@ module.exports = (function() {
|
|
|
383
383
|
}
|
|
384
384
|
});
|
|
385
385
|
|
|
386
|
+
routes.get('/clients/:id/scriptUsage', isAuthorizedAdmin,
|
|
387
|
+
function (req, res, next) {
|
|
388
|
+
const id = req.params.id;
|
|
389
|
+
setEventData(
|
|
390
|
+
req,
|
|
391
|
+
CONSTANTS.EVENT_BASE_APC,
|
|
392
|
+
CONSTANTS.EVENT_ACTION_QUERY,
|
|
393
|
+
CONSTANTS.FORM_APC_CLIENTS,
|
|
394
|
+
id
|
|
395
|
+
);
|
|
396
|
+
try {
|
|
397
|
+
const clientScripts = config.getClientScripts(id);
|
|
398
|
+
if (clientScripts == null || clientScripts == undefined) {
|
|
399
|
+
req.responseStatus = 404;
|
|
400
|
+
}
|
|
401
|
+
req.result = {
|
|
402
|
+
"data": clientScripts
|
|
403
|
+
};
|
|
404
|
+
next();
|
|
405
|
+
} catch (error) {
|
|
406
|
+
next(error);
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
386
410
|
/*routes.get('/clients/:id/designPackage',
|
|
387
411
|
async function (req, res, next) {
|
|
388
412
|
const id = req.params.id;
|
|
@@ -507,4 +531,4 @@ module.exports = (function() {
|
|
|
507
531
|
});
|
|
508
532
|
|
|
509
533
|
return routes;
|
|
510
|
-
})();
|
|
534
|
+
})();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const log = require('@manyos/logger').setupLog('SMILEconnect', path.basename(__filename));
|
|
3
|
+
const {body, validationResult, oneOf} = require('express-validator/check');
|
|
4
|
+
const scriptEnpointController = require('../controller/scriptEndpointController');
|
|
5
|
+
const eventLog = require('../controller/eventLogController');
|
|
6
|
+
const CONSTANTS = require('../util/constants');
|
|
7
|
+
|
|
8
|
+
module.exports = (function() {
|
|
9
|
+
const routes = require('express').Router();
|
|
10
|
+
|
|
11
|
+
const errorFormatter = ({location, msg, param, value, nestedErrors}) => {
|
|
12
|
+
// Build your resulting errors however you want! String, object, whatever - it works!
|
|
13
|
+
return `${location}[${param}]: ${msg}`;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
routes.post('/', function (req, res, next) {
|
|
17
|
+
const endpointName = req.formConfig.endpointName;
|
|
18
|
+
log.debug('Start endpoint WF', endpointName)
|
|
19
|
+
//todo Errorhandling prüfen. Wenn parameter fehlen, wird nicht zurückgegeben welche
|
|
20
|
+
const origData = JSON.parse(JSON.stringify(req.body));
|
|
21
|
+
const includeString = req.query.include;
|
|
22
|
+
eventLog.setEventData(
|
|
23
|
+
req,
|
|
24
|
+
req.parentEventBase,
|
|
25
|
+
CONSTANTS.EVENT_ACTION_CREATE,
|
|
26
|
+
req.formConfig.endpointName,
|
|
27
|
+
null,
|
|
28
|
+
origData
|
|
29
|
+
);
|
|
30
|
+
const errors = validationResult(req).formatWith(errorFormatter);
|
|
31
|
+
if (!errors.isEmpty()) {
|
|
32
|
+
req.errorStatus = 422;
|
|
33
|
+
next(errors.array());
|
|
34
|
+
} else if (!req.user.config || !req.user.config.scriptEndpoints || !req.user.config.scriptEndpoints[endpointName]) {
|
|
35
|
+
req.errorStatus = 404;
|
|
36
|
+
next("Endpoint not defined");
|
|
37
|
+
} else {
|
|
38
|
+
scriptEnpointController.executeScripts(req.user.config, endpointName, req.body, req.globalScriptParams).then(async function (scriptResult) {
|
|
39
|
+
if (scriptResult) {
|
|
40
|
+
if (scriptResult.data) {
|
|
41
|
+
req.result = scriptResult.data;
|
|
42
|
+
}
|
|
43
|
+
if (scriptResult.code) {
|
|
44
|
+
req.responseStatus = scriptResult.code;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
req.noInclude = true;
|
|
48
|
+
log.debug("Scripts run successful", scriptResult);
|
|
49
|
+
next();
|
|
50
|
+
}).catch(function (reason) {
|
|
51
|
+
next(reason);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return routes;
|
|
57
|
+
})();
|
package/util/config.js
CHANGED
|
@@ -270,11 +270,11 @@ function checkClientConfig(client) {
|
|
|
270
270
|
const clientConfigKeys = Object.keys(clientConfig);
|
|
271
271
|
//delete too many
|
|
272
272
|
clientConfigKeys.forEach(key=>{
|
|
273
|
-
if (!clientKeys.includes(key) && !(key === 'options') && !(key.startsWith('custom_'))) {
|
|
273
|
+
if (!clientKeys.includes(key) && !(key === 'options') && !(key.startsWith('custom_')) && !(key === 'scriptEndpoints')) {
|
|
274
274
|
log.warn('delete from clientconfig', key);
|
|
275
275
|
delete clientConfig[key];
|
|
276
276
|
updateRequired = true;
|
|
277
|
-
} else if (clientKeys.includes(key) && !(key === 'options')) {
|
|
277
|
+
} else if (clientKeys.includes(key) && !(key === 'options') && !(key === 'scriptEndpoints') ) {
|
|
278
278
|
if (!(typeof clientConfig[key].basequery === 'string')) {
|
|
279
279
|
clientConfig[key].basequery = '';
|
|
280
280
|
log.warn('add basequery', key);
|
|
@@ -316,6 +316,11 @@ function checkClientConfig(client) {
|
|
|
316
316
|
updateRequired = true;
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
if (!clientConfig.scriptEndpoints) {
|
|
320
|
+
clientConfig.scriptEndpoints = {};
|
|
321
|
+
updateRequired = true;
|
|
322
|
+
}
|
|
323
|
+
|
|
319
324
|
if (clientConfig.options.translateSelectionFields === undefined) {
|
|
320
325
|
clientConfig.options.translateSelectionFields = true;
|
|
321
326
|
updateRequired = true;
|
|
@@ -372,6 +377,11 @@ async function getDesignPackage(clientId) {
|
|
|
372
377
|
}
|
|
373
378
|
|
|
374
379
|
const clientConfig = await getClientConfig(clientId)
|
|
380
|
+
|
|
381
|
+
if (clientConfig && clientConfig.options && clientConfig.options.openAPIDescription) {
|
|
382
|
+
info.description = clientConfig.options.openAPIDescription;
|
|
383
|
+
}
|
|
384
|
+
|
|
375
385
|
const schemas = {}
|
|
376
386
|
let paths = {}
|
|
377
387
|
|
|
@@ -449,6 +459,27 @@ async function getDesignPackage(clientId) {
|
|
|
449
459
|
}
|
|
450
460
|
}
|
|
451
461
|
|
|
462
|
+
//generate docs for scriptEndpoints
|
|
463
|
+
if (clientConfig && clientConfig.scriptEndpoints) {
|
|
464
|
+
//const customFormMappings = await getCustomFormMapping()
|
|
465
|
+
const scriptKeys = Object.keys(clientConfig.scriptEndpoints)
|
|
466
|
+
for (let x=0; x < scriptKeys.length; x++) {
|
|
467
|
+
const key = scriptKeys[x]
|
|
468
|
+
log.debug('key', key)
|
|
469
|
+
//schemas[key] = await getObjectSchema(clientObjectConfig.fields, customFormMappings[key].mapping, formName)
|
|
470
|
+
const pathDef = {}
|
|
471
|
+
pathDef[`/v1/scriptEndpoints/${key}`] = {};
|
|
472
|
+
pathDef[`/v1/scriptEndpoints/${key}`].post = {
|
|
473
|
+
tags: [key],
|
|
474
|
+
summary: `Run scripts associated with this endpoint`,
|
|
475
|
+
description: "Run scripts associated that are associated with this endpoint. The return Schema is defined in the scripts.",
|
|
476
|
+
parameters: [],
|
|
477
|
+
responses: await getApiResponse("scriptEndpoint_" + key, true)
|
|
478
|
+
}
|
|
479
|
+
schemas["scriptEndpoint_" + key] = {};
|
|
480
|
+
paths = {...paths, ... pathDef}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
452
483
|
|
|
453
484
|
//generate docs for cmdb
|
|
454
485
|
const cmdbMapping = getDeprecatedMappingAsCustom('cmdbobject')
|
|
@@ -759,6 +790,63 @@ const ticketConfig = {
|
|
|
759
790
|
}
|
|
760
791
|
};
|
|
761
792
|
|
|
793
|
+
function getClientScripts(clientId) {
|
|
794
|
+
const usages = [];
|
|
795
|
+
const client = getClient(clientId);
|
|
796
|
+
log.debug("Search scripts for " + clientId);
|
|
797
|
+
//check each client entry for scripts
|
|
798
|
+
Object.keys(client.config).forEach(clientKey => {
|
|
799
|
+
const clientScripts = client.config[clientKey].scripts;
|
|
800
|
+
//check all script operations
|
|
801
|
+
if (clientScripts) {
|
|
802
|
+
Object.keys(clientScripts).forEach(operation => {
|
|
803
|
+
//log.debug ('ops', operation);
|
|
804
|
+
const opsScripts = clientScripts[operation];
|
|
805
|
+
Object.keys(opsScripts).forEach(scriptType => {
|
|
806
|
+
const opsTypeScripts = opsScripts[scriptType]
|
|
807
|
+
//log.debug ('opsTypeSc', opsTypeScripts);
|
|
808
|
+
if (opsTypeScripts && Array.isArray(opsTypeScripts)) {
|
|
809
|
+
opsTypeScripts.forEach(script => {
|
|
810
|
+
//log.debug (scriptType, scriptId, script);
|
|
811
|
+
const usage = {
|
|
812
|
+
client: client.name,
|
|
813
|
+
key: clientKey,
|
|
814
|
+
operation,
|
|
815
|
+
scriptType,
|
|
816
|
+
script
|
|
817
|
+
}
|
|
818
|
+
log.debug ('script found', usage);
|
|
819
|
+
usages.push(usage);
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
})
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
//log.debug("ScriptEndpoints: ", client.config.scriptEndpoints);
|
|
827
|
+
if (client && client.config && client.config.scriptEndpoints) {
|
|
828
|
+
//log.debug("ScriptEndpoints: ", client.config.scriptEndpoints);
|
|
829
|
+
Object.keys(client.config.scriptEndpoints).forEach(scriptEndpoint => {
|
|
830
|
+
const endpointScripts = client.config.scriptEndpoints[scriptEndpoint].scripts;
|
|
831
|
+
log.debug("EndpointScripts", scriptEndpoint, endpointScripts);
|
|
832
|
+
if (endpointScripts && Array.isArray(endpointScripts)) {
|
|
833
|
+
endpointScripts.forEach(script => {
|
|
834
|
+
const usage = {
|
|
835
|
+
client: client.name,
|
|
836
|
+
key: scriptEndpoint,
|
|
837
|
+
operation: "POST",
|
|
838
|
+
scriptType: "SCRIPTENDPOINT",
|
|
839
|
+
script
|
|
840
|
+
}
|
|
841
|
+
log.debug ('script found', usage);
|
|
842
|
+
usages.push(usage);
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
return usages;
|
|
848
|
+
}
|
|
849
|
+
|
|
762
850
|
module.exports = {
|
|
763
851
|
getClientConfig,
|
|
764
852
|
getMapping,
|
|
@@ -776,5 +864,6 @@ module.exports = {
|
|
|
776
864
|
getCustomFormMapping,
|
|
777
865
|
setCustomFormMapping,
|
|
778
866
|
getDesignPackage,
|
|
779
|
-
getFormFieldById
|
|
780
|
-
|
|
867
|
+
getFormFieldById,
|
|
868
|
+
getClientScripts
|
|
869
|
+
};
|
package/util/responsehandler.js
CHANGED
|
@@ -81,7 +81,7 @@ function eventQueueHandler(req, res, next) {
|
|
|
81
81
|
if (!eventData.jsonData) {
|
|
82
82
|
eventData.jsonData = {};
|
|
83
83
|
}
|
|
84
|
-
eventData.
|
|
84
|
+
eventData.jsonDas= {
|
|
85
85
|
headers: req.headers,
|
|
86
86
|
body: req.body
|
|
87
87
|
}
|
|
@@ -127,4 +127,4 @@ function throwSchemaError(errors) {
|
|
|
127
127
|
|
|
128
128
|
module.exports = {
|
|
129
129
|
logErrors, errorHandler, eventQueueHandler, logRequest, throwSchemaError
|
|
130
|
-
};
|
|
130
|
+
};
|