iobroker.eos-admin 7.10.0 → 7.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/INSTALL_TEST_V7.10.2.md +22 -0
  2. package/MERGE_UPDATE_README_V7.10.2.md +11 -0
  3. package/NEXOWATT_EOS_BUILD_INFO.json +19 -21
  4. package/NEXOWATT_EOS_PREBUILT_MANIFEST.json +1410 -0
  5. package/PUBLISH_STABLE_V7.10.2.md +21 -0
  6. package/README.md +16 -6
  7. package/README_STABILITY_V7.10.2.md +20 -0
  8. package/RELEASE_ACCEPTANCE_V7.10.2.md +13 -0
  9. package/RELEASE_NOTES_V7.10.2.md +11 -0
  10. package/adminWww/assets/Intro-DkwRiz1n-v84.js +1 -1
  11. package/adminWww/assets/bootstrap-COulQZax-v84.js +2 -2
  12. package/adminWww/css/eos-ems-overview.css +5 -3
  13. package/adminWww/css/nexowatt-native-shell.css +85 -413
  14. package/adminWww/index.html +20 -21
  15. package/adminWww/js/eos-account-management.js +28 -19
  16. package/adminWww/js/eos-assistant.js +1 -1
  17. package/adminWww/js/eos-ems-overview.js +1 -1
  18. package/adminWww/js/eos-role-bootstrap.js +17 -80
  19. package/adminWww/js/eos-role-ui.js +28 -4
  20. package/adminWww/js/nexowatt-native-shell.js +1 -1
  21. package/adminWww/static/js/nexowatt-stable-login.js +43 -70
  22. package/adminWww/static/js/nexowatt-stable-v7101.js +27 -0
  23. package/build/lib/eosAutoUpdate.js +418 -20
  24. package/build/lib/eosAutoUpdate.js.map +1 -0
  25. package/build/lib/eosRequestSecurity.js +4 -1
  26. package/build/lib/eosRequestSecurity.js.map +1 -0
  27. package/build/lib/web.js +161 -254
  28. package/build/lib/web.js.map +1 -1
  29. package/build/main.js +39 -67
  30. package/io-package.json +72 -7
  31. package/package.json +24 -25
  32. package/tools/nexowatt-account-management-selftest.cjs +15 -19
  33. package/tools/nexowatt-account-password-flow-selftest.cjs +15 -0
  34. package/tools/nexowatt-apply-ems-overview.cjs +4 -2
  35. package/tools/nexowatt-auto-update-selftest.cjs +144 -32
  36. package/tools/nexowatt-backend-runtime-selftest.cjs +147 -0
  37. package/tools/nexowatt-clean-legacy-runtime.cjs +1 -1
  38. package/tools/nexowatt-ems-overview-selftest.cjs +1 -1
  39. package/tools/nexowatt-ensure-release-defaults.cjs +1 -1
  40. package/tools/nexowatt-login-layout-selftest.cjs +9 -13
  41. package/tools/nexowatt-merge-update-selftest.cjs +7 -1
  42. package/tools/nexowatt-modern-ui-selftest.cjs +10 -46
  43. package/tools/nexowatt-password-write-selftest.cjs +46 -16
  44. package/tools/nexowatt-prebuilt-release-selftest.cjs +292 -0
  45. package/tools/nexowatt-release-defaults-selftest.cjs +1 -1
  46. package/tools/nexowatt-runtime-cleanup-selftest.cjs +6 -8
  47. package/tools/nexowatt-stable-v7102-selftest.cjs +51 -0
  48. package/tools/nexowatt-sync-release-version.cjs +43 -5
  49. package/tools/nexowatt-ui-overview-runtime-selftest.cjs +2 -3
  50. package/tools/nexowatt-validate-package.cjs +54 -29
  51. package/tools/nexowatt-version-sync-selftest.cjs +18 -1
  52. package/INSTALL_TEST_V7.10.0.md +0 -11
  53. package/MERGE_UPDATE_README_V7.10.0.md +0 -5
  54. package/PUBLISH_STABLE_V7.10.0.md +0 -15
  55. package/README_STABILITY_V7.10.0.md +0 -3
  56. package/RELEASE_ACCEPTANCE_V7.10.0.md +0 -11
  57. package/RELEASE_NOTES_V7.10.0.md +0 -17
  58. package/adminWww/js/eos-release-watch.js +0 -77
  59. package/adminWww/static/js/nexowatt-stable-v7100.js +0 -111
  60. package/build/lib/eosPassword.js +0 -72
  61. package/build/lib/nexowattStableAuth.js +0 -74
  62. package/src/lib/eosAutoUpdate.ts +0 -320
  63. package/tools/nexowatt-cache-update-selftest.cjs +0 -12
  64. package/tools/nexowatt-request-security-selftest.cjs +0 -11
  65. package/tools/nexowatt-stable-v7100-selftest.cjs +0 -17
