@frangoteam/fuxa-min 1.2.3 → 1.2.5

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.
Files changed (156) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +2 -1
  3. package/api/command/index.js +2 -2
  4. package/api/index.js +5 -0
  5. package/api/jwt-helper.js +24 -13
  6. package/api/projects/index.js +14 -9
  7. package/api/resources/index.js +46 -1
  8. package/api/scripts/index.js +3 -3
  9. package/dist/3rdpartylicenses.txt +30 -0
  10. package/dist/assets/i18n/de.json +12 -12
  11. package/dist/assets/i18n/en.json +93 -8
  12. package/dist/assets/i18n/es.json +63 -64
  13. package/dist/assets/i18n/fr.json +10 -7
  14. package/dist/assets/i18n/ko.json +8 -8
  15. package/dist/assets/i18n/pt.json +5 -5
  16. package/dist/assets/i18n/ru.json +14 -14
  17. package/dist/assets/i18n/sv.json +1691 -0
  18. package/dist/assets/i18n/tr.json +52 -52
  19. package/dist/assets/i18n/ua.json +4 -4
  20. package/dist/assets/i18n/zh-cn.json +19 -11
  21. package/dist/assets/images/marker-icon.png +0 -0
  22. package/dist/assets/images/marker-shadow.png +0 -0
  23. package/dist/assets/lib/svgeditor/extensions/ext-bundle.min.js +1 -1
  24. package/dist/assets/lib/svgeditor/fuxa-editor.min.js +7 -7
  25. package/dist/assets/lib/svgeditor/shapes/img/shape-circlehalf.svg +13 -0
  26. package/dist/assets/lib/svgeditor/shapes/img/shape-radiuskorner.svg +13 -0
  27. package/dist/assets/lib/svgeditor/shapes/my-shapes.js +21 -13
  28. package/dist/index.html +2 -2
  29. package/dist/layers-2x.9859cd1231006a4a.png +0 -0
  30. package/dist/layers.ef6db8722c2c3f9a.png +0 -0
  31. package/dist/main.ba5fa312f4ed2f21.js +329 -0
  32. package/dist/marker-icon.d577052aa271e13f.png +0 -0
  33. package/dist/{styles.fde36dafd04e2e1d.css → styles.fa64b052ace779bf.css} +1 -1
  34. package/main.js +13 -2
  35. package/package.json +9 -4
  36. package/runtime/alarms/index.js +3 -2
  37. package/runtime/devices/device-utils.js +1 -1
  38. package/runtime/devices/device.js +13 -3
  39. package/runtime/devices/gpio/index.js +296 -0
  40. package/runtime/devices/index.js +1 -1
  41. package/runtime/devices/modbus/index.js +1 -1
  42. package/runtime/devices/mqtt/index.js +0 -1
  43. package/runtime/devices/opcua/index.js +1 -0
  44. package/runtime/index.js +26 -14
  45. package/runtime/plugins/index.js +3 -3
  46. package/runtime/project/index.js +117 -10
  47. package/runtime/project/prjstorage.js +15 -12
  48. package/runtime/scripts/index.js +15 -5
  49. package/runtime/scripts/msm.js +4 -0
  50. package/runtime/storage/influxdb/index.js +4 -7
  51. package/runtime/users/usrstorage.js +11 -9
  52. package/runtime/utils.js +30 -1
  53. package/screenshot/fuxa-thinglinks.gif +0 -0
  54. package/settings.default.js +9 -3
  55. package/_widgets/controls/draggingIndicatorExample.svg +0 -243
  56. package/_widgets/controls/timePickerHHmmSS.svg +0 -396
  57. package/_widgets/controls/timePickerHHmmSSsss.svg +0 -428
  58. package/_widgets/dynamicSVG/blower3.svg +0 -282
  59. package/_widgets/dynamicSVG/blower3_flipped.svg +0 -282
  60. package/_widgets/dynamicSVG/blower4.svg +0 -304
  61. package/_widgets/dynamicSVG/blower4_flipped.svg +0 -304
  62. package/_widgets/dynamicSVG/checkvalve_closed.svg +0 -333
  63. package/_widgets/dynamicSVG/checkvalve_closed_flipped.svg +0 -333
  64. package/_widgets/dynamicSVG/checkvalve_open.svg +0 -316
  65. package/_widgets/dynamicSVG/checkvalve_open_flipped.svg +0 -316
  66. package/_widgets/dynamicSVG/compressor3.svg +0 -361
  67. package/_widgets/dynamicSVG/compressor6.svg +0 -299
  68. package/_widgets/dynamicSVG/condensor_3d_h1.svg +0 -300
  69. package/_widgets/dynamicSVG/conveyor.svg +0 -316
  70. package/_widgets/dynamicSVG/conveyor4.svg +0 -314
  71. package/_widgets/dynamicSVG/conveyor_20degdecline.svg +0 -341
  72. package/_widgets/dynamicSVG/conveyor_20degincline.svg +0 -340
  73. package/_widgets/dynamicSVG/cyclonicseparator.svg +0 -317
  74. package/_widgets/dynamicSVG/fanblades.svg +0 -280
  75. package/_widgets/dynamicSVG/flange_3d_1.svg +0 -286
  76. package/_widgets/dynamicSVG/flowmeter.svg +0 -305
  77. package/_widgets/dynamicSVG/flowmeter1.svg +0 -281
  78. package/_widgets/dynamicSVG/gaugedial_3d_h1.svg +0 -288
  79. package/_widgets/dynamicSVG/generator_1.svg +0 -534
  80. package/_widgets/dynamicSVG/heatexchanger_pipetopipe.svg +0 -329
  81. package/_widgets/dynamicSVG/heatexchanger_shelltube.svg +0 -329
  82. package/_widgets/dynamicSVG/heatexchanger_singlepipetopipe.svg +0 -299
  83. package/_widgets/dynamicSVG/meter_3d_h1.svg +0 -299
  84. package/_widgets/dynamicSVG/meter_3d_h2.svg +0 -293
  85. package/_widgets/dynamicSVG/mixer1.svg +0 -369
  86. package/_widgets/dynamicSVG/motor.svg +0 -285
  87. package/_widgets/dynamicSVG/motor1.svg +0 -300
  88. package/_widgets/dynamicSVG/motor1_flipped.svg +0 -300
  89. package/_widgets/dynamicSVG/motor_wshaft.svg +0 -325
  90. package/_widgets/dynamicSVG/pipe_3d_elbow.svg +0 -287
  91. package/_widgets/dynamicSVG/pipe_3d_elbow2.svg +0 -285
  92. package/_widgets/dynamicSVG/pipe_3d_h1.svg +0 -286
  93. package/_widgets/dynamicSVG/pipe_3d_h2.svg +0 -287
  94. package/_widgets/dynamicSVG/pipe_3d_h3.svg +0 -286
  95. package/_widgets/dynamicSVG/pipe_3d_heatexchange1.svg +0 -298
  96. package/_widgets/dynamicSVG/pipe_3d_heatexchange2.svg +0 -293
  97. package/_widgets/dynamicSVG/pipe_3d_heatexchange3.svg +0 -289
  98. package/_widgets/dynamicSVG/pipe_3d_tjunction.svg +0 -286
  99. package/_widgets/dynamicSVG/piperedirect1.svg +0 -294
  100. package/_widgets/dynamicSVG/piperedirect1_flipped.svg +0 -294
  101. package/_widgets/dynamicSVG/pressure_regulator.svg +0 -374
  102. package/_widgets/dynamicSVG/pulsationdampener.svg +0 -300
  103. package/_widgets/dynamicSVG/pump1.svg +0 -328
  104. package/_widgets/dynamicSVG/pump2.svg +0 -310
  105. package/_widgets/dynamicSVG/pump2_flipped.svg +0 -310
  106. package/_widgets/dynamicSVG/pump_3d_180.svg +0 -323
  107. package/_widgets/dynamicSVG/pump_3d_180_flipped.svg +0 -323
  108. package/_widgets/dynamicSVG/pump_3d_90_1.svg +0 -318
  109. package/_widgets/dynamicSVG/pump_3d_90_1_flipped.svg +0 -318
  110. package/_widgets/dynamicSVG/pump_3d_example.svg +0 -292
  111. package/_widgets/dynamicSVG/pump_3d_straight1.svg +0 -321
  112. package/_widgets/dynamicSVG/pump_3d_straight1_flipped.svg +0 -321
  113. package/_widgets/dynamicSVG/pumphead_profile_3d.svg +0 -303
  114. package/_widgets/dynamicSVG/reducer_3d_1.svg +0 -290
  115. package/_widgets/dynamicSVG/reducer_3d_2.svg +0 -287
  116. package/_widgets/dynamicSVG/sensor_rtd.svg +0 -391
  117. package/_widgets/dynamicSVG/sensor_rtd_silhouette.svg +0 -286
  118. package/_widgets/dynamicSVG/strainer_basket.svg +0 -376
  119. package/_widgets/dynamicSVG/strainer_basket_r.svg +0 -377
  120. package/_widgets/dynamicSVG/strainer_wye.svg +0 -401
  121. package/_widgets/dynamicSVG/strainer_wye_r.svg +0 -403
  122. package/_widgets/dynamicSVG/tank_3d_medium_rtop1.svg +0 -286
  123. package/_widgets/dynamicSVG/tank_3d_v1.svg +0 -291
  124. package/_widgets/dynamicSVG/tank_3d_v2.svg +0 -295
  125. package/_widgets/dynamicSVG/tank_3d_v4.svg +0 -290
  126. package/_widgets/dynamicSVG/tank_3d_v5.svg +0 -295
  127. package/_widgets/dynamicSVG/tank_3d_v6.svg +0 -290
  128. package/_widgets/dynamicSVG/tank_3d_v7.svg +0 -292
  129. package/_widgets/dynamicSVG/trucking.svg +0 -297
  130. package/_widgets/dynamicSVG/turbine1.svg +0 -284
  131. package/_widgets/dynamicSVG/turbine2.svg +0 -329
  132. package/_widgets/dynamicSVG/turbinerounded.svg +0 -291
  133. package/_widgets/dynamicSVG/valve_1path_down.svg +0 -291
  134. package/_widgets/dynamicSVG/valve_3d_3way1.svg +0 -329
  135. package/_widgets/dynamicSVG/valve_3d_3way1_nopipe.svg +0 -310
  136. package/_widgets/dynamicSVG/valve_3d_4way1.svg +0 -358
  137. package/_widgets/dynamicSVG/valve_3d_4way1_nopipe.svg +0 -328
  138. package/_widgets/dynamicSVG/valve_3d_angled1.svg +0 -325
  139. package/_widgets/dynamicSVG/valve_3d_angled1_nopipe.svg +0 -305
  140. package/_widgets/dynamicSVG/valve_3d_angled2.svg +0 -323
  141. package/_widgets/dynamicSVG/valve_3d_angled2_nopipe.svg +0 -301
  142. package/_widgets/dynamicSVG/valve_3d_common1.svg +0 -321
  143. package/_widgets/dynamicSVG/valve_3d_common2.svg +0 -327
  144. package/_widgets/dynamicSVG/valve_3d_common2_nopipe.svg +0 -298
  145. package/_widgets/dynamicSVG/valve_3d_common3.svg +0 -327
  146. package/_widgets/dynamicSVG/valve_3d_common4.svg +0 -329
  147. package/_widgets/dynamicSVG/valve_3d_common4_nopipe.svg +0 -299
  148. package/_widgets/dynamicSVG/valve_3d_h1.svg +0 -286
  149. package/_widgets/dynamicSVG/valve_3d_h2_closed.svg +0 -299
  150. package/_widgets/dynamicSVG/valve_3d_h2_open.svg +0 -291
  151. package/_widgets/dynamicSVG/valve_circle.svg +0 -295
  152. package/_widgets/indicators/analogIndicatorExample.svg +0 -272
  153. package/_widgets/indicators/timeDisplayHHmmSS.svg +0 -160
  154. package/_widgets/indicators/timeDisplayHHmmSSsss.svg +0 -164
  155. package/dist/main.060518cfc6cd1872.js +0 -329
  156. package/screenshot/fuxa-ani.gif +0 -0
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019-2021 frangoteam 4frango@gmail.com
3
+ Copyright (c) 2019-2025 frangoteam info@frangoteam.org
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -4,7 +4,7 @@ FUXA is a web-based Process Visualization (SCADA/HMI/Dashboard) software. With F
4
4
 
