iobroker.rest-api 0.4.0 → 0.5.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/README.md +3 -1
- package/io-package.json +13 -13
- package/lib/api/controllers/common.js +30 -11
- package/lib/api/controllers/enum.js +11 -11
- package/lib/api/controllers/history.js +17 -16
- package/lib/api/controllers/object.js +55 -53
- package/lib/api/controllers/state.js +170 -138
- package/lib/api/swagger/swagger.yaml +0 -23
- package/lib/rest-api.js +10 -9
- package/main.js +1 -1
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -126,7 +126,6 @@ You cannot send POST request to commands via GUI.
|
|
|
126
126
|
- `extendObject(id, obj)` - modify object by ID with JSON. (.e.g. `{"common":{"enabled": true}}`)
|
|
127
127
|
- `getForeignObjects(pattern, type)` - same as getObjects
|
|
128
128
|
- `getForeignStates(pattern)` - same as getStates
|
|
129
|
-
- `delObjects(id, options)` - delete objects by pattern
|
|
130
129
|
|
|
131
130
|
### Others
|
|
132
131
|
- `log(text, level[info])` - no answer - add log entry to ioBroker log
|
|
@@ -145,6 +144,9 @@ You cannot send POST request to commands via GUI.
|
|
|
145
144
|
-->
|
|
146
145
|
|
|
147
146
|
## Changelog
|
|
147
|
+
### 0.5.0 (2022-05-17)
|
|
148
|
+
* (bluefox) Some access errors were corrected
|
|
149
|
+
|
|
148
150
|
### 0.4.0 (2022-04-26)
|
|
149
151
|
* (bluefox) Added socket commands
|
|
150
152
|
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "rest-api",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"news": {
|
|
6
|
+
"0.5.0": {
|
|
7
|
+
"en": "Some access errors were corrected",
|
|
8
|
+
"de": "Einige Zugriffsfehler wurden behoben",
|
|
9
|
+
"ru": "Исправлены некоторые ошибки доступа",
|
|
10
|
+
"pt": "Alguns erros de acesso foram corrigidos",
|
|
11
|
+
"nl": "Sommige toegangsfouten zijn gecorrigeerd",
|
|
12
|
+
"fr": "Certaines erreurs d'accès ont été corrigées",
|
|
13
|
+
"it": "Alcuni errori di accesso sono stati corretti",
|
|
14
|
+
"es": "Se corrigieron algunos errores de acceso",
|
|
15
|
+
"pl": "Poprawiono niektóre błędy dostępu",
|
|
16
|
+
"zh-cn": "一些访问错误已得到纠正"
|
|
17
|
+
},
|
|
6
18
|
"0.4.0": {
|
|
7
19
|
"en": "Added socket commands",
|
|
8
20
|
"de": "Socket-Befehle hinzugefügt",
|
|
@@ -74,18 +86,6 @@
|
|
|
74
86
|
"es": "Suscripción corregida",
|
|
75
87
|
"pl": "Poprawiona subskrypcja",
|
|
76
88
|
"zh-cn": "更正订阅"
|
|
77
|
-
},
|
|
78
|
-
"0.3.1": {
|
|
79
|
-
"en": "First release",
|
|
80
|
-
"de": "Erste Veröffentlichung",
|
|
81
|
-
"ru": "Первый выпуск",
|
|
82
|
-
"pt": "Primeiro lançamento",
|
|
83
|
-
"nl": "Eerste uitgave",
|
|
84
|
-
"fr": "Première sortie",
|
|
85
|
-
"it": "Prima uscita",
|
|
86
|
-
"es": "Primer lanzamiento",
|
|
87
|
-
"pl": "Pierwsze wydanie",
|
|
88
|
-
"zh-cn": "首次发布"
|
|
89
89
|
}
|
|
90
90
|
},
|
|
91
91
|
"title": "REST API",
|
|
@@ -31,7 +31,7 @@ function findState(adapter, idOrName, user, type, callback) {
|
|
|
31
31
|
callback = type;
|
|
32
32
|
type = null;
|
|
33
33
|
}
|
|
34
|
-
adapter.findForeignObject(idOrName, type, {user: user, checked: true}, callback);
|
|
34
|
+
adapter.findForeignObject(idOrName, type, {user: user, checked: true, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, callback);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function getState(adapter, idOrName, user, type, callback) {
|
|
@@ -40,18 +40,23 @@ function getState(adapter, idOrName, user, type, callback) {
|
|
|
40
40
|
type = null;
|
|
41
41
|
}
|
|
42
42
|
findState(adapter, idOrName, user, type, (err, id, originId) => {
|
|
43
|
-
if (err) {
|
|
43
|
+
if (err && (!err.message || !err.message.includes('permissionError'))) {
|
|
44
44
|
callback && callback(err, undefined, null, originId);
|
|
45
|
-
} else
|
|
46
|
-
if (id) {
|
|
47
|
-
adapter.getForeignState(id, {user: user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, (err, state) => {
|
|
48
|
-
if (err || !state) {
|
|
49
|
-
state = undefined;
|
|
50
|
-
}
|
|
51
|
-
callback && callback (err, state, id, originId);
|
|
52
|
-
});
|
|
53
45
|
} else {
|
|
54
|
-
|
|
46
|
+
if (err && err.message.includes('permissionError')) {
|
|
47
|
+
// assume it is ID
|
|
48
|
+
id = idOrName;
|
|
49
|
+
}
|
|
50
|
+
if (id) {
|
|
51
|
+
adapter.getForeignState(id, {user: user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}, (err, state) => {
|
|
52
|
+
if (err || !state) {
|
|
53
|
+
state = undefined;
|
|
54
|
+
}
|
|
55
|
+
callback && callback (err, state, id, originId);
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
callback && callback(null, undefined, null, originId);
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
});
|
|
57
62
|
}
|
|
@@ -86,9 +91,23 @@ function parseUrl(url, swagger, webExtensionPrefix) {
|
|
|
86
91
|
return result;
|
|
87
92
|
}
|
|
88
93
|
|
|
94
|
+
function errorResponse(req, res, error, response) {
|
|
95
|
+
error = error.toString();
|
|
96
|
+
if (error === 'Error: permissionError') {
|
|
97
|
+
error = 'permissionError';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
req._adapter.log.warn(`Warning by "${req.url}": ${error}`);
|
|
101
|
+
|
|
102
|
+
res
|
|
103
|
+
.status(error.toString().includes('permissionError') ? 403 : 500)
|
|
104
|
+
.json(Object.assign(response || {}, {error: error}));
|
|
105
|
+
}
|
|
106
|
+
|
|
89
107
|
module.exports = {
|
|
90
108
|
checkPermissions,
|
|
91
109
|
findState,
|
|
92
110
|
getState,
|
|
93
111
|
parseUrl,
|
|
112
|
+
errorResponse,
|
|
94
113
|
};
|
|
@@ -3,29 +3,30 @@ const commonLib = require('./common.js');
|
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
readMainEnums: function (req, res) {
|
|
6
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
7
|
-
if (
|
|
8
|
-
|
|
6
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
7
|
+
if (error) {
|
|
8
|
+
commonLib.errorResponse(req, res, error);
|
|
9
9
|
} else {
|
|
10
10
|
// check if instance is alive
|
|
11
11
|
try {
|
|
12
|
-
const enums = await req._adapter.getEnumsAsync('', {user: req._user});
|
|
12
|
+
const enums = await req._adapter.getEnumsAsync('', {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
13
13
|
res.json(enums);
|
|
14
14
|
} catch (error) {
|
|
15
|
-
|
|
15
|
+
req._adapter.log.warn(`Cannot read enums: ${error}`);
|
|
16
|
+
commonLib.errorResponse(req, res, error);
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
});
|
|
19
20
|
},
|
|
20
21
|
readEnums: function (req, res) {
|
|
21
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
22
|
-
if (
|
|
23
|
-
|
|
22
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
23
|
+
if (error) {
|
|
24
|
+
commonLib.errorResponse(req, res, error);
|
|
24
25
|
} else {
|
|
25
26
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
26
27
|
// check if instance is alive
|
|
27
28
|
try {
|
|
28
|
-
const enums = await req._adapter.getEnumAsync(params.enumId, {user: req._user});
|
|
29
|
+
const enums = await req._adapter.getEnumAsync(params.enumId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
29
30
|
if (enums && enums.result) {
|
|
30
31
|
res.json(Object.keys(enums.result).filter(id => id.split('.').length > 2).map(id => ({
|
|
31
32
|
_id: id,
|
|
@@ -35,9 +36,8 @@ module.exports = {
|
|
|
35
36
|
res.json([]);
|
|
36
37
|
}
|
|
37
38
|
} catch (error) {
|
|
38
|
-
|
|
39
|
+
commonLib.errorResponse(req, res, error);
|
|
39
40
|
}
|
|
40
|
-
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
},
|
|
@@ -31,9 +31,9 @@ const PARAMETERS_ADD = {
|
|
|
31
31
|
|
|
32
32
|
module.exports = {
|
|
33
33
|
getHistory: function (req, res) {
|
|
34
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'other', operation: 'sendto'}], async
|
|
35
|
-
if (
|
|
36
|
-
|
|
34
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'other', operation: 'sendto'}], async error => {
|
|
35
|
+
if (error) {
|
|
36
|
+
commonLib.errorResponse(req, res, error);
|
|
37
37
|
} else {
|
|
38
38
|
if (req._adapter.config.dataSource) {
|
|
39
39
|
// check if instance is alive
|
|
@@ -63,7 +63,7 @@ module.exports = {
|
|
|
63
63
|
|
|
64
64
|
req._adapter.sendTo(req._adapter.config.dataSource, 'getHistory', {id: params.stateId, options}, (result, step, error) => {
|
|
65
65
|
if (error) {
|
|
66
|
-
|
|
66
|
+
commonLib.errorResponse(req, res, error);
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
// req._adapter.log.debug(`[QUERY] sendTo result = ${JSON.stringify(result)}`);
|
|
@@ -79,9 +79,9 @@ module.exports = {
|
|
|
79
79
|
});
|
|
80
80
|
},
|
|
81
81
|
postHistory: function (req, res) {
|
|
82
|
-
commonLib.checkPermissions(req._adapter, req._user, req.body.options, async
|
|
83
|
-
if (
|
|
84
|
-
|
|
82
|
+
commonLib.checkPermissions(req._adapter, req._user, req.body.options, async error => {
|
|
83
|
+
if (error) {
|
|
84
|
+
commonLib.errorResponse(req, res, error);
|
|
85
85
|
} else {
|
|
86
86
|
if (req._adapter.config.dataSource) {
|
|
87
87
|
const state = await req._adapter.getForeignStateAsync(`system.adapter.${req._adapter.config.dataSource}.alive`);
|
|
@@ -114,7 +114,7 @@ module.exports = {
|
|
|
114
114
|
|
|
115
115
|
req._adapter.sendTo(req._adapter.config.dataSource, 'getHistory', options, (result, step, error) => {
|
|
116
116
|
if (error) {
|
|
117
|
-
|
|
117
|
+
commonLib.errorResponse(req, res, error);
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
120
120
|
// req._adapter.log.debug(`[QUERY] sendTo result = ${JSON.stringify(result)}`);
|
|
@@ -129,10 +129,11 @@ module.exports = {
|
|
|
129
129
|
}
|
|
130
130
|
});
|
|
131
131
|
},
|
|
132
|
+
|
|
132
133
|
addHistoryByGet: function (req, res) {
|
|
133
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'other', operation: 'sendto'}], async
|
|
134
|
-
if (
|
|
135
|
-
|
|
134
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'other', operation: 'sendto'}], async error => {
|
|
135
|
+
if (error) {
|
|
136
|
+
commonLib.errorResponse(req, res, error);
|
|
136
137
|
} else {
|
|
137
138
|
if (req._adapter.config.dataSource) {
|
|
138
139
|
// check if instance is alive
|
|
@@ -167,7 +168,7 @@ module.exports = {
|
|
|
167
168
|
|
|
168
169
|
req._adapter.sendTo(req._adapter.config.dataSource, 'storeState', {id: params.stateId, state}, (result, step, error) => {
|
|
169
170
|
if (error) {
|
|
170
|
-
|
|
171
|
+
commonLib.errorResponse(req, res, error);
|
|
171
172
|
return;
|
|
172
173
|
}
|
|
173
174
|
// req._adapter.log.debug(`[QUERY] sendTo result = ${JSON.stringify(result)}`);
|
|
@@ -186,9 +187,9 @@ module.exports = {
|
|
|
186
187
|
});
|
|
187
188
|
},
|
|
188
189
|
addHistoryByPost: function (req, res) {
|
|
189
|
-
commonLib.checkPermissions(req._adapter, req._user, req.body.options, async
|
|
190
|
-
if (
|
|
191
|
-
|
|
190
|
+
commonLib.checkPermissions(req._adapter, req._user, req.body.options, async error => {
|
|
191
|
+
if (error) {
|
|
192
|
+
commonLib.errorResponse(req, res, error);
|
|
192
193
|
} else {
|
|
193
194
|
if (req._adapter.config.dataSource) {
|
|
194
195
|
const state = await req._adapter.getForeignStateAsync(`system.adapter.${req._adapter.config.dataSource}.alive`);
|
|
@@ -217,7 +218,7 @@ module.exports = {
|
|
|
217
218
|
|
|
218
219
|
req._adapter.sendTo(req._adapter.config.dataSource, 'storeState', options, (result, step, error) => {
|
|
219
220
|
if (error) {
|
|
220
|
-
|
|
221
|
+
commonLib.errorResponse(req, res, error);
|
|
221
222
|
return;
|
|
222
223
|
}
|
|
223
224
|
// req._adapter.log.debug(`[QUERY] sendTo result = ${JSON.stringify(result)}`);
|
|
@@ -3,14 +3,14 @@ const commonLib = require('./common.js');
|
|
|
3
3
|
|
|
4
4
|
module.exports = {
|
|
5
5
|
readObject: function (req, res) {
|
|
6
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}],
|
|
7
|
-
if (
|
|
8
|
-
|
|
6
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], error => {
|
|
7
|
+
if (error) {
|
|
8
|
+
commonLib.errorResponse(req, res, error);
|
|
9
9
|
} else {
|
|
10
10
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
11
|
-
req._adapter.getForeignObject(params.objectId, {user: req._user}, (
|
|
12
|
-
if (
|
|
13
|
-
|
|
11
|
+
req._adapter.getForeignObject(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner}, (error, obj) => {
|
|
12
|
+
if (error) {
|
|
13
|
+
commonLib.errorResponse(req, res, error, {objectId: req.query.objectId});
|
|
14
14
|
} else {
|
|
15
15
|
if (!obj) {
|
|
16
16
|
res.status(404).json({error: 'object not found'});
|
|
@@ -24,16 +24,16 @@ module.exports = {
|
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
updateObject: function (req, res) {
|
|
27
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async
|
|
28
|
-
if (
|
|
29
|
-
|
|
27
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async error => {
|
|
28
|
+
if (error) {
|
|
29
|
+
commonLib.errorResponse(req, res, error);
|
|
30
30
|
} else {
|
|
31
31
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
32
32
|
const body = req.body;
|
|
33
33
|
try {
|
|
34
|
-
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user});
|
|
34
|
+
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
35
35
|
if (!obj) {
|
|
36
|
-
await req._adapter.setForeignObjectAsync(params.objectId, body, {user: req._user});
|
|
36
|
+
await req._adapter.setForeignObjectAsync(params.objectId, body, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
37
37
|
res.status(200).json(body);
|
|
38
38
|
} else {
|
|
39
39
|
// merge objects together
|
|
@@ -54,70 +54,70 @@ module.exports = {
|
|
|
54
54
|
obj[attr] = body[attr];
|
|
55
55
|
}
|
|
56
56
|
});
|
|
57
|
-
await req._adapter.setForeignObjectAsync(params.objectId, obj, {user: req._user});
|
|
57
|
+
await req._adapter.setForeignObjectAsync(params.objectId, obj, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
58
58
|
res.status(200).json(obj);
|
|
59
59
|
}
|
|
60
60
|
} catch (error) {
|
|
61
|
-
|
|
61
|
+
commonLib.errorResponse(req, res, error, {objectId: params.objectId});
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
});
|
|
65
65
|
},
|
|
66
66
|
|
|
67
67
|
createObject: function (req, res) {
|
|
68
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async
|
|
69
|
-
if (
|
|
70
|
-
|
|
68
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async error => {
|
|
69
|
+
if (error) {
|
|
70
|
+
commonLib.errorResponse(req, res, error);
|
|
71
71
|
} else {
|
|
72
72
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
73
73
|
const body = req.body;
|
|
74
74
|
try {
|
|
75
|
-
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user});
|
|
75
|
+
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
76
76
|
if (!obj) {
|
|
77
|
-
await req._adapter.setForeignObjectAsync(params.objectId, body, {user: req._user});
|
|
77
|
+
await req._adapter.setForeignObjectAsync(params.objectId, body, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
78
78
|
res.status(200).json(body);
|
|
79
79
|
} else {
|
|
80
80
|
res.status(409).json({error: 'Object already exists', id: params.objectId});
|
|
81
81
|
}
|
|
82
82
|
} catch (error) {
|
|
83
|
-
|
|
83
|
+
commonLib.errorResponse(req, res, error, {objectId: params.objectId});
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
87
|
},
|
|
88
88
|
|
|
89
89
|
deleteObject: function (req, res) {
|
|
90
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async
|
|
91
|
-
if (
|
|
92
|
-
|
|
90
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'write'}], async error => {
|
|
91
|
+
if (error) {
|
|
92
|
+
commonLib.errorResponse(req, res, error);
|
|
93
93
|
} else {
|
|
94
94
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
95
95
|
try {
|
|
96
|
-
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user});
|
|
96
|
+
const obj = await req._adapter.getForeignObjectAsync(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
97
97
|
if (!obj) {
|
|
98
98
|
res.status(404).json({objectId: params.objectId, error: 'object not found'});
|
|
99
99
|
} else {
|
|
100
|
-
await req._adapter.delForeignObjectAsync(params.objectId, {user: req._user});
|
|
100
|
+
await req._adapter.delForeignObjectAsync(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
101
101
|
res.status(200).json({});
|
|
102
102
|
}
|
|
103
103
|
} catch (error) {
|
|
104
|
-
|
|
104
|
+
commonLib.errorResponse(req, res, error, {objectId: params.objectId});
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
});
|
|
108
108
|
},
|
|
109
109
|
|
|
110
110
|
listObjects: function (req, res) {
|
|
111
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}],
|
|
112
|
-
if (
|
|
113
|
-
|
|
111
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], error => {
|
|
112
|
+
if (error) {
|
|
113
|
+
commonLib.errorResponse(req, res, error);
|
|
114
114
|
} else {
|
|
115
115
|
req._adapter.getForeignObjects(req.query.filter || '*', req.query.type || null, {
|
|
116
116
|
user: req._user,
|
|
117
117
|
limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner
|
|
118
|
-
}, (
|
|
119
|
-
if (
|
|
120
|
-
|
|
118
|
+
}, (error, list) => {
|
|
119
|
+
if (error) {
|
|
120
|
+
commonLib.errorResponse(req, res, error, {filter: req.query.filter});
|
|
121
121
|
} else {
|
|
122
122
|
res.json(list || []);
|
|
123
123
|
}
|
|
@@ -127,9 +127,9 @@ module.exports = {
|
|
|
127
127
|
},
|
|
128
128
|
|
|
129
129
|
subscribeObject: function (req, res) {
|
|
130
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
131
|
-
if (
|
|
132
|
-
|
|
130
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
131
|
+
if (error) {
|
|
132
|
+
commonLib.errorResponse(req, res, error);
|
|
133
133
|
} else {
|
|
134
134
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
135
135
|
|
|
@@ -144,25 +144,26 @@ module.exports = {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
try {
|
|
147
|
-
const obj = await req._adapter.getForeignObjectAsync(params.stateId, {user: req._user});
|
|
147
|
+
const obj = await req._adapter.getForeignObjectAsync(params.stateId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
148
148
|
if (!obj) {
|
|
149
149
|
res.status(404).json({error: 'object not found'});
|
|
150
150
|
} else {
|
|
151
151
|
await req._swaggerObject.registerSubscribe(url, params.objectId, 'object', req._user, (req.query && req.query.method) || (req.body && req.body.method));
|
|
152
|
-
const obj = await req._adapter.getForeignStateAsync(params.objectId, {user: req._user});
|
|
152
|
+
const obj = await req._adapter.getForeignStateAsync(params.objectId, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
153
153
|
res.status(200).json(obj);
|
|
154
154
|
}
|
|
155
155
|
} catch (error) {
|
|
156
|
-
|
|
156
|
+
req._adapter.log.warn(`Cannot read ${params.objectId}: ${error}`);
|
|
157
|
+
commonLib.errorResponse(req, res, error, {objectId: params.objectId});
|
|
157
158
|
}
|
|
158
159
|
}
|
|
159
160
|
});
|
|
160
161
|
},
|
|
161
162
|
|
|
162
163
|
unsubscribeObject: function (req, res) {
|
|
163
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
164
|
-
if (
|
|
165
|
-
|
|
164
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
165
|
+
if (error) {
|
|
166
|
+
commonLib.errorResponse(req, res, error);
|
|
166
167
|
} else {
|
|
167
168
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
168
169
|
|
|
@@ -179,16 +180,16 @@ module.exports = {
|
|
|
179
180
|
await req._swaggerObject.unregisterSubscribe(url, params.objectId, 'object', req._user, (req.query && req.query.method) || (req.body && req.body.method));
|
|
180
181
|
res.status(200).json({result: 'OK'});
|
|
181
182
|
} catch (error) {
|
|
182
|
-
|
|
183
|
+
commonLib.errorResponse(req, res, error, {objectId: params.objectId});
|
|
183
184
|
}
|
|
184
185
|
}
|
|
185
186
|
});
|
|
186
187
|
},
|
|
187
188
|
|
|
188
189
|
subscribeObjects: function (req, res) {
|
|
189
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
190
|
-
if (
|
|
191
|
-
|
|
190
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
191
|
+
if (error) {
|
|
192
|
+
commonLib.errorResponse(req, res, error);
|
|
192
193
|
} else {
|
|
193
194
|
let url = req.body.url;
|
|
194
195
|
if (req.body.method === 'polling') {
|
|
@@ -209,16 +210,16 @@ module.exports = {
|
|
|
209
210
|
try {
|
|
210
211
|
await req._swaggerObject.registerSubscribe(url, req.body.pattern, 'object', req._user, req.body.method);
|
|
211
212
|
} catch (error) {
|
|
212
|
-
|
|
213
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
213
214
|
}
|
|
214
215
|
}
|
|
215
216
|
});
|
|
216
217
|
},
|
|
217
218
|
|
|
218
219
|
unsubscribeObjects: function (req, res) {
|
|
219
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async
|
|
220
|
-
if (
|
|
221
|
-
|
|
220
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'object', operation: 'read'}], async error => {
|
|
221
|
+
if (error) {
|
|
222
|
+
commonLib.errorResponse(req, res, error);
|
|
222
223
|
} else {
|
|
223
224
|
let url = req.body.url;
|
|
224
225
|
if (req.body.method === 'polling') {
|
|
@@ -234,15 +235,16 @@ module.exports = {
|
|
|
234
235
|
await req._swaggerObject.unregisterSubscribe(url, req.body.pattern, 'object', req._user, req.body.method);
|
|
235
236
|
res.status(200).json({result: 'OK'});
|
|
236
237
|
} catch (error) {
|
|
237
|
-
|
|
238
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
238
239
|
}
|
|
239
240
|
}
|
|
240
241
|
});
|
|
241
242
|
},
|
|
243
|
+
|
|
242
244
|
getObjectsSubscribes: function (req, res) {
|
|
243
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
244
|
-
if (
|
|
245
|
-
|
|
245
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
246
|
+
if (error) {
|
|
247
|
+
commonLib.errorResponse(req, res, error);
|
|
246
248
|
} else {
|
|
247
249
|
let url = req.body.url;
|
|
248
250
|
if ((req.query && req.query.method === 'polling') || (req.body && req.body.method === 'polling')) {
|
|
@@ -263,7 +265,7 @@ module.exports = {
|
|
|
263
265
|
res.json({states: result});
|
|
264
266
|
|
|
265
267
|
} catch (error) {
|
|
266
|
-
|
|
268
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
267
269
|
}
|
|
268
270
|
}
|
|
269
271
|
});
|
|
@@ -8,13 +8,18 @@ function getIDs(oids) {
|
|
|
8
8
|
async function updateState(adapter, user, id, timeout, val, res) {
|
|
9
9
|
if (val && typeof val !== 'object') {
|
|
10
10
|
if (val === 'true' || val === 'false') {
|
|
11
|
-
const obj = await adapter.getForeignObjectAsync(id);
|
|
11
|
+
const obj = await adapter.getForeignObjectAsync(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
12
12
|
if (obj && obj.common && obj.common.type === 'boolean') {
|
|
13
13
|
val = val === 'true';
|
|
14
14
|
}
|
|
15
|
-
} else if (typeof val === 'string' &&
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
} else if (typeof val === 'string' && isFinite(val)) {
|
|
16
|
+
try {
|
|
17
|
+
const obj = await adapter.getForeignObjectAsync(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
18
|
+
if (obj && obj.common && obj.common.type === 'number') {
|
|
19
|
+
val = parseFloat(val);
|
|
20
|
+
}
|
|
21
|
+
} catch (error) {
|
|
22
|
+
adapter.log.warn(`Cannot read object ${id}: ${error.toString()}`);
|
|
18
23
|
val = parseFloat(val);
|
|
19
24
|
}
|
|
20
25
|
}
|
|
@@ -23,30 +28,30 @@ async function updateState(adapter, user, id, timeout, val, res) {
|
|
|
23
28
|
try {
|
|
24
29
|
if (!timeout) {
|
|
25
30
|
if (typeof val !== 'object') {
|
|
26
|
-
await adapter.
|
|
31
|
+
await adapter.setForeignStateAsync(id, val, false, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
27
32
|
res.json({id, val});
|
|
28
33
|
} else {
|
|
29
|
-
await adapter.
|
|
34
|
+
await adapter.setForeignStateAsync(id, val, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
30
35
|
val.id = id;
|
|
31
36
|
res.json(val);
|
|
32
37
|
}
|
|
33
38
|
} else {
|
|
34
39
|
await adapter._addTimeout({id, val, res, timeout});
|
|
35
40
|
if (typeof val !== 'object') {
|
|
36
|
-
await adapter.
|
|
41
|
+
await adapter.setForeignStateAsync(id, val, false, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
37
42
|
} else {
|
|
38
|
-
await adapter.
|
|
43
|
+
await adapter.setForeignStateAsync(id, val, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
} catch (error) {
|
|
42
|
-
|
|
47
|
+
commonLib.errorResponse({_adapter: adapter, url: 'updateState'}, res, error, {id});
|
|
43
48
|
}
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
function subscribeState(req, res) {
|
|
47
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
48
|
-
if (
|
|
49
|
-
res.status(403).json({error:
|
|
52
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
53
|
+
if (error) {
|
|
54
|
+
res.status(403).json({error: error});
|
|
50
55
|
} else {
|
|
51
56
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
52
57
|
let url = req.body.url;
|
|
@@ -72,14 +77,97 @@ function subscribeState(req, res) {
|
|
|
72
77
|
onchange: (req.query && req.query.onchange) || (req.body && req.body.onchange),
|
|
73
78
|
});
|
|
74
79
|
if (error) {
|
|
75
|
-
|
|
80
|
+
commonLib.errorResponse(req, res, error, {stateId: params.stateId, url: req.body.url});
|
|
76
81
|
return;
|
|
77
82
|
}
|
|
78
83
|
const state = await req._adapter.getForeignStateAsync(params.stateId, {user: req._user});
|
|
79
84
|
res.status(200).json(state);
|
|
80
85
|
}
|
|
81
86
|
} catch (error) {
|
|
82
|
-
|
|
87
|
+
commonLib.errorResponse(req, res, error, {stateId: params.stateId});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function toggleState(req, res, oId) {
|
|
94
|
+
let timeout = 0;
|
|
95
|
+
if (req.query.timeout) {
|
|
96
|
+
timeout = parseInt(req.query.timeout, 10);
|
|
97
|
+
|
|
98
|
+
if (timeout > 60000) {
|
|
99
|
+
timeout = 60000;
|
|
100
|
+
} // maximum 1 minute
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
commonLib.findState(req._adapter, oId, req._user, async (error, id, originId) => {
|
|
104
|
+
if (error && error.message && error.message.includes('permissionError')) {
|
|
105
|
+
// assume it is ID
|
|
106
|
+
id = oId;
|
|
107
|
+
error = null;
|
|
108
|
+
}
|
|
109
|
+
if (error) {
|
|
110
|
+
commonLib.errorResponse(req, res, error, {id: oId});
|
|
111
|
+
} else if (!id) {
|
|
112
|
+
res.status(404).json({error: 'ID not found', id: originId});
|
|
113
|
+
} else {
|
|
114
|
+
try {
|
|
115
|
+
const state = await req._adapter.getForeignStateAsync(id, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
116
|
+
if (!state || typeof state !== 'object') {
|
|
117
|
+
res.status(500).json({error: 'State not initiated', id: originId});
|
|
118
|
+
} else {
|
|
119
|
+
let obj;
|
|
120
|
+
try {
|
|
121
|
+
obj = await req._adapter.getForeignObjectAsync(id, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
122
|
+
} catch (error) {
|
|
123
|
+
req._adapter.log.warn(`Cannot read object ${id}: ${error}`);
|
|
124
|
+
}
|
|
125
|
+
let val;
|
|
126
|
+
if (state.val === 'true') {
|
|
127
|
+
val = 'false';
|
|
128
|
+
} else if (state.val === 'false') {
|
|
129
|
+
val = 'true';
|
|
130
|
+
} else if (state.val === 'on') {
|
|
131
|
+
val = 'off';
|
|
132
|
+
} else if (state.val === 'off') {
|
|
133
|
+
val = 'on';
|
|
134
|
+
} else if (state.val === 'OFF') {
|
|
135
|
+
val = 'ON';
|
|
136
|
+
} else if (state.val === 'ON') {
|
|
137
|
+
val = 'OFF';
|
|
138
|
+
} else if (state.val === '0') {
|
|
139
|
+
val = '1';
|
|
140
|
+
} else if (state.val === '1') {
|
|
141
|
+
val = '0';
|
|
142
|
+
} else if (typeof state.val === 'number') {
|
|
143
|
+
val = state.val ? 0 : 1;
|
|
144
|
+
} else {
|
|
145
|
+
val = !state.val;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (obj && obj.common) {
|
|
149
|
+
if (obj.common.type === 'boolean') {
|
|
150
|
+
state.val = state.val === 'true' || state.val === true;
|
|
151
|
+
} else if (obj.common.type === 'number') {
|
|
152
|
+
if (obj.common.min !== undefined && obj.common.max !== undefined) {
|
|
153
|
+
val = parseFloat(state.val);
|
|
154
|
+
if (val > obj.common.max) {
|
|
155
|
+
val = obj.common.max;
|
|
156
|
+
} else
|
|
157
|
+
if (val < obj.common.min) {
|
|
158
|
+
val = obj.common.min;
|
|
159
|
+
}
|
|
160
|
+
val = obj.common.max + obj.common.min - val;
|
|
161
|
+
} else {
|
|
162
|
+
val = parseFloat(val);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
await updateState(req._adapter, req._user, id, timeout, val, res);
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
commonLib.errorResponse(req, res, error, {id: oId});
|
|
83
171
|
}
|
|
84
172
|
}
|
|
85
173
|
});
|
|
@@ -87,9 +175,9 @@ function subscribeState(req, res) {
|
|
|
87
175
|
|
|
88
176
|
module.exports = {
|
|
89
177
|
updateState: function (req, res) {
|
|
90
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'write'}],
|
|
91
|
-
if (
|
|
92
|
-
|
|
178
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'write'}], error => {
|
|
179
|
+
if (error) {
|
|
180
|
+
commonLib.errorResponse(req, res, error);
|
|
93
181
|
} else {
|
|
94
182
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
95
183
|
const oId = getIDs(params.stateId);
|
|
@@ -102,9 +190,15 @@ module.exports = {
|
|
|
102
190
|
} // maximum 1 minute
|
|
103
191
|
}
|
|
104
192
|
|
|
105
|
-
commonLib.findState(req._adapter, oId[0], req._user, async (
|
|
106
|
-
if (
|
|
107
|
-
|
|
193
|
+
commonLib.findState(req._adapter, oId[0], req._user, async (error, id, originId) => {
|
|
194
|
+
if (error && error.message && error.message.includes('permissionError')) {
|
|
195
|
+
// assume it is ID
|
|
196
|
+
id = oId[0];
|
|
197
|
+
error = null;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (error) {
|
|
201
|
+
commonLib.errorResponse(req, res, error, {id: oId[0]});
|
|
108
202
|
} else if (!id) {
|
|
109
203
|
res.status(404).json({error: 'ID not found', id: originId});
|
|
110
204
|
} else {
|
|
@@ -116,90 +210,21 @@ module.exports = {
|
|
|
116
210
|
},
|
|
117
211
|
|
|
118
212
|
toggleState: function (req, res) {
|
|
119
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'write'}],
|
|
120
|
-
if (
|
|
121
|
-
|
|
213
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'write'}], error => {
|
|
214
|
+
if (error) {
|
|
215
|
+
commonLib.errorResponse(req, res, error);
|
|
122
216
|
} else {
|
|
123
217
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
124
218
|
const oId = getIDs(params.stateId);
|
|
125
|
-
|
|
126
|
-
if (req.query.timeout) {
|
|
127
|
-
timeout = parseInt(req.query.timeout, 10);
|
|
128
|
-
|
|
129
|
-
if (timeout > 60000) {
|
|
130
|
-
timeout = 60000;
|
|
131
|
-
} // maximum 1 minute
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
commonLib.findState(req._adapter, oId[0], req._user, async (err, id, originId) => {
|
|
135
|
-
if (err) {
|
|
136
|
-
res.status(500).json({error: err, id: originId});
|
|
137
|
-
} else if (!id) {
|
|
138
|
-
res.status(404).json({error: 'ID not found', id: originId});
|
|
139
|
-
} else {
|
|
140
|
-
try {
|
|
141
|
-
const state = await req._adapter.getForeignStateAsync(id, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
142
|
-
if (!state || typeof state !== 'object') {
|
|
143
|
-
res.status(500).json({error: 'State not initiated', id: originId});
|
|
144
|
-
} else {
|
|
145
|
-
const obj = await req._adapter.getForeignObjectAsync(id, {user: req._user, limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner});
|
|
146
|
-
let val;
|
|
147
|
-
if (state.val === 'true') {
|
|
148
|
-
val = 'false';
|
|
149
|
-
} else if (state.val === 'false') {
|
|
150
|
-
val = 'true';
|
|
151
|
-
} else if (state.val === 'on') {
|
|
152
|
-
val = 'off';
|
|
153
|
-
} else if (state.val === 'off') {
|
|
154
|
-
val = 'on';
|
|
155
|
-
} else if (state.val === 'OFF') {
|
|
156
|
-
val = 'ON';
|
|
157
|
-
} else if (state.val === 'ON') {
|
|
158
|
-
val = 'OFF';
|
|
159
|
-
} else if (state.val === '0') {
|
|
160
|
-
val = '1';
|
|
161
|
-
} else if (state.val === '1') {
|
|
162
|
-
val = '0';
|
|
163
|
-
} else if (typeof state.val === 'number') {
|
|
164
|
-
val = state.val ? 0 : 1;
|
|
165
|
-
} else {
|
|
166
|
-
val = !state.val;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (obj && obj.common) {
|
|
170
|
-
if (obj.common.type === 'boolean') {
|
|
171
|
-
state.val = state.val === 'true' || state.val === true;
|
|
172
|
-
} else if (obj.common.type === 'number') {
|
|
173
|
-
if (obj.common.min !== undefined && obj.common.max !== undefined) {
|
|
174
|
-
val = parseFloat(state.val);
|
|
175
|
-
if (val > obj.common.max) {
|
|
176
|
-
val = obj.common.max;
|
|
177
|
-
} else
|
|
178
|
-
if (val < obj.common.min) {
|
|
179
|
-
val = obj.common.min;
|
|
180
|
-
}
|
|
181
|
-
val = obj.common.max + obj.common.min - val;
|
|
182
|
-
} else {
|
|
183
|
-
val = parseFloat(val);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
await updateState(req._adapter, req._user, id, timeout, val, res);
|
|
189
|
-
}
|
|
190
|
-
} catch (error) {
|
|
191
|
-
res.status(500).json({error: err, id: originId});
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
});
|
|
219
|
+
toggleState(req, res, oId[0]);
|
|
195
220
|
}
|
|
196
221
|
});
|
|
197
222
|
},
|
|
198
223
|
|
|
199
224
|
readState: function (req, res) {
|
|
200
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
201
|
-
if (
|
|
202
|
-
|
|
225
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
226
|
+
if (error) {
|
|
227
|
+
commonLib.errorResponse(req, res, error);
|
|
203
228
|
} else {
|
|
204
229
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
205
230
|
const oId = getIDs(params.stateId);
|
|
@@ -212,12 +237,11 @@ module.exports = {
|
|
|
212
237
|
} // maximum 1 minute
|
|
213
238
|
}
|
|
214
239
|
|
|
215
|
-
|
|
216
240
|
let result;
|
|
217
241
|
for (let k = 0; k < oId.length; k++) {
|
|
218
242
|
try {
|
|
219
|
-
const {state, id, originId} = await new Promise((resolve, reject) => commonLib.getState(req._adapter, oId[k], req._user, (
|
|
220
|
-
|
|
243
|
+
const {state, id, originId} = await new Promise((resolve, reject) => commonLib.getState(req._adapter, oId[k], req._user, (error, state, id, originId) =>
|
|
244
|
+
error ? reject(error) : resolve({state, id, originId})));
|
|
221
245
|
|
|
222
246
|
if (!id) {
|
|
223
247
|
res.status(404).json({error: 'ID not found', id: originId});
|
|
@@ -226,20 +250,27 @@ module.exports = {
|
|
|
226
250
|
if (req.query.value !== undefined) {
|
|
227
251
|
await updateState(req._adapter, req._user, id, timeout, req.query.value, res);
|
|
228
252
|
return;
|
|
253
|
+
} else if (req.query.toggle !== undefined) {
|
|
254
|
+
await toggleState(req, res, id);
|
|
255
|
+
return;
|
|
229
256
|
}
|
|
230
257
|
|
|
231
258
|
const vObj = state || {};
|
|
232
259
|
if (req.query.withInfo === 'true') {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
260
|
+
try {
|
|
261
|
+
const obj = await req._adapter.getForeignObjectAsync(id);
|
|
262
|
+
// copy all attributes of the object into state
|
|
263
|
+
if (obj) {
|
|
264
|
+
Object.keys(obj).forEach(attr => {
|
|
265
|
+
if (attr === '_id') {
|
|
266
|
+
vObj.id = obj._id;
|
|
267
|
+
} else {
|
|
268
|
+
vObj[attr] = obj[attr];
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
req._adapter.log.warn(`Error by reading of object "${id}": ${error}`);
|
|
243
274
|
}
|
|
244
275
|
}
|
|
245
276
|
|
|
@@ -253,7 +284,8 @@ module.exports = {
|
|
|
253
284
|
}
|
|
254
285
|
}
|
|
255
286
|
} catch (error) {
|
|
256
|
-
|
|
287
|
+
req._adapter.log.warn(`Cannot read ${oId}: ${error}`);
|
|
288
|
+
commonLib.errorResponse(req, res, error, {id: oId});
|
|
257
289
|
return;
|
|
258
290
|
}
|
|
259
291
|
}
|
|
@@ -264,15 +296,15 @@ module.exports = {
|
|
|
264
296
|
},
|
|
265
297
|
|
|
266
298
|
plainState: function (req, res) {
|
|
267
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
268
|
-
if (
|
|
269
|
-
|
|
299
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
300
|
+
if (error) {
|
|
301
|
+
commonLib.errorResponse(req, res, error);
|
|
270
302
|
} else {
|
|
271
303
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
272
304
|
const oId = getIDs(params.stateId);
|
|
273
305
|
try {
|
|
274
|
-
const {state, id, originId} = await new Promise((resolve, reject) => commonLib.getState(req._adapter, oId[0], req._user, (
|
|
275
|
-
|
|
306
|
+
const {state, id, originId} = await new Promise((resolve, reject) => commonLib.getState(req._adapter, oId[0], req._user, (error, state, id, originId) =>
|
|
307
|
+
error ? reject(error) : resolve({state, id, originId})));
|
|
276
308
|
|
|
277
309
|
if (!id) {
|
|
278
310
|
res.status(404).json({error: 'ID not found', id: originId});
|
|
@@ -292,23 +324,23 @@ module.exports = {
|
|
|
292
324
|
}
|
|
293
325
|
}
|
|
294
326
|
} catch (error) {
|
|
295
|
-
|
|
327
|
+
commonLib.errorResponse(req, res, error, {id: oId});
|
|
296
328
|
}
|
|
297
329
|
}
|
|
298
330
|
});
|
|
299
331
|
},
|
|
300
332
|
|
|
301
333
|
listStates: function (req, res) {
|
|
302
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'list'}],
|
|
303
|
-
if (
|
|
304
|
-
|
|
334
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'list'}], error => {
|
|
335
|
+
if (error) {
|
|
336
|
+
commonLib.errorResponse(req, res, error);
|
|
305
337
|
} else {
|
|
306
338
|
req._adapter.getForeignStates(req.query.filter || '*', {
|
|
307
339
|
user: req._user,
|
|
308
340
|
limitToOwnerRights: req._adapter.config.onlyAllowWhenUserIsOwner
|
|
309
|
-
},
|
|
310
|
-
if (
|
|
311
|
-
|
|
341
|
+
}, (error, list) => {
|
|
342
|
+
if (error) {
|
|
343
|
+
commonLib.errorResponse(req, res, error, {filter: req.query.filter});
|
|
312
344
|
} else {
|
|
313
345
|
res.json(list || []);
|
|
314
346
|
}
|
|
@@ -322,9 +354,9 @@ module.exports = {
|
|
|
322
354
|
subscribeState: subscribeState,
|
|
323
355
|
|
|
324
356
|
unsubscribeState: function (req, res) {
|
|
325
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
326
|
-
if (
|
|
327
|
-
|
|
357
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
358
|
+
if (error) {
|
|
359
|
+
commonLib.errorResponse(req, res, error);
|
|
328
360
|
} else {
|
|
329
361
|
const params = commonLib.parseUrl(req.url, req.swagger, req._adapter.WEB_EXTENSION_PREFIX);
|
|
330
362
|
|
|
@@ -342,16 +374,16 @@ module.exports = {
|
|
|
342
374
|
await req._swaggerObject.unregisterSubscribe(url, params.stateId, 'state', req._user, (req.query && req.query.method) || (req.body && req.body.method));
|
|
343
375
|
res.status(200).json({result: 'OK'});
|
|
344
376
|
} catch (error) {
|
|
345
|
-
|
|
377
|
+
commonLib.errorResponse(req, res, error, {stateId: params.stateId});
|
|
346
378
|
}
|
|
347
379
|
}
|
|
348
380
|
});
|
|
349
381
|
},
|
|
350
382
|
|
|
351
383
|
subscribeStates: function (req, res) {
|
|
352
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
353
|
-
if (
|
|
354
|
-
|
|
384
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
385
|
+
if (error) {
|
|
386
|
+
commonLib.errorResponse(req, res, error);
|
|
355
387
|
} else {
|
|
356
388
|
let url = req.body.url;
|
|
357
389
|
if ((req.query && req.query.method === 'polling') || (req.body && req.body.method === 'polling')) {
|
|
@@ -377,16 +409,16 @@ module.exports = {
|
|
|
377
409
|
delta: req.body.delta !== undefined ? parseFloat(req.body.delta) : undefined,
|
|
378
410
|
});
|
|
379
411
|
} catch (error) {
|
|
380
|
-
|
|
412
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
381
413
|
}
|
|
382
414
|
}
|
|
383
415
|
});
|
|
384
416
|
},
|
|
385
417
|
|
|
386
418
|
unsubscribeStates: function (req, res) {
|
|
387
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
388
|
-
if (
|
|
389
|
-
|
|
419
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
420
|
+
if (error) {
|
|
421
|
+
commonLib.errorResponse(req, res, error);
|
|
390
422
|
} else {
|
|
391
423
|
let url = req.body.url;
|
|
392
424
|
if (req.body.method === 'polling') {
|
|
@@ -401,16 +433,16 @@ module.exports = {
|
|
|
401
433
|
await req._swaggerObject.unregisterSubscribe(url, req.body.pattern, 'state', req._user, req.body.method);
|
|
402
434
|
res.status(200).json({result: 'OK'});
|
|
403
435
|
} catch (error) {
|
|
404
|
-
|
|
436
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
405
437
|
}
|
|
406
438
|
}
|
|
407
439
|
});
|
|
408
440
|
},
|
|
409
441
|
|
|
410
442
|
getStatesSubscribes: function (req, res) {
|
|
411
|
-
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async
|
|
412
|
-
if (
|
|
413
|
-
|
|
443
|
+
commonLib.checkPermissions(req._adapter, req._user, [{type: 'state', operation: 'read'}], async error => {
|
|
444
|
+
if (error) {
|
|
445
|
+
commonLib.errorResponse(req, res, error);
|
|
414
446
|
} else {
|
|
415
447
|
let url = req.body.url;
|
|
416
448
|
if ((req.query && req.query.method === 'polling') || (req.body && req.body.method === 'polling')) {
|
|
@@ -430,7 +462,7 @@ module.exports = {
|
|
|
430
462
|
}
|
|
431
463
|
res.json({states: result});
|
|
432
464
|
} catch (error) {
|
|
433
|
-
|
|
465
|
+
commonLib.errorResponse(req, res, error, {pattern: req.body.pattern, url: req.body.url});
|
|
434
466
|
}
|
|
435
467
|
}
|
|
436
468
|
});
|
|
@@ -1838,29 +1838,6 @@ paths:
|
|
|
1838
1838
|
responses:
|
|
1839
1839
|
200:
|
|
1840
1840
|
description: "successful operation"
|
|
1841
|
-
/command/delObjects:
|
|
1842
|
-
get:
|
|
1843
|
-
tags:
|
|
1844
|
-
- "commands"
|
|
1845
|
-
summary: "delete objects by pattern"
|
|
1846
|
-
produces:
|
|
1847
|
-
- "application/json"
|
|
1848
|
-
parameters:
|
|
1849
|
-
|
|
1850
|
-
- name: "id"
|
|
1851
|
-
in: "query"
|
|
1852
|
-
description: ""
|
|
1853
|
-
type: "string"
|
|
1854
|
-
required: true
|
|
1855
|
-
|
|
1856
|
-
- name: "options"
|
|
1857
|
-
in: "query"
|
|
1858
|
-
description: "JSON object"
|
|
1859
|
-
type: "string"
|
|
1860
|
-
required: false
|
|
1861
|
-
responses:
|
|
1862
|
-
200:
|
|
1863
|
-
description: "successful operation"
|
|
1864
1841
|
# admin commands end
|
|
1865
1842
|
/command/log:
|
|
1866
1843
|
get:
|
package/lib/rest-api.js
CHANGED
|
@@ -12,11 +12,12 @@ const crypto = require('crypto');
|
|
|
12
12
|
const axios = require('axios');
|
|
13
13
|
const cors = require('cors');
|
|
14
14
|
const fs = require('fs');
|
|
15
|
-
const
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const utils = require('@iobroker/adapter-core'); // Get common adapter utils
|
|
17
|
+
const tools = require(utils.controllerDir + '/lib/tools');
|
|
16
18
|
const CommandsAdmin = require('@iobroker/socket-classes').SocketCommandsAdmin;
|
|
17
19
|
const CommandsCommon = require('@iobroker/socket-classes').SocketCommands;
|
|
18
20
|
const common = require('./common');
|
|
19
|
-
const path = require("path");
|
|
20
21
|
|
|
21
22
|
process.env.SUPPRESS_NO_CONFIG_WARNING = 'true';
|
|
22
23
|
|
|
@@ -512,9 +513,9 @@ function SwaggerUI(_ignore, webSettings, adapter, instanceSettings, app, callbac
|
|
|
512
513
|
|
|
513
514
|
if (type === 'state') {
|
|
514
515
|
this.adapter.log.debug(`[${urlHook}] Subscribe on state "${id}"`);
|
|
515
|
-
await this.adapter.subscribeForeignStatesAsync(id, {user});
|
|
516
|
+
await this.adapter.subscribeForeignStatesAsync(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
516
517
|
if (!item.regEx && (options.onchange || options.delta)) {
|
|
517
|
-
item.val = await this.adapter.getForeignStateAsync(id);
|
|
518
|
+
item.val = await this.adapter.getForeignStateAsync(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
518
519
|
if (item.val) {
|
|
519
520
|
item.val = item.val.val;
|
|
520
521
|
} else {
|
|
@@ -523,7 +524,7 @@ function SwaggerUI(_ignore, webSettings, adapter, instanceSettings, app, callbac
|
|
|
523
524
|
}
|
|
524
525
|
} else {
|
|
525
526
|
this.adapter.log.debug(`[${urlHook}] Subscribe on object "${id}"`);
|
|
526
|
-
await this.adapter.subscribeForeignObjectsAsync(id, {user});
|
|
527
|
+
await this.adapter.subscribeForeignObjectsAsync(id, {user, limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner});
|
|
527
528
|
}
|
|
528
529
|
}
|
|
529
530
|
|
|
@@ -559,10 +560,10 @@ function SwaggerUI(_ignore, webSettings, adapter, instanceSettings, app, callbac
|
|
|
559
560
|
this.subscribes[urlHash][type].splice(pos, 1);
|
|
560
561
|
if (type === 'state') {
|
|
561
562
|
this.adapter.log.debug(`Unsubscribe from state "${id}"`);
|
|
562
|
-
await this.adapter.unsubscribeForeignStatesAsync(id, {user: user || 'system.user.admin'}); // allow unsubscribing always
|
|
563
|
+
await this.adapter.unsubscribeForeignStatesAsync(id, {user: user || 'system.user.admin', limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}); // allow unsubscribing always
|
|
563
564
|
} else {
|
|
564
565
|
this.adapter.log.debug(`Unsubscribe from object "${id}"`);
|
|
565
|
-
await this.adapter.unsubscribeForeignObjectsAsync(id, {user: user || 'system.user.admin'}); // allow unsubscribing always
|
|
566
|
+
await this.adapter.unsubscribeForeignObjectsAsync(id, {user: user || 'system.user.admin', limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}); // allow unsubscribing always
|
|
566
567
|
}
|
|
567
568
|
} else {
|
|
568
569
|
break;
|
|
@@ -571,9 +572,9 @@ function SwaggerUI(_ignore, webSettings, adapter, instanceSettings, app, callbac
|
|
|
571
572
|
} else {
|
|
572
573
|
for (let i = 0; i < this.subscribes[urlHash][type].length; i++) {
|
|
573
574
|
if (type === 'state') {
|
|
574
|
-
await this.adapter.unsubscribeForeignStatesAsync(this.subscribes[urlHash][type][i].id, {user: user || 'system.user.admin'}); // allow unsubscribing always
|
|
575
|
+
await this.adapter.unsubscribeForeignStatesAsync(this.subscribes[urlHash][type][i].id, {user: user || 'system.user.admin', limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}); // allow unsubscribing always
|
|
575
576
|
} else {
|
|
576
|
-
await this.adapter.unsubscribeForeignObjectsAsync(this.subscribes[urlHash][type][i].id, {user: user || 'system.user.admin'}); // allow unsubscribing always
|
|
577
|
+
await this.adapter.unsubscribeForeignObjectsAsync(this.subscribes[urlHash][type][i].id, {user: user || 'system.user.admin', limitToOwnerRights: adapter.config.onlyAllowWhenUserIsOwner}); // allow unsubscribing always
|
|
577
578
|
}
|
|
578
579
|
}
|
|
579
580
|
this.subscribes[urlHash][type] = [];
|
package/main.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
6
|
const utils = require('@iobroker/adapter-core'); // Get common adapter utils
|
|
7
|
-
const RestAPI = require('./lib/rest-api.js');
|
|
8
7
|
const LE = require(utils.controllerDir + '/lib/letsencrypt.js');
|
|
8
|
+
const RestAPI = require('./lib/rest-api.js');
|
|
9
9
|
const adapterName = require('./package.json').name.split('.').pop();
|
|
10
10
|
|
|
11
11
|
let webServer = null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.rest-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "RESTful interface for ioBroker with GUI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "bluefox",
|
|
@@ -20,26 +20,26 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@iobroker/adapter-core": "^2.6.0",
|
|
23
|
-
"@iobroker/socket-classes": "^0.1.
|
|
24
|
-
"
|
|
23
|
+
"@iobroker/socket-classes": "^0.1.5",
|
|
24
|
+
"axios": "^0.27.2",
|
|
25
25
|
"body-parser": "^1.20.0",
|
|
26
|
+
"cors": "^2.8.5",
|
|
27
|
+
"express": "^4.18.1",
|
|
26
28
|
"swagger-node-runner-fork": "^0.8.0",
|
|
27
29
|
"swagger-ui-express": "^4.3.0",
|
|
28
|
-
"yamljs": "^0.3.0"
|
|
29
|
-
"axios": "^0.26.1",
|
|
30
|
-
"cors": "^2.8.5"
|
|
30
|
+
"yamljs": "^0.3.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@alcalzone/release-script": "^3.5.
|
|
34
|
-
"@alcalzone/release-script-plugin-iobroker": "^3.5.
|
|
35
|
-
"@alcalzone/release-script-plugin-license": "^3.5.
|
|
33
|
+
"@alcalzone/release-script": "^3.5.9",
|
|
34
|
+
"@alcalzone/release-script-plugin-iobroker": "^3.5.9",
|
|
35
|
+
"@alcalzone/release-script-plugin-license": "^3.5.9",
|
|
36
|
+
"@iobroker/testing": "^3.0.2",
|
|
37
|
+
"chai": "^4.3.6",
|
|
36
38
|
"eslint-plugin-eqeqeq-fix": "^1.0.3",
|
|
37
39
|
"eslint-plugin-only-warn": "^1.0.3",
|
|
38
40
|
"eslint-plugin-react": "^7.29.4",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"@iobroker/testing": "^2.6.0",
|
|
42
|
-
"gulp": "^4.0.2"
|
|
41
|
+
"gulp": "^4.0.2",
|
|
42
|
+
"mocha": "^9.2.2"
|
|
43
43
|
},
|
|
44
44
|
"bugs": {
|
|
45
45
|
"url": "https://github.com/ioBroker/ioBroker.rest-api/issues"
|