iobroker.eos-admin 7.10.5 → 7.10.6

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.
@@ -1,6 +1,6 @@
1
- # Installation test 7.10.5
1
+ # Installation test 7.10.6
2
2
 
3
- - Install/update EOS Admin 7.10.5 and verify port 8081 remains reachable.
3
+ - Install/update EOS Admin 7.10.6 and verify port 8081 remains reachable.
4
4
  - Sign in as Admin: datapoints are writable; expert mode can be enabled and disabled; Admin and XTerm overview cards are visible.
5
5
  - Sign in as Installer: no expert head, ioBroker Admin, XTerm, App Center, License, Simulation or Users/Rights page.
6
6
  - Sign in as End User: Datapoints tab is visible but every write/edit/delete action is disabled; restricted tools are absent.
@@ -1,7 +1,7 @@
1
- # Merge/update note 7.10.5
1
+ # Merge/update note 7.10.6
2
2
 
3
- Always replace the previous repository with the complete 7.10.5 repository. Do not merge old `adminWww` bundles or deleted role-security files back into this release. In particular, `nexowatt-role-security.js` and `build/lib/eosRoleSecurity.js` are obsolete and must stay absent.
3
+ Always replace the previous repository with the complete 7.10.6 repository. Do not merge old `adminWww` bundles or deleted role-security files back into this release. In particular, `nexowatt-role-security.js` and `build/lib/eosRoleSecurity.js` are obsolete and must stay absent.
4
4
 
5
5
  After a merge, run the package, stability, role-security and publish dry-run checks before publishing.
6
6
 
7
- The 7.10.5 publish workflow now removes all three obsolete 7.10.4 role-security files automatically before sealing and packaging, including when the ZIP was extracted over an existing working directory.
7
+ The 7.10.6 publish workflow now removes all three obsolete 7.10.4 role-security files automatically before sealing and packaging, including when the ZIP was extracted over an existing working directory.
@@ -1,32 +1,29 @@
1
1
  {
2
- "version": "7.10.5",
2
+ "version": "7.10.6",
3
3
  "channel": "stable-latest",
4
- "baseFrontend": "validated v84 runtime with authoritative RBAC, restored administrator rights and restart-safe navigation layout",
4
+ "baseFrontend": "validated v84 runtime with authoritative RBAC and End User read-only UI correction",
5
5
  "runtimeEntry": "v84",
6
- "releaseType": "stable-admin-rights-rbac-navigation",
7
- "release": "stable-admin-rights-rbac-navigation",
8
- "label": "v7-10-5",
6
+ "releaseType": "stable-enduser-readonly-system-info",
7
+ "release": "stable-enduser-readonly-system-info",
8
+ "label": "v7-10-6",
9
9
  "notes": [
10
- "Administrator authority is derived only from the authenticated backend security context; DOM text is never used to classify a role.",
11
- "Admin keeps full datapoint write access, all overview cards and reversible expert mode.",
12
- "Installer and End User do not see ioBroker Admin, XTerm, App Center, License, Simulation or account administration.",
13
- "End User can open Datapoints in read-only mode; backend socket writes are denied independently of the browser.",
14
- "Navigation visibility/order is stored in eos-admin.0.info.uiTabsVisible and no longer modifies system.config or restarts the adapter.",
15
- "Backup navigation is shown only while a supported backup instance is enabled."
10
+ "Administrator authority and all Admin controls remain unchanged.",
11
+ "End User datapoints remain visible but all edit, delete and settings actions are hidden.",
12
+ "End User datapoint writes remain denied by the backend role guard.",
13
+ "The End User system card receives read-only platform, RAM, Node.js and NPM information from an authenticated endpoint.",
14
+ "The restricted End User system-card info popup is removed to prevent permissionError dialogs."
16
15
  ],
17
16
  "changes": [
18
- "Removed the legacy DOM-text role heuristic that could downgrade system.user.admin to End User.",
19
- "Added explicit Admin bypass regression guards in source, backend runtime and frontend bundles.",
20
- "Added End User-only ObjectBrowser read-only wiring while retaining Admin/Installer native write controls.",
21
- "Moved menu layout persistence away from system.config into a dedicated adapter state.",
22
- "Hid Admin/XTerm cards only for restricted roles and forced them visible for Admin.",
23
- "Protected App Center, License and Simulation in the authenticated role layer and cleared inherited UI-admin sessions for non-admin roles."
17
+ "Added an authenticated read-only system information endpoint for restricted roles.",
18
+ "Added End User-only action-column suppression in the ObjectBrowser.",
19
+ "Kept the system.user.admin full-rights bypass untouched.",
20
+ "Raised the release and browser cache identity to 7.10.6 / 7106."
24
21
  ],
25
- "brandingCacheVersion": 7105,
26
- "shellCacheVersion": 7105,
27
- "nativeShellVersion": 7105,
28
- "shellCacheTag": "7105",
29
- "repositoryEntry": "nexowatt-eos-admin-repository-entry-v7-10-5.json",
22
+ "brandingCacheVersion": 7106,
23
+ "shellCacheVersion": 7106,
24
+ "nativeShellVersion": 7106,
25
+ "shellCacheTag": "7106",
26
+ "repositoryEntry": "nexowatt-eos-admin-repository-entry-v7-10-6.json",
30
27
  "autoUpdateCacheVersion": 7103,
31
28
  "autoUpdateCacheTag": "7103"
32
29
  }
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "format": 1,
3
3
  "package": "iobroker.eos-admin",
4
- "version": "7.10.5",
4
+ "version": "7.10.6",
5
5
  "algorithm": "sha256",
