iobroker.eos-admin 7.10.1 → 7.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL_TEST_V7.10.3.md +7 -0
- package/MERGE_UPDATE_README_V7.10.3.md +3 -0
- package/NEXOWATT_EOS_BUILD_INFO.json +16 -16
- package/NEXOWATT_EOS_PREBUILT_MANIFEST.json +1412 -0
- package/PUBLISH_STABLE_V7.10.3.md +10 -0
- package/README.md +4 -4
- package/README_STABILITY_V7.10.3.md +5 -0
- package/RELEASE_ACCEPTANCE_V7.10.3.md +3 -0
- package/RELEASE_NOTES_V7.10.3.md +7 -0
- package/adminWww/css/eos-auto-update.css +4 -3
- package/adminWww/index.html +2 -2
- package/adminWww/js/eos-auto-update.js +127 -33
- package/build/lib/eosAutoUpdate.js +418 -20
- package/build/lib/eosAutoUpdate.js.map +1 -0
- package/build/lib/eosRequestSecurity.js +4 -1
- package/build/lib/eosRequestSecurity.js.map +1 -0
- package/build/lib/web.js +40 -9
- package/build/lib/web.js.map +1 -1
- package/io-package.json +65 -5
- package/package.json +24 -16
- package/tools/nexowatt-auto-update-placement-selftest.cjs +46 -0
- package/tools/nexowatt-auto-update-selftest.cjs +144 -32
- package/tools/nexowatt-backend-runtime-selftest.cjs +147 -0
- package/tools/nexowatt-merge-update-selftest.cjs +7 -1
- package/tools/nexowatt-prebuilt-release-selftest.cjs +292 -0
- package/tools/nexowatt-stable-v7103-selftest.cjs +61 -0
- package/tools/nexowatt-validate-package.cjs +45 -12
- package/INSTALL_TEST_V7.10.1.md +0 -10
- package/MERGE_UPDATE_README_V7.10.1.md +0 -10
- package/PUBLISH_STABLE_V7.10.1.md +0 -10
- package/README_STABILITY_V7.10.1.md +0 -10
- package/RELEASE_ACCEPTANCE_V7.10.1.md +0 -10
- package/RELEASE_NOTES_V7.10.1.md +0 -10
- package/adminWww/js/eos-release-watch.js +0 -77
- package/build/lib/eosPassword.js +0 -72
- package/build/lib/nexowattStableAuth.js +0 -74
- package/tools/nexowatt-stable-v7101-selftest.cjs +0 -15
|
@@ -1,43 +1,441 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* NexoWatt stable adapter auto-update policy manager.
|
|
4
|
+
*
|
|
5
|
+
* This class does not install packages itself. It configures ioBroker's native
|
|
6
|
+
* adapterAutoUpgrade manager so only installed NexoWatt adapters present in the
|
|
7
|
+
* detected Stable repository receive the `major` policy. All other adapters and
|
|
8
|
+
* existing user policies are preserved.
|
|
9
|
+
*
|
|
10
|
+
* Runtime status is deliberately stored in adapter states, never in the native
|
|
11
|
+
* configuration of the running eos-admin instance. Changing an instance native
|
|
12
|
+
* object causes ioBroker to restart that instance. Version 7.10.1 persisted a
|
|
13
|
+
* fresh timestamp there during every startup and therefore created an endless
|
|
14
|
+
* restart loop while the browser was still loading its JavaScript and CSS.
|
|
15
|
+
*/
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
17
|
exports.NexoWattStableUpdateManager = void 0;
|
|
4
18
|
exports.isNexoWattRepositoryEntry = isNexoWattRepositoryEntry;
|
|
5
19
|
const ADMIN_USER = 'system.user.admin';
|
|
6
20
|
const POLICY = 'major';
|
|
7
21
|
const RECONCILE_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
|
22
|
+
const STARTUP_RECONCILE_DELAY_MS = 30_000;
|
|
8
23
|
const REPOSITORY_REFRESH_DELAY_MS = 2500;
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
24
|
+
const ENABLED_STATE_ID = 'info.nexowattStableUpdatesEnabled';
|
|
25
|
+
const STATUS_STATE_ID = 'info.nexowattStableUpdatesState';
|
|
26
|
+
const clone = (value) => JSON.parse(JSON.stringify(value));
|
|
27
|
+
const normalizedName = (value) => String(value || '').trim().replace(/^system\.adapter\./, '').replace(/\.\d+$/, '');
|
|
28
|
+
const stableVersion = (value) => /^\d+\.\d+\.\d+$/.test(String(value || '').trim());
|
|
12
29
|
function isNexoWattRepositoryEntry(name, entry) {
|
|
13
30
|
const adapterName = normalizedName(entry?.name || name).toLowerCase();
|
|
14
31
|
if (adapterName === 'eos-admin' || adapterName.startsWith('nexowatt-') || adapterName.startsWith('eos-'))
|
|
15
32
|
return true;
|
|
16
|
-
const evidence = JSON.stringify({
|
|
33
|
+
const evidence = JSON.stringify({
|
|
34
|
+
name,
|
|
35
|
+
adapterName,
|
|
36
|
+
title: entry?.title,
|
|
37
|
+
desc: entry?.desc,
|
|
38
|
+
author: entry?.author,
|
|
39
|
+
authors: entry?.authors,
|
|
40
|
+
publisher: entry?.publisher,
|
|
41
|
+
url: entry?.url,
|
|
42
|
+
meta: entry?.meta,
|
|
43
|
+
readme: entry?.readme,
|
|
44
|
+
extIcon: entry?.extIcon,
|
|
45
|
+
licenseInformation: entry?.licenseInformation,
|
|
46
|
+
}).toLowerCase();
|
|
17
47
|
return evidence.includes('nexowatt') || evidence.includes('github.com/nexowatt/');
|
|
18
48
|
}
|
|
19
49
|
class NexoWattStableUpdateManager {
|
|
20
50
|
adapter;
|
|
21
51
|
timer;
|
|
52
|
+
startupTimer;
|
|
22
53
|
reconcilePromise;
|
|
23
54
|
refreshTimer;
|
|
24
55
|
retryTimer;
|
|
25
|
-
|
|
56
|
+
stopped = false;
|
|
57
|
+
cachedEnabled;
|
|
58
|
+
cachedState = {};
|
|
59
|
+
constructor(adapter) {
|
|
60
|
+
this.adapter = adapter;
|
|
61
|
+
}
|
|
26
62
|
get instanceId() { return `system.adapter.${this.adapter.namespace}`; }
|
|
27
|
-
async start() {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
63
|
+
async start() {
|
|
64
|
+
this.stopped = false;
|
|
65
|
+
const status = await this.getStatus(false);
|
|
66
|
+
this.scheduleStartupReconcile();
|
|
67
|
+
this.ensurePeriodicTimer();
|
|
68
|
+
return status;
|
|
69
|
+
}
|
|
70
|
+
stop() {
|
|
71
|
+
this.stopped = true;
|
|
72
|
+
if (this.timer)
|
|
73
|
+
clearInterval(this.timer);
|
|
74
|
+
if (this.startupTimer)
|
|
75
|
+
clearTimeout(this.startupTimer);
|
|
76
|
+
if (this.refreshTimer)
|
|
77
|
+
clearTimeout(this.refreshTimer);
|
|
78
|
+
if (this.retryTimer)
|
|
79
|
+
clearTimeout(this.retryTimer);
|
|
80
|
+
this.timer = undefined;
|
|
81
|
+
this.startupTimer = undefined;
|
|
82
|
+
this.refreshTimer = undefined;
|
|
83
|
+
this.retryTimer = undefined;
|
|
84
|
+
}
|
|
85
|
+
async getStatus(refresh = false) {
|
|
86
|
+
if (refresh)
|
|
87
|
+
return this.reconcile('status');
|
|
88
|
+
const persisted = await this.readPersisted();
|
|
89
|
+
return this.statusFromPersisted(persisted.enabled, persisted.state);
|
|
90
|
+
}
|
|
91
|
+
async setEnabled(enabled) {
|
|
92
|
+
this.stopped = false;
|
|
93
|
+
if (this.startupTimer) {
|
|
94
|
+
clearTimeout(this.startupTimer);
|
|
95
|
+
this.startupTimer = undefined;
|
|
96
|
+
}
|
|
97
|
+
const persisted = await this.readPersisted();
|
|
98
|
+
await this.persist(enabled, persisted.state);
|
|
99
|
+
const status = await this.reconcile(enabled ? 'enabled' : 'disabled');
|
|
100
|
+
this.ensurePeriodicTimer();
|
|
101
|
+
return status;
|
|
102
|
+
}
|
|
103
|
+
async reconcile(reason = 'manual') {
|
|
104
|
+
if (this.reconcilePromise)
|
|
105
|
+
return this.reconcilePromise;
|
|
106
|
+
this.reconcilePromise = this.reconcileInternal(reason).finally(() => { this.reconcilePromise = undefined; });
|
|
107
|
+
return this.reconcilePromise;
|
|
108
|
+
}
|
|
109
|
+
scheduleStartupReconcile() {
|
|
110
|
+
if (this.startupTimer || this.stopped)
|
|
111
|
+
return;
|
|
112
|
+
this.startupTimer = setTimeout(() => {
|
|
113
|
+
this.startupTimer = undefined;
|
|
114
|
+
if (!this.stopped) {
|
|
115
|
+
void this.reconcile('startup').catch(error => this.adapter.log.warn(`[NexoWatt stable updates] Startup reconciliation failed: ${error instanceof Error ? error.message : error}`));
|
|
116
|
+
}
|
|
117
|
+
}, STARTUP_RECONCILE_DELAY_MS);
|
|
118
|
+
this.startupTimer.unref?.();
|
|
119
|
+
}
|
|
120
|
+
ensurePeriodicTimer() {
|
|
121
|
+
if (this.timer || this.stopped)
|
|
122
|
+
return;
|
|
123
|
+
this.timer = setInterval(() => {
|
|
124
|
+
if (!this.stopped)
|
|
125
|
+
void this.reconcile('interval');
|
|
126
|
+
}, RECONCILE_INTERVAL_MS);
|
|
127
|
+
this.timer.unref?.();
|
|
128
|
+
}
|
|
129
|
+
parseState(value) {
|
|
130
|
+
if (value && typeof value === 'object' && !Array.isArray(value))
|
|
131
|
+
return clone(value);
|
|
132
|
+
if (typeof value !== 'string' || !value.trim())
|
|
133
|
+
return null;
|
|
134
|
+
try {
|
|
135
|
+
const parsed = JSON.parse(value);
|
|
136
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async readPersisted() {
|
|
143
|
+
// Legacy 7.10.1 values are read once as a migration fallback. They are
|
|
144
|
+
// never written back to the instance native object.
|
|
145
|
+
let legacyNative = {};
|
|
146
|
+
try {
|
|
147
|
+
const instance = await this.adapter.getForeignObjectAsync(this.instanceId);
|
|
148
|
+
legacyNative = instance?.native || {};
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
this.adapter.log.debug(`[NexoWatt stable updates] Cannot read legacy native state: ${error instanceof Error ? error.message : error}`);
|
|
152
|
+
}
|
|
153
|
+
let enabled = this.cachedEnabled ?? (legacyNative.eosNexoWattAutoUpdate !== false);
|
|
154
|
+
let state = Object.keys(this.cachedState).length
|
|
155
|
+
? clone(this.cachedState)
|
|
156
|
+
: clone((legacyNative.eosNexoWattAutoUpdateState || {}));
|
|
157
|
+
try {
|
|
158
|
+
const enabledState = await this.adapter.getStateAsync(ENABLED_STATE_ID);
|
|
159
|
+
if (typeof enabledState?.val === 'boolean')
|
|
160
|
+
enabled = enabledState.val;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
this.adapter.log.debug(`[NexoWatt stable updates] Cannot read enabled state: ${error instanceof Error ? error.message : error}`);
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const persistedState = await this.adapter.getStateAsync(STATUS_STATE_ID);
|
|
167
|
+
const parsed = this.parseState(persistedState?.val);
|
|
168
|
+
if (parsed)
|
|
169
|
+
state = parsed;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
this.adapter.log.debug(`[NexoWatt stable updates] Cannot read status state: ${error instanceof Error ? error.message : error}`);
|
|
173
|
+
}
|
|
174
|
+
this.cachedEnabled = enabled;
|
|
175
|
+
this.cachedState = clone(state);
|
|
176
|
+
return { enabled, state };
|
|
177
|
+
}
|
|
178
|
+
statusFromPersisted(enabled, state) {
|
|
179
|
+
return {
|
|
180
|
+
enabled,
|
|
181
|
+
repository: String(state.selectedRepository || ''),
|
|
182
|
+
managedAdapters: Array.isArray(state.managedAdapters) ? state.managedAdapters.map(String).sort() : [],
|
|
183
|
+
availableStableAdapters: Array.isArray(state.availableStableAdapters) ? state.availableStableAdapters.map(String).sort() : [],
|
|
184
|
+
lastSync: Number(state.lastSync || 0),
|
|
185
|
+
lastRepositoryRefresh: Number(state.lastRepositoryRefresh || 0),
|
|
186
|
+
error: String(state.error || ''),
|
|
187
|
+
policy: POLICY,
|
|
188
|
+
source: 'ioBroker-native-auto-upgrade',
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
async reconcileInternal(reason) {
|
|
192
|
+
const persisted = await this.readPersisted();
|
|
193
|
+
const { enabled } = persisted;
|
|
194
|
+
const state = clone(persisted.state);
|
|
195
|
+
if (this.stopped)
|
|
196
|
+
return this.statusFromPersisted(enabled, state);
|
|
197
|
+
try {
|
|
198
|
+
if (!enabled)
|
|
199
|
+
return await this.disable(state, reason);
|
|
200
|
+
return await this.enable(state, reason);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const message = error instanceof Error ? error.message : String(error || 'unknownError');
|
|
204
|
+
state.error = message;
|
|
205
|
+
state.lastSync = Date.now();
|
|
206
|
+
if (!this.stopped)
|
|
207
|
+
await this.persist(enabled, state);
|
|
208
|
+
if (enabled && !this.stopped)
|
|
209
|
+
this.scheduleRetry();
|
|
210
|
+
if (!this.stopped)
|
|
211
|
+
this.adapter.log.warn(`[NexoWatt stable updates] ${message}`);
|
|
212
|
+
return this.statusFromPersisted(enabled, state);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async readInstalledAdapters() {
|
|
216
|
+
const view = await this.adapter.getObjectViewAsync('system', 'adapter', {
|
|
217
|
+
startkey: 'system.adapter.',
|
|
218
|
+
endkey: 'system.adapter.\u9999',
|
|
219
|
+
}, { user: ADMIN_USER });
|
|
220
|
+
const result = new Map();
|
|
221
|
+
for (const row of view?.rows || []) {
|
|
222
|
+
const object = row?.value || row?.doc;
|
|
223
|
+
const name = normalizedName(object?.common?.name || row?.id || object?._id);
|
|
224
|
+
if (name && object?.common?.version)
|
|
225
|
+
result.set(name, object);
|
|
226
|
+
}
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
229
|
+
async readRepositorySelection(systemConfig) {
|
|
230
|
+
const repositories = await this.adapter.getForeignObjectAsync('system.repositories');
|
|
231
|
+
const rows = repositories?.native?.repositories || {};
|
|
232
|
+
const active = Array.isArray(systemConfig?.common?.activeRepo) ? systemConfig.common.activeRepo.map(String) : [];
|
|
233
|
+
const candidates = Object.entries(rows).map(([name, repo]) => {
|
|
234
|
+
const entries = repo?.json && typeof repo.json === 'object' ? repo.json : {};
|
|
235
|
+
const stableNames = Object.entries(entries)
|
|
236
|
+
.filter(([entryName, entry]) => stableVersion(entry?.version) && isNexoWattRepositoryEntry(entryName, entry))
|
|
237
|
+
.map(([entryName, entry]) => normalizedName(entry?.name || entryName))
|
|
238
|
+
.filter(Boolean);
|
|
239
|
+
return { name, entries, stableNames: [...new Set(stableNames)].sort(), activeIndex: active.indexOf(name) };
|
|
240
|
+
}).filter(row => row.stableNames.length > 0);
|
|
241
|
+
if (!candidates.length)
|
|
242
|
+
throw new Error('nexowattStableRepositoryNotFound');
|
|
243
|
+
candidates.sort((a, b) => {
|
|
244
|
+
const aa = a.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : a.activeIndex;
|
|
245
|
+
const bb = b.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : b.activeIndex;
|
|
246
|
+
return aa - bb || b.stableNames.length - a.stableNames.length || a.name.localeCompare(b.name);
|
|
247
|
+
});
|
|
248
|
+
return candidates[0];
|
|
249
|
+
}
|
|
250
|
+
async enable(state, reason) {
|
|
251
|
+
const systemConfig = await this.adapter.getForeignObjectAsync('system.config');
|
|
252
|
+
if (!systemConfig?.common)
|
|
253
|
+
throw new Error('systemConfigUnavailable');
|
|
254
|
+
const selected = await this.readRepositorySelection(systemConfig);
|
|
255
|
+
const installed = await this.readInstalledAdapters();
|
|
256
|
+
const managedNames = selected.stableNames.filter(name => installed.has(name)).sort();
|
|
257
|
+
if (!managedNames.length)
|
|
258
|
+
throw new Error('noInstalledNexoWattStableAdapters');
|
|
259
|
+
if (this.stopped)
|
|
260
|
+
return this.statusFromPersisted(true, state);
|
|
261
|
+
state.previousPolicies ||= {};
|
|
262
|
+
for (const name of managedNames) {
|
|
263
|
+
if (this.stopped)
|
|
264
|
+
return this.statusFromPersisted(true, state);
|
|
265
|
+
if (!(name in state.previousPolicies)) {
|
|
266
|
+
const current = installed.get(name)?.common?.automaticUpgrade;
|
|
267
|
+
state.previousPolicies[name] = current == null ? null : current;
|
|
268
|
+
}
|
|
269
|
+
await this.writeAdapterPolicy(name, POLICY);
|
|
270
|
+
}
|
|
271
|
+
const common = systemConfig.common;
|
|
272
|
+
const activeRepo = Array.isArray(common.activeRepo) ? [...common.activeRepo] : [];
|
|
273
|
+
const auto = common.adapterAutoUpgrade && typeof common.adapterAutoUpgrade === 'object'
|
|
274
|
+
? clone(common.adapterAutoUpgrade)
|
|
275
|
+
: { repositories: {}, defaultPolicy: 'none' };
|
|
276
|
+
auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {};
|
|
277
|
+
let systemConfigChanged = false;
|
|
278
|
+
if (state.previousRepositoryEnabled === undefined) {
|
|
279
|
+
state.previousRepositoryEnabled = Object.prototype.hasOwnProperty.call(auto.repositories, selected.name)
|
|
280
|
+
? Boolean(auto.repositories[selected.name])
|
|
281
|
+
: null;
|
|
282
|
+
}
|
|
283
|
+
if (auto.repositories[selected.name] !== true) {
|
|
284
|
+
auto.repositories[selected.name] = true;
|
|
285
|
+
systemConfigChanged = true;
|
|
286
|
+
}
|
|
287
|
+
if (!auto.defaultPolicy) {
|
|
288
|
+
auto.defaultPolicy = 'none';
|
|
289
|
+
systemConfigChanged = true;
|
|
290
|
+
}
|
|
291
|
+
if (JSON.stringify(common.adapterAutoUpgrade) !== JSON.stringify(auto)) {
|
|
292
|
+
common.adapterAutoUpgrade = auto;
|
|
293
|
+
systemConfigChanged = true;
|
|
294
|
+
}
|
|
295
|
+
if (activeRepo[0] !== selected.name) {
|
|
296
|
+
if (!state.previousActiveRepo)
|
|
297
|
+
state.previousActiveRepo = [...activeRepo];
|
|
298
|
+
state.ownsActiveRepoOrder = true;
|
|
299
|
+
common.activeRepo = [selected.name, ...activeRepo.filter((name) => name !== selected.name)];
|
|
300
|
+
systemConfigChanged = true;
|
|
301
|
+
}
|
|
302
|
+
if (systemConfigChanged && !this.stopped) {
|
|
303
|
+
await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER });
|
|
304
|
+
}
|
|
305
|
+
state.selectedRepository = selected.name;
|
|
306
|
+
state.availableStableAdapters = selected.stableNames;
|
|
307
|
+
state.managedAdapters = managedNames;
|
|
308
|
+
state.lastSync = Date.now();
|
|
309
|
+
state.error = '';
|
|
310
|
+
if (!this.stopped)
|
|
311
|
+
await this.persist(true, state);
|
|
312
|
+
if (!this.stopped)
|
|
313
|
+
this.scheduleRepositoryRefresh(selected.name, state);
|
|
314
|
+
if (!this.stopped)
|
|
315
|
+
this.adapter.log.info(`[NexoWatt stable updates] Enabled for ${managedNames.join(', ')} from repository "${selected.name}" (${reason})`);
|
|
316
|
+
return this.statusFromPersisted(true, state);
|
|
317
|
+
}
|
|
318
|
+
async disable(state, reason) {
|
|
319
|
+
for (const [name, previous] of Object.entries(state.previousPolicies || {})) {
|
|
320
|
+
if (this.stopped)
|
|
321
|
+
return this.statusFromPersisted(false, state);
|
|
322
|
+
const current = await this.adapter.getForeignObjectAsync(`system.adapter.${normalizedName(name)}`);
|
|
323
|
+
if (current?.common?.automaticUpgrade === POLICY)
|
|
324
|
+
await this.writeAdapterPolicy(name, previous);
|
|
325
|
+
}
|
|
326
|
+
const systemConfig = await this.adapter.getForeignObjectAsync('system.config');
|
|
327
|
+
if (systemConfig?.common) {
|
|
328
|
+
let systemConfigChanged = false;
|
|
329
|
+
const auto = systemConfig.common.adapterAutoUpgrade && typeof systemConfig.common.adapterAutoUpgrade === 'object'
|
|
330
|
+
? clone(systemConfig.common.adapterAutoUpgrade)
|
|
331
|
+
: null;
|
|
332
|
+
if (auto && state.selectedRepository) {
|
|
333
|
+
auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {};
|
|
334
|
+
if (auto.repositories[state.selectedRepository] === true) {
|
|
335
|
+
if (state.previousRepositoryEnabled === null || state.previousRepositoryEnabled === undefined) {
|
|
336
|
+
delete auto.repositories[state.selectedRepository];
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
auto.repositories[state.selectedRepository] = state.previousRepositoryEnabled;
|
|
340
|
+
}
|
|
341
|
+
systemConfigChanged = true;
|
|
342
|
+
}
|
|
343
|
+
if (JSON.stringify(systemConfig.common.adapterAutoUpgrade) !== JSON.stringify(auto)) {
|
|
344
|
+
systemConfig.common.adapterAutoUpgrade = auto;
|
|
345
|
+
systemConfigChanged = true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
if (state.ownsActiveRepoOrder && Array.isArray(state.previousActiveRepo)
|
|
349
|
+
&& Array.isArray(systemConfig.common.activeRepo)
|
|
350
|
+
&& systemConfig.common.activeRepo[0] === state.selectedRepository) {
|
|
351
|
+
systemConfig.common.activeRepo = [...state.previousActiveRepo];
|
|
352
|
+
systemConfigChanged = true;
|
|
353
|
+
}
|
|
354
|
+
if (systemConfigChanged && !this.stopped) {
|
|
355
|
+
await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
state.previousPolicies = {};
|
|
359
|
+
state.previousRepositoryEnabled = undefined;
|
|
360
|
+
state.previousActiveRepo = undefined;
|
|
361
|
+
state.ownsActiveRepoOrder = false;
|
|
362
|
+
state.managedAdapters = [];
|
|
363
|
+
state.lastSync = Date.now();
|
|
364
|
+
state.error = '';
|
|
365
|
+
if (!this.stopped)
|
|
366
|
+
await this.persist(false, state);
|
|
367
|
+
if (!this.stopped)
|
|
368
|
+
this.adapter.log.info(`[NexoWatt stable updates] Disabled and previous policies restored (${reason})`);
|
|
369
|
+
return this.statusFromPersisted(false, state);
|
|
370
|
+
}
|
|
371
|
+
async writeAdapterPolicy(name, policy) {
|
|
372
|
+
const id = `system.adapter.${normalizedName(name)}`;
|
|
373
|
+
const object = await this.adapter.getForeignObjectAsync(id);
|
|
374
|
+
if (!object?.common || this.stopped)
|
|
375
|
+
return;
|
|
376
|
+
const current = object.common.automaticUpgrade;
|
|
377
|
+
if ((policy === null && current === undefined) || current === policy)
|
|
378
|
+
return;
|
|
379
|
+
if (policy === null)
|
|
380
|
+
delete object.common.automaticUpgrade;
|
|
381
|
+
else
|
|
382
|
+
object.common.automaticUpgrade = policy;
|
|
383
|
+
await this.adapter.setForeignObjectAsync(id, object, { user: ADMIN_USER });
|
|
384
|
+
}
|
|
385
|
+
async persist(enabled, state) {
|
|
386
|
+
if (this.stopped)
|
|
387
|
+
return;
|
|
388
|
+
this.cachedEnabled = enabled;
|
|
389
|
+
this.cachedState = clone(state);
|
|
390
|
+
const currentEnabled = await this.adapter.getStateAsync(ENABLED_STATE_ID).catch(() => null);
|
|
391
|
+
if (currentEnabled?.val !== enabled) {
|
|
392
|
+
await this.adapter.setStateAsync(ENABLED_STATE_ID, enabled, true);
|
|
393
|
+
}
|
|
394
|
+
const serialized = JSON.stringify(state);
|
|
395
|
+
const currentState = await this.adapter.getStateAsync(STATUS_STATE_ID).catch(() => null);
|
|
396
|
+
const currentSerialized = typeof currentState?.val === 'string'
|
|
397
|
+
? currentState.val
|
|
398
|
+
: currentState?.val == null ? '' : JSON.stringify(currentState.val);
|
|
399
|
+
if (currentSerialized !== serialized) {
|
|
400
|
+
await this.adapter.setStateAsync(STATUS_STATE_ID, serialized, true);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
scheduleRetry() {
|
|
404
|
+
if (this.retryTimer)
|
|
405
|
+
clearTimeout(this.retryTimer);
|
|
406
|
+
this.retryTimer = setTimeout(() => {
|
|
407
|
+
this.retryTimer = undefined;
|
|
408
|
+
if (!this.stopped)
|
|
409
|
+
void this.reconcile('retry');
|
|
410
|
+
}, 60_000);
|
|
411
|
+
this.retryTimer.unref?.();
|
|
412
|
+
}
|
|
413
|
+
scheduleRepositoryRefresh(repository, state) {
|
|
414
|
+
if (!this.adapter.sendToHostAsync || !this.adapter.host || this.stopped)
|
|
415
|
+
return;
|
|
416
|
+
if (this.refreshTimer)
|
|
417
|
+
clearTimeout(this.refreshTimer);
|
|
418
|
+
this.refreshTimer = setTimeout(() => {
|
|
419
|
+
this.refreshTimer = undefined;
|
|
420
|
+
if (this.stopped)
|
|
421
|
+
return;
|
|
422
|
+
void this.adapter.sendToHostAsync?.(this.adapter.host, 'getRepository', { repo: repository, update: true })
|
|
423
|
+
.then(async () => {
|
|
424
|
+
if (this.stopped)
|
|
425
|
+
return;
|
|
426
|
+
const current = await this.readPersisted();
|
|
427
|
+
if (!current.enabled)
|
|
428
|
+
return;
|
|
429
|
+
const nextState = { ...current.state, ...state, lastRepositoryRefresh: Date.now() };
|
|
430
|
+
await this.persist(true, nextState);
|
|
431
|
+
})
|
|
432
|
+
.catch(error => {
|
|
433
|
+
if (!this.stopped)
|
|
434
|
+
this.adapter.log.warn(`[NexoWatt stable updates] Repository refresh failed: ${error instanceof Error ? error.message : error}`);
|
|
435
|
+
});
|
|
436
|
+
}, REPOSITORY_REFRESH_DELAY_MS);
|
|
437
|
+
this.refreshTimer.unref?.();
|
|
438
|
+
}
|
|
42
439
|
}
|
|
43
440
|
exports.NexoWattStableUpdateManager = NexoWattStableUpdateManager;
|
|
441
|
+
//# sourceMappingURL=eosAutoUpdate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eosAutoUpdate.js","sourceRoot":"./src/","sources":["eosAutoUpdate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isEosSameOriginRequest = isEosSameOriginRequest;
|
|
4
|
+
/** Testable same-origin guard for EOS JSON write routes. */
|
|
4
5
|
function isEosSameOriginRequest(headers) {
|
|
5
6
|
const origin = String(headers.origin || '').trim();
|
|
6
7
|
if (!origin) {
|
|
8
|
+
// Older embedded browsers can omit Origin for same-site POST requests.
|
|
7
9
|
return true;
|
|
8
10
|
}
|
|
9
11
|
try {
|
|
@@ -12,7 +14,7 @@ function isEosSameOriginRequest(headers) {
|
|
|
12
14
|
return false;
|
|
13
15
|
}
|
|
14
16
|
const allowedHosts = new Set();
|
|
15
|
-
const addHost = value => {
|
|
17
|
+
const addHost = (value) => {
|
|
16
18
|
const host = String(value || '').split(',')[0].trim().toLowerCase();
|
|
17
19
|
if (host)
|
|
18
20
|
allowedHosts.add(host);
|
|
@@ -29,3 +31,4 @@ function isEosSameOriginRequest(headers) {
|
|
|
29
31
|
return false;
|
|
30
32
|
}
|
|
31
33
|
}
|
|
34
|
+
//# sourceMappingURL=eosRequestSecurity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eosRequestSecurity.js","sourceRoot":"./src/","sources":["eosRequestSecurity.ts"],"names":[],"mappings":";;AACA,wDA0BC;AA3BD,4DAA4D;AAC5D,SAAgB,sBAAsB,CAAC,OAAgC;IACnE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,uEAAuE;QACvE,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC9D,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,KAAc,EAAQ,EAAE;YACrC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACpE,IAAI,IAAI;gBAAE,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC,CAAC;QACF,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtB,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACrE,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC/E,OAAO,CAAC,SAAS,IAAI,SAAS,KAAK,aAAa,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,MAAM,CAAC;IAC1G,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC"}
|
package/build/lib/web.js
CHANGED
|
@@ -195,6 +195,7 @@ class Web {
|
|
|
195
195
|
this.checkTimeout = null;
|
|
196
196
|
}
|
|
197
197
|
this.mcpServer?.unload();
|
|
198
|
+
this.nexowattStableUpdateManager?.stop();
|
|
198
199
|
void this.adapter.setState('info.connection', false, true);
|
|
199
200
|
this.server.server?.close();
|
|
200
201
|
}
|
|
@@ -724,7 +725,9 @@ class Web {
|
|
|
724
725
|
return userName;
|
|
725
726
|
}
|
|
726
727
|
async setEosUserPassword(userId, password) {
|
|
727
|
-
// ioBroker's password API expects the account name
|
|
728
|
+
// ioBroker's password API expects the account name (for example "user"), not the
|
|
729
|
+
// object id ("system.user.user"). Supplying the object id can return without changing
|
|
730
|
+
// the password on some controller versions. Always normalize to the real account name.
|
|
728
731
|
const userName = this.getEosPasswordUserName(userId);
|
|
729
732
|
// The server-side Admin/Service context performs the controller password write, so managed
|
|
730
733
|
// Installer and End User accounts do not need global users.write rights in the browser.
|
|
@@ -740,6 +743,8 @@ class Web {
|
|
|
740
743
|
else {
|
|
741
744
|
throw new Error('passwordApiUnavailable');
|
|
742
745
|
}
|
|
746
|
+
// Verify the write with the controller API whenever it is exposed. This prevents the
|
|
747
|
+
// UI from reporting success while the object database still contains the old hash.
|
|
743
748
|
if (typeof this.adapter.checkPasswordAsync === 'function') {
|
|
744
749
|
const result = await this.adapter.checkPasswordAsync(userName, password, options);
|
|
745
750
|
const valid = Array.isArray(result) ? result[0] === true : result === true;
|
|
@@ -748,6 +753,7 @@ class Web {
|
|
|
748
753
|
}
|
|
749
754
|
return;
|
|
750
755
|
}
|
|
756
|
+
// Compatibility fallback for older controllers: require a non-empty stored password hash.
|
|
751
757
|
const userObject = (await this.adapter.getForeignObjectAsync(userId));
|
|
752
758
|
if (!String(userObject?.common?.password || '').trim()) {
|
|
753
759
|
throw new Error('passwordWriteFailed');
|
|
@@ -762,6 +768,8 @@ class Web {
|
|
|
762
768
|
const account = { ...(native.nexowattEosAccount || {}) };
|
|
763
769
|
native.nexowattEosAccount = account;
|
|
764
770
|
updater(native, account);
|
|
771
|
+
// Extend only the EOS metadata. Replacing the complete user object here could overwrite the
|
|
772
|
+
// password hash which was just written by setPasswordAsync/changePassword.
|
|
765
773
|
await this.adapter.extendForeignObjectAsync(userId, { native }, { user: EOS_PASSWORD_SERVICE_USER });
|
|
766
774
|
}
|
|
767
775
|
async destroyEosRequestSessions(req) {
|
|
@@ -1270,12 +1278,37 @@ class Web {
|
|
|
1270
1278
|
],
|
|
1271
1279
|
});
|
|
1272
1280
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1281
|
+
getNexoWattStableUpdateManager() {
|
|
1282
|
+
this.nexowattStableUpdateManager ||= new eosAutoUpdate_1.NexoWattStableUpdateManager(this.adapter);
|
|
1283
|
+
return this.nexowattStableUpdateManager;
|
|
1284
|
+
}
|
|
1285
|
+
async sendNexoWattStableUpdateStatus(req, res) {
|
|
1286
|
+
const access = await this.getEosRequestAccess(req);
|
|
1287
|
+
if (access.role !== 'admin') {
|
|
1288
|
+
res.status(403).json({ error: 'permissionError' });
|
|
1289
|
+
return;
|
|
1290
|
+
}
|
|
1291
|
+
res.status(200).json(await this.getNexoWattStableUpdateManager().getStatus(false));
|
|
1292
|
+
}
|
|
1293
|
+
async saveNexoWattStableUpdateSettings(req, res) {
|
|
1294
|
+
const access = await this.getEosRequestAccess(req);
|
|
1295
|
+
if (access.role !== 'admin') {
|
|
1296
|
+
res.status(403).json({ error: 'permissionError' });
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
if (req.headers['x-nexowatt-eos-auto-update'] !== '1' || !this.isEosSameOriginWrite(req)) {
|
|
1300
|
+
res.status(403).json({ error: 'invalidRequest' });
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
if (typeof req.body?.enabled !== 'boolean') {
|
|
1304
|
+
res.status(400).json({ error: 'invalidEnabledValue' });
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
res.status(200).json(await this.getNexoWattStableUpdateManager().setEnabled(req.body.enabled));
|
|
1308
|
+
}
|
|
1309
|
+
isEosSameOriginWrite(req) {
|
|
1310
|
+
return (0, eosRequestSecurity_1.isEosSameOriginRequest)(req.headers);
|
|
1311
|
+
}
|
|
1279
1312
|
async saveEosBasicSettings(req, res) {
|
|
1280
1313
|
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
|
1281
1314
|
const access = await this.getEosRequestAccess(req);
|
|
@@ -1505,11 +1538,9 @@ class Web {
|
|
|
1505
1538
|
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
|
|
1506
1539
|
next();
|
|
1507
1540
|
});*/
|
|
1508
|
-
|
|
1509
1541
|
void this.getNexoWattStableUpdateManager().start().catch(error => this.adapter.log.warn(`[NexoWatt stable updates] Startup reconciliation failed: ${error instanceof Error ? error.message : error}`));
|
|
1510
1542
|
this.server.app.get('/nexowatt/updates/status', (req, res) => { void this.sendNexoWattStableUpdateStatus(req, res).catch(error => res.status(500).json({ error: String(error) })); });
|
|
1511
1543
|
this.server.app.post('/nexowatt/updates/settings', (req, res) => { void this.saveNexoWattStableUpdateSettings(req, res).catch(error => res.status(500).json({ error: String(error) })); });
|
|
1512
|
-
|
|
1513
1544
|
this.server.app.get('/version', (_req, res) => {
|
|
1514
1545
|
res.status(200).send(this.adapter.version);
|
|
1515
1546
|
});
|