@frangoteam/fuxa-min 1.2.11 → 1.3.1
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/api/auth/index.js +141 -3
- package/api/command/index.js +1 -1
- package/api/index.js +21 -2
- package/api/jwt-helper.js +3 -1
- package/api/resources/index.js +19 -2
- package/api/scripts/index.js +7 -3
- package/dist/3rdpartylicenses.txt +139 -7
- package/dist/assets/i18n/de.json +10 -0
- package/dist/assets/i18n/en.json +21 -3
- package/dist/assets/i18n/es.json +12 -0
- package/dist/assets/i18n/fr.json +11 -0
- package/dist/assets/i18n/ja.json +16 -6
- package/dist/assets/i18n/ko.json +12 -0
- package/dist/assets/i18n/pt.json +9 -2
- package/dist/assets/i18n/ru.json +11 -0
- package/dist/assets/i18n/sv.json +11 -1
- package/dist/assets/i18n/tr.json +8 -1
- package/dist/assets/i18n/ua.json +9 -2
- package/dist/assets/i18n/zh-cn.json +11 -0
- package/dist/assets/i18n/zh-tw.json +12 -1
- package/dist/assets/lib/svgeditor/fuxa-editor.min.js +17 -23
- package/dist/index.html +2 -2
- package/dist/main.72bdfed42c527918.js +329 -0
- package/dist/polyfills.d7de05f9af2fb559.js +1 -0
- package/dist/{runtime.8ef63094e52a66ba.js → runtime.9136a61a9b98f987.js} +1 -1
- package/dist/{scripts.40b60f02658462e4.js → scripts.d9e6ee984bf6f3b7.js} +1 -1
- package/dist/styles.545e37beb3e671ba.css +1 -0
- package/docs/openapi.yaml +3 -0
- package/integrations/node-red/index.js +4 -5
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-daq.html +56 -5
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-daq.js +8 -2
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag-change.html +56 -5
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag-change.js +12 -12
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag-daq-settings.html +56 -5
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag-daq-settings.js +14 -10
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag.html +69 -14
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-get-tag.js +44 -12
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-set-tag-daq-settings.html +56 -5
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-set-tag-daq-settings.js +24 -20
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-set-tag.html +72 -13
- package/integrations/node-red/node-red-contrib-fuxa/nodes/fuxa-set-tag.js +33 -7
- package/main.js +38 -17
- package/package.json +10 -5
- package/runtime/alarms/alarmstorage.js +45 -30
- package/runtime/apikeys/apiKeysStorage.js +34 -22
- package/runtime/devices/adsclient/index.js +1 -1
- package/runtime/devices/ethernetip/index.js +1 -1
- package/runtime/devices/gpio/index.js +1 -1
- package/runtime/devices/odbc/index.js +14 -9
- package/runtime/devices/s7/index.js +2 -2
- package/runtime/devices/template/index.js +14 -14
- package/runtime/notificator/notifystorage.js +34 -23
- package/runtime/project/index.js +16 -0
- package/runtime/project/prjstorage.js +78 -40
- package/runtime/scripts/index.js +6 -2
- package/runtime/storage/calculator.js +17 -13
- package/runtime/storage/daqstorage.js +28 -2
- package/runtime/storage/influxdb/index.js +8 -3
- package/runtime/storage/questdb/index.js +224 -0
- package/runtime/storage/sqlite/index.js +11 -8
- package/runtime/storage/tdengine/index.js +24 -9
- package/runtime/users/usrstorage.js +65 -61
- package/runtime/utils.js +5 -0
- package/settings.default.js +8 -2
- package/dist/main.92522279642ef880.js +0 -329
- package/dist/polyfills.c8e7db9850a3ad8b.js +0 -1
- package/dist/styles.03cc550382689976.css +0 -1
package/api/auth/index.js
CHANGED
|
@@ -10,12 +10,78 @@ const authJwt = require('../jwt-helper');
|
|
|
10
10
|
var runtime;
|
|
11
11
|
var secretCode;
|
|
12
12
|
var tokenExpiresIn;
|
|
13
|
+
var enableRefreshCookieAuth = false;
|
|
14
|
+
var refreshTokenExpiresIn = '7d';
|
|
15
|
+
const refreshCookieName = 'fuxa_refresh';
|
|
16
|
+
|
|
17
|
+
function parseExpiresToMs(expiresIn) {
|
|
18
|
+
if (expiresIn === undefined || expiresIn === null) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (typeof expiresIn === 'number') {
|
|
22
|
+
return expiresIn * 1000;
|
|
23
|
+
}
|
|
24
|
+
if (typeof expiresIn !== 'string') {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const match = expiresIn.trim().match(/^(\d+)\s*([smhd])?$/i);
|
|
28
|
+
if (!match) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const value = Number(match[1]);
|
|
32
|
+
const unit = (match[2] || 's').toLowerCase();
|
|
33
|
+
const multipliers = { s: 1000, m: 60000, h: 3600000, d: 86400000 };
|
|
34
|
+
return value * (multipliers[unit] || 1000);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getCookieValue(req, name) {
|
|
38
|
+
const cookieHeader = req.headers.cookie;
|
|
39
|
+
if (!cookieHeader) return null;
|
|
40
|
+
const cookies = cookieHeader.split(';');
|
|
41
|
+
for (const cookie of cookies) {
|
|
42
|
+
const [key, ...rest] = cookie.trim().split('=');
|
|
43
|
+
if (key === name) {
|
|
44
|
+
return decodeURIComponent(rest.join('='));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function buildAccessToken(user) {
|
|
51
|
+
return jwt.sign({ id: user.username, groups: user.groups }, secretCode, { expiresIn: tokenExpiresIn });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function buildRefreshToken(user) {
|
|
55
|
+
return jwt.sign({ id: user.username, groups: user.groups, type: 'refresh' }, secretCode, { expiresIn: refreshTokenExpiresIn });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function setRefreshCookie(res, token) {
|
|
59
|
+
const maxAge = parseExpiresToMs(refreshTokenExpiresIn);
|
|
60
|
+
const options = {
|
|
61
|
+
httpOnly: true,
|
|
62
|
+
sameSite: 'lax',
|
|
63
|
+
secure: !!runtime?.settings?.https,
|
|
64
|
+
path: '/api/refresh'
|
|
65
|
+
};
|
|
66
|
+
if (maxAge) {
|
|
67
|
+
options.maxAge = maxAge;
|
|
68
|
+
}
|
|
69
|
+
res.cookie(refreshCookieName, token, options);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function clearRefreshCookie(res) {
|
|
73
|
+
res.clearCookie(refreshCookieName, { path: '/api/refresh' });
|
|
74
|
+
}
|
|
13
75
|
|
|
14
76
|
module.exports = {
|
|
15
|
-
init: function (_runtime, _secretCode, _tokenExpires) {
|
|
77
|
+
init: function (_runtime, _secretCode, _tokenExpires, _enableRefreshCookieAuth, _refreshTokenExpires) {
|
|
16
78
|
runtime = _runtime;
|
|
17
79
|
secretCode = _secretCode;
|
|
18
80
|
tokenExpiresIn = _tokenExpires;
|
|
81
|
+
enableRefreshCookieAuth = !!_enableRefreshCookieAuth;
|
|
82
|
+
if (_refreshTokenExpires) {
|
|
83
|
+
refreshTokenExpiresIn = _refreshTokenExpires;
|
|
84
|
+
}
|
|
19
85
|
},
|
|
20
86
|
app: function () {
|
|
21
87
|
var authApp = express();
|
|
@@ -35,7 +101,11 @@ module.exports = {
|
|
|
35
101
|
runtime.users.findOne(req.body).then(function (userInfo) {
|
|
36
102
|
if (userInfo && userInfo.length && userInfo[0].password) {
|
|
37
103
|
if (bcrypt.compareSync(req.body.password, userInfo[0].password)) {
|
|
38
|
-
const token =
|
|
104
|
+
const token = buildAccessToken(userInfo[0]);
|
|
105
|
+
if (enableRefreshCookieAuth) {
|
|
106
|
+
const refreshToken = buildRefreshToken(userInfo[0]);
|
|
107
|
+
setRefreshCookie(res, refreshToken);
|
|
108
|
+
}
|
|
39
109
|
res.json({
|
|
40
110
|
status: 'success',
|
|
41
111
|
message: 'user found!!!',
|
|
@@ -66,6 +136,74 @@ module.exports = {
|
|
|
66
136
|
});
|
|
67
137
|
});
|
|
68
138
|
|
|
139
|
+
/**
|
|
140
|
+
* POST Refresh
|
|
141
|
+
* Refresh access token using HttpOnly refresh cookie
|
|
142
|
+
*/
|
|
143
|
+
authApp.post('/api/refresh', async function (req, res, next) {
|
|
144
|
+
if (!runtime?.settings?.secureEnabled || !enableRefreshCookieAuth) {
|
|
145
|
+
return res.status(204).end();
|
|
146
|
+
}
|
|
147
|
+
const refreshToken = getCookieValue(req, refreshCookieName);
|
|
148
|
+
if (!refreshToken) {
|
|
149
|
+
return res.status(401).json({ status: 'error', message: 'Refresh token missing' });
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const decoded = jwt.verify(refreshToken, secretCode);
|
|
153
|
+
if (decoded?.type !== 'refresh') {
|
|
154
|
+
clearRefreshCookie(res);
|
|
155
|
+
return res.status(401).json({ status: 'error', message: 'Invalid refresh token' });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let userData = null;
|
|
159
|
+
try {
|
|
160
|
+
const users = await runtime.users.getUsers({ username: decoded.id });
|
|
161
|
+
if (users && users.length) {
|
|
162
|
+
userData = users[0];
|
|
163
|
+
}
|
|
164
|
+
} catch (err) {
|
|
165
|
+
runtime.logger.error(`api refresh: user lookup failed ${err}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const user = {
|
|
169
|
+
username: decoded.id,
|
|
170
|
+
fullname: userData?.fullname,
|
|
171
|
+
groups: userData?.groups || decoded.groups,
|
|
172
|
+
info: userData?.info
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const newAccessToken = buildAccessToken(user);
|
|
176
|
+
const newRefreshToken = buildRefreshToken(user);
|
|
177
|
+
setRefreshCookie(res, newRefreshToken);
|
|
178
|
+
|
|
179
|
+
res.json({
|
|
180
|
+
status: 'success',
|
|
181
|
+
message: 'token refreshed',
|
|
182
|
+
data: {
|
|
183
|
+
username: user.username,
|
|
184
|
+
fullname: user.fullname,
|
|
185
|
+
groups: user.groups,
|
|
186
|
+
info: user.info,
|
|
187
|
+
token: newAccessToken
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
} catch (err) {
|
|
191
|
+
clearRefreshCookie(res);
|
|
192
|
+
res.status(401).json({ status: 'error', message: 'Invalid refresh token' });
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* POST SignOut
|
|
198
|
+
* Clear refresh cookie
|
|
199
|
+
*/
|
|
200
|
+
authApp.post('/api/signout', function (req, res, next) {
|
|
201
|
+
if (enableRefreshCookieAuth) {
|
|
202
|
+
clearRefreshCookie(res);
|
|
203
|
+
}
|
|
204
|
+
res.status(204).end();
|
|
205
|
+
});
|
|
206
|
+
|
|
69
207
|
return authApp;
|
|
70
208
|
}
|
|
71
|
-
}
|
|
209
|
+
}
|
package/api/command/index.js
CHANGED
|
@@ -78,7 +78,7 @@ module.exports = {
|
|
|
78
78
|
if (res.statusCode === 403) {
|
|
79
79
|
runtime.logger.error("api get getTagValue: Tocken Expired");
|
|
80
80
|
} else if (!authJwt.haveAdminPermission(permission) && !runtime.scriptsMgr.isAuthorisedByScriptName(req.query.sourceScriptName, permission)) {
|
|
81
|
-
res.status(
|
|
81
|
+
res.status(401).json({error:"unauthorized_error", message: "Unauthorized!"});
|
|
82
82
|
runtime.logger.error("api get getTagValue: Unauthorized");
|
|
83
83
|
} else {
|
|
84
84
|
try {
|
package/api/index.js
CHANGED
|
@@ -56,7 +56,7 @@ function init(_server, _runtime) {
|
|
|
56
56
|
apiApp.use(usersApi.app());
|
|
57
57
|
alarmsApi.init(runtime, authMiddleware, verifyGroups);
|
|
58
58
|
apiApp.use(alarmsApi.app());
|
|
59
|
-
authApi.init(runtime, authJwt.secretCode, authJwt.tokenExpiresIn);
|
|
59
|
+
authApi.init(runtime, authJwt.secretCode, authJwt.tokenExpiresIn, runtime.settings.enableRefreshCookieAuth, runtime.settings.refreshTokenExpiresIn);
|
|
60
60
|
apiApp.use(authApi.app());
|
|
61
61
|
pluginsApi.init(runtime, authMiddleware, verifyGroups);
|
|
62
62
|
apiApp.use(pluginsApi.app());
|
|
@@ -146,9 +146,15 @@ function init(_server, _runtime) {
|
|
|
146
146
|
if (!req.body.secretCode && runtime.settings.secretCode) {
|
|
147
147
|
req.body.secretCode = runtime.settings.secretCode;
|
|
148
148
|
}
|
|
149
|
+
if (req.body.secureEnabled && !req.body.secretCode) {
|
|
150
|
+
req.body.secretCode = utils.generateSecretCode();
|
|
151
|
+
runtime.logger.warn('Generated random JWT secret because secureEnabled=true and no secretCode was provided.');
|
|
152
|
+
}
|
|
149
153
|
const prevAuth = {
|
|
150
154
|
secureEnabled: runtime.settings.secureEnabled,
|
|
151
155
|
tokenExpiresIn: runtime.settings.tokenExpiresIn,
|
|
156
|
+
enableRefreshCookieAuth: runtime.settings.enableRefreshCookieAuth,
|
|
157
|
+
refreshTokenExpiresIn: runtime.settings.refreshTokenExpiresIn,
|
|
152
158
|
secretCode: runtime.settings.secretCode
|
|
153
159
|
};
|
|
154
160
|
if (req.body.nodeRedEnabled === true &&
|
|
@@ -160,9 +166,11 @@ function init(_server, _runtime) {
|
|
|
160
166
|
mergeUserSettings(req.body);
|
|
161
167
|
if (prevAuth.secureEnabled !== runtime.settings.secureEnabled ||
|
|
162
168
|
prevAuth.tokenExpiresIn !== runtime.settings.tokenExpiresIn ||
|
|
169
|
+
prevAuth.enableRefreshCookieAuth !== runtime.settings.enableRefreshCookieAuth ||
|
|
170
|
+
prevAuth.refreshTokenExpiresIn !== runtime.settings.refreshTokenExpiresIn ||
|
|
163
171
|
prevAuth.secretCode !== runtime.settings.secretCode) {
|
|
164
172
|
authJwt.init(runtime.settings.secureEnabled, runtime.settings.secretCode, runtime.settings.tokenExpiresIn);
|
|
165
|
-
authApi.init(runtime, authJwt.secretCode, authJwt.tokenExpiresIn);
|
|
173
|
+
authApi.init(runtime, authJwt.secretCode, authJwt.tokenExpiresIn, runtime.settings.enableRefreshCookieAuth, runtime.settings.refreshTokenExpiresIn);
|
|
166
174
|
}
|
|
167
175
|
runtime.restart(true).then(function(result) {
|
|
168
176
|
res.end();
|
|
@@ -221,6 +229,9 @@ function mergeUserSettings(settings) {
|
|
|
221
229
|
if (settings.language) {
|
|
222
230
|
runtime.settings.language = settings.language;
|
|
223
231
|
}
|
|
232
|
+
if (!utils.isNullOrUndefined(settings.hideEditorOnboarding)) {
|
|
233
|
+
runtime.settings.hideEditorOnboarding = settings.hideEditorOnboarding;
|
|
234
|
+
}
|
|
224
235
|
runtime.settings.broadcastAll = settings.broadcastAll;
|
|
225
236
|
runtime.settings.secureEnabled = settings.secureEnabled;
|
|
226
237
|
runtime.settings.logFull = settings.logFull;
|
|
@@ -229,6 +240,12 @@ function mergeUserSettings(settings) {
|
|
|
229
240
|
if (!utils.isNullOrUndefined(settings.nodeRedAuthMode)) {
|
|
230
241
|
runtime.settings.nodeRedAuthMode = settings.nodeRedAuthMode;
|
|
231
242
|
}
|
|
243
|
+
if (!utils.isNullOrUndefined(settings.enableRefreshCookieAuth)) {
|
|
244
|
+
runtime.settings.enableRefreshCookieAuth = settings.enableRefreshCookieAuth;
|
|
245
|
+
}
|
|
246
|
+
if (!utils.isNullOrUndefined(settings.refreshTokenExpiresIn)) {
|
|
247
|
+
runtime.settings.refreshTokenExpiresIn = settings.refreshTokenExpiresIn;
|
|
248
|
+
}
|
|
232
249
|
if (!utils.isNullOrUndefined(settings.nodeRedUnsafeModules)) {
|
|
233
250
|
runtime.settings.nodeRedUnsafeModules = settings.nodeRedUnsafeModules;
|
|
234
251
|
}
|
|
@@ -238,6 +255,8 @@ function mergeUserSettings(settings) {
|
|
|
238
255
|
}
|
|
239
256
|
if (settings.secureEnabled) {
|
|
240
257
|
runtime.settings.tokenExpiresIn = settings.tokenExpiresIn;
|
|
258
|
+
runtime.settings.enableRefreshCookieAuth = settings.enableRefreshCookieAuth;
|
|
259
|
+
runtime.settings.refreshTokenExpiresIn = settings.refreshTokenExpiresIn;
|
|
241
260
|
}
|
|
242
261
|
if (settings.smtp) {
|
|
243
262
|
runtime.settings.smtp = settings.smtp;
|
package/api/jwt-helper.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const jwt = require('jsonwebtoken');
|
|
4
|
+
const utils = require('../runtime/utils');
|
|
4
5
|
|
|
5
6
|
var secureEnabled = false;
|
|
6
|
-
|
|
7
|
+
// Runtime fallback secret used only when no persistent secret is configured.
|
|
8
|
+
var secretCode = utils.generateSecretCode();
|
|
7
9
|
var tokenExpiresIn = 60 * 60; // 60 minutes
|
|
8
10
|
const adminGroups = [-1, 255];
|
|
9
11
|
|
package/api/resources/index.js
CHANGED
|
@@ -275,10 +275,13 @@ module.exports = {
|
|
|
275
275
|
var group = { name: resourcesDirs[i], items: [] };
|
|
276
276
|
var dirPath = path.resolve(runtime.settings.widgetsFileDir, resourcesDirs[i]);
|
|
277
277
|
var wwwSubDir = path.join('_widgets', resourcesDirs[i]);
|
|
278
|
-
var files =
|
|
278
|
+
var files = getFilesRecursive(dirPath, ['.svg']);
|
|
279
279
|
for (var x = 0; x < files.length; x++) {
|
|
280
280
|
var filename = files[x];
|
|
281
|
-
group.items.push({
|
|
281
|
+
group.items.push({
|
|
282
|
+
path: path.join(wwwSubDir, files[x]).split(path.sep).join(path.posix.sep),
|
|
283
|
+
name: filename
|
|
284
|
+
});
|
|
282
285
|
}
|
|
283
286
|
result.groups.push(group);
|
|
284
287
|
}
|
|
@@ -358,3 +361,17 @@ function getFiles(pathDir, extensions) {
|
|
|
358
361
|
.filter((item) => extensions.indexOf(path.extname(item).toLowerCase()) !== -1);
|
|
359
362
|
return filesInDIrectory;
|
|
360
363
|
}
|
|
364
|
+
|
|
365
|
+
function getFilesRecursive(pathDir, extensions, baseDir = pathDir) {
|
|
366
|
+
const entries = fs.readdirSync(pathDir, { withFileTypes: true });
|
|
367
|
+
const files = [];
|
|
368
|
+
for (const entry of entries) {
|
|
369
|
+
const entryPath = path.join(pathDir, entry.name);
|
|
370
|
+
if (entry.isDirectory()) {
|
|
371
|
+
files.push(...getFilesRecursive(entryPath, extensions, baseDir));
|
|
372
|
+
} else if (extensions.indexOf(path.extname(entry.name).toLowerCase()) !== -1) {
|
|
373
|
+
files.push(path.relative(baseDir, entryPath));
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return files;
|
|
377
|
+
}
|
package/api/scripts/index.js
CHANGED
|
@@ -32,15 +32,19 @@ module.exports = {
|
|
|
32
32
|
*/
|
|
33
33
|
scriptsApp.post("/api/runscript", secureFnc, function (req, res, next) {
|
|
34
34
|
const permission = checkGroupsFnc(req);
|
|
35
|
+
const script = req.body?.params?.script;
|
|
35
36
|
if (res.statusCode === 403) {
|
|
36
37
|
runtime.logger.error("api post runscript: Tocken Expired");
|
|
37
38
|
//runtime.settings.secureEnabled
|
|
38
|
-
} else if (!
|
|
39
|
+
} else if (script?.test && (!req.isAuthenticated || !authJwt.haveAdminPermission(permission))) {
|
|
40
|
+
res.status(401).json({ error: "unauthorized_error", message: "Unauthorized!" });
|
|
41
|
+
runtime.logger.error("api post runscript: Unauthorized test mode");
|
|
42
|
+
} else if (!runtime.scriptsMgr.isAuthorised(script, permission)) {
|
|
39
43
|
res.status(400).json({ error: "unauthorized_error", message: "Unauthorized!" });
|
|
40
44
|
runtime.logger.error("api post runscript: Unauthorized");
|
|
41
45
|
} else {
|
|
42
46
|
//req.body.params.script.parameters.permission = groups;
|
|
43
|
-
runtime.scriptsMgr.runScript(
|
|
47
|
+
runtime.scriptsMgr.runScript(script, req.body.params.toLogEvent).then(function (result) {
|
|
44
48
|
res.json(result);
|
|
45
49
|
}).catch(function (err) {
|
|
46
50
|
if (err.code) {
|
|
@@ -82,4 +86,4 @@ module.exports = {
|
|
|
82
86
|
});
|
|
83
87
|
return scriptsApp;
|
|
84
88
|
}
|
|
85
|
-
}
|
|
89
|
+
}
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
@angular/animations
|
|
2
2
|
MIT
|
|
3
|
+
The MIT License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
THE SOFTWARE.
|
|
24
|
+
|
|
3
25
|
|
|
4
26
|
@angular/cdk
|
|
5
27
|
MIT
|
|
6
28
|
The MIT License
|
|
7
29
|
|
|
8
|
-
Copyright (c)
|
|
30
|
+
Copyright (c) 2024 Google LLC.
|
|
9
31
|
|
|
10
32
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
33
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -28,18 +50,84 @@ THE SOFTWARE.
|
|
|
28
50
|
|
|
29
51
|
@angular/common
|
|
30
52
|
MIT
|
|
53
|
+
The MIT License
|
|
54
|
+
|
|
55
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
56
|
+
|
|
57
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
58
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
59
|
+
in the Software without restriction, including without limitation the rights
|
|
60
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
61
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
62
|
+
furnished to do so, subject to the following conditions:
|
|
63
|
+
|
|
64
|
+
The above copyright notice and this permission notice shall be included in
|
|
65
|
+
all copies or substantial portions of the Software.
|
|
66
|
+
|
|
67
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
68
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
69
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
70
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
71
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
72
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
73
|
+
THE SOFTWARE.
|
|
74
|
+
|
|
31
75
|
|
|
32
76
|
@angular/core
|
|
33
77
|
MIT
|
|
78
|
+
The MIT License
|
|
79
|
+
|
|
80
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
81
|
+
|
|
82
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
83
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
84
|
+
in the Software without restriction, including without limitation the rights
|
|
85
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
86
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
87
|
+
furnished to do so, subject to the following conditions:
|
|
88
|
+
|
|
89
|
+
The above copyright notice and this permission notice shall be included in
|
|
90
|
+
all copies or substantial portions of the Software.
|
|
91
|
+
|
|
92
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
93
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
94
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
95
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
96
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
97
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
98
|
+
THE SOFTWARE.
|
|
99
|
+
|
|
34
100
|
|
|
35
101
|
@angular/forms
|
|
36
102
|
MIT
|
|
103
|
+
The MIT License
|
|
104
|
+
|
|
105
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
106
|
+
|
|
107
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
108
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
109
|
+
in the Software without restriction, including without limitation the rights
|
|
110
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
111
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
112
|
+
furnished to do so, subject to the following conditions:
|
|
113
|
+
|
|
114
|
+
The above copyright notice and this permission notice shall be included in
|
|
115
|
+
all copies or substantial portions of the Software.
|
|
116
|
+
|
|
117
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
118
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
119
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
120
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
121
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
122
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
123
|
+
THE SOFTWARE.
|
|
124
|
+
|
|
37
125
|
|
|
38
126
|
@angular/material
|
|
39
127
|
MIT
|
|
40
128
|
The MIT License
|
|
41
129
|
|
|
42
|
-
Copyright (c)
|
|
130
|
+
Copyright (c) 2024 Google LLC.
|
|
43
131
|
|
|
44
132
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
45
133
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -64,7 +152,7 @@ THE SOFTWARE.
|
|
|
64
152
|
MIT
|
|
65
153
|
The MIT License
|
|
66
154
|
|
|
67
|
-
Copyright (c)
|
|
155
|
+
Copyright (c) 2024 Google LLC.
|
|
68
156
|
|
|
69
157
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
70
158
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -87,9 +175,53 @@ THE SOFTWARE.
|
|
|
87
175
|
|
|
88
176
|
@angular/platform-browser
|
|
89
177
|
MIT
|
|
178
|
+
The MIT License
|
|
179
|
+
|
|
180
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
181
|
+
|
|
182
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
183
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
184
|
+
in the Software without restriction, including without limitation the rights
|
|
185
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
186
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
187
|
+
furnished to do so, subject to the following conditions:
|
|
188
|
+
|
|
189
|
+
The above copyright notice and this permission notice shall be included in
|
|
190
|
+
all copies or substantial portions of the Software.
|
|
191
|
+
|
|
192
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
193
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
194
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
195
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
196
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
197
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
198
|
+
THE SOFTWARE.
|
|
199
|
+
|
|
90
200
|
|
|
91
201
|
@angular/router
|
|
92
202
|
MIT
|
|
203
|
+
The MIT License
|
|
204
|
+
|
|
205
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.dev/license
|
|
206
|
+
|
|
207
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
208
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
209
|
+
in the Software without restriction, including without limitation the rights
|
|
210
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
211
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
212
|
+
furnished to do so, subject to the following conditions:
|
|
213
|
+
|
|
214
|
+
The above copyright notice and this permission notice shall be included in
|
|
215
|
+
all copies or substantial portions of the Software.
|
|
216
|
+
|
|
217
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
218
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
219
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
220
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
221
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
222
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
223
|
+
THE SOFTWARE.
|
|
224
|
+
|
|
93
225
|
|
|
94
226
|
@babel/runtime
|
|
95
227
|
MIT
|
|
@@ -179,7 +311,7 @@ angular-gridster2
|
|
|
179
311
|
MIT
|
|
180
312
|
MIT License
|
|
181
313
|
|
|
182
|
-
Copyright (c)
|
|
314
|
+
Copyright (c) 2024 Tiberiu Zuld
|
|
183
315
|
|
|
184
316
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
185
317
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -990,7 +1122,7 @@ MIT
|
|
|
990
1122
|
The MIT License (MIT)
|
|
991
1123
|
|
|
992
1124
|
Copyright (c) 2014-2015 bpampuch
|
|
993
|
-
2016-
|
|
1125
|
+
2016-2026 liborm85
|
|
994
1126
|
|
|
995
1127
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
996
1128
|
this software and associated documentation files (the "Software"), to deal in
|
|
@@ -1222,7 +1354,7 @@ socket.io-parser
|
|
|
1222
1354
|
MIT
|
|
1223
1355
|
(The MIT License)
|
|
1224
1356
|
|
|
1225
|
-
Copyright (c) 2014 Guillermo Rauch
|
|
1357
|
+
Copyright (c) 2014-present Guillermo Rauch and Socket.IO contributors
|
|
1226
1358
|
|
|
1227
1359
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
1228
1360
|
this software and associated documentation files (the 'Software'), to deal in
|
|
@@ -1316,7 +1448,7 @@ zone.js
|
|
|
1316
1448
|
MIT
|
|
1317
1449
|
The MIT License
|
|
1318
1450
|
|
|
1319
|
-
Copyright (c) 2010-
|
|
1451
|
+
Copyright (c) 2010-2024 Google LLC. https://angular.io/license
|
|
1320
1452
|
|
|
1321
1453
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1322
1454
|
of this software and associated documentation files (the "Software"), to deal
|
package/dist/assets/i18n/de.json
CHANGED
|
@@ -834,6 +834,8 @@
|
|
|
834
834
|
"device.tag-daq-changed": "Wert speichern, wenn geändert",
|
|
835
835
|
"device.tag-daq-interval": "Intervall für Speichern (Sek.)",
|
|
836
836
|
"device.tag-format": "Ziffern formatieren (2 = #.##)",
|
|
837
|
+
|
|
838
|
+
"device.tag-uns-path": "UNS Path",
|
|
837
839
|
"device.tag-scale": "Skalierungsmodus",
|
|
838
840
|
"device.tag-scale-mode-undefined": "Keine Skalierung",
|
|
839
841
|
"device.tag-scale-mode-undefined-tooltip": "Tag-Wert",
|
|
@@ -1240,6 +1242,11 @@
|
|
|
1240
1242
|
"dlg.app-settings-daqstore": "DAQ-Speicher",
|
|
1241
1243
|
"dlg.app-settings-daqstore-type": "Datenbanktyp",
|
|
1242
1244
|
"dlg.app-settings-daqstore-url": "URL",
|
|
1245
|
+
"dlg.app-settings-daqstore-configurl": "Config URL",
|
|
1246
|
+
"dlg.app-settings-daqstore-queryconn": "Query connection (PGWire)",
|
|
1247
|
+
|
|
1248
|
+
"dlg.app-settings-daqstore-questdb-host": "QuestDB Host",
|
|
1249
|
+
"dlg.app-settings-daqstore-ingestconn": "Ingestion connection (ILP)",
|
|
1243
1250
|
"dlg.app-settings-daqstore-token": "Token",
|
|
1244
1251
|
"dlg.app-settings-daqstore-bucket": "Bucket",
|
|
1245
1252
|
"dlg.app-settings-daqstore-organization": "Organisation",
|
|
@@ -1306,3 +1313,6 @@
|
|
|
1306
1313
|
"msg.report-build-error": "Senden zum Erstellen des Berichts fehlgeschlagen!",
|
|
1307
1314
|
"msg.device-tags-request-result": "Lade {{value}} von {{current}}"
|
|
1308
1315
|
}
|
|
1316
|
+
|
|
1317
|
+
|
|
1318
|
+
|
package/dist/assets/i18n/en.json
CHANGED
|
@@ -307,6 +307,9 @@
|
|
|
307
307
|
"chart.property-refresh-interval": "Refresh interval (min.)",
|
|
308
308
|
"chart.property-hide-toolbar": "Hide toolbar",
|
|
309
309
|
"chart.property-thouch-zoom": "Thouch Zoom",
|
|
310
|
+
"chart.property-mouse-wheel-scroll": "Mouse wheel scroll",
|
|
311
|
+
"chart.property-mouse-wheel-zoom": "Mouse wheel zoom",
|
|
312
|
+
"chart.property-static-chart": "Static chart",
|
|
310
313
|
"chart.property-load-old-values": "Load history",
|
|
311
314
|
"chart.property-date.format": "Date format",
|
|
312
315
|
"chart.property-time.format": "Time format",
|
|
@@ -575,6 +578,12 @@
|
|
|
575
578
|
"editor.controls-slider": "Slider",
|
|
576
579
|
"editor.controls-slider-settings": "Slider settings",
|
|
577
580
|
"editor.controls-shape-settings": "Shape settings",
|
|
581
|
+
"editor.onboarding-wizard-title": "Initial Security Setup",
|
|
582
|
+
"editor.onboarding-wizard-message": "Configure the editor's initial security now to avoid unprotected access and the use of default credentials.",
|
|
583
|
+
"editor.onboarding-wizard-hide": "Do not show this wizard again",
|
|
584
|
+
"editor.onboarding-wizard-admin-password": "Administrator password",
|
|
585
|
+
"editor.onboarding-wizard-admin-password-message": "Set a new password for the default administrator account 'admin'.",
|
|
586
|
+
"editor.onboarding-wizard-admin-password-required": "Administrator password required",
|
|
578
587
|
"editor.controls-html-switch-settings": "Switch settings",
|
|
579
588
|
"editor.controls-switch": "Switch",
|
|
580
589
|
"editor.controls-graphbar": "Bar Graph",
|
|
@@ -992,6 +1001,7 @@
|
|
|
992
1001
|
"device.property-name": "Name",
|
|
993
1002
|
"device.property-type": "Type",
|
|
994
1003
|
"device.property-polling": "Polling",
|
|
1004
|
+
"device.property-polling-warning": "Warning: Low polling intervals may cause high CPU and network load. Use with care.",
|
|
995
1005
|
"device.property-enable": "Enable",
|
|
996
1006
|
"device.property-subscribe": "Subscribe",
|
|
997
1007
|
"device.property-address": "Address (IP or opc.tcp://[server]:[port])",
|
|
@@ -1153,6 +1163,8 @@
|
|
|
1153
1163
|
|
|
1154
1164
|
"device.tag-format": "Format digits (2 = #.##)",
|
|
1155
1165
|
"device.tag-deadband": "Deadband",
|
|
1166
|
+
|
|
1167
|
+
"device.tag-uns-path": "UNS Path",
|
|
1156
1168
|
"device.tag-scale": "Scale Mode / Convertion",
|
|
1157
1169
|
"device.tag-scale-mode-undefined": "No Scaling",
|
|
1158
1170
|
"device.tag-scale-mode-undefined-tooltip": "Tag Value",
|
|
@@ -1615,6 +1627,7 @@
|
|
|
1615
1627
|
"report.item-interval": "Interval (period)",
|
|
1616
1628
|
"report.item-interval-min5": "5 minutes",
|
|
1617
1629
|
"report.item-interval-min10": "10 minutes",
|
|
1630
|
+
"report.item-interval-min15": "15 minutes",
|
|
1618
1631
|
"report.item-interval-min30": "30 minutes",
|
|
1619
1632
|
"report.item-interval-hour": "1 Hour",
|
|
1620
1633
|
"report.item-interval-day": "1 Day",
|
|
@@ -1811,6 +1824,11 @@
|
|
|
1811
1824
|
"dlg.app-settings-daqstore": "DAQ storage",
|
|
1812
1825
|
"dlg.app-settings-daqstore-type": "Database type",
|
|
1813
1826
|
"dlg.app-settings-daqstore-url": "URL",
|
|
1827
|
+
"dlg.app-settings-daqstore-configurl": "Config URL",
|
|
1828
|
+
"dlg.app-settings-daqstore-queryconn": "Query connection (PGWire)",
|
|
1829
|
+
|
|
1830
|
+
"dlg.app-settings-daqstore-questdb-host": "QuestDB Host",
|
|
1831
|
+
"dlg.app-settings-daqstore-ingestconn": "Ingestion connection (ILP)",
|
|
1814
1832
|
"dlg.app-settings-daqstore-token": "Token",
|
|
1815
1833
|
"dlg.app-settings-daqstore-bucket": "Bucket",
|
|
1816
1834
|
"dlg.app-settings-daqstore-organization": "Organization",
|
|
@@ -1868,7 +1886,7 @@
|
|
|
1868
1886
|
"msg.alarmproperty-missing-value": "Some values are missing!",
|
|
1869
1887
|
"msg.textproperty-error-exist": "Text-ID exists!",
|
|
1870
1888
|
"msg.textproperty-missing-value": "Some values are missing!",
|
|
1871
|
-
"msg.device-remove": "Would you like to remove Device?",
|
|
1889
|
+
"msg.device-remove": "Would you like to remove Device '{{value}}'?",
|
|
1872
1890
|
"msg.device-tag-remove": "Would you like to remove Tag?",
|
|
1873
1891
|
"msg.device-tag-exist": "Tag name exists!",
|
|
1874
1892
|
"msg.device-tag-invalid-char": "The '@' character is not allowed in tag names!",
|
|
@@ -1884,7 +1902,7 @@
|
|
|
1884
1902
|
"msg.project-load-error": "Unable to read '{{value}}'",
|
|
1885
1903
|
"msg.project": "Would you like to save the Project changes?",
|
|
1886
1904
|
"msg.tags-remove-all": "Would you like to remove all Tags?",
|
|
1887
|
-
"msg.view-remove": "Would you like to remove View '{{value}}'?",
|
|
1905
|
+
"msg.view-remove": "Would you like to remove View '{{value}}' ?",
|
|
1888
1906
|
"msg.chart-remove": "Would you like to remove Chart '{{value}}'?",
|
|
1889
1907
|
"msg.role-remove": "Would you like to remove Role '{{value}}'?",
|
|
1890
1908
|
"msg.graph-remove": "Would you like to remove Bar chart '{{value}}'?",
|
|
@@ -1895,7 +1913,7 @@
|
|
|
1895
1913
|
"msg.sendmail-success": "Mail send successful!",
|
|
1896
1914
|
"msg.sendmail-error": "Mail send failed!",
|
|
1897
1915
|
"msg.users-save-error": "User save failed!",
|
|
1898
|
-
"msg.user-remove": "Would you like to remove User ",
|
|
1916
|
+
"msg.user-remove": "Would you like to remove User '{{value}}'?",
|
|
1899
1917
|
"msg.project-save-success": "Project save successful!",
|
|
1900
1918
|
"msg.project-save-error": "Project save failed!",
|
|
1901
1919
|
"msg.project-format-error": "Project wrong format!",
|