5
5
  ![fuxa editor](/screenshot/fuxa-editor.png)
6
6
 
7
- ![fuxa ani](/screenshot/fuxa-ani.gif)
7
+ ![fuxa ani](/screenshot/fuxa-thinglinks.gif)
8
8
 
9
9
  ![fuxa action](/screenshot/feature-action-move.gif)
10
10
 
@@ -20,6 +20,7 @@ Here is a [live demo](https://frangoteam.github.io) example of FUXA editor.
20
20
  FUXA is developed with NodeJS (backend) and Angular (frontend).
21
21
 
22
22
  **WARNING** You need to have installed [Node](https://nodejs.org/en/about/previous-releases) Version 14 || 16 || 18
23
+ If you don't intend communicate with Siemens PLCs via S7 (node-snap7 library) you can install from [NPM @frangoteam/fuxa-min](https://www.npmjs.com/package/@frangoteam/fuxa-min)
23
24
 
24
25
  Install from [NPM](https://www.npmjs.com/package/@frangoteam/fuxa)
25
26
  ```
@@ -71,8 +71,8 @@ module.exports = {
71
71
  const permission = checkGroupsFnc(req);
72
72
  if (res.statusCode === 403) {
73
73
  runtime.logger.error("api get getTagValue: Tocken Expired");
74
- } else if (!authJwt.haveAdminPermission(permission)) {
75
- res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"});
74
+ } else if (!authJwt.haveAdminPermission(permission) && !runtime.scriptsMgr.isAuthorisedByScriptName(req.query.sourceScriptName, permission)) {
75
+ res.status(400).json({error:"unauthorized_error", message: "Unauthorized!"});
76
76
  runtime.logger.error("api get getTagValue: Unauthorized");
77
77
  } else {
78
78
  try {
package/api/index.js CHANGED
@@ -134,6 +134,11 @@ function init(_server, _runtime) {
134
134
  } else {
135
135
  res.end();
136
136
  }
137
+ } else if (req.userId === 'guest') {
138
+ res.status(200).json({
139
+ message: 'guest',
140
+ token: authJwt.getGuestToken()
141
+ });
137
142
  } else {
138
143
  res.end();
139
144
  }
package/api/jwt-helper.js CHANGED
@@ -20,7 +20,7 @@ function init(_secureEnabled, _secretCode, _tokenExpires) {
20
20
 
21
21
  /**
22
22
  * Verify token
23
- * @param {*} token
23
+ * @param {*} token
24
24
  */
25
25
  function verify (token) {
26
26
  return new Promise ((resolve, reject) => {
@@ -31,29 +31,28 @@ function verify (token) {
31
31
  } else {
32
32
  resolve(true);
33
33
  }
34
- });
34
+ });
35
35
  });
36
36
  }
37
37
 
38
38
  /**
39
39
  * Verify WebAPI token (take from header)
40
- * @param {*} req
40
+ * @param {*} req
41
41
  * @param {*} res
42
42
  * @param {*} next
43
43
  */
44
44
  function verifyToken (req, res, next) {
45
45
  let token = req.headers['x-access-token'];
46
46
 
47
+ if (!token) {
48
+ token = getGuestToken();
49
+ }
50
+
47
51
  if (token) {
48
52
  jwt.verify(token, secretCode, (err, decoded) => {
49
53
  if (err) {
50
- req.userId = null;
51
- req.userGroups = null;
52
- if (err.name === 'TokenExpiredError' || err.name === 'JsonWebTokenError') {
53
- req.tokenExpired = true;
54
- res.status(403).json({error:"unauthorized_error", message: "Token Expired!"});
55
- }
56
- next();
54
+ req.userId = "guest";
55
+ req.userGroups = ["guest"];
57
56
  } else {
58
57
  req.userId = decoded.id;
59
58
  req.userGroups = decoded.groups;
@@ -63,8 +62,8 @@ function verifyToken (req, res, next) {
63
62
  res.status(403).json({ error: "unauthorized_error", message: "User Profile Corrupted!" });
64
63
  }
65
64
  }
66
- next();
67
65
  }
66
+ next();
68
67
  });
69
68
  } else {
70
69
  // notice that no token was provided...}
@@ -84,13 +83,24 @@ function getNewToken(headers) {
84
83
  id: authUser.user,
85
84
  groups: authUser.groups
86
85
  },
87
- secretCode, {
88
- expiresIn: tokenExpiresIn
86
+ secretCode, {
87
+ expiresIn: tokenExpiresIn
89
88
  });
90
89
  }
91
90
  return null;
92
91
  }
93
92
 
93
+ function getGuestToken() {
94
+ const token = jwt.sign({
95
+ id: "guest",
96
+ groups: ["guest"]
97
+ },
98
+ secretCode, {
99
+ expiresIn: tokenExpiresIn
100
+ });
101
+ return token;
102
+ }
103
+
94
104
  function haveAdminPermission(permission) {
95
105
  if (permission === null || permission === undefined) {
96
106
  return false;
@@ -110,6 +120,7 @@ module.exports = {
110
120
  verify: verify,
111
121
  verifyToken: verifyToken,
112
122
  getNewToken: getNewToken,
123
+ getGuestToken: getGuestToken,
113
124
  get secretCode() { return secretCode },
114
125
  get tokenExpiresIn() { return tokenExpiresIn },
115
126
  haveAdminPermission: haveAdminPermission,
@@ -29,7 +29,7 @@ module.exports = {
29
29
 
30
30
  /**
31
31
  * GET Project data
32
- * Take from project storage and reply
32
+ * Take from project storage and reply
33
33
  */
34
34
  prjApp.get("/api/project", secureFnc, function(req, res) {
35
35
  const permission = checkGroupsFnc(req);
@@ -113,7 +113,7 @@ module.exports = {
113
113
 
114
114
  /**
115
115
  * GET Project demo data
116
- * Take the project demo file from server folder
116
+ * Take the project demo file from server folder
117
117
  */
118
118
  prjApp.get("/api/projectdemo", secureFnc, function (req, res) {
119
119
  const data = runtime.project.getProjectDemo();
@@ -129,7 +129,7 @@ module.exports = {
129
129
 
130
130
  /**
131
131
  * GET Device property like security
132
- * Take from project storage and reply
132
+ * Take from project storage and reply
133
133
  */
134
134
  prjApp.get("/api/device", secureFnc, function(req, res) {
135
135
  const permission = checkGroupsFnc(req);
@@ -181,7 +181,7 @@ module.exports = {
181
181
  res.status(400).json({error:"unexpected_error", message: err});
182
182
  runtime.logger.error("api post device: " + err);
183
183
  }
184
- });
184
+ });
185
185
  }
186
186
  });
187
187
 
@@ -198,20 +198,25 @@ module.exports = {
198
198
  // let basedata = file.data.replace(/^data:.*,/, '');
199
199
  // let basedata = file.data.replace(/^data:image\/png;base64,/, "");
200
200
  let fileName = file.name.replace(new RegExp('../', 'g'), '');
201
+ let fullPath = file.fullPath || file.name;
202
+ fullPath = fullPath.replace(/(\.\.[/\\])/g, '');
203
+ fullPath = path.normalize(fullPath).replace(/^(\.\.[/\\])+/, '');
204
+
201
205
  if (file.type !== 'svg') {
202
206
  basedata = file.data.replace(/^data:.*,/, '');
203
207
  encoding = {encoding: 'base64'};
204
208
  }
205
- var filePath = path.join(runtime.settings.uploadFileDir, fileName);
209
+ var filePath = path.join(runtime.settings.uploadFileDir, fullPath || fileName);
206
210
  if (destination) {
207
211
  const destinationDir = path.resolve(runtime.settings.appDir, `_${destination}`);
208
- if (!fs.existsSync(destinationDir)) {
209
- fs.mkdirSync(destinationDir);
212
+ filePath = path.join(destinationDir, fullPath || fileName);
213
+ const dir = path.dirname(filePath);
214
+ if (!fs.existsSync(dir)) {
215
+ fs.mkdirSync(dir, { recursive: true });
210
216
  }
211
- filePath = path.join(destinationDir, fileName);
212
217
  }
213
218
  fs.writeFileSync(filePath, basedata, encoding);
214
- let result = {'location': '/' + runtime.settings.httpUploadFileStatic + '/' + fileName };
219
+ let result = {'location': '/' + runtime.settings.httpUploadFileStatic + '/' + fullPath || fileName };
215
220
  res.json(result);
216
221
  } catch (err) {
217
222
  if (err && err.code) {
@@ -120,7 +120,7 @@ module.exports = {
120
120
  var wwwSubDir = path.join('_widgets', resourcesDirs[i]);
121
121
  var files = getFiles(dirPath, ['.svg']);
122
122
  for (var x = 0; x < files.length; x++) {
123
- var filename = files[x].replace(/\.[^\/.]+$/, '');
123
+ var filename = files[x];
124
124
  group.items.push({ path: path.join(wwwSubDir, files[x]).split(path.sep).join(path.posix.sep), name: filename });
125
125
  }
126
126
  result.groups.push(group);
@@ -137,6 +137,51 @@ module.exports = {
137
137
  }
138
138
  });
139
139
 
140
+ /**
141
+ * POST Remove Server widget item
142
+ */
143
+ resourcesApp.post('/api/resources/removeWidget', secureFnc, function (req, res) {
144
+ const permission = checkGroupsFnc(req);
145
+ if (res.statusCode === 403) {
146
+ runtime.logger.error("api resources/removeWidget: Tocken Expired");
147
+ } else if (!authJwt.haveAdminPermission(permission)) {
148
+ runtime.logger.error("api resources/removeWidget: Unauthorized!");
149
+ return res.status(401).json({ error: "unauthorized_error", message: "Unauthorized!" });
150
+ }
151
+ try {
152
+ const relPath = req.body?.path;
153
+ if (!relPath || typeof relPath !== 'string') {
154
+ return res.status(400).json({ error: "invalid_path", message: "Missing or invalid widget path." });
155
+ }
156
+ const basePath = path.resolve(runtime.settings.appDir);
157
+ const fullPath = path.resolve(basePath, relPath);
158
+
159
+ if (!fullPath.startsWith(basePath)) {
160
+ runtime.logger.error("api resources/widgets: security_violation " + fullPath);
161
+ return res.status(403).json({ error: 'security_violation', message: 'Invalid path' });
162
+ }
163
+
164
+ if (!fs.existsSync(fullPath)) {
165
+ return res.status(404).json({ error: "not_found", message: "Widget file not found." });
166
+ }
167
+
168
+ try {
169
+ fs.unlinkSync(fullPath);
170
+ res.json({ success: true, path: relPath });
171
+ } catch (err) {
172
+ runtime.logger.error("api removeWidget: " + err.message);
173
+ res.status(500).json({ error: "delete_failed", message: err.message });
174
+ }
175
+ } catch (err) {
176
+ if (err.code) {
177
+ res.status(400).json({ error: err.code, message: err.message });
178
+ } else {
179
+ res.status(400).json({ error: "unexpected_error", message: err.toString() });
180
+ }
181
+ runtime.logger.error("api resources/removeWidget: " + err.message);
182
+ }
183
+ });
184
+
140
185
  return resourcesApp;
141
186
  }
142
187
  }
@@ -36,11 +36,11 @@ module.exports = {
36
36
  runtime.logger.error("api post runscript: Tocken Expired");
37
37
  //runtime.settings.secureEnabled
38
38
  } else if (!runtime.scriptsMgr.isAuthorised(req.body.params.script, permission)) {
39
- res.status(401).json({ error: "unauthorized_error", message: "Unauthorized!" });
39
+ res.status(400).json({ error: "unauthorized_error", message: "Unauthorized!" });
40
40
  runtime.logger.error("api post runscript: Unauthorized");
41
41
  } else {
42
42
  //req.body.params.script.parameters.permission = groups;
43
- runtime.scriptsMgr.runScript(req.body.params.script).then(function (result) {
43
+ runtime.scriptsMgr.runScript(req.body.params.script, req.body.params.toLogEvent).then(function (result) {
44
44
  res.json(result);
45
45
  }).catch(function (err) {
46
46
  if (err.code) {
@@ -62,7 +62,7 @@ module.exports = {
62
62
  if (res.statusCode === 403) {
63
63
  runtime.logger.error("api post runSysFunction: Tocken Expired");
64
64
  } else if (authJwt.adminGroups.indexOf(groups) === -1 ) {
65
- res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"});
65
+ res.status(400).json({error:"unauthorized_error", message: "Unauthorized!"});
66
66
  runtime.logger.error("api post runSysFunction: Unauthorized");
67
67
  } else {
68
68
  try {
@@ -815,6 +815,36 @@ indexof
815
815
  isarray
816
816
  MIT
817
817
 
818
+ leaflet
819
+ BSD-2-Clause
820
+ BSD 2-Clause License
821
+
822
+ Copyright (c) 2010-2023, Volodymyr Agafonkin
823
+ Copyright (c) 2010-2011, CloudMade
824
+ All rights reserved.
825
+
826
+ Redistribution and use in source and binary forms, with or without
827
+ modification, are permitted provided that the following conditions are met:
828
+
829
+ 1. Redistributions of source code must retain the above copyright notice, this
830
+ list of conditions and the following disclaimer.
831
+
832
+ 2. Redistributions in binary form must reproduce the above copyright notice,
833
+ this list of conditions and the following disclaimer in the documentation
834
+ and/or other materials provided with the distribution.
835
+
836
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
837
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
838
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
839
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
840
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
841
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
842
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
843
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
844
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
845
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
846
+
847
+
818
848
  lodash-es
819
849
  MIT
820
850
  Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
@@ -326,7 +326,7 @@
326
326
  "graph.property-datalabels-show": "Anzeigen",
327
327
  "graph.property-datalabels-fontsize": "Schriftgröße",
328
328
  "graph.property-datalabels-align": "Ausrichten",
329
-
329
+
330
330
  "graph.rangetype-last1h": "Letzte Stunde",
331
331
  "graph.rangetype-last1d": "Letzter Tag",
332
332
  "graph.rangetype-last3d": "Letzte 3 Tage",
@@ -353,7 +353,7 @@
353
353
  "table.property-row-height": "Höhe",
354
354
  "table.property-row-background": "Hintergrund",
355
355
  "table.property-row-color": "Farbe",
356
- "table.property-row-fontSize": "Schriftgröße",
356
+ "table.property-row-fontSize": "Schriftgröße",
357
357
  "table.property-layout": "Layout",
358
358
  "table.property-filter": "Filter",
359
359
  "table.property-paginator": "Paginator",
@@ -806,7 +806,7 @@
806
806
  "device.topic-name-exist": "Der Topic-Name '{{value}}' existiert bereits",
807
807
  "device.topic-subs-address-exist": "Das zu abonnierende Topic mit der Adresse '{{value}}' existiert bereits",
808
808
  "device.topic-pubs-address-exist": "Das zu veröffentlichende Thema mit der Adresse '{{value}}' existiert bereits",
809
-
809
+
810
810
  "device.property-mqtt-address": "Adresse (mqtt://[Server]:[Port])",
811
811
  "device.tag-property-title": "Tag-Eigenschaft",
812
812
  "device.browsetag-property-title": "Tags im Server durchsuchen",
@@ -823,8 +823,8 @@
823
823
  "device.tag-property-obj-name": "Name",
824
824
  "device.tag-property-path": "Pfad",
825
825
  "device.tag-property-unit": "Einheit",
826
- "device.tag-property-digits": "Dezimal",
827
- "device.tag-property-initvalue": "Initialwert",
826
+ "device.tag-property-digits": "Dezimal",
827
+ "device.tag-property-initvalue": "Initialwert",
828
828
  "device.tag-array-id": "Array-ID:",
829
829
  "device.tag-array-value": "Wert:",
830
830
  "device-tag-dialog-title": "Tag-Auswahl",
@@ -843,7 +843,7 @@
843
843
  "device.tag-raw-high": "Raw High",
844
844
  "device.tag-scaled-low": "Skaliert niedrig",
845
845
  "device.tag-scaled-high": "Skaliert hoch",
846
-
846
+
847
847
  "device.connect-ok": "Ok",
848
848
  "device.connect-error": "Fehler",
849
849
  "device.connect-failed": "Fehlgeschlagen",
@@ -1120,7 +1120,7 @@
1120
1120
  "report.item-interval-min10": "10 Minuten",
1121
1121
  "report.item-interval-min30": "30 Minuten",
1122
1122
  "report.item-interval-hour": "1 Stunde",
1123
- "report.item-interval-day": "1 Tag",
1123
+ "report.item-interval-day": "1 Tag",
1124
1124
  "report.item-function-type": "Funktionstyp",
1125
1125
  "report.item-function-min": "Min",
1126
1126
  "report.item-function-max": "Max",
@@ -1162,6 +1162,11 @@
1162
1162
  "texts.list-group": "Gruppe",
1163
1163
  "texts.list-value": "Text",
1164
1164
 
1165
+ "text.settings-title": "Text",
1166
+ "text.settings-id": "ID",
1167
+ "text.settings-group": "Group",
1168
+ "text.settings-value": "Text",
1169
+
1165
1170
  "gui.range-number-min": "Min",
1166
1171
  "gui.range-number-max": "Max",
1167
1172
  "gui.range-number-boolean": "Maskenwert",
@@ -1171,11 +1176,6 @@
1171
1176
 
1172
1177
  "dlg.bitmask-title": "Bitmaske",
1173
1178
 
1174
- "dlg.textproperty-title": "Text",
1175
- "dlg.textproperty-id": "ID",
1176
- "dlg.textproperty-group": "Gruppe",
1177
- "dlg.textproperty-value": "Text",
1178
-
1179
1179
  "dlg.plugins-title": "Plugins",
1180
1180
  "dlg.plugins-name": "Name",
1181
1181
  "dlg.plugins-version": "Version",