@manyos/smileconnect-api 1.28.1 → 1.29.2

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 CHANGED
@@ -31,6 +31,7 @@ const supportgroupRoutes = require('./routes/supportgroupRoutes');
31
31
  const ciRelationRoutes = require('./routes/ciRelationRoutes');
32
32
  const peopleRelationRoutes = require('./routes/peopleRelationRoutes');
33
33
  const appConfigRoutes = require('./routes/appConfigRoutes');
34
+ const scriptRoutes = require('./routes/scriptRoutes');
34
35
  const relatedObjectsController = require('./controller/relatedObjectsController');
35
36
  const addRequestId = require('express-request-id')();
36
37
  const compression = require('compression');
@@ -210,17 +211,25 @@ app.use(passport.authenticate('jwt', {session: false}), responseHandler.logReque
210
211
 
211
212
  // setup routes
212
213
 
213
- app.use('/v1/cmdbobjects', cmdbObjectRoutes);
214
+ app.use('/v1/cmdbobjects', function(req, res, next) {
215
+ const ticketType = req.baseUrl.split('/')[2];
216
+ log.debug('ticketType', ticketType);
217
+ req.ticketType = ticketType;
218
+ req.parentType = ticketType;
219
+ req.requestType = ticketType;
220
+ next();
221
+ }, cmdbObjectRoutes);
222
+
214
223
  app.use('/v1/persons', personRoutes);
215
224
  app.use('/v1/supportgroups', supportgroupRoutes);
216
225
  app.use('/v1/organisations', organisationRoutes);
217
226
  app.use('/v1/cirelations', ciRelationRoutes);
218
227
  app.use('/v1/peoplerelations', peopleRelationRoutes);
219
228
  app.use('/v1/appconfig', appConfigRoutes);
229
+ app.use('/v1/scripts', scriptRoutes);
220
230
 
221
231
  //tickethandling
222
232
  app.use('/v1/(|incidents|problems|workorders|changes)', function(req, res, next) {
223
- log.debug('dad');
224
233
  const ticketType = req.baseUrl.split('/')[2];
225
234
  req.ticketType = ticketType;
226
235
  req.parentType = ticketType;
@@ -0,0 +1,11 @@
1
+ const allowedCats = [
2
+ "Request",
3
+ "Failure"
4
+ ];
5
+
6
+ //Validate opsCat1
7
+ if (requestData.opsCat1 && !allowedCats.find(element => element === requestData.opsCat1)) {
8
+ reject(`opsCat1 ${requestData.opsCat1} not in allowed values ${allowedCats}`);
9
+ }
10
+ requestData.summary = `Da kam an: ${requestData.summary}`
11
+ resolve();
@@ -9,10 +9,17 @@ const searchUtil = require('../util/searchUtil');
9
9
  const {getIncludeArray} = require('../util/paramHelper');
10
10
  const relationUtil = require('../util/relationUtil');
11
11
  const ticketCIRelationController = require('../controller/ticketCIRelationController');
12
+ const mappingUtil = require('../util/mappingUtil');
13
+ const { v4 } = require('uuid');
14
+ const CMDBOBJECT = 'cmdbobject';
12
15
 
13
16
  const cmdbCache = new CacheService(process.env.CACHETTL_CMDB || 600); // Create a new cache service instance
14
17
  const schemaCache = new CacheService(process.env.CACHETTL_SCHEMANAMES || 3600); // Create a new cache service instance
15
18
 
19
+ function getRandomId() {
20
+ return v4();
21
+ }
22
+
16
23
  function getCmdbObjects(config, category, ciIds, includeString) {
17
24
  let query = '1=1';
18
25
  if (category)
@@ -113,7 +120,7 @@ function getSchemaName(classId) {
113
120
  }
114
121
  }
115
122
 
116
- function queryCMDBObject(clientConfig, query, customFields, customOptions, includeString) {
123
+ function queryCMDBObject(clientConfig, query, customFields, customOptions, includeString, mapping) {
117
124
  let fields = clientConfig.cmdbobject.fields;
118
125
  let deleteClassId = false;
119
126
 
@@ -138,7 +145,9 @@ function queryCMDBObject(clientConfig, query, customFields, customOptions, inclu
138
145
  const key = clientConfig.cmdbobject.basequery + fields.toString() + query + JSON.stringify(options) + includeArray;
139
146
  log.debug('Cachekey is', key);
140
147
 
141
- const mapping = config.getMapping('cmdbobject');
148
+ if (mapping == null || mapping == undefined) {
149
+ mapping = config.getMapping('cmdbobject');
150
+ }
142
151
  log.debug('mapping', mapping);
143
152
 
144
153
  return cmdbCache.get(key, async function () {
@@ -164,7 +173,7 @@ async function handleCMDBObjectResult(cmdbObject, mapping, clientConfig, include
164
173
  //get class form
165
174
  const classId = cmdbObject['Class Id'];
166
175
  if (deleteClassId === true) {
167
- delete cmdbObject['Class Id'];
176
+ delete cmdbObject[CMDBOBJECT];
168
177
  }
169
178
  //Apply mapping
170
179
  mapping.forEach(function (mappingEntry) {
@@ -218,9 +227,11 @@ async function handleCMDBObjectResult(cmdbObject, mapping, clientConfig, include
218
227
  return cmdbObject;
219
228
  }
220
229
 
221
- async function getCMDBObjectClassAttributes(id, classId, clientConfig) {
230
+ async function getCMDBObjectClassAttributes(id, classId, clientConfig, mapping) {
222
231
  const schemaName = await getSchemaName(classId);
223
- const mapping = config.getMapping('cmdbobject_' + schemaName);
232
+ if (!mapping) {
233
+ mapping = config.getMapping('cmdbobject_' + schemaName);
234
+ }
224
235
  const fields = clientConfig.cmdbobject['fields_' + schemaName];
225
236
  if (schemaName && fields && mapping) {
226
237
  return cmdbCache.get(id+classId+fields, async function () {
@@ -246,9 +257,9 @@ async function getCMDBObjectClassAttributes(id, classId, clientConfig) {
246
257
  }
247
258
  }
248
259
 
249
- async function getCmdbObject(config, id, includeString) {
260
+ async function getCmdbObject(config, id, includeString, mapping) {
250
261
  const query = `'Instance Id'=\"${id}\"`;
251
- const returnValue = await queryCMDBObject(config, query, null, null, includeString);
262
+ const returnValue = await queryCMDBObject(config, query, null, null, includeString, mapping);
252
263
  log.debug (returnValue);
253
264
  const cmdbObject = returnValue.data[0];
254
265
  return {data: cmdbObject, included: returnValue.included};
@@ -262,7 +273,7 @@ async function hasAccess(config, id) {
262
273
  }
263
274
 
264
275
  async function applyMapping(clientConfig, data) {
265
- const mapping = config.getMapping('cmdbobject');
276
+ const mapping = config.getMapping(CMDBOBJECT);
266
277
  const mappedRecord = searchUtil.applyMapping2record(data, clientConfig, mapping);
267
278
  return mappedRecord;
268
279
  }
@@ -273,13 +284,116 @@ function searchCmdbObjectByName(config, name, includeString) {
273
284
  }
274
285
 
275
286
  function searchCmdbObject(clientConfig, searchString, fields, options, includeString) {
276
- const mapping = config.getMapping('cmdbobject');
287
+ const mapping = config.getMapping(CMDBOBJECT);
277
288
  const mappedString = searchUtil.applyMapping(searchString, mapping);
278
289
  const customFields = searchUtil.getCustomFields(clientConfig.cmdbobject.fields, mapping, fields);
279
290
  options.sort = searchUtil.applySortMapping(options.sort, mapping);
280
291
  return queryCMDBObject(clientConfig, mappedString, customFields, options, includeString);
281
292
  }
282
293
 
294
+ async function updateCmdbObject(ticketConfig, clientConfig, id, ciData, classId) {
295
+ const formName = classId || 'AST:BaseElement';
296
+
297
+ const scripts = clientConfig[CMDBOBJECT].scripts.PUT;
298
+ //const fields = clientConfig[ticketConfig.requestType].fields
299
+
300
+ //run preScripts
301
+ if (scripts && scripts.preMapping) {
302
+ await scriptController.runScripts(scripts.preMapping, ciData);
303
+ }
304
+
305
+ const myClientConfig = {};
306
+ myClientConfig[CMDBOBJECT] = {baseQuery: clientConfig[CMDBOBJECT].baseQuery, fields: [1, 400079600]};
307
+ myClientConfig[CMDBOBJECT+'_AST:ComputerSystem'] = myClientConfig[CMDBOBJECT];
308
+
309
+ //sarch CI to updata
310
+
311
+ const result = await arquery.executeARQuery(formName, null, `'179'="${id}"`, '1');
312
+ const ci = result.data[0];
313
+ log.debug('CI to Update', ci);
314
+
315
+ if (!ci) {
316
+ throw new Error("CI not found")
317
+ }
318
+
319
+ const mapping = getClassMapping(classId);
320
+
321
+ //Constants work only on new.
322
+ ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, clientConfig.cmdbobject.fields);
323
+
324
+ //run postMapping
325
+ if (scripts && scripts.postMapping) {
326
+ await scriptController.runScripts(scripts.postMapping, ciData);
327
+ }
328
+
329
+ const update = await arquery.updateEntry(formName, ci['Request ID'], ciData);
330
+
331
+ //run afterExecution
332
+ if (scripts && scripts.afterExecution) {
333
+ await scriptController.runScripts(scripts.afterExecution, ciData);
334
+ }
335
+
336
+ return update;
337
+ }
338
+
339
+ function getClassMapping(classId) {
340
+ const mappings = [];
341
+ const globalMappings = config.getMapping(CMDBOBJECT);
342
+ const classMappings = config.getMapping(`${CMDBOBJECT}_${classId}`);
343
+
344
+ //Add all global Mappings that are not in ClassMapping
345
+ globalMappings.forEach(globalMapping => {
346
+ const foundInClassMappings = classMappings.find(element => element.newName === globalMapping.newName);
347
+ if (!foundInClassMappings) {
348
+ mappings.push(globalMapping);
349
+ }
350
+ });
351
+
352
+ //Add class Mapping
353
+ classMappings.forEach(classMapping => {
354
+ mappings.push(classMapping);
355
+ });
356
+ return mappings;
357
+ }
358
+
359
+ async function createCmdbObject(assetConfig, clientConfig, classId, ciData) {
360
+ const reconId = getRandomId();
361
+ const instanceId = getRandomId();
362
+
363
+ const scripts = clientConfig[CMDBOBJECT].scripts.PUT;
364
+ //const fields = clientConfig[ticketConfig.requestType].fields
365
+
366
+ //run preScripts
367
+ if (scripts && scripts.preMapping) {
368
+ await scriptController.runScripts(scripts.preMapping, ciData);
369
+ }
370
+
371
+ const mapping = getClassMapping(classId);
372
+
373
+ log.debug('Combined Mapping', mapping);
374
+
375
+ //Constants work only on new.
376
+ ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, clientConfig.cmdbobject.fields);
377
+
378
+ //run postMapping
379
+ if (scripts && scripts.postMapping) {
380
+ await scriptController.runScripts(scripts.postMapping, ciData);
381
+ }
382
+
383
+ ciData['Data Set Id'] = "BMC.ASSET"
384
+ ciData['400129200'] = reconId;
385
+ ciData['Instance Id'] = instanceId;
386
+
387
+ const update = await arquery.createEntry(classId, ciData);
388
+
389
+ //run afterExecution
390
+ if (scripts && scripts.afterExecution) {
391
+ await scriptController.runScripts(scripts.afterExecution, ciData);
392
+ }
393
+
394
+ return instanceId;
395
+ }
396
+
283
397
  module.exports = {
284
398
  getCmdbObjects,
285
399
  getCmdbObject,
@@ -287,5 +401,7 @@ module.exports = {
287
401
  searchCmdbObject,
288
402
  getCIRelations,
289
403
  hasAccess,
290
- applyMapping
404
+ applyMapping,
405
+ updateCmdbObject,
406
+ createCmdbObject
291
407
  };
@@ -52,7 +52,7 @@ function setEventData(req, eventName, schemaName, ticketNumber, jsonData, ticket
52
52
  };
53
53
  }
54
54
 
55
- function setEventData(req, eventBase, eventAction, schemaName, ticketNumber, jsonData, ticketNumber2) {
55
+ function setEventData(req, eventBase, eventAction, schemaName, ticketNumber, jsonData, ticketNumber2, ticketNumber3) {
56
56
  req.eventData = {
57
57
  event: eventBase + '_' + eventAction,
58
58
  schema: schemaName,
@@ -6,6 +6,8 @@ const fs = require('fs');
6
6
  const basePath = 'conf';
7
7
  const basePathGlobalScripts = basePath + '/scripts';
8
8
 
9
+ const {getClients} = require('../util/config');
10
+
9
11
  require('dotenv').config();
10
12
  const {NodeVM} = require('vm2');
11
13
 
@@ -69,7 +71,7 @@ async function executeCode(code, requestData, params, logStream, executedByScrip
69
71
  params,
70
72
  log,
71
73
  script:executeScriptByScript,
72
- env: {}//process.env
74
+ env: process.env
73
75
  };
74
76
 
75
77
  sandbox.executedByScript = executedByScript === true;
@@ -165,6 +167,46 @@ async function readScriptFromFile(fileName) {
165
167
  return script;
166
168
  }
167
169
 
170
+ async function getUsage(scriptId) {
171
+ const clients = getClients();
172
+ const usages = [];
173
+ clients.forEach(client => {
174
+ //check each client entry for scripts
175
+ Object.keys(client.config).forEach(clientKey => {
176
+ //log.debug(clientKey, client.config[clientKey].scripts);
177
+ const clientScripts = client.config[clientKey].scripts;
178
+ //check all script operations
179
+ if (clientScripts) {
180
+ Object.keys(clientScripts).forEach(operation => {
181
+ //log.debug ('ops', operation);
182
+ const opsScripts = clientScripts[operation];
183
+ Object.keys(opsScripts).forEach(scriptType => {
184
+ const opsTypeScripts = opsScripts[scriptType]
185
+ //log.debug ('opsTypeSc', opsTypeScripts);
186
+ if (opsTypeScripts && Array.isArray(opsTypeScripts)) {
187
+ opsTypeScripts.forEach(script => {
188
+ //log.debug (scriptType, scriptId, script);
189
+ if (script === scriptId) {
190
+ const usage = {
191
+ client: client.name,
192
+ key: clientKey,
193
+ operation,
194
+ scriptType,
195
+ script
196
+ }
197
+ log.debug ('script match found', usage);
198
+ usages.push(usage);
199
+ }
200
+ });
201
+ }
202
+ })
203
+ })
204
+ }
205
+ })
206
+ });
207
+ return usages;
208
+ }
209
+
168
210
  async function getScripts(pathName, catalogType, catalogId) {
169
211
  const files = recFindByExt(pathName,'js')
170
212
  const scriptNames = files.map(file => file.substr(0, file.length-3));
@@ -209,5 +251,6 @@ module.exports = {
209
251
  getGlobalScripts,
210
252
  setGlobalScript,
211
253
  deleteGlobalScript,
212
- runScripts
254
+ runScripts,
255
+ getUsage
213
256
  };
@@ -63,3 +63,23 @@ An new worklog has been attached to a workorder.
63
63
  * WOI_WorkLog_Modified
64
64
 
65
65
  An new worklog has been attached to a workorder.
66
+
67
+ * Task
68
+
69
+ A task is modified.
70
+ ```json
71
+ {
72
+ "event": "INC_TAS_Modify",
73
+ "objectId": "INC365840",
74
+ "objetctId2": "TAS30940"
75
+ }
76
+ ```
77
+ A task worklog is created.
78
+ ```json
79
+ {
80
+ "event": "INC_TAS_WorkLog_Create",
81
+ "objectId": "INC365840",
82
+ "objetctId2": "TAS30940",
83
+ "objetctId3": "WLG9039283"
84
+ }
85
+ ```
package/docs/openapi.json CHANGED
@@ -555,31 +555,6 @@
555
555
  },
556
556
  "/appconfig": {
557
557
 
558
- },
559
- "/appconfig/clients": {
560
- "get": {
561
- "tags": [
562
- "AppConfig"
563
- ],
564
- "responses": {
565
- "200": {
566
- "content": {
567
- "application/json": {
568
- "schema": {
569
- "$ref": "#/components/schemas/AppConfigClientResponseList"
570
- }
571
- }
572
- }
573
- }
574
- },
575
- "summary": "Get all clients"
576
- },
577
- "post": {
578
- "tags": [
579
- "AppConfig"
580
- ],
581
- "summary": "Create a new Client"
582
- }
583
558
  },
584
559
  "/appconfig/clients/{client}": {
585
560
  "get": {
@@ -2642,41 +2617,6 @@
2642
2617
  },
2643
2618
  "/appconfig/forms/{id}/fields": {
2644
2619
 
2645
- },
2646
- "/incidents/{id}/worklogs/{worklogId}/attachment": {
2647
- "get": {
2648
- "tags": [
2649
- "Incidents",
2650
- "Worklogs"
2651
- ],
2652
- "responses": {
2653
- "200": {
2654
- "content": {
2655
- "Content-disposition', 'attachment; filename=<fileName>'": {
2656
-
2657
- }
2658
- },
2659
- "description": "Get the attachment of a worklog. Only attachment field1 ist used."
2660
- }
2661
- },
2662
- "summary": "Get an Incident Worklog Attachment"
2663
- },
2664
- "post": {
2665
- "requestBody": {
2666
- "description": "Send the data in the key: \"file\"",
2667
- "content": {
2668
- "application/x-www-form-urlencoded": {
2669
-
2670
- }
2671
- },
2672
- "required": true
2673
- },
2674
- "tags": [
2675
- "Incidents",
2676
- "Worklogs"
2677
- ],
2678
- "summary": "Set an Incident Worklog Attachment"
2679
- }
2680
2620
  },
2681
2621
  "/templates/{templateType}": {
2682
2622
  "get": {
@@ -3272,6 +3212,195 @@
3272
3212
  "required": false
3273
3213
  }
3274
3214
  ]
3215
+ },
3216
+ "/incidents/{id}/worklogs/{worklogId}/attachments/1": {
3217
+ "get": {
3218
+ "tags": [
3219
+ "Incidents",
3220
+ "Worklogs"
3221
+ ],
3222
+ "responses": {
3223
+ "200": {
3224
+ "$ref": "#/components/responses/attachmentResponse"
3225
+ }
3226
+ },
3227
+ "summary": "Get an Incident Worklog Attachment"
3228
+ },
3229
+ "post": {
3230
+ "requestBody": {
3231
+ "description": "Send the data in the key: \"file\"",
3232
+ "content": {
3233
+ "application/x-www-form-urlencoded": {
3234
+
3235
+ }
3236
+ },
3237
+ "required": true
3238
+ },
3239
+ "tags": [
3240
+ "Incidents",
3241
+ "Worklogs"
3242
+ ],
3243
+ "responses": {
3244
+ "200": {
3245
+ "description": "Attachment added"
3246
+ }
3247
+ },
3248
+ "summary": "Set an Incident Worklog Attachment"
3249
+ },
3250
+ "parameters": [
3251
+ {
3252
+ "name": "worklogId",
3253
+ "schema": {
3254
+ "type": "string"
3255
+ },
3256
+ "in": "path",
3257
+ "required": true
3258
+ },
3259
+ {
3260
+ "name": "id",
3261
+ "schema": {
3262
+ "type": "string"
3263
+ },
3264
+ "in": "path",
3265
+ "required": true
3266
+ }
3267
+ ]
3268
+ },
3269
+ "/incidents/{id}/worklogs/{worklogId}/attachments/2": {
3270
+ "get": {
3271
+ "tags": [
3272
+ "Incidents",
3273
+ "Worklogs"
3274
+ ],
3275
+ "responses": {
3276
+ "200": {
3277
+ "$ref": "#/components/responses/attachmentResponse"
3278
+ }
3279
+ },
3280
+ "summary": "Get an Incident Worklog Attachment"
3281
+ },
3282
+ "post": {
3283
+ "requestBody": {
3284
+ "description": "Send the data in the key: \"file\"",
3285
+ "content": {
3286
+ "application/x-www-form-urlencoded": {
3287
+
3288
+ }
3289
+ },
3290
+ "required": true
3291
+ },
3292
+ "tags": [
3293
+ "Incidents",
3294
+ "Worklogs"
3295
+ ],
3296
+ "responses": {
3297
+ "200": {
3298
+ "description": "Attachment added"
3299
+ }
3300
+ },
3301
+ "summary": "Set an Incident Worklog Attachment"
3302
+ },
3303
+ "parameters": [
3304
+ {
3305
+ "name": "worklogId",
3306
+ "schema": {
3307
+ "type": "string"
3308
+ },
3309
+ "in": "path",
3310
+ "required": true
3311
+ },
3312
+ {
3313
+ "name": "id",
3314
+ "schema": {
3315
+ "type": "string"
3316
+ },
3317
+ "in": "path",
3318
+ "required": true
3319
+ }
3320
+ ]
3321
+ },
3322
+ "/incidents/{id}/worklogs/{worklogId}/attachments/3": {
3323
+ "get": {
3324
+ "tags": [
3325
+ "Incidents",
3326
+ "Worklogs"
3327
+ ],
3328
+ "responses": {
3329
+ "200": {
3330
+ "$ref": "#/components/responses/attachmentResponse"
3331
+ }
3332
+ },
3333
+ "summary": "Get an Incident Worklog Attachment"
3334
+ },
3335
+ "post": {
3336
+ "requestBody": {
3337
+ "description": "Send the data in the key: \"file\"",
3338
+ "content": {
3339
+ "application/x-www-form-urlencoded": {
3340
+
3341
+ }
3342
+ },
3343
+ "required": true
3344
+ },
3345
+ "tags": [
3346
+ "Incidents",
3347
+ "Worklogs"
3348
+ ],
3349
+ "responses": {
3350
+ "200": {
3351
+ "description": "Attachment added"
3352
+ }
3353
+ },
3354
+ "summary": "Set an Incident Worklog Attachment"
3355
+ },
3356
+ "parameters": [
3357
+ {
3358
+ "name": "worklogId",
3359
+ "schema": {
3360
+ "type": "string"
3361
+ },
3362
+ "in": "path",
3363
+ "required": true
3364
+ },
3365
+ {
3366
+ "name": "id",
3367
+ "schema": {
3368
+ "type": "string"
3369
+ },
3370
+ "in": "path",
3371
+ "required": true
3372
+ }
3373
+ ]
3374
+ },
3375
+ "/appconfig/clients": {
3376
+ "get": {
3377
+ "tags": [
3378
+ "AppConfig"
3379
+ ],
3380
+ "responses": {
3381
+ "200": {
3382
+ "content": {
3383
+ "application/json": {
3384
+ "schema": {
3385
+ "$ref": "#/components/schemas/AppConfigClientResponseList"
3386
+ }
3387
+ }
3388
+ }
3389
+ }
3390
+ },
3391
+ "summary": "Get all clients"
3392
+ },
3393
+ "post": {
3394
+ "tags": [
3395
+ "AppConfig"
3396
+ ],
3397
+ "responses": {
3398
+ "200": {
3399
+ "description": "Client added"
3400
+ }
3401
+ },
3402
+ "summary": "Create a new Client"
3403
+ }
3275
3404
  }
3276
3405
  },
3277
3406
  "components": {
@@ -15036,6 +15165,26 @@
15036
15165
  }
15037
15166
  },
15038
15167
  "description": "Returns an array of Templates"
15168
+ },
15169
+ "attachmentResponse": {
15170
+ "headers": {
15171
+ "content-disposition": {
15172
+ "schema": {
15173
+ "format": "attachment; filename=<filename>",
15174
+ "type": "string"
15175
+ },
15176
+ "description": "The name of the attachment"
15177
+ }
15178
+ },
15179
+ "content": {
15180
+ "application/octet-stream": {
15181
+ "schema": {
15182
+ "format": "binary",
15183
+ "type": "string"
15184
+ }
15185
+ }
15186
+ },
15187
+ "description": "Get the attachment of a worklog."
15039
15188
  }
15040
15189
  },
15041
15190
  "securitySchemes": {
package/nodemon.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "ignore": ["conf/*.json", "Config"]
2
+ "ignore": ["conf/*.json", "Config", "conf/scrips/*.js"]
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyos/smileconnect-api",
3
- "version": "1.28.1",
3
+ "version": "1.29.2",
4
4
  "description": "A proxy and abstraction layer for BMCs IT Service Management Suite",
5
5
  "main": "app.js",
6
6
  "scripts": {
@@ -21,9 +21,9 @@
21
21
  "express-fileupload": "^1.2.1",
22
22
  "express-rate-limit": "^5.2.6",
23
23
  "express-request-id": "^1.4.1",
24
- "express-validator": "^5.3.1",
24
+ "express-validator": "^6.10.0",
25
25
  "moment": "^2.29.1",
26
- "mongoose": "^5.12.1",
26
+ "mongoose": "^5.12.3",
27
27
  "node-cache": "^4.2.1",
28
28
  "only": "0.0.2",
29
29
  "p-limit": "^2.3.0",
@@ -35,7 +35,7 @@
35
35
  "request-promise-native": "^1.0.9",
36
36
  "socket.io": "^2.4.1",
37
37
  "uuid": "^3.4.0",
38
- "vm2": "^3.9.2"
38
+ "vm2": "^3.9.3"
39
39
  },
40
40
  "devDependencies": {
41
41
  "chai": "^4.3.4",
@@ -150,5 +150,68 @@ module.exports = (function () {
150
150
  }
151
151
  });
152
152
 
153
+ cmdbObjectRoutes.put('/:id', async function (req, res, next) {
154
+ const id = req.params.id;
155
+ const classId = req.body.classId;
156
+ const includeString = req.query.include;
157
+ eventLog.setEventData(
158
+ req,
159
+ CONSTANTS.EVENT_BASE_AST,
160
+ CONSTANTS.EVENT_ACTION_MODIFY,
161
+ CONSTANTS.FORM_ASSET,
162
+ id
163
+ );
164
+ const errors = validationResult(req);
165
+ if (!errors.isEmpty()) {
166
+ req.errorStatus = 422;
167
+ next(errors.array());
168
+ } else {
169
+ //const clientConfig = config.getClientConfig(clientId);
170
+ const result = [];
171
+ try {
172
+ const ci = req.body.data;
173
+ const hasAccess = await cmdbobjects.hasAccess(req.user.config, id);
174
+ if (hasAccess) {
175
+ const result = await cmdbobjects.updateCmdbObject(req.ticketConfig, req.user.config, id, req.body.data, classId);
176
+ const ci = await cmdbobjects.getCmdbObject(req.user.config, id, includeString);
177
+ req.result = ci;
178
+ next();
179
+ } else {
180
+ req.errorStatus = 403;
181
+ next('Access forbidden.')
182
+ }
183
+ } catch (e) {
184
+ next(e);
185
+ }
186
+ }
187
+ });
188
+
189
+ cmdbObjectRoutes.post('/', async function (req, res, next) {
190
+ const classId = req.body.classId;
191
+ const includeString = req.query.include;
192
+ eventLog.setEventData(
193
+ req,
194
+ CONSTANTS.EVENT_BASE_AST,
195
+ CONSTANTS.EVENT_ACTION_MODIFY,
196
+ classId
197
+ );
198
+ const errors = validationResult(req);
199
+ if (!errors.isEmpty()) {
200
+ req.errorStatus = 422;
201
+ next(errors.array());
202
+ } else {
203
+ //const clientConfig = config.getClientConfig(clientId);
204
+ const result = [];
205
+ try {
206
+ const ciInstanceId = await cmdbobjects.createCmdbObject(req.ticketConfig, req.user.config, classId, req.body.data);
207
+ const ci = await cmdbobjects.getCmdbObject(req.user.config, ciInstanceId, includeString);
208
+ req.result = ci;
209
+ next();
210
+ } catch (e) {
211
+ next(e);
212
+ }
213
+ }
214
+ });
215
+
153
216
  return cmdbObjectRoutes;
154
217
  })();
@@ -0,0 +1,142 @@
1
+ const path = require('path');
2
+ const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
3
+ const scriptController = require('../controller/scriptController');
4
+ const eventLog = require('../controller/eventLogController');
5
+ const CONSTANTS = require('../util/constants');
6
+ const scriptDefinitionSchema = require('../util/schemas/scriptDefinitionSchema');
7
+ const {isAuthorizedAdmin} = require('../util/auth');
8
+
9
+ const {checkSchema, validationResult} = require('express-validator');
10
+
11
+ const {throwSchemaError} = require('../util/responsehandler');
12
+
13
+ module.exports = (function() {
14
+ const scriptRoutes = require('express').Router();
15
+
16
+ scriptRoutes.get('/',
17
+ isAuthorizedAdmin,
18
+ function (req, res, next) {
19
+ eventLog.setEventData(
20
+ req,
21
+ CONSTANTS.EVENT_BASE_SCRIPT,
22
+ CONSTANTS.EVENT_ACTION_QUERY,
23
+ CONSTANTS.FORM_SCRIPTS
24
+ );
25
+
26
+ scriptController.getGlobalScripts().then(function (result) {
27
+ log.debug('result', result);
28
+
29
+ req.includeObjectsList = result.included;
30
+ req.result = {data:result};
31
+ next();
32
+ }).catch(function (reason) {
33
+ next(reason);
34
+ });
35
+ });
36
+
37
+ scriptRoutes.get('/:scriptId*', isAuthorizedAdmin, async function (req, res, next) {
38
+ const scriptId = req.path.replace(`/`,"");
39
+ eventLog.setEventData(
40
+ req,
41
+ CONSTANTS.EVENT_BASE_SCRIPT,
42
+ CONSTANTS.EVENT_ACTION_QUERY,
43
+ CONSTANTS.FORM_SCRIPTS,
44
+ scriptId
45
+ );
46
+
47
+ try {
48
+ const code = await scriptController.getGlobalScript(scriptId);
49
+ const usage = await scriptController.getUsage(scriptId);
50
+ req.result = {
51
+ id: scriptId,
52
+ code,
53
+ usage
54
+ };
55
+ next();
56
+ } catch (error) {
57
+ next (error);
58
+ }
59
+ });
60
+
61
+ async function createAndUpdateScript(scriptId, code) {
62
+ await scriptController.setGlobalScript(scriptId, code);
63
+ return {
64
+ id: scriptId,
65
+ code: code
66
+ }
67
+ }
68
+
69
+ scriptRoutes.put('/:scriptId*',
70
+ isAuthorizedAdmin,
71
+ checkSchema(scriptDefinitionSchema),
72
+ function (req, res, next) {
73
+
74
+ //validate schema
75
+ const errors = validationResult(req);
76
+ throwSchemaError(errors);
77
+
78
+ const scriptId = req.path.replace(`/`,"");
79
+
80
+ eventLog.setEventData(
81
+ req,
82
+ CONSTANTS.EVENT_BASE_SCRIPT,
83
+ CONSTANTS.EVENT_ACTION_MODIFY,
84
+ CONSTANTS.FORM_SCRIPTS,
85
+ scriptId
86
+ );
87
+
88
+ createAndUpdateScript(scriptId, req.body.code).then(script => {
89
+ req.result = script;
90
+ next();
91
+ }).catch (error=> {
92
+ next(error);
93
+ });
94
+ });
95
+
96
+ scriptRoutes.delete('/:scriptId*', isAuthorizedAdmin, function (req, res, next) {
97
+ const scriptId = req.path.replace(`/`,"");
98
+ eventLog.setEventData(
99
+ req,
100
+ CONSTANTS.EVENT_BASE_SCRIPT,
101
+ CONSTANTS.EVENT_ACTION_DELETE,
102
+ CONSTANTS.FORM_SCRIPTS,
103
+ scriptId
104
+ );
105
+
106
+ scriptController.deleteGlobalScript(scriptId).then(script => {
107
+ req.result = script;
108
+ next();
109
+ }).catch (error=> {
110
+ next(error);
111
+ });
112
+ });
113
+
114
+ scriptRoutes.post('/',
115
+ isAuthorizedAdmin,
116
+ checkSchema(scriptDefinitionSchema),
117
+ function (req, res, next) {
118
+ //validate schema
119
+ const errors = validationResult(req);
120
+ throwSchemaError(errors);
121
+
122
+ const scriptId = req.body.id;
123
+
124
+ eventLog.setEventData(
125
+ req,
126
+ CONSTANTS.EVENT_BASE_SCRIPT,
127
+ CONSTANTS.EVENT_ACTION_CREATE,
128
+ CONSTANTS.FORM_SCRIPTS,
129
+ scriptId
130
+ );
131
+
132
+ createAndUpdateScript(scriptId, req.body.code).then(script => {
133
+ req.result = script;
134
+ log.debug('run next');
135
+ next();
136
+ }).catch (error=> {
137
+ next(error);
138
+ });
139
+ });
140
+
141
+ return scriptRoutes;
142
+ })();
@@ -18,7 +18,7 @@ module.exports = (function () {
18
18
  //todo customize eventbase
19
19
  eventLog.setEventData(
20
20
  req,
21
- req.parentEventBase,
21
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
22
22
  CONSTANTS.EVENT_ACTION_QUERY,
23
23
  CONSTANTS.FORM_TASK,
24
24
  id
@@ -35,8 +35,8 @@ module.exports = (function () {
35
35
  const origData = JSON.parse(JSON.stringify(req.body));
36
36
  eventLog.setEventData(
37
37
  req,
38
- req.parentEventBase,
39
- CONSTANTS.EVENT_ACTION_MODIFY,
38
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
39
+ CONSTANTS.EVENT_ACTION_CREATE,
40
40
  CONSTANTS.FORM_TASK,
41
41
  req.parentId,
42
42
  origData
@@ -87,7 +87,7 @@ module.exports = (function () {
87
87
  const taskId = req.params.taskId;
88
88
  eventLog.setEventData(
89
89
  req,
90
- req.parentEventBase,
90
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
91
91
  CONSTANTS.EVENT_ACTION_QUERY,
92
92
  CONSTANTS.FORM_TASK,
93
93
  parentId,
@@ -106,7 +106,7 @@ module.exports = (function () {
106
106
  const origData = JSON.parse(JSON.stringify(req.body));
107
107
  eventLog.setEventData(
108
108
  req,
109
- req.parentEventBase,
109
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
110
110
  CONSTANTS.EVENT_ACTION_MODIFY,
111
111
  CONSTANTS.FORM_TASK,
112
112
  req.parentId,
@@ -136,7 +136,7 @@ module.exports = (function () {
136
136
  const taskId = req.params.taskId;
137
137
  eventLog.setEventData(
138
138
  req,
139
- req.parentEventBase,
139
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
140
140
  CONSTANTS.EVENT_ACTION_QUERY,
141
141
  CONSTANTS.FORM_TASK_WORKLOG,
142
142
  req.parentId,
@@ -160,7 +160,7 @@ module.exports = (function () {
160
160
  const taskId = req.params.taskId;
161
161
  eventLog.setEventData(
162
162
  req,
163
- req.parentEventBase,
163
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
164
164
  CONSTANTS.EVENT_ACTION_CREATE,
165
165
  CONSTANTS.FORM_TASK_WORKLOG,
166
166
  req.parentId,
@@ -201,12 +201,13 @@ module.exports = (function () {
201
201
  const worklogId = req.params.worklogId;
202
202
  eventLog.setEventData(
203
203
  req,
204
- req.parentEventBase,
204
+ req.parentEventBase + '_' + CONSTANTS.EVENT_BASE_TAS,
205
205
  CONSTANTS.EVENT_ACTION_QUERY,
206
206
  CONSTANTS.FORM_TASK_WORKLOG,
207
207
  req.parentId,
208
208
  null,
209
- taskId
209
+ taskId,
210
+ worklogId
210
211
  );
211
212
 
212
213
  const result = await task.getTaskWorklog(req.user.config, taskId, worklogId);
package/util/config.js CHANGED
@@ -341,7 +341,6 @@ const ticketConfig = {
341
341
  "requestTemplate": "taskTemplate",
342
342
  "templateRequestId": "Template ID"
343
343
  }
344
-
345
344
  };
346
345
 
347
346
  module.exports = {
package/util/constants.js CHANGED
@@ -26,6 +26,8 @@ module.exports = {
26
26
  FORM_APC_FORMS: "Forms",
27
27
  FORM_APC_FORMS_META: "Metadata",
28
28
 
29
+ FORM_SCRIPTS: "Scripts",
30
+
29
31
  FORM_PEOPLE: "CTM:People",
30
32
  FORM_SUPPORTGROUP: "CTM:Support Group",
31
33
  FORM_ORGANISATION: "CTM:People Organization",
@@ -46,6 +48,8 @@ module.exports = {
46
48
 
47
49
  EVENT_BASE_APC: "APC",
48
50
 
51
+ EVENT_BASE_SCRIPT: "SCRIPT",
52
+
49
53
  EVENT_BASE_INC: "INC",
50
54
  EVENT_BASE_INC_WORKLOG: "INC_Worklog",
51
55
  EVENT_BASE_INC_WORKLOG_ATTACHTMENT: "INC_Worklog_Attachment",
@@ -60,9 +64,12 @@ module.exports = {
60
64
 
61
65
  EVENT_BASE_WOI: "WOI",
62
66
 
67
+ EVENT_BASE_TAS: "TAS",
68
+
63
69
  EVENT_ACTION_QUERY: 'Query',
64
70
  EVENT_ACTION_CREATE: 'Create',
65
71
  EVENT_ACTION_MODIFY: 'Modify',
72
+ EVENT_ACTION_DELETE: 'Delete',
66
73
  EVENT_ACTION_SEARCH: 'Search',
67
74
 
68
75
  EVENT_BASE_ORG_PEOPLE: "ORG_People",
@@ -87,6 +87,13 @@ function eventQueueHandler(req, res, next) {
87
87
  }
88
88
  }
89
89
 
90
+ function throwSchemaError(errors) {
91
+ if (!errors.isEmpty()) {
92
+ log.error(errors.array());
93
+ throw ({validationErrors: errors.array(), status:400});
94
+ }
95
+ }
96
+
90
97
  module.exports = {
91
- logErrors, errorHandler, eventQueueHandler, logRequest
98
+ logErrors, errorHandler, eventQueueHandler, logRequest, throwSchemaError
92
99
  };
@@ -0,0 +1,14 @@
1
+ module.exports = {
2
+ 'id': {
3
+ in: ['body'],
4
+ exists: {
5
+ errorMessage: 'Is required'
6
+ }
7
+ },
8
+ 'code': {
9
+ in: ['body'],
10
+ exists: {
11
+ errorMessage: 'Is required'
12
+ }
13
+ }
14
+ };