iobroker.eos-admin 7.9.99 → 7.10.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.
Files changed (45) hide show
  1. package/{INSTALL_TEST_V7.9.99.md → INSTALL_TEST_V7.10.0.md} +2 -2
  2. package/{MERGE_UPDATE_README_V7.9.99.md → MERGE_UPDATE_README_V7.10.0.md} +1 -1
  3. package/NEXOWATT_EOS_BUILD_INFO.json +21 -21
  4. package/{PUBLISH_STABLE_V7.9.99.md → PUBLISH_STABLE_V7.10.0.md} +2 -2
  5. package/README_STABILITY_V7.10.0.md +3 -0
  6. package/{RELEASE_ACCEPTANCE_V7.9.99.md → RELEASE_ACCEPTANCE_V7.10.0.md} +1 -1
  7. package/RELEASE_NOTES_V7.10.0.md +17 -0
  8. package/adminWww/assets/bootstrap-COulQZax-v84.js +1 -1
  9. package/adminWww/css/eos-auto-update.css +4 -0
  10. package/adminWww/css/eos-ems-overview.css +1 -1
  11. package/adminWww/css/nexowatt-native-shell.css +432 -2
  12. package/adminWww/index.html +21 -19
  13. package/adminWww/js/eos-account-management.js +1 -1
  14. package/adminWww/js/eos-assistant.js +1 -1
  15. package/adminWww/js/eos-auto-update.js +78 -0
  16. package/adminWww/js/eos-ems-overview.js +1 -1
  17. package/adminWww/js/eos-release-watch.js +1 -1
  18. package/adminWww/js/eos-role-bootstrap.js +69 -12
  19. package/adminWww/js/eos-role-ui.js +2 -2
  20. package/adminWww/js/nexowatt-native-shell.js +1 -1
  21. package/adminWww/static/js/nexowatt-stable-login.js +70 -43
  22. package/adminWww/static/js/nexowatt-stable-v7100.js +111 -0
  23. package/build/lib/eosAutoUpdate.js +43 -0
  24. package/build/lib/eosPassword.js +49 -39
  25. package/build/lib/web.js +142 -19
  26. package/build/main.js +1 -1
  27. package/io-package.json +7 -6
  28. package/package.json +20 -14
  29. package/src/lib/eosAutoUpdate.ts +320 -0
  30. package/tools/nexowatt-account-management-selftest.cjs +2 -2
  31. package/tools/nexowatt-auto-update-selftest.cjs +34 -0
  32. package/tools/nexowatt-cache-update-selftest.cjs +6 -5
  33. package/tools/nexowatt-login-layout-selftest.cjs +11 -10
  34. package/tools/nexowatt-merge-update-selftest.cjs +1 -1
  35. package/tools/nexowatt-modern-ui-selftest.cjs +1 -1
  36. package/tools/nexowatt-password-write-selftest.cjs +13 -41
  37. package/tools/nexowatt-runtime-cleanup-selftest.cjs +6 -4
  38. package/tools/nexowatt-stable-v7100-selftest.cjs +17 -0
  39. package/tools/nexowatt-sync-release-version.cjs +4 -1
  40. package/tools/nexowatt-ui-overview-runtime-selftest.cjs +1 -1
  41. package/tools/nexowatt-validate-package.cjs +11 -11
  42. package/README_STABILITY_V7.9.99.md +0 -18
  43. package/RELEASE_NOTES_V7.9.99.md +0 -9
  44. package/adminWww/static/js/nexowatt-stable-v99.js +0 -33
  45. package/tools/nexowatt-stable-v99-selftest.cjs +0 -25
package/build/lib/web.js CHANGED
@@ -23,6 +23,7 @@ const cookieParser = require("cookie-parser");
23
23
  const iobroker_mcp_1 = require("iobroker.mcp");
24
24
  const eosPassword_1 = require("./eosPassword");
25
25
  const eosRequestSecurity_1 = require("./eosRequestSecurity");
