@manyos/smileconnect-api 1.49.1 → 1.50.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/conf/clients.json CHANGED
@@ -154,6 +154,13 @@
154
154
  "Class Start Date & Time"
155
155
  ]
156
156
  },
157
+ "custom_CTM:People": {
158
+ "basequery": "1=1",
159
+ "fields": [
160
+ "Remedy Login ID",
161
+ "Full Name"
162
+ ]
163
+ },
157
164
  "cmdbobject": {
158
165
  "basequery": "'Data Set Id' = \"BMC.ASSET\" AND ('Mark As Deleted' = \"No\" OR 'Mark As Deleted' = $NULL$)",
159
166
  "fields": [
@@ -332,9 +332,10 @@ async function updateCmdbObject(ticketConfig, clientConfig, id, ciData, classId,
332
332
  }
333
333
 
334
334
  const mapping = getClassMapping(classId);
335
+ const classFields = getClassFields(clientConfig, classId)
335
336
 
336
337
  //Constants work only on new.
337
- ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, clientConfig.cmdbobject.fields);
338
+ ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, classFields);
338
339
 
339
340
  //run postMapping
340
341
  if (scripts && scripts.postMapping) {
@@ -351,11 +352,26 @@ async function updateCmdbObject(ticketConfig, clientConfig, id, ciData, classId,
351
352
  return update;
352
353
  }
353
354
 
355
+ function getClassFields(clientConfig, classId) {
356
+ //Add globalFields
357
+ const globalFields = clientConfig.cmdbobject.fields;
358
+ log.debug('Global class fields', globalFields)
359
+ if (classId) {
360
+ const classFields = clientConfig.cmdbobject[`fields_${classId}`]
361
+ log.debug('Local class fields', classFields)
362
+ return [...new Set([...globalFields,...classFields])]
363
+ }
364
+ return globalFields
365
+ }
366
+
354
367
  function getClassMapping(classId) {
355
368
  const mappings = [];
356
369
  const globalMappings = config.getMapping(CMDBOBJECT);
357
370
  const classMappings = config.getMapping(`${CMDBOBJECT}_${classId}`);
358
371
 
372
+ log.debug('Found global Mapping', globalMappings)
373
+ log.debug('Found class Mapping', classMappings)
374
+
359
375
  //Add all global Mappings that are not in ClassMapping
360
376
  globalMappings.forEach(globalMapping => {
361
377
  const foundInClassMappings = classMappings.find(element => element.newName === globalMapping.newName);
@@ -368,6 +384,8 @@ function getClassMapping(classId) {
368
384
  classMappings.forEach(classMapping => {
369
385
  mappings.push(classMapping);
370
386
  });
387
+
388
+ log.debug('Created joined Mapping', mappings)
371
389
  return mappings;
372
390
  }
373
391
 
@@ -385,10 +403,10 @@ async function createCmdbObject(assetConfig, clientConfig, classId, ciData, glob
385
403
 
386
404
  const mapping = getClassMapping(classId);
387
405
 
388
- log.debug('Combined Mapping', mapping);
406
+ const classFields = getClassFields(clientConfig, classId)
389
407
 
390
408
  //Constants work only on new.
391
- ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, clientConfig.cmdbobject.fields);
409
+ ciData = mappingUtil.applyMapping2Remedy(ciData, mapping, undefined, classFields);
392
410
 
393
411
  //run postMapping
394
412
  if (scripts && scripts.postMapping) {
@@ -12,6 +12,15 @@ const mappingUtil = require('../util/mappingUtil');
12
12
 
13
13
  const ticketCache = new CacheService(process.env.CACHETTL_TICKETS || 1); // Create a new cache service instance
14
14
 
15
+ function getIdField(formConfig) {
16
+ const mapping = formConfig.mapping
17
+ const idField = Object.keys(mapping).find(key => mapping[key] === 'id');
18
+ if (!idField) {
19
+ return '1'
20
+ }
21
+ return idField
22
+ }
23
+
15
24
  function getRecords(formConfig, clientConfig, includeString, customOptions, globalScriptParams) {
16
25
  let query = '1=1';
17
26
  return queryRecords(formConfig, clientConfig, query, null, null, customOptions, includeString, globalScriptParams);
@@ -141,8 +150,9 @@ async function handleRecord(formConfig, record, mapping, clientConfig, includeAr
141
150
  }
142
151
 
143
152
  async function getRecord(formConfig, clientConfig, id, mapping, includeString, globalScriptParams) {
144
- const query = `'1'=\"${id}\"`;
145
- const returnValue = await queryRecords(formConfig, clientConfig, query, mapping, null, null, includeString, globalScriptParams);
153
+ const idField = getIdField(formConfig)
154
+ const query = `'${idField}'=\"${id}\"`;
155
+ const returnValue = await queryRecords(formConfig, clientConfig, query, mapping, null, {limit:1}, includeString, globalScriptParams);
146
156
  const record = returnValue.data[0];
147
157
  return {data: record};
148
158
  }
@@ -169,7 +179,9 @@ async function updateRecord(formConfig, clientConfig, id, recordData, globalScri
169
179
  await scriptController.runScripts(scripts.postMapping, recordData, clientConfig.clientId, globalScriptParams);
170
180
  }
171
181
 
172
- const update = await arquery.updateEntry(formConfig.formName, id, recordData);
182
+ const internalId = await getInternalId(formConfig, clientConfig, id)
183
+
184
+ const update = await arquery.updateEntry(formConfig.formName, internalId, recordData);
173
185
 
174
186
  //run afterExecution
175
187
  if (scripts && scripts.afterExecution) {
@@ -179,6 +191,16 @@ async function updateRecord(formConfig, clientConfig, id, recordData, globalScri
179
191
  return update;
180
192
  }
181
193
 
194
+ async function getInternalId(formConfig, clientConfig, id) {
195
+ const idField = getIdField(formConfig)
196
+ const query = `'${idField}'=\"${id}\"`;
197
+ const result = await arquery.executeARQuery(formConfig.formName, clientConfig[formConfig.configName].basequery || null, query , '1', {limit:1})
198
+ if (result && result.data && result.data.length >0) {
199
+ return Object.values(result.data[0])[0]
200
+ }
201
+ throw new Error (`Internal Id for Record ${id} in Form ${formConfig.formName} could not be found`)
202
+ }
203
+
182
204
  function searchRecords(formConfig, clientConfig, searchString, fields, options, includeString, globalScriptParams) {
183
205
  const mapping = formConfig.mapping
184
206
  const mappedString = searchUtil.applyCustomFormMapping(searchString, mapping);
package/docs/releases.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## API
4
4
 
5
+ ### 1.50.0 - 05.11.21
6
+ Use custom defined id in customForms
7
+
8
+ ### 1.49.2 - 05.11.21
9
+ Fix issue: Custom classAttributes not working in cmdbObjects PUT & POST
10
+
5
11
  ### 1.49.1 - 04.11.21
6
12
  Fix issue: Self Mapping in custom Forms removed attribute
7
13
 
@@ -112,6 +118,9 @@ Update Record added to [Remedy Adapter](adapter#remedy).
112
118
  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.
113
119
 
114
120
  ## GUI
121
+ ### 1.6.0 - 05.11.21
122
+ Added attachmentScripts to GUI
123
+
115
124
  ### 1.5.5 - 03.11.21
116
125
  Add Parameter REACT_APP_OIDC_SCOPE to choose the oicd scope
117
126
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyos/smileconnect-api",
3
- "version": "1.49.1",
3
+ "version": "1.50.0",
4
4
  "description": "A proxy and abstraction layer for BMCs IT Service Management Suite",
5
5
  "main": "app.js",
6
6
  "scripts": {
@@ -0,0 +1,111 @@
1
+ const assert = require('chai').assert;
2
+ let chai = require('chai');
3
+ let chaiHttp = require('chai-http');
4
+ let should = chai.should();
5
+ let server = require('../app');
6
+ const TestUtils = require('./testUtils')
7
+ require('dotenv').config();
8
+
9
+ //Integrations Tests here
10
+
11
+ chai.use(chaiHttp);
12
+
13
+ describe('Integration Tests - customForms', function () {
14
+
15
+ let authUser = {'id':process.env.TEST_ID, 'secret':process.env.TEST_SECRET};
16
+
17
+ before((done) => {
18
+
19
+ // Authenticate the user to get a token
20
+ TestUtils.authenticateUser(authUser, server)
21
+ .then((accessToken) => {
22
+ // Keep the token on the user so we can use it in the tests
23
+ authUser.access_token = accessToken;
24
+ return done();
25
+ })
26
+ .catch((err) => done(err));
27
+ });
28
+
29
+ describe('GET custom Form Data', function () {
30
+ it ('it should get a spezific record by id', function (done) {
31
+ chai.request(server)
32
+ .get('/v1/customForms/persons/rhannemann')
33
+ .set('Authorization', 'Bearer ' + authUser.access_token)
34
+ .end(function(err, res) {
35
+ res.should.have.status(200);
36
+ res.body.data.should.be.an('object');
37
+ res.body.data.should.have.property('name');
38
+ res.body.data.should.have.property('id');
39
+ done();
40
+ })
41
+ })
42
+
43
+ it ('it should get all customForm records', function (done) {
44
+ chai.request(server)
45
+ .get('/v1/customForms/persons?limit=5')
46
+ .set('Authorization', 'Bearer ' + authUser.access_token)
47
+ .end(function(err, res) {
48
+ res.should.have.status(200);
49
+ res.body.data.should.be.an('array');
50
+ res.body.data.length.should.be.above(0);
51
+ done();
52
+ })
53
+ })
54
+
55
+ it ('it should search customForms', function (done) {
56
+ const searchString = `'name' LIKE "Robert Hannemann%"`;
57
+ chai.request(server)
58
+ .post('/v1/customForms/persons/search')
59
+ .set('Authorization', 'Bearer ' + authUser.access_token)
60
+ .send({searchString})
61
+ .end(function(err, res) {
62
+ res.should.have.status(200);
63
+ res.body.data.should.be.an('array');
64
+ res.body.data.length.should.be.above(0);
65
+ done();
66
+ })
67
+ })
68
+
69
+ it ('it should update a customForm Record by id', function (done) {
70
+ const data = {
71
+ name: 'Robert Hannemann' + new Date()
72
+ }
73
+ chai.request(server)
74
+ .put('/v1/customForms/persons/rhannemann')
75
+ .set('Authorization', 'Bearer ' + authUser.access_token)
76
+ .send({data})
77
+ .end(function(err, res) {
78
+ res.should.have.status(200);
79
+ res.body.data.should.be.an('object');
80
+ res.body.data.should.have.property('name');
81
+ res.body.data.should.have.property('id');
82
+ res.body.data.name.should.be.equal(data.name)
83
+ done();
84
+ })
85
+ })
86
+
87
+ it ('it should create a customForm Record', function (done) {
88
+ const data = {
89
+ "userId": "Demo",
90
+ "classId": "00001",
91
+ "Department": "Mux",
92
+ "classTitle": "Blup",
93
+ "cost": 55,
94
+ "location": "Muc",
95
+ "startDate": "Mon Nov 07 16:00:00 GMT 2005"
96
+ }
97
+ chai.request(server)
98
+ .post('/v1/customForms/enrollments')
99
+ .set('Authorization', 'Bearer ' + authUser.access_token)
100
+ .send({data})
101
+ .end(function(err, res) {
102
+ res.should.have.status(200);
103
+ res.body.data.should.be.an('object');
104
+ res.body.data.should.have.property('location');
105
+ res.body.data.should.have.property('id');
106
+ res.body.data.location.should.be.equal(data.location)
107
+ done();
108
+ })
109
+ })
110
+ })
111
+ })
package/util/arquery.js CHANGED
@@ -92,10 +92,10 @@ async function executeARQuery(form, baseQuery, query, fields, options) {
92
92
  if (limit) {
93
93
  uri = uri + "&maxEntries=" + limit;
94
94
  }
95
- log.debug('start request on:', uri);
95
+ log.debug('start GET request on:', uri);
96
96
 
97
97
  const value = await request(uri).auth(process.env.AR_USER, process.env.AR_PASSWORD, true);
98
- log.debug('request done', uri, value);
98
+ log.debug('GET request done', uri, value);
99
99
 
100
100
  if (value && value.status && value.status === 'error') {
101
101
  throw new Error(value);
@@ -216,8 +216,8 @@ function createEntry(form, entryData, clientOptions) {
216
216
  json: true // Automatically stringifies the body to JSON
217
217
  };
218
218
 
219
- log.debug('start request with:', options.body);
220
- log.debug('start request on:', uri);
219
+ log.debug('start POST request with:', options.body);
220
+ log.debug('start POST request on:', uri);
221
221
  const singleRecord = Object.keys(finalEntries).length == 1;
222
222
  request(options).auth(process.env.AR_USER, process.env.AR_PASSWORD, true)
223
223
  .then(function (response) {
@@ -390,8 +390,8 @@ function updateEntry(form, id, entryData) {
390
390
  json: true // Automatically stringifies the body to JSON
391
391
  };
392
392
 
393
- log.debug('start request with:', options.body);
394
- log.debug('start request on:', uri);
393
+ log.debug('start PUT request with:', options.body);
394
+ log.debug('start PUT request on:', uri);
395
395
  request(options).auth(process.env.AR_USER, process.env.AR_PASSWORD, true)
396
396
  .then(function (response) {
397
397
  log.debug('RAPI update return', response);