@manyos/smileconnect-api 1.62.0 → 1.63.3

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
@@ -152,6 +152,8 @@ passport.use(
152
152
  const clientConfig = config.getClientConfig(clientId)
153
153
  clientConfig.clientId = clientId
154
154
 
155
+ req.clientId = clientId;
156
+
155
157
  const user = {
156
158
  'id': jwt_payload.sub,
157
159
  'azp': jwt_payload.azp,
@@ -196,7 +198,8 @@ const maxFilesize = process.env.MAX_FILESIZE || 5;
196
198
 
197
199
  app.use(fileUpload({
198
200
  limits: { fileSize: maxFilesize * 1024 * 1024 },
199
- abortOnLimit: true
201
+ abortOnLimit: true,
202
+ debug: true
200
203
  }));
201
204
 
202
205
  //global check for compatibility
@@ -265,7 +268,8 @@ app.use(function (req, res, next) {
265
268
  app.use(function (req, res, next) {
266
269
  req.globalScriptParams = {
267
270
  query: req.query,
268
- user: req.user
271
+ user: req.user,
272
+ log: log.child({req_id: req.id, clientId:req.clientId}, true)
269
273
  }
270
274
  // Für Scripte einen globalen parameter bereitstellen, der den org. Body enthält. Damit hat man auch noch in Post Scripten Zugriff auf customAttributes die beim Mapping entfernt werden.
271
275
  if (req.body) {
package/conf/clients.json CHANGED
@@ -128,6 +128,9 @@
128
128
  "fields": [],
129
129
  "constants": [],
130
130
  "scripts": {}
131
+ },
132
+ "options": {
133
+ "translateSelectionFields": true
131
134
  }
132
135
  }
133
136
  },
@@ -135,7 +138,8 @@
135
138
  "name": "smileconnectGui",
136
139
  "config": {
137
140
  "options": {
138
- "dateFormati": "dd.MM.yyyy HH:mm.ss"
141
+ "dateFormati": "dd.MM.yyyy HH:mm.ss",
142
+ "translateSelectionFields": true
139
143
  },
140
144
  "cmdbobject": {
141
145
  "basequery": "'Data Set Id' = \"BMC.ASSET\" AND ('Mark As Deleted' = \"No\" OR 'Mark As Deleted' = $NULL$)",
@@ -600,7 +604,8 @@
600
604
  "name": "ismsNeu",
601
605
  "config": {
602
606
  "options": {
603
- "dateFormati": "dd.MM.yyyy HH:mm.ss"
607
+ "dateFormati": "dd.MM.yyyy HH:mm.ss",
608
+ "translateSelectionFields": true
604
609
  },
605
610
  "cmdbobject": {
606
611
  "basequery": "'Data Set Id' = \"BMC.ASSET\" AND ('Mark As Deleted' = \"No\" OR 'Mark As Deleted' = $NULL$)",
@@ -1060,7 +1065,8 @@
1060
1065
  "name": "ismsNeu2",
1061
1066
  "config": {
1062
1067
  "options": {
1063
- "dateFormat": "dd.MM.yyyy HH:mm.ss"
1068
+ "dateFormat": "dd.MM.yyyy HH:mm.ss",
1069
+ "translateSelectionFields": true
1064
1070
  },
1065
1071
  "cmdbobject": {
1066
1072
  "basequery": "'Data Set Id' = \"BMC.ASSET\" AND ('Mark As Deleted' = \"No\" OR 'Mark As Deleted' = $NULL$)",
@@ -1519,7 +1525,8 @@
1519
1525
  "name": "robert2",
1520
1526
  "config": {
1521
1527
  "options": {
1522
- "dateFormati": "dd.MM.yyyy HH:mm.ss"
1528
+ "dateFormati": "dd.MM.yyyy HH:mm.ss",
1529
+ "translateSelectionFields": true
1523
1530
  },
1524
1531
  "cmdbobject": {
1525
1532
  "basequery": "'Data Set Id' = \"BMC.ASSET\" AND ('Mark As Deleted' = \"No\" OR 'Mark As Deleted' = $NULL$)",
@@ -1982,7 +1989,8 @@
1982
1989
  "clientLimit": 100000,
1983
1990
  "impersonateUser": "rhannemann",
1984
1991
  "allowDynamicImpersonate": true,
1985
- "translateSelectionFieldsX": false
1992
+ "translateSelectionFieldsX": false,
1993
+ "translateSelectionFields": true
1986
1994
  },
1987
1995
  "custom_Sample:Enrollments": {
1988
1996
  "basequery": "1=1",
@@ -2389,9 +2397,7 @@
2389
2397
  },
2390
2398
  "PUT": {
2391
2399
  "preMapping": [],
2392
- "postMapping": [
2393
- "notFetchResult"
2394
- ],
2400
+ "postMapping": [],
2395
2401
  "afterExecution": []
2396
2402
  }
2397
2403
  }
@@ -16,7 +16,13 @@ const {getClients, getClient, setClient} = require('../util/config');
16
16
  require('dotenv').config();
17
17
  const {NodeVM} = require('vm2');
18
18
 
19
- const adapterConfigScript = fs.readFileSync('conf/adapterConfig.js',{encoding: 'utf8'});
19
+ //try to read adapterConfig
20
+ let adapterConfigScript = `return {}`;
21
+ try {
22
+ adapterConfigScript = fs.readFileSync('conf/adapterConfig.js',{encoding: 'utf8'});
23
+ } catch (error) {
24
+ log.error(`Can't conf/adapterConfig.js - adapterFoundation not available.`, error);
25
+ }
20
26
 
21
27
  const adapter = adapterFoundation.getAdapter(adapterConfigScript);
22
28
 
@@ -80,7 +86,7 @@ async function executeCode(code, requestData, params, logStream, executedByScrip
80
86
  requestData,
81
87
  params,
82
88
  adapter,
83
- log,
89
+ log: globalScriptParams.log.child({script: scriptId}, true),
84
90
  clientId,
85
91
  xmlParser,
86
92
  script:executeScriptByScript,
@@ -445,6 +445,9 @@ async function updateTask(clientConfig, id, taskData, globalScriptParams) {
445
445
  await scriptController.runScripts(scripts.postMapping, taskData, clientConfig.clientId, globalScriptParams);
446
446
  }
447
447
 
448
+ //remove ticket id to prevent change
449
+ delete taskData['Task ID'];
450
+
448
451
  const result = await arquery.updateEntry('TMS:Task', id, taskData, clientConfig.options);
449
452
 
450
453
  //flow update
@@ -309,12 +309,17 @@ async function updateTicket(ticketConfig, clientConfig, id, ticketData, globalSc
309
309
  if (scripts && scripts.postMapping) {
310
310
  await scriptController.runScripts(scripts.postMapping, ticketData, clientConfig.clientId, globalScriptParams);
311
311
  }
312
+
312
313
  const ticket = await getTicket(ticketConfig, myClientConfig, id, myMapping, undefined, globalScriptParams);
313
314
  log.debug('Ticket to Update', ticket);
314
315
  //keep businessService CI Relation
315
316
  if (ticket && ticket.data && ticket.data.serviceReconId && relations) {
316
317
  relations.keepCIs = [ticket.data.serviceReconId]
317
318
  }
319
+
320
+ //remove ticket id to prevent change
321
+ delete ticketData[ticketConfig.ticketIdField];
322
+
318
323
  //todo Abfangen wenn getTicket nichts liefert.
319
324
  const update = await arquery.updateEntry(ticketConfig.forms.regular, ticket.data.internalId, ticketData, clientConfig.options);
320
325
  relationErrors = await ticketCIRelationController.updateRelations(ticketConfig, clientConfig, id, relations);
package/docs/_sidebar.md CHANGED
@@ -18,6 +18,12 @@
18
18
  - [Scripts](scripts)
19
19
  - [Adapter](adapter)
20
20
 
21
+ - Getting started
22
+
23
+ - [Introduction](getting-started/introduction)
24
+ - [Hands on](getting-started/hands-on)
25
+ - [Tips & Tricks](getting-started/tips)
26
+
21
27
  - How-Tos
22
28
 
23
29
  - [Authentication](howto/token)
package/docs/adapter.md CHANGED
@@ -584,6 +584,7 @@ The SMILEconnect adapter is an open source project.
584
584
  **secure**: Is secure communication use? True/False
585
585
 
586
586
  **auth.user**: User for SMTP Authentication
587
+
587
588
  **auth.pass**: Pass for SMTP Authentication
588
589
 
589
590
  ## Functions
@@ -626,6 +627,8 @@ const mailData = {
626
627
  text: "Hello world?", // plain text body
627
628
  html: "<b>Hello world?</b>", // html body
628
629
  }
630
+
631
+ const result = adapter.mail.sendMail(mailData);
629
632
  ```
630
633
 
631
634
  # DeepL
@@ -1,8 +1,15 @@
1
1
  # Architecture
2
2
 
3
- In this guide we will explain the different components of ISAPI and how you can use them.
3
+ In this guide we will explain the different components of SMILEconnect and how you can use them.
4
+
5
+ General logical architecture:
4
6
 
5
7
  ![architecure of smileconnect](_media/architecture.jpeg)
6
8
 
9
+ Deployment architecture in Kubernetes / Docker:
10
+
11
+ ![architecure of smileconnect](_media/architecture-deployment.png)
12
+
13
+ Dataflow incl. Authentication:
7
14
 
8
15
  ![architecure of smileconnect](_media/dataflow.png)
@@ -156,6 +156,10 @@ Sample:
156
156
 
157
157
  Loglevel of the api. Defaults to *error*
158
158
 
159
+ ### LOG_REQUEST
160
+
161
+ If set to true, the incoming request & headers will be written to the JsonValue field in the QueueForm.
162
+
159
163
  ## Rate Limits
160
164
 
161
165
  ### RATE_LIMIT
@@ -387,6 +391,9 @@ Use REACT_APP_OIDC_TOKEN to choose the token to use. Default is access_token
387
391
 
388
392
  Use REACT_APP_OIDC_SCOPE to choose the oidc scope
389
393
 
394
+ Use REACT_APP_CLIENT_SECRET to use confidential SSO client
395
+
396
+
390
397
  ## GUI
391
398
 
392
399
  ### REACT_APP_GUI_URL
@@ -0,0 +1,59 @@
1
+ # Hands-on Exercises
2
+
3
+ ## Setup Field Mapping
4
+
5
+ In this exercise, participants will learn how to configure the global field mapping for all SMILEconnect interfaces with BMC HELIX ITSM. Global field mapping ensures that BMC field names are translated into valid REST-compatible values, promoting seamless data transfer between systems.
6
+
7
+ SMILEconnect creates new records using the appropriate "Interface Create Forms." Occasionally, field names in BMC may differ between the standard forms and the "Interface Create Forms." To address this, SMILEconnect provides separate mappings for both the standard objects and the creation process. The system attempts to synchronize both mappings automatically to maintain consistency and data accuracy.
8
+
9
+ ### Review the mapping
10
+
11
+ ### Manage mappings
12
+
13
+ ### New vs. Normal Mappings
14
+
15
+ ## Configuring Clients
16
+
17
+ In this exercise, participants will learn how to configure client applications to interact with the SMILEconnect integrated REST API with BMC HELIX ITSM. Efficient client configuration is crucial for seamless communication and data exchange between various systems.
18
+
19
+ New clients are created by copying an existing client, which allows for the development of a library of clients. This library facilitates the rapid creation of new clients as needed, streamlining the process and reducing the time it takes to set up new connections.
20
+
21
+ ### View the client library
22
+
23
+ ### Copy a Client
24
+
25
+ ### Modify client configuration
26
+
27
+ For each object in a client, a base query is defined to determine which objects the client can see. For example, a client might only have access to incidents within its own support groups. Then, for each object, the attributes that the client can view are specified.
28
+
29
+ In addition to attribute visibility, constant values can be predefined for specific attributes. These constant values cannot be overwritten by the client. This feature can be used to:
30
+
31
+ * Provide default values for certain attributes, reducing the need for the client to supply them (e.g., a template ID).
32
+
33
+ * Restrict the client from modifying specific attributes, such as the ticket priority, ensuring that only authorized users or systems can make changes.
34
+
35
+ ### Setup Base query
36
+
37
+ ### Manage fields
38
+
39
+ ### Manage constants
40
+
41
+ ## Todo
42
+
43
+ * Creating and Updating Tickets
44
+
45
+ * Search for Data
46
+
47
+ * Creating and Reading Worklogs
48
+
49
+ * Handling Attachments
50
+
51
+ * Querying Assets and Configuration Items (CIs)
52
+
53
+ * Creating Outbound Events
54
+
55
+ * Using Scripts for advanced workflows
56
+
57
+ * Understanding Script Timing
58
+
59
+ * Troubleshooting and Debugging
@@ -0,0 +1,56 @@
1
+ # Introduction to SMILEconnect REST API
2
+
3
+ ## Overview of SMILEconnect
4
+
5
+ The primary objective of integrating SMILEconnect with BMC HELIX ITSM is to provide ITSM departments with a powerful and flexible solution for creating and managing new interfaces rapidly. This integration focuses on the following key aspects:
6
+
7
+ * Streamlined Interface Creation: With SMILEconnect, ITSM teams can create new interfaces in minutes, reducing the time and effort required to establish connections between various systems and applications.
8
+
9
+ * Minimal Customization: SMILEconnect integration does not require any customization of the ITSM system, allowing for seamless implementation without altering the existing setup. This approach ensures smooth operation and compatibility with future updates.
10
+
11
+ * Configurable Workflows: Despite the minimal customization requirements, SMILEconnect enables ITSM departments to design and configure complex workflows that cater to their specific needs. This flexibility ensures that organizations can adapt to changing requirements and streamline their processes.
12
+
13
+ * Future-proof ITSM Systems: As interfaces play a crucial role in the evolution of ITSM systems, integrating SMILEconnect with BMC HELIX ITSM helps organizations stay ahead of the curve by providing a scalable and adaptable solution for managing various interfaces.
14
+
15
+ * Enhanced Collaboration: The integration of SMILEconnect facilitates better communication and collaboration between different teams and departments within the organization. By offering a unified platform for managing interfaces, SMILEconnect fosters efficient information exchange and streamlined processes.
16
+
17
+ * Automatic Documentation Generation: SMILEconnect is capable of automatically generating individual documentation for each interface created. This feature ensures that interface partners can quickly and efficiently implement the interface on their end. By providing comprehensive documentation, potential misunderstandings or misconfigurations can be minimized, resulting in faster implementation and a more reliable connection between systems.
18
+
19
+ By addressing these objectives, the SMILEconnect integration with BMC HELIX ITSM aims to enhance the overall efficiency and effectiveness of ITSM departments, ensuring they can meet the ever-evolving needs of their organizations.
20
+
21
+ ## What is a REST API?
22
+
23
+ This section provides an overview of the basic concepts and principles of REST APIs to help participants understand the underlying technology used in SMILEconnect and BMC HELIX ITSM integration.
24
+
25
+ ### What is a REST API?
26
+
27
+ REST (Representational State Transfer) is an architectural style used for designing networked applications. A REST API (Application Programming Interface) allows communication between different software systems using standard HTTP methods. It is designed to be simple, stateless, and scalable, making it a popular choice for modern web services.
28
+
29
+ ### HTTP Methods and Status Codes
30
+
31
+ REST APIs utilize HTTP methods to interact with resources. The most common HTTP methods include:
32
+
33
+ * GET: Retrieves data from a specified resource.
34
+ * POST: Submits new data to a resource, creating a new object.
35
+ * PUT: Updates an existing resource with new data.
36
+ * DELETE: Removes a specified resource.
37
+
38
+ HTTP status codes are three-digit numbers that indicate the outcome of an HTTP request. Some common status codes include:
39
+
40
+ * 200 OK: The request was successful.
41
+ * 201 Created: The request has created a new resource.
42
+ * 400 Bad Request: The request was malformed or invalid.
43
+ * 401 Unauthorized: The request requires authentication.
44
+ * 403 Forbidden: The requester lacks permission to access the resource.
45
+ * 404 Not Found: The requested resource could not be found.
46
+ * 500 Internal Server Error: The server encountered an error while processing the request.
47
+
48
+ ### Authentication and Authorization
49
+
50
+ Security is crucial for REST APIs, and SMILEconnect uses OAuth for authentication. OAuth is a standardized method that allows users to grant third-party applications limited access without sharing their credentials. In most organizations, an Identity Provider (IdP) is already in place and can be used for OAuth authentication.
51
+
52
+ ### API Endpoints and Resources
53
+
54
+ An API endpoint is a specific address (URL) used to access and interact with resources in an API. Resources are the data objects and services that the API provides access to. In SMILEconnect, automatically provided endpoints cover ITSM objects such as Incident, Problem, Change, Work Order, Task, Assets, and Worklogs. Each endpoint is associated with a specific HTTP method to perform actions such as creating, retrieving, updating, or deleting resources.
55
+
56
+ In summary, understanding the fundamentals of REST APIs helps participants effectively utilize the SMILEconnect integration with BMC HELIX ITSM. Familiarity with these concepts, including OAuth authentication and the automatically provided endpoints, ensures that participants can design, configure, and maintain interfaces, optimizing their ITSM processes and adapting to ever-changing organizational needs.
@@ -0,0 +1,7 @@
1
+ # Best Practices and Tips
2
+
3
+ * API Rate Limits and Performance
4
+ * Data Validation and Cleansing
5
+ * Maintenance and Updating the Integration
6
+ * Useful Resources and Links
7
+ * Support and Contact Information
package/docs/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.0.2",
3
3
  "info": {
4
4
  "title": "SMILEconnect",
5
- "version": "1.47.0",
5
+ "version": "1.63.0",
6
6
  "contact": {
7
7
  "name": "manyos technology GmbH",
8
8
  "url": "https://manyos.it",
@@ -4536,6 +4536,34 @@
4536
4536
  "required": true
4537
4537
  }
4538
4538
  ]
4539
+ },
4540
+ "/health": {
4541
+ "get": {
4542
+ "tags": [
4543
+ "AppConfig"
4544
+ ],
4545
+ "responses": {
4546
+ "200": {
4547
+ "content": {
4548
+ "application/json": {
4549
+ "schema": {
4550
+ "$ref": "#/components/schemas/HealthStatus"
4551
+ },
4552
+ "examples": {
4553
+ "healthResponse": {
4554
+ "value": {
4555
+ "status": "ok"
4556
+ }
4557
+ }
4558
+ }
4559
+ }
4560
+ },
4561
+ "description": "Returns ok if API is up."
4562
+ }
4563
+ },
4564
+ "summary": "Get API health status",
4565
+ "description": "Responds with 200 if API is ready. No auth needed."
4566
+ }
4539
4567
  }
4540
4568
  },
4541
4569
  "components": {
@@ -16339,6 +16367,19 @@
16339
16367
  "description": ""
16340
16368
  }
16341
16369
  }
16370
+ },
16371
+ "HealthStatus": {
16372
+ "title": "Root Type for HealthStatus",
16373
+ "description": "",
16374
+ "type": "object",
16375
+ "properties": {
16376
+ "status": {
16377
+ "type": "string"
16378
+ }
16379
+ },
16380
+ "example": {
16381
+ "status": "ok"
16382
+ }
16342
16383
  }
16343
16384
  },
16344
16385
  "responses": {
package/docs/releases.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # Release Notes
2
2
 
3
3
  ## API
4
+ ### 1.63.0 - 10.01.23
5
+ Security fix for jsonwebtoken https://github.com/advisories/GHSA-27h2-hvpr-p74q
6
+
4
7
  ### 1.62.0 - 18.11.22
5
8
  Add Deepl Translation Adapter
6
9
 
@@ -182,6 +185,9 @@ e.g.
182
185
  */v1/incidents?impersonateUser=abc123
183
186
 
184
187
  ## Event Manager
188
+ ### 1.29.1 - 10.01.23
189
+ Security fix for jsonwebtoken https://github.com/advisories/GHSA-27h2-hvpr-p74q
190
+
185
191
  ### 1.29.0 - 18.11.22
186
192
  Add Deepl Translation Adapter
187
193
 
@@ -226,6 +232,12 @@ The eventmanager will check all outbound webhooks for an event. If one fails, th
226
232
 
227
233
  ## GUI
228
234
 
235
+ ### 1.11.0 - 05.04.23
236
+ Feat: Add REACT_APP_CLIENT_SECRET Parameter to allow confidential SSO clients
237
+
238
+ ### 1.10.3 - 29.03.23
239
+ Fixed: GUI crash when customForm name contains blank.
240
+
229
241
  ### 1.10.2 - 30.09.22
230
242
  Fixed: openApi page is not loading.
231
243
 
package/docs/scripts.md CHANGED
@@ -266,6 +266,14 @@ const myInstanceId = uid();
266
266
  requestData['Instance Id'] = myInstanceId;
267
267
  ```
268
268
 
269
+ ## customHeaders
270
+
271
+ Allows custom headers in outbound events.
272
+
273
+ ```javascript
274
+ customHeaders['X-API-GATEWAYUSER'] = 'gatewayuser1';
275
+ ```
276
+
269
277
  # Returning values
270
278
 
271
279
  Values can be returned with the function *resolve()*
@@ -311,23 +319,25 @@ This script looks up the previous assignment group if an incident is set to "ass
311
319
  //lookup Previous Assigned Support Group for Incident
312
320
  // and assign this group if status is changed to "assigned", and assignedGroup is not set.
313
321
 
322
+ if ( globalScriptParams && globalScriptParams.id && requestData['status']=="Assigned" && !requestData.hasOwnProperty("assignedGroup") ) {
314
323
 
315
- if ( requestData['id'] && requestData['status']=="Assigned" && !requestData.hasOwnProperty("assignedGroup") ) {
316
- const remedyResult = await adapter.remedy.search("HPD:Help Desk Assignment Log", `'Incident Number' = "${requestData.id}"`, "Submit Date,Assigned Support Company,Assigned Support Organization,Assigned Group,Assigned Group ID")
317
-
318
- if (remedyResult && remedyResult.data && Array.isArray(remedyResult.data)) {
319
- const data = remedyResult.data;
320
- let entry = 0;
321
- if (data.length > 1) {
322
- entry = data.length - 2;
323
- }
324
-
325
- if (data[entry] && data[entry].hasOwnProperty("Assigned Group ID")) {
326
- requestData['assignedGroup'] = data[entry]['Assigned Group ID'];
327
- } else {
328
- reject("could not find previous group. automatic re-ssignement failed. set assigendGroup manually")
324
+ const remedyOptions = {
325
+ limit: 1,
326
+ sort: {
327
+ "Last Date Duration Calculated": -1
329
328
  }
330
-
329
+ }
330
+
331
+ const remedyResult = await adapter.remedy.search("HPD:Help Desk Assignment Log", `'Incident Number' = "${globalScriptParams.id}"`, "Submit Date, Assigned Support Company, Assigned Support Organization, Assigned Group, Assigned Group ID", remedyOptions);
332
+
333
+ if (remedyResult && remedyResult.data && Array.isArray(remedyResult.data) && remedyResult.data.length > 0) {
334
+ const prevGroupData = remedyResult.data[0];
335
+ requestData.assignedGroup = prevGroupData['Assigned Group ID'];
336
+ requestData.assignedCompany = prevGroupData['Assigned Support Company'];
337
+ requestData.assignedSupportOrg = prevGroupData['Assigned Support Organization'];
338
+ requestData.assignedGroupName = prevGroupData['Assigned Group'];
339
+ } else {
340
+ reject("could not find previous group. automatic re-ssignement failed. set assigendGroup manually")
331
341
  }
332
342
  }
333
343
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyos/smileconnect-api",
3
- "version": "1.62.0",
3
+ "version": "1.63.3",
4
4
  "description": "A proxy and abstraction layer for BMCs IT Service Management Suite",
5
5
  "main": "app.js",
6
6
  "scripts": {
@@ -10,6 +10,9 @@
10
10
  },
11
11
  "author": "Robert Hannemann",
12
12
  "license": "ISC",
13
+ "engines": {
14
+ "node": ">=0.10.3"
15
+ },
13
16
  "dependencies": {
14
17
  "@manyos/adapter-foundation": "^1.1.2",
15
18
  "@manyos/logger": "^1.3.0",
@@ -19,7 +22,7 @@
19
22
  "cors": "^2.8.4",
20
23
  "dotenv": "^4.0.0",
21
24
  "express": "^4.17.1",
22
- "express-fileupload": "^1.2.1",
25
+ "express-fileupload": "^1.3.1",
23
26
  "express-rate-limit": "^5.2.6",
24
27
  "express-request-id": "^1.4.1",
25
28
  "express-validator": "^6.10.1",
@@ -2,6 +2,7 @@ const path = require('path');
2
2
  const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
3
3
  const {body, validationResult, oneOf} = require('express-validator/check');
4
4
  const ticketWorkLogController = require('../controller/ticketWorkLogController');
5
+ const ticketValidationUtil = require('../util/ticketValidationUtil');
5
6
  const eventLog = require('../controller/eventLogController');
6
7
  const CONSTANTS = require('../util/constants');
7
8
 
@@ -13,6 +14,25 @@ module.exports = (function() {
13
14
  return `${location}[${param}]: ${msg}`;
14
15
  };
15
16
 
17
+ ticketWorkLogRoutes.use(async function (req, res, next) {
18
+ const id = req.parentId;
19
+ log.debug('Check Ticket Access and Id');
20
+
21
+ const ticket = await ticketValidationUtil.checkTicket(req.ticketConfig, id, req.globalScriptParams);
22
+ log.error(ticket);
23
+
24
+ if (ticket && ticket.data) {
25
+ if (ticket.data.id) {
26
+ req.parentId = ticket.data.id;
27
+ }
28
+ log.error(ticket.data.id);
29
+ next();
30
+ } else {
31
+ req.errorStatus = 404;
32
+ next(`Ticket ${id} does not exist`);
33
+ }
34
+ });
35
+
16
36
  ticketWorkLogRoutes.get('/', function (req, res, next) {
17
37
  const id = req.parentId;
18
38
  eventLog.setEventData(
package/util/config.js CHANGED
@@ -284,6 +284,15 @@ function checkClientConfig(client) {
284
284
  clientConfig[clientKey] = clientConfigItemTemplate;
285
285
  }
286
286
  });
287
+
288
+ if (!clientConfig.options) {
289
+ clientConfig.options = {};
290
+ }
291
+
292
+ if (clientConfig.options.translateSelectionFields === undefined) {
293
+ clientConfig.options.translateSelectionFields = true;
294
+ }
295
+
287
296
  client.config = clientConfig;
288
297
  //save
289
298
  setClient(client.name, client);
@@ -72,6 +72,19 @@ function eventQueueHandler(req, res, next) {
72
72
  //write to eventQueue if provided
73
73
  if (req.eventData) {
74
74
  const eventData = req.eventData;
75
+ if (process.env.LOG_REQUEST && (process.env.LOG_REQUEST === true || process.env.LOG_REQUEST.toLowerCase() === 'true')) {
76
+ if (!eventData.jsonData) {
77
+ eventData.jsonData = {};
78
+ }
79
+ eventData.jsonData['req'] = {
80
+ headers: req.headers,
81
+ body: req.body
82
+ }
83
+ // remove auth header
84
+ if (eventData.jsonData.req && eventData.jsonData.req.headers && eventData.jsonData.req.headers.authorization) {
85
+ eventData.jsonData.req.headers.authorization = '*** REMOVED ***';
86
+ }
87
+ }
75
88
  eventLog.createSuccessLog(
76
89
  req.id,
77
90
  req.user.config.clientId,
@@ -0,0 +1,36 @@
1
+ const path = require('path');
2
+ const ticketController = require("../controller/ticketController");
3
+ const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
4
+
5
+
6
+ async function checkTicket(ticketConfig, id, globalScriptParams) {
7
+ const myClientConfig = {};
8
+ const fields = [];
9
+ const myMapping = [];
10
+ const requestType = ticketConfig.requestType;
11
+ if (requestType === 'incident') {
12
+ fields.push('Incident Number');
13
+ myMapping.push({"oldName":'Incident Number', "newName" : "id"});
14
+ } else if (requestType === 'change') {
15
+ fields.push('Infrastructure Change ID');
16
+ myMapping.push({"oldName":'Infrastructure Change ID', "newName" : "id"});
17
+ } else if (requestType === 'problem') {
18
+ fields.push('Problem Investigation ID');
19
+ myMapping.push({"oldName":'Problem Investigation ID', "newName" : "id"});
20
+ } else if (requestType === 'workOrder') {
21
+ fields.push('Work Order ID');
22
+ myMapping.push({"oldName":'Work Order ID', "newName" : "id"});
23
+ }
24
+
25
+ //An dieser Stelle könnte auch die Basequery vom User verwendet werden. Dann gibt es nur noch Zugriff auf Tickets die der User auch sieht. Am besten per Config steuern.
26
+
27
+ myClientConfig[ticketConfig.requestType] = {
28
+ baseQuery: '1=1',
29
+ fields
30
+ };
31
+ return await ticketController.getTicket(ticketConfig, myClientConfig, id, myMapping, undefined, globalScriptParams);
32
+ };
33
+
34
+ module.exports = {
35
+ checkTicket
36
+ };