@@ -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 clone = value => JSON.parse(JSON.stringify(value));
10
- const normalizedName = value => String(value || '').trim().replace(/^system\.adapter\./, '').replace(/\.\d+$/, '');
11
- const stableVersion = value => /^\d+\.\d+\.\d+$/.test(String(value || '').trim());
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({ name, adapterName, title: entry?.title, desc: entry?.desc, author: entry?.author, authors: entry?.authors, publisher: entry?.publisher, url: entry?.url, meta: entry?.meta, readme: entry?.readme, extIcon: entry?.extIcon, licenseInformation: entry?.licenseInformation }).toLowerCase();
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
- constructor(adapter) { this.adapter = adapter; }
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() { const status = await this.reconcile('startup'); if (!this.timer) { this.timer = setInterval(() => void this.reconcile('interval'), RECONCILE_INTERVAL_MS); this.timer.unref?.(); } return status; }
28
- stop() { if (this.timer) clearInterval(this.timer); if (this.refreshTimer) clearTimeout(this.refreshTimer); if (this.retryTimer) clearTimeout(this.retryTimer); this.timer = undefined; this.refreshTimer = undefined; this.retryTimer = undefined; }
29
- async getStatus(refresh = false) { if (refresh) return this.reconcile('status'); const instance = await this.adapter.getForeignObjectAsync(this.instanceId); return this.statusFromNative(instance?.native || {}); }
30
- async setEnabled(enabled) { await this.adapter.extendForeignObjectAsync(this.instanceId, { native: { eosNexoWattAutoUpdate: enabled } }, { user: ADMIN_USER }); return this.reconcile(enabled ? 'enabled' : 'disabled'); }
31
- async reconcile(reason = 'manual') { if (this.reconcilePromise) return this.reconcilePromise; this.reconcilePromise = this.reconcileInternal(reason).finally(() => { this.reconcilePromise = undefined; }); return this.reconcilePromise; }
32
- statusFromNative(native) { const state = native.eosNexoWattAutoUpdateState || {}; return { enabled: native.eosNexoWattAutoUpdate !== false, repository: String(state.selectedRepository || ''), managedAdapters: Array.isArray(state.managedAdapters) ? state.managedAdapters.map(String).sort() : [], availableStableAdapters: Array.isArray(state.availableStableAdapters) ? state.availableStableAdapters.map(String).sort() : [], lastSync: Number(state.lastSync || 0), lastRepositoryRefresh: Number(state.lastRepositoryRefresh || 0), error: String(state.error || ''), policy: POLICY, source: 'ioBroker-native-auto-upgrade' }; }
33
- async reconcileInternal(reason) { const instance = await this.adapter.getForeignObjectAsync(this.instanceId); const native = instance?.native || {}; const enabled = native.eosNexoWattAutoUpdate !== false; const state = clone(native.eosNexoWattAutoUpdateState || {}); try { if (!enabled) return await this.disable(state, reason); return await this.enable(state, reason); } catch (error) { const message = error instanceof Error ? error.message : String(error || 'unknownError'); state.error = message; state.lastSync = Date.now(); await this.persist(false, state); this.adapter.log.warn(`[NexoWatt stable updates] ${message}`); return this.statusFromNative({ eosNexoWattAutoUpdate: enabled, eosNexoWattAutoUpdateState: state }); } }
34
- async readInstalledAdapters() { const view = await this.adapter.getObjectViewAsync('system', 'adapter', { startkey: 'system.adapter.', endkey: 'system.adapter.\u9999' }, { user: ADMIN_USER }); const result = new Map(); for (const row of view?.rows || []) { const object = row?.value || row?.doc; const name = normalizedName(object?.common?.name || row?.id || object?._id); if (name && object?.common?.version) result.set(name, object); } return result; }
35
- async readRepositorySelection(systemConfig) { const repositories = await this.adapter.getForeignObjectAsync('system.repositories'); const rows = repositories?.native?.repositories || {}; const active = Array.isArray(systemConfig?.common?.activeRepo) ? systemConfig.common.activeRepo.map(String) : []; const candidates = Object.entries(rows).map(([name, repo]) => { const entries = repo?.json && typeof repo.json === 'object' ? repo.json : {}; const stableNames = Object.entries(entries).filter(([entryName, entry]) => stableVersion(entry?.version) && isNexoWattRepositoryEntry(entryName, entry)).map(([entryName, entry]) => normalizedName(entry?.name || entryName)).filter(Boolean); return { name, entries, stableNames: [...new Set(stableNames)].sort(), activeIndex: active.indexOf(name) }; }).filter(row => row.stableNames.length > 0); if (!candidates.length) throw new Error('nexowattStableRepositoryNotFound'); candidates.sort((a, b) => { const aa = a.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : a.activeIndex; const bb = b.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : b.activeIndex; return aa - bb || b.stableNames.length - a.stableNames.length || a.name.localeCompare(b.name); }); return candidates[0]; }
36
- async enable(state, reason) { const systemConfig = await this.adapter.getForeignObjectAsync('system.config'); if (!systemConfig?.common) throw new Error('systemConfigUnavailable'); const selected = await this.readRepositorySelection(systemConfig); const installed = await this.readInstalledAdapters(); const managedNames = selected.stableNames.filter(name => installed.has(name)).sort(); if (!managedNames.length) throw new Error('noInstalledNexoWattStableAdapters'); state.previousPolicies ||= {}; for (const name of managedNames) { if (!(name in state.previousPolicies)) { const current = installed.get(name)?.common?.automaticUpgrade; state.previousPolicies[name] = current == null ? null : current; } await this.writeAdapterPolicy(name, POLICY); } const common = systemConfig.common; const activeRepo = Array.isArray(common.activeRepo) ? [...common.activeRepo] : []; const auto = common.adapterAutoUpgrade && typeof common.adapterAutoUpgrade === 'object' ? clone(common.adapterAutoUpgrade) : { repositories: {}, defaultPolicy: 'none' }; auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {}; if (state.previousRepositoryEnabled === undefined) state.previousRepositoryEnabled = Object.prototype.hasOwnProperty.call(auto.repositories, selected.name) ? Boolean(auto.repositories[selected.name]) : null; auto.repositories[selected.name] = true; if (!auto.defaultPolicy) auto.defaultPolicy = 'none'; common.adapterAutoUpgrade = auto; if (activeRepo[0] !== selected.name) { if (!state.previousActiveRepo) state.previousActiveRepo = [...activeRepo]; state.ownsActiveRepoOrder = true; common.activeRepo = [selected.name, ...activeRepo.filter(name => name !== selected.name)]; } await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER }); state.selectedRepository = selected.name; state.availableStableAdapters = selected.stableNames; state.managedAdapters = managedNames; state.lastSync = Date.now(); state.error = ''; await this.persist(true, state); this.scheduleRepositoryRefresh(selected.name, state); this.adapter.log.info(`[NexoWatt stable updates] Enabled for ${managedNames.join(', ')} from repository "${selected.name}" (${reason})`); return this.statusFromNative({ eosNexoWattAutoUpdate: true, eosNexoWattAutoUpdateState: state }); }
37
- async disable(state, reason) { for (const [name, previous] of Object.entries(state.previousPolicies || {})) { const current = await this.adapter.getForeignObjectAsync(`system.adapter.${normalizedName(name)}`); if (current?.common?.automaticUpgrade === POLICY) await this.writeAdapterPolicy(name, previous); } const systemConfig = await this.adapter.getForeignObjectAsync('system.config'); if (systemConfig?.common) { const auto = systemConfig.common.adapterAutoUpgrade && typeof systemConfig.common.adapterAutoUpgrade === 'object' ? clone(systemConfig.common.adapterAutoUpgrade) : null; if (auto && state.selectedRepository) { auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {}; if (auto.repositories[state.selectedRepository] === true) { if (state.previousRepositoryEnabled === null || state.previousRepositoryEnabled === undefined) delete auto.repositories[state.selectedRepository]; else auto.repositories[state.selectedRepository] = state.previousRepositoryEnabled; } systemConfig.common.adapterAutoUpgrade = auto; } if (state.ownsActiveRepoOrder && Array.isArray(state.previousActiveRepo) && Array.isArray(systemConfig.common.activeRepo) && systemConfig.common.activeRepo[0] === state.selectedRepository) systemConfig.common.activeRepo = [...state.previousActiveRepo]; await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER }); } state.previousPolicies = {}; state.previousRepositoryEnabled = undefined; state.previousActiveRepo = undefined; state.ownsActiveRepoOrder = false; state.managedAdapters = []; state.lastSync = Date.now(); state.error = ''; await this.persist(false, state); this.adapter.log.info(`[NexoWatt stable updates] Disabled and previous policies restored (${reason})`); return this.statusFromNative({ eosNexoWattAutoUpdate: false, eosNexoWattAutoUpdateState: state }); }
38
- async writeAdapterPolicy(name, policy) { const id = `system.adapter.${normalizedName(name)}`; const object = await this.adapter.getForeignObjectAsync(id); if (!object?.common) return; if (policy === null) delete object.common.automaticUpgrade; else object.common.automaticUpgrade = policy; await this.adapter.setForeignObjectAsync(id, object, { user: ADMIN_USER }); }
39
- async persist(enabled, state) { await this.adapter.extendForeignObjectAsync(this.instanceId, { native: { eosNexoWattAutoUpdate: enabled, eosNexoWattAutoUpdateState: state } }, { user: ADMIN_USER }); }
40
- scheduleRetry() { if (this.retryTimer) clearTimeout(this.retryTimer); this.retryTimer = setTimeout(() => void this.reconcile('retry'), 60000); this.retryTimer.unref?.(); }
41
- scheduleRepositoryRefresh(repository, state) { if (!this.adapter.sendToHostAsync || !this.adapter.host) return; if (this.refreshTimer) clearTimeout(this.refreshTimer); this.refreshTimer = setTimeout(() => { void this.adapter.sendToHostAsync?.(this.adapter.host, 'getRepository', { repo: repository, update: true }).then(async () => { const current = await this.adapter.getForeignObjectAsync(this.instanceId); if (current?.native?.eosNexoWattAutoUpdate === false) return; state.lastRepositoryRefresh = Date.now(); await this.persist(true, state); }).catch(error => this.adapter.log.warn(`[NexoWatt stable updates] Repository refresh failed: ${error instanceof Error ? error.message : error}`)); }, REPOSITORY_REFRESH_DELAY_MS); this.refreshTimer.unref?.(); }
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"}