26
+ const eosAutoUpdate_1 = require("./eosAutoUpdate");
26
27
  let AdapterStore;
27
28
  /** Content of a socket-io file */
28
29
  let socketIoFile;
@@ -163,6 +164,8 @@ class Web {
163
164
  mcpServer = null;
164
165
  /** Short-lived passwordless first-activation claims. Keys are SHA-256 hashes of HttpOnly cookie tokens. */
165
166
  eosPasswordClaims = new Map();
167
+ /** One-time authenticated tickets for the mandatory personal-password POST. */
168
+ eosPasswordSetupTickets = new Map();
166
169
  /** Small in-memory rate limiter for unauthenticated first-activation requests. */
167
170
  eosPasswordClaimRates = new Map();
168
171
  /**
@@ -742,11 +745,6 @@ class Web {
742
745
  }
743
746
  async saveEosFirstLoginPassword(req, res) {
744
747
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
745
- const access = await this.getEosRequestAccess(req);
746
- if (!access.userId || access.role === 'admin') {
747
- res.status(403).json({ error: 'passwordSetupNotAllowed' });
748
- return;
749
- }
750
748
  if (req.headers['x-nexowatt-eos-first-login'] !== '1') {
751
749
  res.status(403).json({ error: 'invalidRequest' });
752
750
  return;
@@ -755,22 +753,41 @@ class Web {
755
753
  res.status(403).json({ error: 'invalidRequestOrigin' });
756
754
  return;
757
755
  }
756
+ const body = req.body || {};
757
+ const suppliedToken = String(req.headers['x-nexowatt-eos-password-setup-token'] || body.setupToken || '').trim();
758
+ const ticket = this.resolveEosPasswordSetupTicket(req, suppliedToken);
759
+ const requestAccess = await this.getEosRequestAccess(req);
760
+ if (suppliedToken && !ticket) {
761
+ res.status(403).json({ error: 'passwordSetupTokenExpired' });
762
+ return;
763
+ }
764
+ if (ticket && requestAccess.userId && requestAccess.userId !== ticket.userId) {
765
+ res.status(403).json({ error: 'passwordSetupTokenMismatch' });
766
+ return;
767
+ }
768
+ const access = ticket ? { ...requestAccess, userId: ticket.userId, role: ticket.role } : requestAccess;
769
+ if (!access.userId || access.role === 'admin') {
770
+ res.status(403).json({ error: suppliedToken ? 'passwordSetupTokenMismatch' : 'passwordSetupNotAllowed' });
771
+ return;
772
+ }
758
773
  const passwordState = await this.getEosFirstLoginPasswordState(access.userId, access.role);
759
774
  if (!passwordState.required) {
775
+ this.invalidateEosPasswordSetupTicketsForUser(access.userId);
760
776
  res.status(200).json({ success: true, alreadyInitialized: true });
761
777
  return;
762
778
  }
763
- const body = (req.body || {});
764
779
  const validation = this.validateEosFirstLoginPassword(body.password, body.passwordRepeat, access.userId);
765
780
  if (!validation.valid) {
766
- res.status(400).json({
767
- error: validation.error,
768
- minLength: passwordState.minLength,
769
- });
781
+ res.status(400).json({ error: validation.error, minLength: passwordState.minLength });
770
782
  return;
771
783
  }
772
- await this.setEosUserPassword(access.userId, validation.password);
773
- const userObject = (await this.adapter.getForeignObjectAsync(access.userId));
784
+ if (body.passwordAlreadyWritten === true) {
785
+ await (0, eosPassword_1.verifyEosUserPasswordCredential)(this.adapter, access.userId, validation.password, EOS_PASSWORD_SERVICE_USER);
786
+ }
787
+ else {
788
+ await this.setEosUserPassword(access.userId, validation.password);
789
+ }
790
+ const userObject = await this.adapter.getForeignObjectAsync(access.userId);
774
791
  if (!userObject) {
775
792
  throw new Error('userObjectUnavailableAfterPasswordChange');
776
793
  }
@@ -798,13 +815,17 @@ class Web {
798
815
  if (persistedState.required || !persistedState.initialized) {
799
816
  throw new Error('passwordMetadataNotPersisted');
800
817
  }
801
- await this.destroyEosRequestSessions(req);
818
+ this.invalidateEosPasswordSetupTicketsForUser(access.userId);
802
819
  for (const cookie of ['access_token', 'refresh_token', 'connect.sid']) {
803
820
  res.clearCookie(cookie);
804
821
  }
805
- this.adapter.log.info(`EOS first-login password initialized for ${access.userId}`);
806
822
  res.status(200).json({ success: true, role: access.role, logoutRequired: true, sessionInvalidated: true });
823
+ void this.destroyEosRequestSessions(req).catch(error => {
824
+ this.adapter.log.debug(`Deferred EOS session cleanup failed: ${error instanceof Error ? error.message : error}`);
825
+ });
826
+ this.adapter.log.info(`EOS first-login password initialized for ${access.userId}`);
807
827
  }
828
+
808
829
  isEosPasswordlessFirstLoginEnabled() {
809
830
  return this.settings.eosPasswordlessFirstLogin !== false;
810
831
  }
@@ -843,6 +864,53 @@ class Web {
843
864
  hashEosPasswordClaim(token) {
844
865
  return (0, node_crypto_1.createHash)('sha256').update(token).digest('hex');
845
866
  }
867
+ cleanEosPasswordSetupTickets() {
868
+ const now = Date.now();
869
+ for (const [key, ticket] of this.eosPasswordSetupTickets.entries()) {
870
+ if (ticket.expiresAt <= now) {
871
+ this.eosPasswordSetupTickets.delete(key);
872
+ }
873
+ }
874
+ }
875
+ invalidateEosPasswordSetupTicketsForUser(userId) {
876
+ for (const [key, ticket] of this.eosPasswordSetupTickets.entries()) {
877
+ if (ticket.userId === userId) {
878
+ this.eosPasswordSetupTickets.delete(key);
879
+ }
880
+ }
881
+ }
882
+ issueEosPasswordSetupTicket(req, userId, role) {
883
+ if (role !== 'installer' && role !== 'enduser') {
884
+ return null;
885
+ }
886
+ this.cleanEosPasswordSetupTickets();
887
+ // Policy-client refreshes must not invalidate the token displayed by bootstrap.
888
+ // Tokens are short-lived and all are removed after a successful password change.
889
+ const token = (0, node_crypto_1.randomBytes)(32).toString('base64url');
890
+ const expiresAt = Date.now() + 10 * 60_000;
891
+ this.eosPasswordSetupTickets.set(this.hashEosPasswordClaim(token), {
892
+ userId,
893
+ role,
894
+ expiresAt,
895
+ remoteAddress: this.getEosRemoteAddress(req),
896
+ });
897
+ return { token, expiresAt };
898
+ }
899
+ resolveEosPasswordSetupTicket(req, token) {
900
+ this.cleanEosPasswordSetupTickets();
901
+ if (!token) {
902
+ return null;
903
+ }
904
+ const ticket = this.eosPasswordSetupTickets.get(this.hashEosPasswordClaim(token));
905
+ if (!ticket || ticket.expiresAt <= Date.now()) {
906
+ return null;
907
+ }
908
+ const address = this.getEosRemoteAddress(req);
909
+ if (ticket.remoteAddress && address && ticket.remoteAddress !== address) {
910
+ return null;
911
+ }
912
+ return ticket;
913
+ }
846
914
  readEosCookie(req, name) {
847
915
  const row = String(req.headers.cookie || '')
848
916
  .split(';')
@@ -1250,6 +1318,38 @@ class Web {
1250
1318
  ],
1251
1319
  });
1252
1320
  }
1321
+ getNexoWattStableUpdateManager() {
1322
+ this.nexowattStableUpdateManager ||= new eosAutoUpdate_1.NexoWattStableUpdateManager(this.adapter);
1323
+ return this.nexowattStableUpdateManager;
1324
+ }
1325
+ async sendNexoWattStableUpdateStatus(req, res) {
1326
+ const access = await this.getEosRequestAccess(req);
1327
+ if (access.role !== 'admin') {
1328
+ res.status(403).json({ error: 'permissionError' });
1329
+ return;
1330
+ }
1331
+ res.status(200).json(await this.getNexoWattStableUpdateManager().getStatus(false));
1332
+ }
1333
+ async saveNexoWattStableUpdateSettings(req, res) {
1334
+ const access = await this.getEosRequestAccess(req);
1335
+ if (access.role !== 'admin') {
1336
+ res.status(403).json({ error: 'permissionError' });
1337
+ return;
1338
+ }
1339
+ if (req.headers['x-nexowatt-eos-auto-update'] !== '1') {
1340
+ res.status(403).json({ error: 'invalidRequest' });
1341
+ return;
1342
+ }
1343
+ if (!this.isEosSameOriginWrite(req)) {
1344
+ res.status(403).json({ error: 'invalidRequestOrigin' });
1345
+ return;
1346
+ }
1347
+ if (typeof req.body?.enabled !== 'boolean') {
1348
+ res.status(400).json({ error: 'invalidEnabledValue' });
1349
+ return;
1350
+ }
1351
+ res.status(200).json(await this.getNexoWattStableUpdateManager().setEnabled(req.body.enabled));
1352
+ }
1253
1353
  isEosSameOriginWrite(req) {
1254
1354
  return (0, eosRequestSecurity_1.isEosSameOriginRequest)(req.headers);
1255
1355
  }
@@ -1321,6 +1421,7 @@ class Web {
1321
1421
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
1322
1422
  const { userId, groups, groupNames, adminGroups, role } = await this.getEosRequestAccess(req);
1323
1423
  const passwordSetup = await this.getEosFirstLoginPasswordState(userId, role);
1424
+ const setupTicket = passwordSetup.required && userId ? this.issueEosPasswordSetupTicket(req, userId, role) : null;
1324
1425
  const isAdministrator = role === 'admin' && (userId === 'system.user.admin' || groups.includes('system.group.administrator'));
1325
1426
  const isEosAdminGroup = role === 'admin';
1326
1427
  const isInstaller = role === 'installer';
@@ -1341,7 +1442,12 @@ class Web {
1341
1442
  isEndUser,
1342
1443
  isAdmin: isEosAdminGroup,
1343
1444
  mustChangePassword: passwordSetup.required,
1344
- passwordSetup: { ...passwordSetup, userName: userId?.replace(/^system\.user\./, '') || '' },
1445
+ passwordSetup: {
1446
+ ...passwordSetup,
1447
+ userName: userId?.replace(/^system\.user\./, '') || '',
1448
+ setupToken: setupTicket?.token || '',
1449
+ setupTokenExpiresAt: setupTicket?.expiresAt || 0,
1450
+ },
1345
1451
  capabilities: this.getEosRoleCapabilities(role),
1346
1452
  hideLegacyAdminForNonAdmins: this.settings.eosHideLegacyAdminForNonAdmins !== false && this.settings.eosHideLegacyAdminFromNonAdmins !== false,
1347
1453
  hideLegacyAdminFromNonAdmins: this.settings.eosHideLegacyAdminForNonAdmins !== false && this.settings.eosHideLegacyAdminFromNonAdmins !== false,
@@ -1483,6 +1589,21 @@ class Web {
1483
1589
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
1484
1590
  next();
1485
1591
  });*/
1592
+ void this.getNexoWattStableUpdateManager().start().catch(error => {
1593
+ this.adapter.log.warn(`[NexoWatt stable updates] Startup reconciliation failed: ${error instanceof Error ? error.message : error}`);
1594
+ });
1595
+ this.server.app.get('/nexowatt/updates/status', (req, res) => {
1596
+ void this.sendNexoWattStableUpdateStatus(req, res).catch(error => {
1597
+ this.adapter.log.warn(`[NexoWatt stable updates] Cannot read status: ${error instanceof Error ? error.message : error}`);
1598
+ res.status(500).json({ error: 'autoUpdateStatusFailed' });
1599
+ });
1600
+ });
1601
+ this.server.app.post('/nexowatt/updates/settings', (req, res) => {
1602
+ void this.saveNexoWattStableUpdateSettings(req, res).catch(error => {
1603
+ this.adapter.log.warn(`[NexoWatt stable updates] Cannot save settings: ${error instanceof Error ? error.message : error}`);
1604
+ res.status(500).json({ error: 'autoUpdateSettingsFailed' });
1605
+ });
1606
+ });
1486
1607
  this.server.app.get('/version', (_req, res) => {
1487
1608
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
1488
1609
  res.setHeader('Pragma', 'no-cache');
@@ -1766,12 +1887,13 @@ class Web {
1766
1887
  this.server.app.post('/nexowatt/account/first-password', (req, res) => {
1767
1888
  void this.saveEosFirstLoginPassword(req, res).catch(e => {
1768
1889
  const detail = e instanceof Error ? e.message : String(e || '');
1769
- this.adapter.log.warn(`Cannot initialize EOS first-login password: ${detail}`);
1890
+ const code = detail.split(':', 1)[0];
1891
+ this.adapter.log.warn(`Cannot initialize EOS first-login password [${code}]: ${detail}`);
1770
1892
  const known = new Set([
1771
1893
  'passwordApiUnavailable', 'passwordNotPersisted', 'passwordVerificationFailed',
1772
1894
  'passwordMetadataNotPersisted', 'userObjectUnavailableAfterPasswordChange',
1773
1895
  ]);
1774
- res.status(500).json({ error: known.has(detail) ? detail : 'passwordSetupFailed' });
1896
+ res.status(500).json({ error: known.has(code) ? code : 'passwordSetupFailed', detail: code });
1775
1897
  });
1776
1898
  });
1777
1899
  this.server.app.get('/nexowatt/account/manage', (req, res) => {
@@ -1783,12 +1905,13 @@ class Web {
1783
1905
  this.server.app.post('/nexowatt/account/reset', (req, res) => {
1784
1906
  void this.resetEosAccountPassword(req, res).catch(e => {
1785
1907
  const detail = e instanceof Error ? e.message : String(e || '');
1786
- this.adapter.log.warn(`Cannot reset EOS account: ${detail}`);
1908
+ const code = detail.split(':', 1)[0];
1909
+ this.adapter.log.warn(`Cannot reset EOS account [${code}]: ${detail}`);
1787
1910
  const known = new Set([
1788
1911
  'passwordApiUnavailable', 'passwordNotPersisted', 'passwordVerificationFailed',
1789
1912
  'passwordMetadataNotPersisted', 'userObjectUnavailableAfterPasswordReset',
1790
1913
  ]);
1791
- res.status(500).json({ error: known.has(detail) ? detail : 'accountResetFailed' });
1914
+ res.status(500).json({ error: known.has(code) ? code : 'accountResetFailed', detail: code });
1792
1915
  });
1793
1916
  });
1794
1917
  this.server.app.get('/iobroker_check.html', (_req, res) => {
package/build/main.js CHANGED
@@ -215,7 +215,7 @@ async function ensureEosStableInitialAccounts(adapter) {
215
215
  const pendingFirstLogin = eosNative.nexowattPasswordChangeRequired === true || eosNative.eosPasswordChangeRequired === true || eosNative.nexowattFirstLoginPending === true || eosNative.eosFirstLoginRequired === true;
216
216
  const stableCredentialMissing = eosNative.nexowattStableInitialCredentialVersion !== 1;
217
217
  if (created || passwordMissing || resetRequested || (pendingFirstLogin && stableCredentialMissing)) {
218
- await adapter.setPasswordAsync(account.user, EOS_STABLE_INITIAL_PASSWORD, { user: 'system.user.admin' });
218
+ await (0, eosPassword_1.setEosUserPasswordWithVerification)(adapter, id, EOS_STABLE_INITIAL_PASSWORD, 'system.user.admin');
219
219
  await adapter.extendForeignObjectAsync(id, {
220
220
  native: {
221
221
  ...eosNative,
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "eos-admin",
4
- "version": "7.9.99",
4
+ "version": "7.10.0",
5
5
  "titleLang": {
6
6
  "en": "NexoWatt EOS Admin",
7
7
  "de": "NexoWatt EOS Admin",
@@ -329,7 +329,7 @@
329
329
  "icon": "admin.svg",
330
330
  "messagebox": true,
331
331
  "enabled": true,
332
- "extIcon": "https://unpkg.com/iobroker.eos-admin@7.9.99/admin/admin.svg",
332
+ "extIcon": "https://unpkg.com/iobroker.eos-admin@7.10.0/admin/admin.svg",
333
333
  "keywords": [
334
334
  "NexoWatt",
335
335
  "EOS",
@@ -340,7 +340,7 @@
340
340
  "licensed"
341
341
  ],
342
342
  "compact": true,
343
- "readme": "https://unpkg.com/iobroker.eos-admin@7.9.99/README.md",
343
+ "readme": "https://unpkg.com/iobroker.eos-admin@7.10.0/README.md",
344
344
  "authors": [
345
345
  "NexoWatt"
346
346
  ],
@@ -408,7 +408,7 @@
408
408
  "nondeletable": false,
409
409
  "allowAdapterUpdate": true,
410
410
  "allowAdapterDelete": false,
411
- "meta": "https://unpkg.com/iobroker.eos-admin@7.9.99/io-package.json",
411
+ "meta": "https://unpkg.com/iobroker.eos-admin@7.10.0/io-package.json",
412
412
  "npmPackage": "iobroker.eos-admin",
413
413
  "packetName": "iobroker.eos-admin",
414
414
  "publisher": "NexoWatt"
@@ -549,7 +549,8 @@
549
549
  "eosAllowPasswordlessFirstLogin": false,
550
550
  "eosRequireFirstLoginPasswordChange": true,
551
551
  "eosAutoAssignStandardAccounts": true,
552
- "eosAssistEnabled": false
552
+ "eosAssistEnabled": false,
553
+ "eosNexoWattAutoUpdate": true
553
554
  },
554
555
  "notifications": [
555
556
  {
@@ -1117,5 +1118,5 @@
1117
1118
  }
1118
1119
  }
1119
1120
  },
1120
- "version": "7.9.99"
1121
+ "version": "7.10.0"
1121
1122
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iobroker.eos-admin",
3
- "description": "NexoWatt EOS Admin – stable candidate with truthful EMS overview, verified user passwords and deterministic browser updates.",
4
- "version": "7.9.99",
3
+ "description": "NexoWatt EOS Admin – stable candidate with native NexoWatt auto updates, reliable account passwords, clean login and scrollable cockpit.",
4
+ "version": "7.10.0",
5
5
  "contributors": [
6
6
  "bluefox <dogafox@gmail.com>",
7
7
  "apollon77",
@@ -118,22 +118,27 @@
118
118
  "tools/nexowatt-version-sync-selftest.cjs",
119
119
  "tools/nexowatt-merge-update-selftest.cjs",
120
120
  "tools/nexowatt-ems-overview-selftest.cjs",
121
- "README_STABILITY_V7.9.99.md",
122
- "RELEASE_NOTES_V7.9.99.md",
123
- "PUBLISH_STABLE_V7.9.99.md",
124
- "INSTALL_TEST_V7.9.99.md",
125
- "RELEASE_ACCEPTANCE_V7.9.99.md",
126
- "MERGE_UPDATE_README_V7.9.99.md",
121
+ "README_STABILITY_V7.10.0.md",
122
+ "RELEASE_NOTES_V7.10.0.md",
123
+ "PUBLISH_STABLE_V7.10.0.md",
124
+ "INSTALL_TEST_V7.10.0.md",
125
+ "RELEASE_ACCEPTANCE_V7.10.0.md",
126
+ "MERGE_UPDATE_README_V7.10.0.md",
127
127
  "README_EMS_OVERVIEW_MERGE.md",
128
128
  "RC73_EOS_ADMIN_MERGE_VALIDATION.md",
129
129
  "VALIDATION_EMS_OVERVIEW_MERGE.md",
130
130
  "NexoWatt_EOS_Admin_EMS_OVERVIEW_MERGE_VALIDATION.md",
131
131
  "tools/nexowatt-apply-ems-overview.cjs",
132
132
  "tools/nexowatt-ui-overview-runtime-selftest.cjs",
133
- "tools/nexowatt-stable-v99-selftest.cjs",
133
+ "tools/nexowatt-stable-v7100-selftest.cjs",
134
134
  "tools/nexowatt-password-write-selftest.cjs",
135
135
  "tools/nexowatt-request-security-selftest.cjs",
136
- "tools/nexowatt-cache-update-selftest.cjs"
136
+ "tools/nexowatt-cache-update-selftest.cjs",
137
+ "src/lib/eosAutoUpdate.ts",
138
+ "build/lib/eosAutoUpdate.js",
139
+ "adminWww/js/eos-auto-update.js",
140
+ "adminWww/css/eos-auto-update.css",
141
+ "tools/nexowatt-auto-update-selftest.cjs"
137
142
  ],
138
143
  "scripts": {
139
144
  "npm": "npm i -f && cd src-admin && npm i -f",
@@ -168,7 +173,7 @@
168
173
  "nexowatt:repo-entry": "node tools/nexowatt-generate-repo-entry.cjs",
169
174
  "nexowatt:patch-repo": "node tools/nexowatt-patch-repo.cjs",
170
175
  "nexowatt:repair-update": "node tools/nexowatt-repair-eos-admin-update.cjs",
171
- "check:eos-stability": "node tools/nexowatt-stability-check.cjs && node tools/nexowatt-esm-syntax-selftest.cjs && node tools/nexowatt-import-integrity-selftest.cjs && node tools/nexowatt-entrypoint-smoke-selftest.cjs && node tools/nexowatt-frontend-graph-check.cjs && node tools/nexowatt-policy-selftest.cjs && node tools/nexowatt-publish-channel-selftest.cjs && node tools/nexowatt-release-defaults-selftest.cjs && node tools/nexowatt-role-access-selftest.cjs && node tools/nexowatt-internal-reserve-selftest.cjs && node tools/nexowatt-first-login-selftest.cjs && node tools/nexowatt-account-management-selftest.cjs && node tools/nexowatt-cache-update-selftest.cjs && node tools/nexowatt-request-security-selftest.cjs && node tools/nexowatt-password-write-selftest.cjs && node tools/nexowatt-modern-ui-selftest.cjs && node tools/nexowatt-login-layout-selftest.cjs && node tools/nexowatt-branding-selftest.cjs && node tools/nexowatt-default-port-selftest.cjs && node tools/nexowatt-module-popup-selftest.cjs && node tools/nexowatt-datapoint-selftest.cjs && node tools/nexowatt-update-selftest.cjs && node tools/nexowatt-datapoint-interaction-selftest.cjs && node tools/nexowatt-manual-write-policy-selftest.cjs && node tools/nexowatt-value-column-selftest.cjs && node tools/nexowatt-native-shell-selftest.cjs && node tools/nexowatt-assistant-separation-selftest.cjs && node tools/nexowatt-runtime-cleanup-selftest.cjs && node tools/nexowatt-version-sync-selftest.cjs && node tools/nexowatt-merge-update-selftest.cjs && npm run check:eos-stable-v99 && node tools/nexowatt-ems-overview-selftest.cjs && node tools/nexowatt-ui-overview-runtime-selftest.cjs",
176
+ "check:eos-stability": "node tools/nexowatt-stability-check.cjs && node tools/nexowatt-esm-syntax-selftest.cjs && node tools/nexowatt-import-integrity-selftest.cjs && node tools/nexowatt-entrypoint-smoke-selftest.cjs && node tools/nexowatt-frontend-graph-check.cjs && node tools/nexowatt-policy-selftest.cjs && node tools/nexowatt-publish-channel-selftest.cjs && node tools/nexowatt-release-defaults-selftest.cjs && node tools/nexowatt-role-access-selftest.cjs && node tools/nexowatt-internal-reserve-selftest.cjs && node tools/nexowatt-first-login-selftest.cjs && node tools/nexowatt-account-management-selftest.cjs && node tools/nexowatt-cache-update-selftest.cjs && node tools/nexowatt-auto-update-selftest.cjs && node tools/nexowatt-request-security-selftest.cjs && node tools/nexowatt-password-write-selftest.cjs && node tools/nexowatt-modern-ui-selftest.cjs && node tools/nexowatt-login-layout-selftest.cjs && node tools/nexowatt-branding-selftest.cjs && node tools/nexowatt-default-port-selftest.cjs && node tools/nexowatt-module-popup-selftest.cjs && node tools/nexowatt-datapoint-selftest.cjs && node tools/nexowatt-update-selftest.cjs && node tools/nexowatt-datapoint-interaction-selftest.cjs && node tools/nexowatt-manual-write-policy-selftest.cjs && node tools/nexowatt-value-column-selftest.cjs && node tools/nexowatt-native-shell-selftest.cjs && node tools/nexowatt-assistant-separation-selftest.cjs && node tools/nexowatt-runtime-cleanup-selftest.cjs && node tools/nexowatt-version-sync-selftest.cjs && node tools/nexowatt-merge-update-selftest.cjs && npm run check:eos-stable-v7100 && node tools/nexowatt-ems-overview-selftest.cjs && node tools/nexowatt-ui-overview-runtime-selftest.cjs",
172
177
  "nexowatt:patch-built-frontend": "node tools/nexowatt-patch-built-frontend.cjs",
173
178
  "clean:eos-runtime": "node tools/nexowatt-clean-legacy-runtime.cjs",
174
179
  "precheck:eos-package": "npm run sync:eos-version && npm run prepare:eos-release-defaults && npm run clean:eos-runtime",
@@ -192,10 +197,11 @@
192
197
  "sync:eos-version": "node tools/nexowatt-sync-release-version.cjs",
193
198
  "test:eos-version-sync": "node tools/nexowatt-version-sync-selftest.cjs",
194
199
  "verify:eos-merge": "node tools/nexowatt-merge-update-selftest.cjs",
195
- "check:eos-stable-v99": "node tools/nexowatt-stable-v99-selftest.cjs",
196
200
  "test:eos-password-write": "node tools/nexowatt-password-write-selftest.cjs",
197
201
  "test:eos-request-security": "node tools/nexowatt-request-security-selftest.cjs",
198
- "test:eos-cache-update": "node tools/nexowatt-cache-update-selftest.cjs"
202
+ "test:eos-cache-update": "node tools/nexowatt-cache-update-selftest.cjs",
203
+ "check:eos-auto-update": "node tools/nexowatt-auto-update-selftest.cjs",
204
+ "check:eos-stable-v7100": "node tools/nexowatt-stable-v7100-selftest.cjs"
199
205
  },
200
206
  "author": "NexoWatt",
201
207
  "private": false,
@@ -206,7 +212,7 @@
206
212
  },
207
213
  "nexowattReleasePolicy": {
208
214
  "distTag": "latest",
209
- "purpose": "accepted stable NexoWatt EOS sales-product release 7.9.99"
215
+ "purpose": "accepted stable NexoWatt EOS sales-product release 7.10.0"
210
216
  },
211
217
  "publisher": "NexoWatt"
212
218
  }