6
- "fileCount": 1389,
6
+ "fileCount": 1390,
7
7
  "trackedRoots": [
8
8
  "src",
9
9
  "build",
@@ -552,7 +552,7 @@
552
552
  "adminWww/img/le.png": "ef5ebb7112926f646e781a326b639f56888fafe0891b9b000178091b4f8ed9dd",
553
553
  "adminWww/img/logo.svg": "1167118074ff84d8cef82ad80c38609719dacfde9417126e46966c1ec986534b",
554
554
  "adminWww/img/no-image.svg": "25fc382f4ad3a36f8a637cd966b9107368e1f11906d706102ad5f37db6f57f34",
555
- "adminWww/index.html": "9358ac35e93087ed79e3c00ec54899fde92938c438eb86231328d5f08d3ea965",
555
+ "adminWww/index.html": "d0346434c12041cd85b105ef70afb347a2e4913ca116ce46551dd36ad319767a",
556
556
  "adminWww/js/adapter-settings.js": "fb2e538a3385899f7fd47275ec588051c735d8f778a44b89f40f5eb820a31dbc",
557
557
  "adminWww/js/eos-account-management.js": "dbba398605b2391ac1a7ec97cf7eb84da7f929ea16bfb6761750cd700a687fbe",
558
558
  "adminWww/js/eos-assistant.js": "be43f49fd5310d2962365035556c37109d4868856e874e1f964c4b2f05bb6beb",
@@ -563,11 +563,11 @@
563
563
  "adminWww/js/eos-manual-write-policy.js": "3c93487146b4fd5f681aa45a6bb137d9a91c3fa145ebfa94ec5ccb6b15498e8b",
564
564
  "adminWww/js/eos-native-security.js": "33098b98164623fc133314658bca2f622d19971795dd8bd3c90aca68598aab90",
565
565
  "adminWww/js/eos-policy-client.js": "5ffd32270307137fbec69a9b9bea57ca1d2e27ede987ce1eb37ff1df6677d8d2",
566
- "adminWww/js/eos-role-bootstrap.js": "f7f6f4c816cbf694f8e24d812a2aa8e7c84a42af6ad2274f44bf24debcfec63f",
567
- "adminWww/js/eos-role-ui.js": "93424c5959159dd44421365a277b26c2c941f7d418eac4eae36547364cc10afb",
566
+ "adminWww/js/eos-role-bootstrap.js": "4cc1da40837606c0176c50c2bb4561bae8e6733b7561e00e9b19ac10111463f2",
567
+ "adminWww/js/eos-role-ui.js": "d31b2ffbd6367bb8837ef139d44fb4091d644d2d18191ad3b28a17fbbadf7739",
568
568
  "adminWww/js/license.js": "13798e577c82d7a5549b07a244b8b8453ef43e53fc7789f565c35b56e6654007",
569
569
  "adminWww/js/listHeader.js": "ed336a68a64e16a062d1af2269428fd20a08a4b695f17635f55a18bc1ef693a4",
570
- "adminWww/js/nexowatt-native-shell.js": "c0d327669ba12ba3b8e6fc4d1a17eb7092e59a0b23a2852161714c2b214dde15",
570
+ "adminWww/js/nexowatt-native-shell.js": "5ebd9504d08764f48e926790fc1f187a45bf70b9cd8686897a53a1c3721e834f",
571
571
  "adminWww/js/tableEditor.js": "5508044619fec70071895d0ae3ab6ff75dd03bd936e7b133f98d098d4245ec20",
572
572
  "adminWww/js/translate.js": "264442c0f42a10148057125532bf55b7672c4cc051c28e7cbb922984a558f8d3",
573
573
  "adminWww/js/treeTable.js": "8abde0b7880a89f6f927a87bb041945dea1502f51bc9870d8ba0be9d3dd9eed8",
@@ -747,7 +747,7 @@
747
747
  "adminWww/static/js/html.js": "159b7192459d73d92761dab8c4d48e138e94e4d8e7bf99004bac257e403a0c3b",
748
748
  "adminWww/static/js/javascript.js": "6287a6b820c8707a0cd7b9e4545bcb023a8b9228569cfd21be6635d1409aabf4",
749
749
  "adminWww/static/js/nexowatt-stable-login.js": "ff0c6d4dc2086f3ab4be8ef455e5891a2ccb5f534bddfacbef2f5cd6ce65489e",
750
- "adminWww/static/js/nexowatt-stable-v7105.js": "35d329e37a698a71d2825fe1bcbcee4e1073249a59aa56a3c645cf9623461600",
750
+ "adminWww/static/js/nexowatt-stable-v7106.js": "a4a3e460cac1e028cc6a6a889e0a56c303df98cfa556a427cb5b47e0e3794496",
751
751
  "adminWww/static/js/worker-css.js": "83c767cacd6b190e2f083b139cb3f124d1b560afbd7a6dbb74bf5539aa4cadee",
752
752
  "adminWww/static/js/worker-html.js": "661d2448443c0089fba31d2829d77761a5fc042035c38433eff0e20707f17457",
753
753
  "adminWww/static/js/worker-javascript.js": "73fcf007e2d19eacba8f365719ee92d14345505b03f9cf66e6338aef02fccd21",
@@ -793,7 +793,7 @@
793
793
  "build/lib/translations.js.map": "c74bcf48d2dd6ec58c48d48a7fb39c59a84fd58c25095bc0cb5bb46c88cfe24f",
794
794
  "build/lib/utils.js": "b013a5df06f95ed5bfcb851bb87c0617f61f70e6fe7f1fbf2402fd4d0aadec9b",
795
795
  "build/lib/utils.js.map": "74238d0d82cc28d41c4f627b73793f6cda26b338ef1bd97916b6417783949e29",
796
- "build/lib/web.js": "8de94dffdd7c70be6b537c111691c831116338b311f7569739de57f9a32e071f",
796
+ "build/lib/web.js": "172f19ea7ccffada720f03271ff52d00457aaa44cbd7ce4dfe924013535a9ae6",
797
797
  "build/lib/web.js.map": "5fb9f337f3a27c04bb4303cb61ffa5f0da857299a7d2890609eb5f55f24f1789",
798
798
  "build/main.js": "7578ee14ea840950ad5164b0063c091c983528ebc32689dec5dc499062fbc92e",
799
799
  "build/main.js.map": "1cd3887da9b3d4061c59b6ad497c536c6c9a79938b10bbddf7128a1e7930dfbd",
@@ -850,11 +850,11 @@
850
850
  "src-admin/public/js/eos-manual-write-policy.js": "3c93487146b4fd5f681aa45a6bb137d9a91c3fa145ebfa94ec5ccb6b15498e8b",
851
851
  "src-admin/public/js/eos-native-security.js": "33098b98164623fc133314658bca2f622d19971795dd8bd3c90aca68598aab90",
852
852
  "src-admin/public/js/eos-policy-client.js": "5ffd32270307137fbec69a9b9bea57ca1d2e27ede987ce1eb37ff1df6677d8d2",
853
- "src-admin/public/js/eos-role-bootstrap.js": "f7f6f4c816cbf694f8e24d812a2aa8e7c84a42af6ad2274f44bf24debcfec63f",
854
- "src-admin/public/js/eos-role-ui.js": "93424c5959159dd44421365a277b26c2c941f7d418eac4eae36547364cc10afb",
853
+ "src-admin/public/js/eos-role-bootstrap.js": "4cc1da40837606c0176c50c2bb4561bae8e6733b7561e00e9b19ac10111463f2",
854
+ "src-admin/public/js/eos-role-ui.js": "d31b2ffbd6367bb8837ef139d44fb4091d644d2d18191ad3b28a17fbbadf7739",
855
855
  "src-admin/public/js/license.js": "13798e577c82d7a5549b07a244b8b8453ef43e53fc7789f565c35b56e6654007",
856
856
  "src-admin/public/js/listHeader.js": "ed336a68a64e16a062d1af2269428fd20a08a4b695f17635f55a18bc1ef693a4",
857
- "src-admin/public/js/nexowatt-native-shell.js": "c0d327669ba12ba3b8e6fc4d1a17eb7092e59a0b23a2852161714c2b214dde15",
857
+ "src-admin/public/js/nexowatt-native-shell.js": "5ebd9504d08764f48e926790fc1f187a45bf70b9cd8686897a53a1c3721e834f",
858
858
  "src-admin/public/js/tableEditor.js": "5508044619fec70071895d0ae3ab6ff75dd03bd936e7b133f98d098d4245ec20",
859
859
  "src-admin/public/js/translate.js": "264442c0f42a10148057125532bf55b7672c4cc051c28e7cbb922984a558f8d3",
860
860
  "src-admin/public/js/treeTable.js": "8abde0b7880a89f6f927a87bb041945dea1502f51bc9870d8ba0be9d3dd9eed8",
@@ -975,7 +975,7 @@
975
975
  "src-admin/public/manifest.json": "15244d5d50f08420fc5d4793e5699e99c7b900b6908cfbc00a7182f4d4db55bd",
976
976
  "src-admin/public/robots.txt": "90d24bc3bf698ac1e173739502298ccca72adf1f564fab05f484b8c48d1cadd2",
977
977
  "src-admin/public/static/js/nexowatt-stable-login.js": "ff0c6d4dc2086f3ab4be8ef455e5891a2ccb5f534bddfacbef2f5cd6ce65489e",
978
- "src-admin/public/static/js/nexowatt-stable-v7105.js": "35d329e37a698a71d2825fe1bcbcee4e1073249a59aa56a3c645cf9623461600",
978
+ "src-admin/public/static/js/nexowatt-stable-v7106.js": "a4a3e460cac1e028cc6a6a889e0a56c303df98cfa556a427cb5b47e0e3794496",
979
979
  "src-admin/src/App.tsx": "8ab367389c604d5face72cc71da49b08021ffa2e566db4d32df9ad98f9fe762a",
980
980
  "src-admin/src/Workers/AdaptersWorker.tsx": "3a2cdeb8010598c901df0e3cffcdae913e62e7ac7c84fcadf15cb7f961dc6ed9",
981
981
  "src-admin/src/Workers/GenericWorker.tsx": "3b3c6e7856602477c54d1dc085aa23b5cfcac7784cc73710b00622ac04ed5a97",
@@ -1323,7 +1323,7 @@
1323
1323
  "src-admin/src/tabs/Objects.tsx": "2b87a8a7e771e10e1cce49019c4be62578f10096eee5abd17d2685f5f41cc67c",
1324
1324
  "src-admin/src/tabs/Users.tsx": "45ed37e57b66f7e23eb465aef9ad9db55613b40bf44530ab81d6206806de102d",
1325
1325
  "src-admin/src/types.d.ts": "3cfac48af5f8416b55b89c0daca78499dbbd402c0b44cc661112b76953ba3344",
1326
- "src-admin/src/version.json": "13b5e66c3cd1fe6ee1f5f2cf0c4f921660dea2013644d05822ded200018dd14a",
1326
+ "src-admin/src/version.json": "8333ad3db33a8616fc0d4e5990a1a4fd0b1504868d5ec252550520ed5e5001b1",
1327
1327
  "src/i18n/de.json": "85d4ecfedf15d78984922b05377063b808ae8c5a75944af323e72a2c3a483d50",
1328
1328
  "src/i18n/en.json": "6a0156a1b026903821d395ef2ceef845e90531f323a218f97f5abefaabb46a23",
1329
1329
  "src/i18n/es.json": "54369f8044dfa222779849d2f158eb100188a43816d6c42a64575122cb528a30",
@@ -1350,7 +1350,7 @@
1350
1350
  "src/lib/testPassword.ts": "c627432e64b6ed40081e2828af207238bc9e9e1f8b823eaf20c7d3e059c5e938",
1351
1351
  "src/lib/translations.ts": "8fdb51d81c3f98e17e0231f6773381886eb1c68068a3f53dd5e32bf6b58f9d16",
1352
1352
  "src/lib/utils.ts": "5398da6c6a660c4300e2679aa5e001e05297d684cc39bdfab091375768169f30",
1353
- "src/lib/web.ts": "8eae6cc8dc6eb42bc7be5498f91e4064f35564355d7538cfa4d791e7b323ca5e",
1353
+ "src/lib/web.ts": "ca2a04d1bb1e2cd51bea6fc0f70355c963b9251121cfca539be97068b9f94187",
1354
1354
  "src/main.ts": "e9eb8013a229d9616be923850075e8cb5475bde32c882008721225ed37a85a8c",
1355
1355
  "src/types.d.ts": "12117a644a45cb0b551555184126563e80bf909726aa378c7d72327a30c61054",
1356
1356
  "tasks.mts": "84a396f8581e7e3ca499a1c4ce01d22ea29f81700520f804b48a95fb54d72408",
@@ -1378,7 +1378,7 @@
1378
1378
  "tools/nexowatt-internal-reserve-selftest.cjs": "f027a2272a4277d65167d68d4ca4428cd0c28a6c6c2b610eda575abd3f2bc90a",
1379
1379
  "tools/nexowatt-login-layout-selftest.cjs": "7d4baae82f1d53fc14446b8ef80aaffa39b0b3529821599f4a6e2c27fbc7a7f2",
1380
1380
  "tools/nexowatt-manual-write-policy-selftest.cjs": "a41057610972d681120bf35e0321029facc08b098c79da9b131980f80bd3fdce",
1381
- "tools/nexowatt-merge-update-selftest.cjs": "66d250def2c372cceb0fda42b0dc756557d8cdcf268f73a2ff7c68de4522e36a",
1381
+ "tools/nexowatt-merge-update-selftest.cjs": "a029a368a8d1363b3a9a120ac19105ac28986d159fce93e6ebc1c3deb0ee18ac",
1382
1382
  "tools/nexowatt-modern-ui-selftest.cjs": "0145adc4b7d84e996f227dee02c09f767ab9a29bb2151041a50b88bb27a5b93a",
1383
1383
  "tools/nexowatt-module-popup-selftest.cjs": "31f02e8cf0bfd61d7769e1095c93887a34cfbbd76a9805ef4931cea6dff53ddf",
1384
1384
  "tools/nexowatt-native-shell-selftest.cjs": "13aabd3a19f0c0422bbc1c676718685b77c88a526167a7b511fa6c9ab2ac860c",
@@ -1391,20 +1391,21 @@
1391
1391
  "tools/nexowatt-publish-channel-selftest.cjs": "c4efd1104ebe471ce1dc63195f322cffe760af295bf60f13b9766491acd0280e",
1392
1392
  "tools/nexowatt-release-defaults-selftest.cjs": "3e3c96ca774200461978c546d1a937cbae18d7f11497ed84dda639c2358f6e16",
1393
1393
  "tools/nexowatt-repair-eos-admin-update.cjs": "f28c1999b0f75139e582770ad649d17d11f9e909ac49d13c31be5fa5b36253e3",
1394
- "tools/nexowatt-role-access-selftest.cjs": "b855b69cb74a5124c9a5a22b811a5209f70f32979a776401897f7fe910f794e9",
1395
- "tools/nexowatt-role-security-selftest.cjs": "b5b21f3c80f69b03f9c95fb26e11b2706aac86534048ac7251a5275dfcbde6e2",
1394
+ "tools/nexowatt-role-access-selftest.cjs": "51a25973a41d066f421c9517515db4eb9abf737a5da6ee839089ae3e59688bb7",
1395
+ "tools/nexowatt-role-security-selftest.cjs": "a7ab0513d8d7fc232561962554db27ce00e32d4a6b04af088ba5baef6d2f6dd5",
1396
1396
  "tools/nexowatt-runtime-cleanup-selftest.cjs": "f317b09aa0c51ffe7e1b5eaf10c52c886804ec6e8084967cd88e4ebece6ecfb5",
1397
- "tools/nexowatt-stability-check.cjs": "087c74c3f050ebfe3b092cc74a4b99b6e66813d57b0d2065f92fbddcb9e2ed9e",
1397
+ "tools/nexowatt-stability-check.cjs": "2df8d43fa2b5b78b72c71781a85bfc2583e716654b7f23c985dae238dcc04092",
1398
1398
  "tools/nexowatt-stable-v7101-selftest.cjs": "817d09861ef29c52a67f64ec5b8f4ad4654ce7e6486eded786bb16f3c773eaf8",
1399
1399
  "tools/nexowatt-stable-v7102-selftest.cjs": "75baab5f8069569ad4896e5018f3c5ccbbda2c2297aca5c5146bce94f9cf795d",
1400
- "tools/nexowatt-stable-v7103-selftest.cjs": "80491789e636375c21e22335de08c8b4892c056e3fb703f1d5368e81105074b0",
1400
+ "tools/nexowatt-stable-v7103-selftest.cjs": "20e0be31811dfa61772a2438085ae1a83d6e009330b01fcea5a4320f15586406",
1401
1401
  "tools/nexowatt-stable-v94-selftest.cjs": "5226881b3ad8918c67921ffb37716490f053ec88e7c0f24827a5eda7c75d4019",
1402
1402
  "tools/nexowatt-stable-v95-selftest.cjs": "0b15fcd329eb2994e64c407ab04eaafab7c38c4688136c197bf9601e1c35ee07",
1403
1403
  "tools/nexowatt-stable-v97-selftest.cjs": "4f50ad6e53b8de7eb045d56657cccd846883eacd8a877d51240d78153ba53d80",
1404
1404
  "tools/nexowatt-sync-release-version.cjs": "2478d714533ece21a275071ef6e5467f73c2fa33d0a63d76f408dc048a86c6f6",
1405
1405
  "tools/nexowatt-ui-overview-runtime-selftest.cjs": "83255e5d3c9a548013f6e9a74706644d15d98450d0bfa2eb3da83c740d8618ea",
1406
1406
  "tools/nexowatt-update-selftest.cjs": "c38c454135f98de683de8fa15fc4b9032063823f0f55fcfc8b675f551fd342f5",
1407
- "tools/nexowatt-validate-package.cjs": "4995d6db92d59ba4cdb1ed6481304deae348f644064e86fbf81384405e36b851",
1407
+ "tools/nexowatt-user-area-selftest.cjs": "8c1c86c0b3de59f09ad866bbda0e2d8702896f56a4593bbbdb540d3eceef673b",
1408
+ "tools/nexowatt-validate-package.cjs": "97de7ed0308d88d9db0401136acde98136907fb2ae4481a5e08ed57dbb6b6a34",
1408
1409
  "tools/nexowatt-value-column-selftest.cjs": "29d0a9bbea05a87dcf8ee09c86cc81acb6c59e1e34801890768f5e342083871a",
1409
1410
  "tools/nexowatt-version-sync-selftest.cjs": "65d7c8634b6d5581f337365e13a1a9432c7d47dbf5aebc237886730c32ba5e94",
1410
1411
  "tsconfig.build.json": "d3a31263975a13de77b97af9ff246d89931f3abb594047be2739cf11378b97f5",
@@ -1,8 +1,8 @@
1
- # NPM publication 7.10.5
1
+ # NPM publication 7.10.6
2
2
 
3
3
  1. Use a freshly extracted repository ZIP.
4
4
  2. Run `npm publish --dry-run`.
5
- 3. Confirm version `7.10.5`, complete `build/` runtime and all active `adminWww/assets/*-v84.js` files.
5
+ 3. Confirm version `7.10.6`, complete `build/` runtime and all active `adminWww/assets/*-v84.js` files.
6
6
  4. Publish with `npm publish` only after the dry run succeeds.
7
7
 
8
8
  No `npm install`, `npm ci`, `tsc` or `tsx` is required for the sealed prebuilt release.
@@ -1,4 +1,4 @@
1
- # NexoWatt EOS Admin 7.10.5 – stability and RBAC baseline
1
+ # NexoWatt EOS Admin 7.10.6 – stability and RBAC baseline
2
2
 
3
3
  This release retains the validated 7.10.2–7.10.4 crash, package and update-placement fixes. Role decisions now come exclusively from the authenticated `/nexowatt/security/context` response. The removed heuristic must never be restored.
4
4
 
@@ -1,4 +1,4 @@
1
- # Release Acceptance 7.10.5
1
+ # Release Acceptance 7.10.6
2
2
 
3
3
  - [ ] Admin can write every normally writable datapoint.
4
4
  - [ ] Admin can enable and disable expert mode repeatedly.
@@ -0,0 +1,14 @@
1
+ # NexoWatt EOS Admin 7.10.6
2
+
3
+ ## Endkundenbereich
4
+
5
+ - Die Datenpunktansicht bleibt für Endkunden lesbar, blendet aber Bearbeiten-, Löschen- und Einstellungsaktionen vollständig aus.
6
+ - Schreibbefehle bleiben zusätzlich serverseitig gesperrt.
7
+ - Die Systeminformationskarte erhält Plattform, RAM, Node.js und NPM über einen authentifizierten Nur-Lese-Endpunkt.
8
+ - Der fehlerhafte Info-Dialog mit `permissionError` wird für Endkunden nicht mehr angeboten.
9
+ - Administratorrechte und die bestehende Admin-Oberfläche bleiben unverändert und vollständig verfügbar.
10
+
11
+ ## Veröffentlichung
12
+
13
+ - Neue npm-Version 7.10.6, da 7.10.5 bereits veröffentlicht wurde.
14
+ - Release-Dateien, Cache-Tags, Repository-Eintrag und versiegeltes Prebuilt-Artefakt sind auf 7.10.6 synchronisiert.
@@ -1,4 +1,4 @@
1
- # NexoWatt EOS role matrix 7.10.5
1
+ # NexoWatt EOS role matrix 7.10.6
2
2
 
3
3
  | Capability | Admin | Installer | End User |
4
4
  |---|---:|---:|---:|
@@ -8,7 +8,7 @@
8
8
  <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
9
9
  <meta http-equiv="Pragma" content="no-cache" />
10
10
  <meta http-equiv="Expires" content="0" />
11
- <script src="./js/eos-manual-write-policy.js?v=7105"></script>
11
+ <script src="./js/eos-manual-write-policy.js?v=7106"></script>
12
12
  <script type="module" src="./assets/hostInit-v84.js?v=84"></script>
13
13
 
14
14
  <meta charset="utf-8" />
@@ -36,8 +36,8 @@
36
36
  rel="stylesheet"
37
37
  href="css/leaflet.css"
38
38
  />
39
- <link rel="stylesheet" href="./css/nexowatt-native-shell.css?v=7105" />
40
- <link rel="stylesheet" href="./css/eos-ems-overview.css?v=7105" />
39
+ <link rel="stylesheet" href="./css/nexowatt-native-shell.css?v=7106" />
40
+ <link rel="stylesheet" href="./css/eos-ems-overview.css?v=7106" />
41
41
  <link rel="stylesheet" href="./css/eos-auto-update.css?v=7103" />
42
42
  <link
43
43
  rel="manifest"
@@ -160,22 +160,22 @@
160
160
  </script>
161
161
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-BDBacUwf.js">
162
162
  <link rel="modulepreload" crossorigin href="./assets/iobroker_admin__mf_v__runtimeInit__mf_v__-g2X2zhAf.js">
163
- <script defer src="./js/eos-role-bootstrap.js?v=7105" data-eos-entry="./assets/index-CQZugZ1z-v84.js?v=84"></script>
164
- <script defer src="./js/eos-policy-client.js?v=7105"></script>
165
- <script defer src="./js/eos-branding-sanitizer.js?v=7105"></script>
166
- <script defer src="./js/nexowatt-native-shell.js?v=7105"></script>
167
- <script defer src="./js/eos-native-security.js?v=7105"></script>
168
- <script defer src="./js/eos-basic-settings.js?v=7105"></script>
169
- <script defer src="./js/eos-role-ui.js?v=7105"></script>
170
- <script defer src="./js/eos-ems-overview.js?v=7105"></script>
163
+ <script defer src="./js/eos-role-bootstrap.js?v=7106" data-eos-entry="./assets/index-CQZugZ1z-v84.js?v=84"></script>
164
+ <script defer src="./js/eos-policy-client.js?v=7106"></script>
165
+ <script defer src="./js/eos-branding-sanitizer.js?v=7106"></script>
166
+ <script defer src="./js/nexowatt-native-shell.js?v=7106"></script>
167
+ <script defer src="./js/eos-native-security.js?v=7106"></script>
168
+ <script defer src="./js/eos-basic-settings.js?v=7106"></script>
169
+ <script defer src="./js/eos-role-ui.js?v=7106"></script>
170
+ <script defer src="./js/eos-ems-overview.js?v=7106"></script>
171
171
 
172
172
  <script defer src="./js/eos-auto-update.js?v=7103"></script>
173
- <script defer src="./js/eos-assistant.js?v=7105"></script>
173
+ <script defer src="./js/eos-assistant.js?v=7106"></script>
174
174
  </head>
175
175
  <body>
176
176
  <noscript>Für NexoWatt EOS muss JavaScript aktiviert sein.</noscript>
177
177
  <div id="root"></div>
178
- <script defer src="static/js/nexowatt-stable-login.js?v=7105"></script>
179
- <script defer src="static/js/nexowatt-stable-v7105.js?v=7105"></script>
178
+ <script defer src="static/js/nexowatt-stable-login.js?v=7106"></script>
179
+ <script defer src="static/js/nexowatt-stable-v7106.js?v=7106"></script>
180
180
  </body>
181
181
  </html>
@@ -1,7 +1,7 @@
1
1
  (() => {
2
2
  'use strict';
3
3
 
4
- const VERSION = 'v7105-admin-authoritative-rbac';
4
+ const VERSION = 'v7106-admin-authoritative-rbac';
5
5
  const script = document.currentScript || document.querySelector('script[src*="eos-role-bootstrap.js"]');
6
6
  const entry = script?.dataset?.eosEntry || '';
7
7
  let launched = false;
@@ -1,7 +1,7 @@
1
1
  (() => {
2
2
  'use strict';
3
3
 
4
- const VERSION = 'v7105-admin-authoritative-rbac';
4
+ const VERSION = 'v7106-admin-authoritative-rbac';
5
5
  window.NEXOWATT_EOS_ROLE_UI_VERSION = VERSION;
6
6
 
7
7
  const state = {
@@ -15,10 +15,13 @@
15
15
  reserveObserver: null,
16
16
  reservePaper: null,
17
17
  reserveScheduled: false,
18
+ readonlySystemInfo: null,
19
+ readonlySystemInfoPromise: null,
18
20
  };
19
21
  const abort = new AbortController();
20
22
 
21
23
  const safe = fn => { try { return fn(); } catch (_) { return undefined; } };
24
+ const escapeHtml = value => String(value ?? '').replace(/[&<>"']/g, match => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[match] || match));
22
25
  const normalize = value => String(value || '')
23
26
  .toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/ß/g, 'ss')
24
27
  .replace(/[^a-z0-9#/_:.-]+/g, ' ').trim();
@@ -268,6 +271,55 @@
268
271
  role.setAttribute('data-nexowatt-overview-role', state.role);
269
272
  }
270
273
  };
274
+
275
+ const fetchReadonlySystemInfo = () => {
276
+ if (state.readonlySystemInfo) return Promise.resolve(state.readonlySystemInfo);
277
+ if (state.readonlySystemInfoPromise) return state.readonlySystemInfoPromise;
278
+ state.readonlySystemInfoPromise = fetch('/nexowatt/readonly/system-info', {
279
+ credentials: 'same-origin',
280
+ cache: 'no-store',
281
+ headers: { Accept: 'application/json' },
282
+ })
283
+ .then(response => (response.ok ? response.json() : null))
284
+ .then(data => {
285
+ state.readonlySystemInfo = data && typeof data === 'object' ? data : null;
286
+ return state.readonlySystemInfo;
287
+ })
288
+ .catch(() => null)
289
+ .finally(() => {
290
+ state.readonlySystemInfoPromise = null;
291
+ scheduleApply();
292
+ });
293
+ return state.readonlySystemInfoPromise;
294
+ };
295
+ const applyReadonlySystemInfoCard = () => safe(() => {
296
+ if (state.role !== 'enduser' || currentRoute() !== 'tab-intro') return;
297
+ const paper = appPaper();
298
+ if (!paper) return;
299
+ const title = Array.from(paper.querySelectorAll('h1,h2,h3,h4,h5,h6')).find(node => normalize(node.textContent || '') === 'nexowatt');
300
+ const card = title?.closest?.('.MuiCard-root');
301
+ if (!card || !/platform|ram|node\.js|npm/i.test(String(card.textContent || ''))) return;
302
+ Array.from(card.querySelectorAll('button')).forEach(button => {
303
+ if (/info/i.test(textOf(button))) {
304
+ button.classList.add('eos-role-hidden');
305
+ button.setAttribute('aria-hidden', 'true');
306
+ button.disabled = true;
307
+ }
308
+ });
309
+ if (!state.readonlySystemInfo && !state.readonlySystemInfoPromise) {
310
+ void fetchReadonlySystemInfo();
311
+ return;
312
+ }
313
+ const data = state.readonlySystemInfo;
314
+ const list = card.querySelector('ul');
315
+ if (!data || !list) return;
316
+ list.innerHTML = `
317
+ <li><span><span style="font-weight:600">Platform: </span>${escapeHtml(data.platform || '--')}</span></li>
318
+ <li><span><span style="font-weight:600">RAM: </span>${escapeHtml(Number.isFinite(Number(data.ramMb)) ? `${Math.round(Number(data.ramMb))} MB` : '--')}</span></li>
319
+ <li><span><span style="font-weight:600">Node.js: </span>${escapeHtml(data.nodejs || '--')}</span></li>
320
+ <li><span><span style="font-weight:600">NPM: </span>${escapeHtml(data.npm || '--')}</span></li>`;
321
+ });
322
+
271
323
  const hideIntroEditControls = () => {
272
324
  const paper = appPaper();
273
325
  if (!paper) return;
@@ -494,7 +546,7 @@
494
546
  const scrubInheritedUiAdminSession = () => safe(() => {
495
547
  if (state.role === 'admin' || state.role === 'unknown') return;
496
548
  const user = String(state.policy?.user || state.policy?.userId || '').replace(/^system\.user\./, '') || state.role;
497
- const key = `eosUiAdminSessionScrubbed:v7105:${user}:${state.role}`;
549
+ const key = `eosUiAdminSessionScrubbed:v7106:${user}:${state.role}`;
498
550
  if (sessionStorage.getItem(key) === '1') return;
499
551
  sessionStorage.setItem(key, '1');
500
552
  const frame = document.createElement('iframe');
@@ -511,11 +563,38 @@
511
563
  if (!paper) return;
512
564
  const readonly = state.role === 'enduser' && currentRoute() === 'tab-objects';
513
565
  paper.toggleAttribute('data-eos-datapoints-readonly', readonly);
566
+ const clearControl = control => {
567
+ if (!control) return;
568
+ control.removeAttribute('aria-disabled');
569
+ control.removeAttribute('data-eos-enduser-write-blocked');
570
+ control.removeAttribute('data-eos-enduser-action-hidden');
571
+ control.classList.remove('eos-role-hidden');
572
+ control.removeAttribute('aria-hidden');
573
+ if ('disabled' in control) control.disabled = false;
574
+ };
575
+ paper.querySelectorAll('[data-eos-enduser-write-blocked="1"],[data-eos-enduser-action-hidden="1"]').forEach(clearControl);
514
576
  if (!readonly) return;
515
- paper.querySelectorAll('[data-eos-object-writable="1"],button[title*="edit" i],button[title*="delete" i],button[aria-label*="edit" i],button[aria-label*="delete" i]').forEach(control => {
577
+ const blockControl = control => {
578
+ if (!control) return;
516
579
  control.setAttribute('aria-disabled', 'true');
517
580
  control.setAttribute('data-eos-enduser-write-blocked', '1');
518
- });
581
+ };
582
+ const hideControl = control => {
583
+ if (!control) return;
584
+ control.setAttribute('aria-disabled', 'true');
585
+ control.setAttribute('data-eos-enduser-action-hidden', '1');
586
+ control.classList.add('eos-role-hidden');
587
+ control.setAttribute('aria-hidden', 'true');
588
+ if ('disabled' in control) control.disabled = true;
589
+ };
590
+ paper.querySelectorAll('[data-eos-object-writable="1"]').forEach(blockControl);
591
+ paper.querySelectorAll([
592
+ 'button[title*="edit" i]','button[title*="delete" i]','button[title*="remove" i]','button[title*="setting" i]','button[title*="einstell" i]',
593
+ 'button[aria-label*="edit" i]','button[aria-label*="delete" i]','button[aria-label*="remove" i]','button[aria-label*="setting" i]','button[aria-label*="einstell" i]',
594
+ '[role="button"][title*="edit" i]','[role="button"][title*="delete" i]','[role="button"][title*="setting" i]',
595
+ '[role="button"][aria-label*="edit" i]','[role="button"][aria-label*="delete" i]','[role="button"][aria-label*="setting" i]'
596
+ ].join(',')).forEach(hideControl);
597
+ paper.querySelectorAll('svg[data-testid*="Edit"],svg[data-testid*="Delete"],svg[data-testid*="Settings"],svg[data-testid*="Tune"],svg[data-testid*="Build"]').forEach(icon => hideControl(icon.closest('button,[role="button"]')));
519
598
  });
520
599
  const clearLegacyHeuristicRestrictionsForAdmin = () => safe(() => {
521
600
  if (state.role !== 'admin') return;
@@ -524,9 +603,10 @@
524
603
  element.removeAttribute('aria-hidden');
525
604
  element.style.removeProperty('display');
526
605
  });
527
- document.querySelectorAll('[data-eos-readonly],[data-eos-enduser-write-blocked]').forEach(element => {
606
+ document.querySelectorAll('[data-eos-readonly],[data-eos-enduser-write-blocked],[data-eos-enduser-action-hidden]').forEach(element => {
528
607
  element.removeAttribute('data-eos-readonly');
529
608
  element.removeAttribute('data-eos-enduser-write-blocked');
609
+ element.removeAttribute('data-eos-enduser-action-hidden');
530
610
  element.removeAttribute('aria-disabled');
531
611
  element.style.removeProperty('pointer-events');
532
612
  element.style.removeProperty('opacity');
@@ -544,6 +624,7 @@
544
624
  clearLegacyHeuristicRestrictionsForAdmin();
545
625
  redirectIfNeeded();
546
626
  ensureSafeOverview();
627
+ applyReadonlySystemInfoCard();
547
628
  filterNativeUsersPage();
548
629
  hideOfficialReserveSurfaces();
549
630
  applyEndUserDatapointPolicy();
@@ -1,7 +1,7 @@
1
1
  (() => {
2
2
  'use strict';
3
3
 
4
- const VERSION = 'v7105-nexowatt-native-shell-native-overview';
4
+ const VERSION = 'v7106-nexowatt-native-shell-native-overview';
5
5
  const previous = window.NEXOWATT_NATIVE_SHELL;
6
6
  if (previous?.version === VERSION) return;
7
7
  previous?.destroy?.();
@@ -1,6 +1,6 @@
1
1
  (() => {
2
2
  'use strict';
3
- const VERSION = 'v7105-scroll-standard-password';
3
+ const VERSION = 'v7106-scroll-standard-password';
4
4
  const ensureScroll = () => {
5
5
  const root = document.documentElement;
6
6
  const paper = document.getElementById('app-paper');
package/build/lib/web.js CHANGED
@@ -8,6 +8,7 @@ const node_util_1 = require("node:util");
8
8
  const node_path_1 = require("node:path");
9
9
  const node_os_1 = require("node:os");
10
10
  const node_stream_1 = require("node:stream");
11
+ const node_child_process_1 = require("node:child_process");
11
12
  const compression = require("compression");
12
13
  const mime_1 = require("mime");
13
14
  const node_zlib_1 = require("node:zlib");
@@ -1371,6 +1372,35 @@ class Web {
1371
1372
  this.adapter.log.info(`EOS installer basic settings updated by ${access.userId || 'unknown user'}`);
1372
1373
  await this.sendEosBasicSettings(req, res);
1373
1374
  }
1375
+
1376
+ getEosReadonlySystemInfo() {
1377
+ let npm = '--';
1378
+ try {
1379
+ const binary = process.platform === 'win32' ? 'npm.cmd' : 'npm';
1380
+ npm = (0, node_child_process_1.execFileSync)(binary, ['-v'], { encoding: 'utf8', timeout: 1500 }).trim() || '--';
1381
+ }
1382
+ catch {
1383
+ // ignore
1384
+ }
1385
+ return {
1386
+ platform: process.platform || '--',
1387
+ ramMb: Math.round((0, node_os_1.totalmem)() / 1024 / 1024),
1388
+ nodejs: process.version || '--',
1389
+ npm,
1390
+ active: true,
1391
+ };
1392
+ }
1393
+ async sendEosReadonlySystemInfo(req, res) {
1394
+ const access = await this.getEosRequestAccess(req);
1395
+ const authenticated = !this.settings.auth || !!access.userId;
1396
+ if (!authenticated) {
1397
+ res.status(401).json({ error: 'authenticationRequired' });
1398
+ return;
1399
+ }
1400
+ res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
1401
+ res.setHeader('Content-Type', 'application/json; charset=utf-8');
1402
+ res.status(200).json(this.getEosReadonlySystemInfo());
1403
+ }
1374
1404
  async sendEosSecuritySession(req, res) {
1375
1405
  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
1376
1406
  res.setHeader('Content-Type', 'application/json; charset=utf-8');
@@ -1806,6 +1836,10 @@ class Web {
1806
1836
  this.server.app.get('/eos/security/status', sendSecuritySession);
1807
1837
  this.server.app.get('/nexowatt/security/session', sendSecuritySession);
1808
1838
  this.server.app.get('/nexowatt/security/context', sendSecuritySession);
1839
+ this.server.app.get('/nexowatt/readonly/system-info', (req, res) => { void this.sendEosReadonlySystemInfo(req, res).catch(e => {
1840
+ this.adapter.log.warn(`Cannot read EOS readonly system info: ${e instanceof Error ? e.message : e}`);
1841
+ res.status(500).json({ error: 'readonlySystemInfoFailed' });
1842
+ }); });
1809
1843
  this.server.app.get('/nexowatt/role-settings/basic', (req, res) => {
1810
1844
  void this.sendEosBasicSettings(req, res).catch(e => {
1811
1845
  this.adapter.log.warn(`Cannot read EOS basic settings: ${e instanceof Error ? e.message : e}`);
package/io-package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "eos-admin",
4
- "version": "7.10.5",
4
+ "version": "7.10.6",
5
5
  "titleLang": {
6
6
  "en": "NexoWatt EOS Admin",
7
7
  "de": "NexoWatt EOS Admin",
@@ -18,6 +18,11 @@
18
18
  "connectionType": "local",
19
19
  "dataSource": "push",
20
20
  "news": {
21
+ "7.10.6": {
22
+ "de": "Stable 7.10.6 bereinigt ausschließlich den Endkundenbereich: Datenpunkte bleiben sichtbar und nur lesbar, Bearbeiten-/Löschen-/Einstellungsaktionen werden ausgeblendet, und die Systeminfokarte erhält Plattform, RAM, Node.js und NPM über einen authentifizierten Nur-Lese-Endpunkt. Die Administratoroberfläche und sämtliche Adminrechte bleiben unverändert.",
23
+ "en": "Stable 7.10.6 cleans up the End User area only: datapoints stay visible and read-only, edit/delete/settings actions are hidden, and the system information card receives platform, RAM, Node.js and NPM through an authenticated read-only endpoint. The administrator UI and all Admin rights remain unchanged.",
24
+ "nl": "Stable 7.10.6 ruimt uitsluitend het eindgebruikersgedeelte op: datapunten blijven zichtbaar en alleen-lezen, bewerk-/verwijder-/instellingsacties worden verborgen en de systeeminformatiekaart ontvangt platform, RAM, Node.js en NPM via een geauthenticeerd alleen-lezen eindpunt. De beheerdersinterface en alle beheerdersrechten blijven ongewijzigd."
25
+ },
21
26
  "7.10.5": {
22
27
  "de": "Stable 7.10.5 stellt die vollständigen Administratorrechte wieder her und trennt die Rollen verbindlich über den authentifizierten Backend-Kontext. Admin darf Datenpunkte schreiben, den Expertenmodus in beide Richtungen schalten und sieht Admin-/XTerm-Kacheln. Endkunden sehen Datenpunkte ausschließlich lesend; App-Center, Lizenz, Simulation, Benutzerverwaltung, ioBroker Admin, XTerm und Expertenmodus bleiben für Installateur und Endkunde gesperrt. Navigationsänderungen werden neustartsicher im Adapter-State gespeichert; Sicherung erscheint nur bei aktiver Backup-Instanz.",
23
28
  "en": "Stable 7.10.5 restores full administrator authority and binds roles exclusively to the authenticated backend context. Admin can write datapoints, toggle expert mode in both directions and sees the Admin/XTerm cards. End users can view datapoints read-only; App Center, License, Simulation, account management, ioBroker Admin, XTerm and expert mode remain blocked for Installer and End User. Navigation changes are stored restart-safely in an adapter state, and Backup is shown only for an enabled backup instance.",
@@ -354,7 +359,7 @@
354
359
  "icon": "admin.svg",
355
360
  "messagebox": true,
356
361
  "enabled": true,
357
- "extIcon": "https://unpkg.com/iobroker.eos-admin@7.10.5/admin/admin.svg",
362
+ "extIcon": "https://unpkg.com/iobroker.eos-admin@7.10.6/admin/admin.svg",
358
363
  "keywords": [
359
364
  "NexoWatt",
360
365
  "EOS",
@@ -365,7 +370,7 @@
365
370
  "licensed"
366
371
  ],
367
372
  "compact": true,
368
- "readme": "https://unpkg.com/iobroker.eos-admin@7.10.5/README.md",
373
+ "readme": "https://unpkg.com/iobroker.eos-admin@7.10.6/README.md",
369
374
  "authors": [
370
375
  "NexoWatt"
371
376
  ],
@@ -433,7 +438,7 @@
433
438
  "nondeletable": false,
434
439
  "allowAdapterUpdate": true,
435
440
  "allowAdapterDelete": false,
436
- "meta": "https://unpkg.com/iobroker.eos-admin@7.10.5/io-package.json",
441
+ "meta": "https://unpkg.com/iobroker.eos-admin@7.10.6/io-package.json",
437
442
  "npmPackage": "iobroker.eos-admin",
438
443
  "packetName": "iobroker.eos-admin",
439
444
  "publisher": "NexoWatt"
@@ -1210,5 +1215,5 @@
1210
1215
  }
1211
1216
  }
1212
1217
  },
1213
- "version": "7.10.5"
1218
+ "version": "7.10.6"
1214
1219
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "iobroker.eos-admin",
3
3
  "description": "NexoWatt EOS Admin – repaired stable baseline with restart-safe automatic updates, native account passwords and persistent cockpit scrolling.",
4
- "version": "7.10.5",
4
+ "version": "7.10.6",
5
5
  "contributors": [
6
6
  "bluefox <dogafox@gmail.com>",
7
7
  "apollon77",
@@ -133,15 +133,16 @@
133
133
  "NEXOWATT_EOS_PREBUILT_MANIFEST.json",
134
134
  "tools/nexowatt-prebuilt-release-selftest.cjs",
135
135
  "tools/nexowatt-stable-v7103-selftest.cjs",
136
- "README_STABILITY_V7.10.5.md",
137
- "RELEASE_NOTES_V7.10.5.md",
138
- "PUBLISH_STABLE_V7.10.5.md",
139
- "INSTALL_TEST_V7.10.5.md",
140
- "RELEASE_ACCEPTANCE_V7.10.5.md",
141
- "MERGE_UPDATE_README_V7.10.5.md",
136
+ "README_STABILITY_V7.10.6.md",
137
+ "RELEASE_NOTES_V7.10.6.md",
138
+ "PUBLISH_STABLE_V7.10.6.md",
139
+ "INSTALL_TEST_V7.10.6.md",
140
+ "RELEASE_ACCEPTANCE_V7.10.6.md",
141
+ "MERGE_UPDATE_README_V7.10.6.md",
142
142
  "tools/nexowatt-auto-update-placement-selftest.cjs",
143
143
  "tools/nexowatt-role-security-selftest.cjs",
144
- "SECURITY_ROLE_MATRIX_V7.10.5.md"
144
+ "SECURITY_ROLE_MATRIX_V7.10.6.md",
145
+ "tools/nexowatt-user-area-selftest.cjs"
145
146
  ],
146
147
  "scripts": {
147
148
  "npm": "npm i -f && cd src-admin && npm i -f",
@@ -176,7 +177,7 @@
176
177
  "nexowatt:repo-entry": "node tools/nexowatt-generate-repo-entry.cjs",
177
178
  "nexowatt:patch-repo": "node tools/nexowatt-patch-repo.cjs",
178
179
  "nexowatt:repair-update": "node tools/nexowatt-repair-eos-admin-update.cjs",
179
- "check:eos-stability": "node tools/nexowatt-stability-check.cjs && node tools/nexowatt-esm-syntax-selftest.cjs && node tools/nexowatt-backend-runtime-selftest.cjs && node tools/nexowatt-prebuilt-release-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-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 && node tools/nexowatt-password-write-selftest.cjs && node tools/nexowatt-account-password-flow-selftest.cjs && npm run check:eos-stable-v7103 && node tools/nexowatt-ems-overview-selftest.cjs && node tools/nexowatt-ui-overview-runtime-selftest.cjs && node tools/nexowatt-auto-update-selftest.cjs && node tools/nexowatt-auto-update-placement-selftest.cjs && node tools/nexowatt-role-security-selftest.cjs",
180
+ "check:eos-stability": "node tools/nexowatt-stability-check.cjs && node tools/nexowatt-esm-syntax-selftest.cjs && node tools/nexowatt-backend-runtime-selftest.cjs && node tools/nexowatt-prebuilt-release-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-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 && node tools/nexowatt-password-write-selftest.cjs && node tools/nexowatt-account-password-flow-selftest.cjs && npm run check:eos-stable-v7103 && node tools/nexowatt-ems-overview-selftest.cjs && node tools/nexowatt-ui-overview-runtime-selftest.cjs && node tools/nexowatt-auto-update-selftest.cjs && node tools/nexowatt-auto-update-placement-selftest.cjs && node tools/nexowatt-role-security-selftest.cjs && node tools/nexowatt-user-area-selftest.cjs",
180
181
  "nexowatt:patch-built-frontend": "node tools/nexowatt-patch-built-frontend.cjs",
181
182
  "clean:eos-runtime": "node tools/nexowatt-clean-legacy-runtime.cjs",
182
183
  "precheck:eos-package": "npm run sync:eos-version && npm run prepare:eos-release-defaults && npm run clean:eos-runtime",
@@ -216,7 +217,7 @@
216
217
  },
217
218
  "nexowattReleasePolicy": {
218
219
  "distTag": "latest",
219
- "purpose": "accepted stable NexoWatt EOS admin-rights and RBAC correction 7.10.5"
220
+ "purpose": "accepted stable NexoWatt EOS End User read-only UI and system information correction 7.10.6"
220
221
  },
221
222
  "publisher": "NexoWatt"
222
223
  }
@@ -16,7 +16,7 @@ for (const file of [
16
16
  'MERGE_UPDATE.ps1',
17
17
  'MERGE_UPDATE.cmd',
18
18
  'MERGE_UPDATE.sh',
19
- 'MERGE_UPDATE_README_V7.10.5.md',
19
+ 'MERGE_UPDATE_README_V7.10.6.md',
20
20
  'tools/nexowatt-apply-ems-overview.cjs',
21
21
  'tools/nexowatt-sync-release-version.cjs',
22
22
  'tools/nexowatt-version-sync-selftest.cjs',
@@ -16,6 +16,8 @@ const roleUi = read('adminWww/js/eos-role-ui.js');
16
16
  const sourceRoleUi = read('src-admin/public/js/eos-role-ui.js');
17
17
  const sourceMain = read('src/main.ts');
18
18
  const builtMain = read('build/main.js');
19
+ const webSource = read('src/lib/web.ts');
20
+ const webBuilt = read('build/lib/web.js');
19
21
  const appSource = read('src-admin/src/App.tsx');
20
22
  const objectsSource = read('src-admin/src/tabs/Objects.tsx');
21
23
  const introSource = read('src-admin/src/tabs/Intro.tsx');
@@ -30,9 +32,9 @@ const cleanupSource = read('tools/nexowatt-clean-legacy-runtime.cjs');
30
32
  // visible header happened to contain "user". Only authenticated backend policy may define the role.
31
33
  for (const html of [index, sourceIndex]) {
32
34
  assert.doesNotMatch(html, /nexowatt-role-security\.js/i, 'legacy heuristic role guard is still loaded');
33
- assert.match(html, /eos-role-bootstrap\.js\?v=7105/, 'authoritative role bootstrap cache tag is missing');
34
- assert.match(html, /eos-policy-client\.js\?v=7105/, 'authoritative policy client cache tag is missing');
35
- assert.match(html, /eos-role-ui\.js\?v=7105/, 'authoritative role UI cache tag is missing');
35
+ assert.match(html, /eos-role-bootstrap\.js\?v=7106/, 'authoritative role bootstrap cache tag is missing');
36
+ assert.match(html, /eos-policy-client\.js\?v=7106/, 'authoritative policy client cache tag is missing');
37
+ assert.match(html, /eos-role-ui\.js\?v=7106/, 'authoritative role UI cache tag is missing');
36
38
  }
37
39
  assert.equal(fs.existsSync(path.join(root, 'adminWww/nexowatt-role-security.js')), false, 'legacy runtime still exists');
38
40
  assert.equal(fs.existsSync(path.join(root, 'build/lib/eosRoleSecurity.js')), false, 'legacy backend heuristic still exists');
@@ -128,4 +130,20 @@ assert.ok((io.instanceObjects || []).some(object => object?._id === 'info.uiTabs
128
130
  assert.match(drawerSource, /backupAdapters\.has\(adapterName\) && instance\.enabled !== true/);
129
131
  assert.match(builtDrawer, /o\.has\(A\)&&d\.enabled!==!0/);
130
132
 
133
+ // 7.10.6 End User cleanup: system information is read-only and object actions disappear only for End User.
134
+ for (const code of [webSource, webBuilt]) {
135
+ assert.match(code, /nexowatt\/readonly\/system-info/, 'authenticated read-only system-info route is missing');
136
+ assert.match(code, /authenticationRequired/, 'read-only system-info route must require an authenticated session');
137
+ assert.match(code, /ramMb/, 'read-only system-info payload is incomplete');
138
+ }
139
+ for (const code of [roleUi, sourceRoleUi]) {
140
+ assert.match(code, /state\.role !== 'enduser' \|\| currentRoute\(\) !== 'tab-intro'/, 'system-info hydration is not End User-only');
141
+ assert.match(code, /data-eos-enduser-action-hidden/, 'End User object action hiding marker is missing');
142
+ assert.match(code, /svg\[data-testid\*="Edit"\]/, 'Edit icon fallback selector is missing');
143
+ assert.match(code, /svg\[data-testid\*="Settings"\]/, 'Settings icon fallback selector is missing');
144
+ assert.match(code, /svg\[data-testid\*="Delete"\]/, 'Delete icon fallback selector is missing');
145
+ assert.match(code, /state\.role !== 'admin'/, 'Admin restriction guard is missing');
146
+ }
147
+ assert.match(sourceMain, /role === 'enduser' && \['readLogs', 'sendToHost'\]\.includes\(command\)/, 'End User technical diagnostics must remain denied');
148
+
131
149
  console.log('[NexoWatt EOS role security] OK (authoritative Admin rights, End User read-only datapoints, protected tools, restart-safe menu storage)');
@@ -31,7 +31,7 @@ const autoUi = read('adminWww/js/eos-auto-update.js');
31
31
  const autoCss = read('adminWww/css/eos-auto-update.css');
32
32
  const autoTag = String(info.autoUpdateCacheTag || info.autoUpdateCacheVersion || info.shellCacheTag || info.shellCacheVersion);
33
33
 
34
- must(pkg.version === '7.10.5' && io.version === '7.10.5' && io.common.version === '7.10.5' && info.version === '7.10.5', 'version drift');
34
+ must(pkg.version === '7.10.6' && io.version === '7.10.6' && io.common.version === '7.10.6' && info.version === '7.10.6', 'version drift');
35
35
  must(io.native.eosRequireFirstLoginPassword === false && io.native.eosRequireFirstLoginPasswordChange === false, 'forced first password still enabled');
36
36
  must(!index.includes('eos-account-management.js'), 'custom reset UI still loaded');
37
37
  must(!boot.includes('installIntegratedFirstLogin(base);') && !boot.includes('showFirstLoginPassword(resolved, base);'), 'forced first-login UI still active');
@@ -49,7 +49,7 @@ must(!autoBackend.includes('extendForeignObjectAsync(this.instanceId'), 'runtime
49
49
  must(web.includes('this.nexowattStableUpdateManager?.stop();'), 'auto-update manager is not stopped with the web server');
50
50
  must(fs.existsSync(path.join(root, 'build/lib/eosRequestSecurity.js')), 'eosRequestSecurity runtime module missing');
51
51
 
52
- // 7.10.4 placement acceptance remains mandatory in 7.10.5: System Settings only.
52
+ // 7.10.4 placement acceptance remains mandatory in 7.10.6: System Settings only.
53
53
  must(index.includes(`eos-auto-update.js?v=${autoTag}`), 'auto-update JavaScript cache key missing');
54
54
  must(index.includes(`eos-auto-update.css?v=${autoTag}`), 'auto-update CSS cache key missing');
55
55
  must(autoUi.includes('[role="dialog"][aria-labelledby="system-settings-dialog-title"]'), 'System Settings selector missing');
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const root = path.resolve(__dirname, '..');
7
+ const read = file => fs.readFileSync(path.join(root, file), 'utf8');
8
+ const pkg = JSON.parse(read('package.json'));
9
+ const sourceWeb = read('src/lib/web.ts');
10
+ const builtWeb = read('build/lib/web.js');
11
+ const sourceRole = read('src-admin/public/js/eos-role-ui.js');
12
+ const runtimeRole = read('adminWww/js/eos-role-ui.js');
13
+ const sourceMain = read('src/main.ts');
14
+ const builtMain = read('build/main.js');
15
+
16
+ assert.equal(pkg.version, '7.10.6', 'release must use a new npm version');
17
+ for (const web of [sourceWeb, builtWeb]) {
18
+ assert.match(web, /nexowatt\/readonly\/system-info/, 'read-only system information endpoint missing');
19
+ assert.match(web, /sendEosReadonlySystemInfo/, 'read-only system information handler missing');
20
+ assert.match(web, /platform/, 'platform value missing');
21
+ assert.match(web, /ramMb/, 'RAM value missing');
22
+ assert.match(web, /nodejs/, 'Node.js value missing');
23
+ assert.match(web, /npm/, 'NPM value missing');
24
+ }
25
+ for (const role of [sourceRole, runtimeRole]) {
26
+ assert.match(role, /state\.role !== 'enduser' \|\| currentRoute\(\) !== 'tab-intro'/, 'system-card correction must be End User-only');
27
+ assert.match(role, /applyReadonlySystemInfoCard/, 'End User system-card correction missing');
28
+ assert.match(role, /data-eos-enduser-action-hidden/, 'End User action-column suppression missing');
29
+ assert.match(role, /Edit.*Delete.*Settings.*Tune.*Build/s, 'edit/delete/settings icon suppression missing');
30
+ assert.match(role, /const readonly = state\.role === 'enduser' && currentRoute\(\) === 'tab-objects'/, 'datapoint restriction must be End User-only');
31
+ }
32
+ for (const main of [sourceMain, builtMain]) {
33
+ assert.match(main, /if \(role === 'admin'\)/, 'Admin full-rights bypass missing');
34
+ assert.match(main, /end-user datapoints are read-only in EOS Admin/, 'backend End User write denial missing');
35
+ }
36
+ console.log('[NexoWatt EOS user area] OK (End User read-only actions and system info; Admin unchanged)');
@@ -134,14 +134,14 @@ for (const file of [
134
134
  'LICENSE',
135
135
  'NEXOWATT_PROPRIETARY_LICENSE.md',
136
136
  'THIRD_PARTY_NOTICES.md',
137
- 'README_STABILITY_V7.10.5.md',
138
- 'RELEASE_NOTES_V7.10.5.md',
139
- 'PUBLISH_STABLE_V7.10.5.md',
140
- 'INSTALL_TEST_V7.10.5.md',
141
- 'RELEASE_ACCEPTANCE_V7.10.5.md',
137
+ 'README_STABILITY_V7.10.6.md',
138
+ 'RELEASE_NOTES_V7.10.6.md',
139
+ 'PUBLISH_STABLE_V7.10.6.md',
140
+ 'INSTALL_TEST_V7.10.6.md',
141
+ 'RELEASE_ACCEPTANCE_V7.10.6.md',
142
142
  'MERGE_UPDATE.ps1',
143
143
  'MERGE_UPDATE.cmd',
144
- 'MERGE_UPDATE_README_V7.10.5.md',
144
+ 'MERGE_UPDATE_README_V7.10.6.md',
145
145
  'tools/nexowatt-patch-built-frontend.cjs',
146
146
  'tools/nexowatt-native-shell-selftest.cjs',
147
147
  'tools/nexowatt-clean-legacy-runtime.cjs',
@@ -174,7 +174,7 @@ for (const file of [
174
174
  'tools/nexowatt-ui-overview-runtime-selftest.cjs',
175
175
  'adminWww/js/eos-ems-overview.js',
176
176
  'adminWww/css/eos-ems-overview.css',
177
- 'adminWww/static/js/nexowatt-stable-v7105.js',
177
+ 'adminWww/static/js/nexowatt-stable-v7106.js',
178
178
  'src-admin/src/components/Intro/NexoWattEmsOverview.tsx',
179
179
  'tools/nexowatt-publish-channel-guard.cjs',
180
180
  'tools/nexowatt-publish-channel-selftest.cjs',
@@ -1,11 +0,0 @@
1
- # Release Notes 7.10.5
2
-
3
- Version 7.10.5 is the administrator-rights and RBAC correction for NexoWatt EOS Admin.
4
-
5
- - Restores unrestricted administrator datapoint writes and reversible expert mode.
6
- - Removes the legacy DOM-text role classifier that could misclassify `system.user.admin`.
7
- - Keeps ioBroker Admin and XTerm visible for administrators only.
8
- - Exposes Datapoints to End Users as read-only and denies End User state writes in the backend.
9
- - Blocks App Center, License, Simulation and normal account administration for Installer/End User.
10
- - Stores navigation visibility/order in `eos-admin.0.info.uiTabsVisible` instead of `system.config`, avoiding adapter restarts.
11
- - Shows backup navigation only for enabled backup instances.