node-red-contrib-uos-nats 0.1.6 → 0.1.8
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 +4 -4
- package/nodes/datahub-input.html +61 -24
- package/nodes/uos-config.html +9 -4
- package/nodes/uos-config.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,15 +31,15 @@ Fields:
|
|
|
31
31
|
- **Host / Port** – IP address of your controller (e.g. `192.168.10.100`) and the NATS port `49360`.
|
|
32
32
|
- **Client Name** – used for the NATS inbox prefix (`_INBOX.<name>`).
|
|
33
33
|
- **Client ID / Secret** – OAuth2 client credentials created in the Control Center.
|
|
34
|
-
- **Scope** –
|
|
34
|
+
- **Scope** – fixed to `hub.variables.provide hub.variables.readwrite hub.variables.readonly` so the nodes can register providers and query the REST metadata; it is not editable in the UI.
|
|
35
35
|
- **Granted scopes** – click *Refresh* to query the token endpoint and show the scopes currently granted to that client.
|
|
36
36
|
|
|
37
37
|
The config node automatically fetches tokens via Client Credentials flow and exposes helper endpoints so other nodes can list providers and variables. The token endpoint is derived from the configured host (`https://<host>/oauth2/token`), so there is no additional field to maintain.
|
|
38
38
|
|
|
39
39
|
## DataHub Input Node
|
|
40
40
|
|
|
41
|
-
- Select the u-OS config node, then choose one of the discovered providers from the dropdown (the node queries `/datahub/v1/providers` for you).
|
|
42
|
-
- Pick the variables you need from the multi-select list. Leave it empty to receive all variables from the provider.
|
|
41
|
+
- Select the u-OS config node, then choose one of the discovered providers from the dropdown (the node queries `/datahub/v1/providers` for you). If your OAuth client lacks read-only scope, the dropdown is disabled and you can type the provider ID manually.
|
|
42
|
+
- Pick the variables you need from the multi-select list. Leave it empty to receive all variables from the provider. (When manual provider input is used the list may stay empty, because it also requires the read-only permission.)
|
|
43
43
|
- The node outputs messages with the structure:
|
|
44
44
|
```json
|
|
45
45
|
{
|
|
@@ -68,7 +68,7 @@ The config node automatically fetches tokens via Client Credentials flow and exp
|
|
|
68
68
|
## Example Flow
|
|
69
69
|
|
|
70
70
|
1. Drop a **u-OS Config** node, fill in host/port and OAuth credentials from the Control Center.
|
|
71
|
-
2. Add a **DataHub Input** node, select the config,
|
|
71
|
+
2. Add a **DataHub Input** node, select the config, choose the provider from the dropdown (or type the provider ID if the API access is restricted) and pick the variables you care about. Connect the output to a Debug node.
|
|
72
72
|
3. Add a **DataHub Output** node, leave provider ID = `nodered` and send structured JSON (e.g. from a Function node). The values instantly appear in the Data Hub under the provider `nodered`.
|
|
73
73
|
|
|
74
74
|
> Tip: Because both nodes rely on the Control Center HTTP API for metadata they inherit the same permissions as your OAuth client. Make sure the client has at least `hub.variables.readonly` for the input node and `hub.variables.provide hub.variables.readwrite` for the output node.
|
package/nodes/datahub-input.html
CHANGED
|
@@ -14,13 +14,15 @@
|
|
|
14
14
|
oneditprepare: function() {
|
|
15
15
|
const node = this;
|
|
16
16
|
const $config = $('#node-input-connection');
|
|
17
|
-
const $
|
|
17
|
+
const $providerHidden = $('#node-input-providerId');
|
|
18
|
+
const $providerSelect = $('#datahub-provider-select');
|
|
19
|
+
const $providerManual = $('#datahub-provider-manual');
|
|
18
20
|
const $providerStatus = $('#datahub-provider-status');
|
|
19
21
|
const $variablesHidden = $('#node-input-variablesText');
|
|
20
22
|
const $variables = $('#datahub-input-variables');
|
|
21
23
|
const $variablesStatus = $('#datahub-variables-status');
|
|
22
24
|
|
|
23
|
-
const initialProvider =
|
|
25
|
+
const initialProvider = $providerHidden.val() || '';
|
|
24
26
|
const initialVars = ($variablesHidden.val() || '')
|
|
25
27
|
.split(',')
|
|
26
28
|
.map((entry) => entry.trim())
|
|
@@ -68,6 +70,24 @@
|
|
|
68
70
|
const setProviderStatus = (text) => $providerStatus.text(text || '');
|
|
69
71
|
const setVariableStatus = (text) => $variablesStatus.text(text || '');
|
|
70
72
|
|
|
73
|
+
const setProviderValue = (value) => {
|
|
74
|
+
$providerHidden.val(value || '');
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const getProviderValue = () => $providerHidden.val() || '';
|
|
78
|
+
|
|
79
|
+
const showManualProvider = (message) => {
|
|
80
|
+
$providerSelect.hide().prop('disabled', true);
|
|
81
|
+
$providerManual.show().prop('disabled', false);
|
|
82
|
+
$providerManual.val(getProviderValue());
|
|
83
|
+
setProviderStatus(message || 'Enter the provider ID manually.');
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const showSelectProvider = () => {
|
|
87
|
+
$providerManual.hide().prop('disabled', true);
|
|
88
|
+
$providerSelect.show().prop('disabled', false);
|
|
89
|
+
};
|
|
90
|
+
|
|
71
91
|
const loadVariables = (providerId, keepSelection = false) => {
|
|
72
92
|
const configId = $config.val();
|
|
73
93
|
if (!configId || !providerId) {
|
|
@@ -121,10 +141,10 @@
|
|
|
121
141
|
const loadProviders = () => {
|
|
122
142
|
const configId = $config.val();
|
|
123
143
|
if (!configId) {
|
|
124
|
-
$
|
|
125
|
-
$
|
|
126
|
-
$
|
|
127
|
-
|
|
144
|
+
$providerSelect.empty();
|
|
145
|
+
$providerSelect.append('<option value="">Select a u-OS config first</option>');
|
|
146
|
+
$providerSelect.prop('disabled', true);
|
|
147
|
+
showManualProvider('Pick or create a u-OS config node before selecting a provider.');
|
|
128
148
|
setVariableStatus('');
|
|
129
149
|
$variables.empty();
|
|
130
150
|
$variables.prop('disabled', true);
|
|
@@ -132,18 +152,20 @@
|
|
|
132
152
|
}
|
|
133
153
|
const seq = ++providerRequest;
|
|
134
154
|
setProviderStatus('Loading providers…');
|
|
135
|
-
$
|
|
155
|
+
$providerSelect.prop('disabled', true);
|
|
156
|
+
showSelectProvider();
|
|
136
157
|
$.getJSON(`uos/providers/${configId}`)
|
|
137
158
|
.done((payload) => {
|
|
138
159
|
if (seq !== providerRequest) {
|
|
139
160
|
return;
|
|
140
161
|
}
|
|
141
162
|
const list = normalizeProviders(payload);
|
|
142
|
-
$
|
|
163
|
+
$providerSelect.empty();
|
|
143
164
|
if (!list.length) {
|
|
144
|
-
$
|
|
165
|
+
$providerSelect.append('<option value="">No providers available</option>');
|
|
166
|
+
$providerSelect.prop('disabled', true);
|
|
145
167
|
setProviderStatus('No providers returned. Verify Data Hub access.');
|
|
146
|
-
|
|
168
|
+
showManualProvider('No providers returned. Enter the ID manually if you know it.');
|
|
147
169
|
return;
|
|
148
170
|
}
|
|
149
171
|
list.forEach((prov) => {
|
|
@@ -154,24 +176,23 @@
|
|
|
154
176
|
const option = $('<option></option>')
|
|
155
177
|
.attr('value', value)
|
|
156
178
|
.text(providerLabel(prov));
|
|
157
|
-
$
|
|
179
|
+
$providerSelect.append(option);
|
|
158
180
|
});
|
|
159
|
-
$
|
|
181
|
+
$providerSelect.prop('disabled', false);
|
|
160
182
|
if (initialProvider) {
|
|
161
|
-
$
|
|
183
|
+
$providerSelect.val(initialProvider);
|
|
162
184
|
}
|
|
163
|
-
if (!$
|
|
164
|
-
$
|
|
185
|
+
if (!$providerSelect.val()) {
|
|
186
|
+
$providerSelect.val($providerSelect.find('option:first').attr('value'));
|
|
165
187
|
}
|
|
188
|
+
const selected = $providerSelect.val();
|
|
189
|
+
setProviderValue(selected);
|
|
166
190
|
setProviderStatus('Choose the provider you want to subscribe to.');
|
|
167
|
-
loadVariables(
|
|
191
|
+
loadVariables(selected);
|
|
168
192
|
})
|
|
169
193
|
.fail((xhr) => {
|
|
170
194
|
const msg = xhr?.responseJSON?.error || xhr.statusText || 'Failed to load providers.';
|
|
171
|
-
$provider.
|
|
172
|
-
$provider.append('<option value="">Unable to load providers</option>');
|
|
173
|
-
$provider.prop('disabled', true);
|
|
174
|
-
setProviderStatus(msg);
|
|
195
|
+
showManualProvider(`Provider list failed (${msg}). Enter the provider ID manually or grant hub.variables.readonly.`);
|
|
175
196
|
});
|
|
176
197
|
};
|
|
177
198
|
|
|
@@ -179,10 +200,22 @@
|
|
|
179
200
|
syncVariablesField();
|
|
180
201
|
});
|
|
181
202
|
|
|
182
|
-
$
|
|
203
|
+
$providerSelect.on('change', () => {
|
|
204
|
+
const value = $providerSelect.val();
|
|
205
|
+
setProviderValue(value);
|
|
183
206
|
$variablesHidden.val('');
|
|
184
207
|
syncVariablesField();
|
|
185
|
-
loadVariables(
|
|
208
|
+
loadVariables(value, false);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
$providerManual.on('change keyup paste', () => {
|
|
212
|
+
const value = $providerManual.val();
|
|
213
|
+
setProviderValue(value);
|
|
214
|
+
$variablesHidden.val('');
|
|
215
|
+
syncVariablesField();
|
|
216
|
+
if (value) {
|
|
217
|
+
loadVariables(value, false);
|
|
218
|
+
}
|
|
186
219
|
});
|
|
187
220
|
|
|
188
221
|
$config.on('change', () => {
|
|
@@ -212,8 +245,12 @@
|
|
|
212
245
|
<input type="text" id="node-input-connection">
|
|
213
246
|
</div>
|
|
214
247
|
<div class="form-row">
|
|
215
|
-
<label
|
|
216
|
-
<
|
|
248
|
+
<label><i class="fa fa-id-badge"></i> Provider</label>
|
|
249
|
+
<div style="flex:1;">
|
|
250
|
+
<select id="datahub-provider-select" style="width:100%;"></select>
|
|
251
|
+
<input type="text" id="datahub-provider-manual" placeholder="provider id" style="width:100%; display:none;">
|
|
252
|
+
<input type="hidden" id="node-input-providerId">
|
|
253
|
+
</div>
|
|
217
254
|
</div>
|
|
218
255
|
<div class="form-row">
|
|
219
256
|
<label></label>
|
package/nodes/uos-config.html
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script type="text/javascript">
|
|
2
|
+
const FIXED_SCOPE = 'hub.variables.provide hub.variables.readwrite hub.variables.readonly';
|
|
2
3
|
RED.nodes.registerType('uos-config', {
|
|
3
4
|
category: 'config',
|
|
4
5
|
defaults: {
|
|
5
6
|
host: { value: '127.0.0.1', required: true },
|
|
6
7
|
port: { value: 49360, required: true, validate: RED.validators.number() },
|
|
7
8
|
clientName: { value: 'nodered', required: true },
|
|
8
|
-
scope: { value:
|
|
9
|
+
scope: { value: FIXED_SCOPE, required: true },
|
|
9
10
|
},
|
|
10
11
|
credentials: {
|
|
11
12
|
clientId: { type: 'text', required: true },
|
|
@@ -54,6 +55,9 @@
|
|
|
54
55
|
evt.preventDefault();
|
|
55
56
|
fetchScopes();
|
|
56
57
|
});
|
|
58
|
+
$('#node-config-input-scope').val(FIXED_SCOPE);
|
|
59
|
+
$('#uos-scope-fixed').text(FIXED_SCOPE);
|
|
60
|
+
|
|
57
61
|
if (node.credentials && node.credentials.clientId) {
|
|
58
62
|
fetchScopes();
|
|
59
63
|
}
|
|
@@ -82,9 +86,10 @@
|
|
|
82
86
|
<label for="node-config-input-clientSecret"><i class="fa fa-key"></i> Client Secret</label>
|
|
83
87
|
<input type="password" id="node-config-input-clientSecret">
|
|
84
88
|
</div>
|
|
89
|
+
<input type="hidden" id="node-config-input-scope">
|
|
85
90
|
<div class="form-row">
|
|
86
|
-
<label
|
|
87
|
-
<
|
|
91
|
+
<label><i class="fa fa-list"></i> Scope</label>
|
|
92
|
+
<span id="uos-scope-fixed" class="form-tips"></span>
|
|
88
93
|
</div>
|
|
89
94
|
<div class="form-row">
|
|
90
95
|
<label><i class="fa fa-info-circle"></i> Granted scopes</label>
|
|
@@ -102,7 +107,7 @@
|
|
|
102
107
|
<li><strong>Host / Port</strong> – IP and NATS port of the controller (default <code>127.0.0.1:49360</code>).</li>
|
|
103
108
|
<li><strong>Client Name</strong> – Friendly identifier used in NATS connection logs.</li>
|
|
104
109
|
<li><strong>Client ID / Secret</strong> – OAuth credentials from your u-OS Control Center client.</li>
|
|
105
|
-
<li><strong>Scope</strong> –
|
|
110
|
+
<li><strong>Scope</strong> – Fixed to <code>hub.variables.provide hub.variables.readwrite hub.variables.readonly</code> so the nodes can register providers and read metadata. It cannot be edited in the UI.</li>
|
|
106
111
|
<li><strong>Granted scopes</strong> – Click <em>Refresh</em> to show what the token endpoint actually returns for this client.</li>
|
|
107
112
|
</ul>
|
|
108
113
|
</script>
|
package/nodes/uos-config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fetch = require('node-fetch');
|
|
2
2
|
const { connect } = require('nats');
|
|
3
|
+
const DEFAULT_SCOPE = 'hub.variables.provide hub.variables.readwrite hub.variables.readonly';
|
|
3
4
|
|
|
4
5
|
if (!process.env.NODE_TLS_REJECT_UNAUTHORIZED) {
|
|
5
6
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
@@ -13,7 +14,7 @@ module.exports = function (RED) {
|
|
|
13
14
|
this.host = config.host || '127.0.0.1';
|
|
14
15
|
this.port = Number(config.port) || 49360;
|
|
15
16
|
this.clientName = config.clientName || 'nodered';
|
|
16
|
-
this.scope =
|
|
17
|
+
this.scope = DEFAULT_SCOPE;
|
|
17
18
|
this.clientId = this.credentials.clientId;
|
|
18
19
|
this.clientSecret = this.credentials.clientSecret;
|
|
19
20
|
this.tokenInfo = null;
|