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.
- package/INSTALL_TEST_V7.10.2.md +22 -0
- package/MERGE_UPDATE_README_V7.10.2.md +11 -0
- package/NEXOWATT_EOS_BUILD_INFO.json +19 -21
- package/NEXOWATT_EOS_PREBUILT_MANIFEST.json +1410 -0
- package/PUBLISH_STABLE_V7.10.2.md +21 -0
- package/README.md +16 -6
- package/README_STABILITY_V7.10.2.md +20 -0
- package/RELEASE_ACCEPTANCE_V7.10.2.md +13 -0
- package/RELEASE_NOTES_V7.10.2.md +11 -0
- package/adminWww/assets/Intro-DkwRiz1n-v84.js +1 -1
- package/adminWww/assets/bootstrap-COulQZax-v84.js +2 -2
- package/adminWww/css/eos-ems-overview.css +5 -3
- package/adminWww/css/nexowatt-native-shell.css +85 -413
- package/adminWww/index.html +20 -21
- package/adminWww/js/eos-account-management.js +28 -19
- package/adminWww/js/eos-assistant.js +1 -1
- package/adminWww/js/eos-ems-overview.js +1 -1
- package/adminWww/js/eos-role-bootstrap.js +17 -80
- package/adminWww/js/eos-role-ui.js +28 -4
- package/adminWww/js/nexowatt-native-shell.js +1 -1
- package/adminWww/static/js/nexowatt-stable-login.js +43 -70
- package/adminWww/static/js/nexowatt-stable-v7101.js +27 -0
- package/build/lib/eosAutoUpdate.js +418 -20
- package/build/lib/eosAutoUpdate.js.map +1 -0
- package/build/lib/eosRequestSecurity.js +4 -1
- package/build/lib/eosRequestSecurity.js.map +1 -0
- package/build/lib/web.js +161 -254
- package/build/lib/web.js.map +1 -1
- package/build/main.js +39 -67
- package/io-package.json +72 -7
- package/package.json +24 -25
- package/tools/nexowatt-account-management-selftest.cjs +15 -19
- package/tools/nexowatt-account-password-flow-selftest.cjs +15 -0
- package/tools/nexowatt-apply-ems-overview.cjs +4 -2
- package/tools/nexowatt-auto-update-selftest.cjs +144 -32
- package/tools/nexowatt-backend-runtime-selftest.cjs +147 -0
- package/tools/nexowatt-clean-legacy-runtime.cjs +1 -1
- package/tools/nexowatt-ems-overview-selftest.cjs +1 -1
- package/tools/nexowatt-ensure-release-defaults.cjs +1 -1
- package/tools/nexowatt-login-layout-selftest.cjs +9 -13
- package/tools/nexowatt-merge-update-selftest.cjs +7 -1
- package/tools/nexowatt-modern-ui-selftest.cjs +10 -46
- package/tools/nexowatt-password-write-selftest.cjs +46 -16
- package/tools/nexowatt-prebuilt-release-selftest.cjs +292 -0
- package/tools/nexowatt-release-defaults-selftest.cjs +1 -1
- package/tools/nexowatt-runtime-cleanup-selftest.cjs +6 -8
- package/tools/nexowatt-stable-v7102-selftest.cjs +51 -0
- package/tools/nexowatt-sync-release-version.cjs +43 -5
- package/tools/nexowatt-ui-overview-runtime-selftest.cjs +2 -3
- package/tools/nexowatt-validate-package.cjs +54 -29
- package/tools/nexowatt-version-sync-selftest.cjs +18 -1
- package/INSTALL_TEST_V7.10.0.md +0 -11
- package/MERGE_UPDATE_README_V7.10.0.md +0 -5
- package/PUBLISH_STABLE_V7.10.0.md +0 -15
- package/README_STABILITY_V7.10.0.md +0 -3
- package/RELEASE_ACCEPTANCE_V7.10.0.md +0 -11
- package/RELEASE_NOTES_V7.10.0.md +0 -17
- package/adminWww/js/eos-release-watch.js +0 -77
- package/adminWww/static/js/nexowatt-stable-v7100.js +0 -111
- package/build/lib/eosPassword.js +0 -72
- package/build/lib/nexowattStableAuth.js +0 -74
- package/src/lib/eosAutoUpdate.ts +0 -320
- package/tools/nexowatt-cache-update-selftest.cjs +0 -12
- package/tools/nexowatt-request-security-selftest.cjs +0 -11
- package/tools/nexowatt-stable-v7100-selftest.cjs +0 -17
|
@@ -11,6 +11,8 @@ const fail = msg => {
|
|
|
11
11
|
const read = file => fs.readFileSync(path.join(root, file), 'utf8');
|
|
12
12
|
const readJson = file => JSON.parse(read(file));
|
|
13
13
|
const exists = file => fs.existsSync(path.join(root, file));
|
|
14
|
+
const canonicalPrepublishOnly = 'npm run sync:eos-version && npm run prepare:eos-release-defaults && npm run clean:eos-runtime && npm run check:eos-publish-channel && npm run check:eos-package && npm run check:eos-stability';
|
|
15
|
+
const canonicalPrepack = 'node tools/nexowatt-sync-release-version.cjs --quiet && node tools/nexowatt-ensure-release-defaults.cjs && node tools/nexowatt-clean-legacy-runtime.cjs --quiet && node tools/nexowatt-prebuilt-release-selftest.cjs';
|
|
14
16
|
|
|
15
17
|
const pkg = readJson('package.json');
|
|
16
18
|
const pkgLock = readJson('package-lock.json');
|
|
@@ -41,20 +43,34 @@ if (pkg.scripts['test:eos-version-sync'] !== 'node tools/nexowatt-version-sync-s
|
|
|
41
43
|
if (pkg.scripts['verify:eos-merge'] !== 'node tools/nexowatt-merge-update-selftest.cjs') fail('merge update selftest script is missing or incorrect');
|
|
42
44
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-version-sync-selftest.cjs')) fail('version sync selftest is not part of check:eos-stability');
|
|
43
45
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-merge-update-selftest.cjs')) fail('merge update selftest is not part of check:eos-stability');
|
|
44
|
-
if (pkg.scripts['check:eos-stable-
|
|
45
|
-
if (pkg.scripts
|
|
46
|
-
if (pkg.scripts
|
|
47
|
-
if (pkg.scripts['
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
if (pkg.scripts['check:eos-stable-v7102'] !== 'node tools/nexowatt-stable-v7102-selftest.cjs') fail('stable v7102 selftest script is missing or incorrect');
|
|
47
|
+
if (pkg.scripts.prepublishOnly !== canonicalPrepublishOnly) fail('prepublishOnly must use the dependency-free direct-publish workflow');
|
|
48
|
+
if (/\b(?:tsc|tsx)\b|build:(?:backend|frontend)|\bnpx\b|npm\s+(?:i|install|ci)\b/i.test(pkg.scripts.prepublishOnly || '')) fail('prepublishOnly must not require local development dependencies');
|
|
49
|
+
if (pkg.scripts['check:eos-prebuilt-release'] !== 'node tools/nexowatt-prebuilt-release-selftest.cjs') fail('prebuilt release selftest script is missing or incorrect');
|
|
50
|
+
if (pkg.scripts['seal:eos-prebuilt-release'] !== 'node tools/nexowatt-prebuilt-release-selftest.cjs --write') fail('prebuilt release sealing script is missing or incorrect');
|
|
51
|
+
const backendRuntimeSelftest = read('tools/nexowatt-backend-runtime-selftest.cjs');
|
|
52
|
+
if (!backendRuntimeSelftest.includes('dependency-free on Windows')) fail('backend runtime selftest is missing the cross-platform publish marker');
|
|
53
|
+
if (/const\s+npm\s*=\s*process\.platform|spawnSync\(\s*npm\s*,|['"]npm\.cmd['"]/.test(backendRuntimeSelftest)) fail('backend runtime selftest must not spawn a nested npm process');
|
|
54
|
+
if (!(pkg.files || []).some(value => String(value).replace(/\\/g, '/').replace(/\/+$/, '') === 'build')) fail('package.json files must include the complete build directory');
|
|
55
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-prebuilt-release-selftest.cjs')) fail('prebuilt release selftest is not part of check:eos-stability');
|
|
50
56
|
if (pkg.scripts['precheck:eos-package'] !== 'npm run sync:eos-version && npm run prepare:eos-release-defaults && npm run clean:eos-runtime') fail('precheck:eos-package must synchronize versions, normalize release defaults and clean stale runtime files');
|
|
51
57
|
if (pkg.scripts['precheck:eos-stability'] !== 'npm run sync:eos-version && npm run prepare:eos-release-defaults && npm run clean:eos-runtime') fail('precheck:eos-stability must synchronize versions, normalize release defaults and clean stale runtime files');
|
|
52
58
|
if (pkg.scripts['test:eos-publish-channel'] !== 'node tools/nexowatt-publish-channel-selftest.cjs') fail('publish channel selftest script is missing');
|
|
53
59
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-publish-channel-selftest.cjs')) fail('stability check must execute the publish channel selftest');
|
|
54
60
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-release-defaults-selftest.cjs')) fail('stability check must execute the release-default selftest');
|
|
61
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-password-write-selftest.cjs')) fail('password-write selftest is not part of check:eos-stability');
|
|
62
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-account-password-flow-selftest.cjs')) fail('account-password flow selftest is not part of check:eos-stability');
|
|
55
63
|
if (io.native?.auth !== true) fail('fresh sales installations must default to authenticated access');
|
|
56
64
|
if (io.native?.eosHideLegacyBackupFromNonAdmins !== true) fail('internal BackItUp reserve must default to Admin/Service visibility');
|
|
57
65
|
if (io.native?.nexowattHideLegacyBackupFromNonAdmins !== true) fail('NexoWatt backup visibility compatibility flag must default to true');
|
|
66
|
+
const instanceObjectIds = new Set((io.instanceObjects || []).map(object => object?._id));
|
|
67
|
+
if (!instanceObjectIds.has('info.nexowattStableUpdatesEnabled')) fail('restart-safe auto-update enabled state is missing');
|
|
68
|
+
if (!instanceObjectIds.has('info.nexowattStableUpdatesState')) fail('restart-safe auto-update runtime state is missing');
|
|
69
|
+
for (const key of ['description', 'files', 'scripts', 'nexowattReleasePolicy']) {
|
|
70
|
+
if (JSON.stringify(pkgLock.packages?.['']?.[key]) !== JSON.stringify(pkg[key])) {
|
|
71
|
+
fail(`package-lock root ${key} must match package.json`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
58
74
|
for (const [label, value] of [
|
|
59
75
|
['io-package common.version', io.common?.version],
|
|
60
76
|
['io-package top-level version', io.version],
|
|
@@ -104,7 +120,6 @@ for (const file of [
|
|
|
104
120
|
'adminWww/js/eos-basic-settings.js',
|
|
105
121
|
'adminWww/js/eos-role-ui.js',
|
|
106
122
|
'adminWww/js/eos-account-management.js',
|
|
107
|
-
'adminWww/js/eos-release-watch.js',
|
|
108
123
|
'adminWww/js/eos-assistant.js',
|
|
109
124
|
'adminWww/css/nexowatt-native-shell.css',
|
|
110
125
|
'adminWww/img/eos/nexowatt-192.png',
|
|
@@ -112,30 +127,31 @@ for (const file of [
|
|
|
112
127
|
'src-admin/src/components/Drawer.tsx',
|
|
113
128
|
'src-admin/src/components/DrawerItem.tsx',
|
|
114
129
|
'admin/admin.svg',
|
|
130
|
+
'build/lib/eosRequestSecurity.js',
|
|
115
131
|
'LICENSE',
|
|
116
132
|
'NEXOWATT_PROPRIETARY_LICENSE.md',
|
|
117
133
|
'THIRD_PARTY_NOTICES.md',
|
|
118
|
-
'README_STABILITY_V7.10.
|
|
119
|
-
'RELEASE_NOTES_V7.10.
|
|
120
|
-
'PUBLISH_STABLE_V7.10.
|
|
121
|
-
'INSTALL_TEST_V7.10.
|
|
122
|
-
'RELEASE_ACCEPTANCE_V7.10.
|
|
134
|
+
'README_STABILITY_V7.10.2.md',
|
|
135
|
+
'RELEASE_NOTES_V7.10.2.md',
|
|
136
|
+
'PUBLISH_STABLE_V7.10.2.md',
|
|
137
|
+
'INSTALL_TEST_V7.10.2.md',
|
|
138
|
+
'RELEASE_ACCEPTANCE_V7.10.2.md',
|
|
123
139
|
'MERGE_UPDATE.ps1',
|
|
124
140
|
'MERGE_UPDATE.cmd',
|
|
125
|
-
'MERGE_UPDATE_README_V7.10.
|
|
141
|
+
'MERGE_UPDATE_README_V7.10.2.md',
|
|
126
142
|
'tools/nexowatt-patch-built-frontend.cjs',
|
|
127
143
|
'tools/nexowatt-native-shell-selftest.cjs',
|
|
128
144
|
'tools/nexowatt-clean-legacy-runtime.cjs',
|
|
129
145
|
'tools/nexowatt-runtime-cleanup-selftest.cjs',
|
|
130
146
|
'tools/nexowatt-esm-syntax-selftest.cjs',
|
|
131
147
|
'tools/nexowatt-import-integrity-selftest.cjs',
|
|
148
|
+
'tools/nexowatt-backend-runtime-selftest.cjs',
|
|
149
|
+
'tools/nexowatt-prebuilt-release-selftest.cjs',
|
|
150
|
+
'NEXOWATT_EOS_PREBUILT_MANIFEST.json',
|
|
132
151
|
'tools/nexowatt-entrypoint-smoke-selftest.cjs',
|
|
133
152
|
'tools/nexowatt-role-access-selftest.cjs',
|
|
134
153
|
'tools/nexowatt-first-login-selftest.cjs',
|
|
135
154
|
'tools/nexowatt-account-management-selftest.cjs',
|
|
136
|
-
'tools/nexowatt-password-write-selftest.cjs',
|
|
137
|
-
'tools/nexowatt-request-security-selftest.cjs',
|
|
138
|
-
'tools/nexowatt-cache-update-selftest.cjs',
|
|
139
155
|
'tools/nexowatt-modern-ui-selftest.cjs',
|
|
140
156
|
'tools/nexowatt-login-layout-selftest.cjs',
|
|
141
157
|
'tools/nexowatt-internal-reserve-selftest.cjs',
|
|
@@ -143,12 +159,14 @@ for (const file of [
|
|
|
143
159
|
'tools/nexowatt-sync-release-version.cjs',
|
|
144
160
|
'tools/nexowatt-version-sync-selftest.cjs',
|
|
145
161
|
'tools/nexowatt-merge-update-selftest.cjs',
|
|
146
|
-
'tools/nexowatt-stable-
|
|
162
|
+
'tools/nexowatt-stable-v7102-selftest.cjs',
|
|
163
|
+
'tools/nexowatt-password-write-selftest.cjs',
|
|
164
|
+
'tools/nexowatt-account-password-flow-selftest.cjs',
|
|
147
165
|
'tools/nexowatt-ems-overview-selftest.cjs',
|
|
148
166
|
'tools/nexowatt-ui-overview-runtime-selftest.cjs',
|
|
149
167
|
'adminWww/js/eos-ems-overview.js',
|
|
150
168
|
'adminWww/css/eos-ems-overview.css',
|
|
151
|
-
'adminWww/static/js/nexowatt-stable-
|
|
169
|
+
'adminWww/static/js/nexowatt-stable-v7101.js',
|
|
152
170
|
'src-admin/src/components/Intro/NexoWattEmsOverview.tsx',
|
|
153
171
|
'tools/nexowatt-publish-channel-guard.cjs',
|
|
154
172
|
'tools/nexowatt-publish-channel-selftest.cjs',
|
|
@@ -176,8 +194,8 @@ const shellTag = String(buildInfo.shellCacheTag || shellCache);
|
|
|
176
194
|
if (!runtime || !Number.isFinite(runtimeNumber)) fail(`invalid runtimeEntry ${runtime}`);
|
|
177
195
|
if (!Number.isFinite(shellCache)) fail(`invalid shellCacheVersion ${buildInfo.shellCacheVersion}`);
|
|
178
196
|
for (const marker of [
|
|
179
|
-
`hostInit-${runtime}.js?v=${
|
|
180
|
-
`index-CQZugZ1z-${runtime}.js?v=${
|
|
197
|
+
`hostInit-${runtime}.js?v=${runtimeNumber}`,
|
|
198
|
+
`index-CQZugZ1z-${runtime}.js?v=${runtimeNumber}`,
|
|
181
199
|
`eos-manual-write-policy.js?v=${shellTag}`,
|
|
182
200
|
`nexowatt-native-shell.css?v=${shellTag}`,
|
|
183
201
|
`nexowatt-native-shell.js?v=${shellTag}`,
|
|
@@ -187,13 +205,13 @@ for (const marker of [
|
|
|
187
205
|
if (!index.includes(`eos-role-bootstrap.js?v=${shellTag}`)) fail('role bootstrap cache key mismatch');
|
|
188
206
|
if (!index.includes(`eos-branding-sanitizer.js?v=${shellTag}`)) fail('branding sanitizer cache key mismatch');
|
|
189
207
|
if (!index.includes(`eos-role-ui.js?v=${shellTag}`)) fail('role UI cache key mismatch');
|
|
190
|
-
if (
|
|
208
|
+
if (index.includes('eos-account-management.js')) fail('custom account-management runtime must not be loaded in standard password mode');
|
|
209
|
+
if (!index.includes(`eos-auto-update.js?v=${shellTag}`)) fail('auto-update cache key mismatch');
|
|
191
210
|
if (!index.includes(`eos-assistant.js?v=${shellTag}`)) fail('EOS Assist cache key mismatch');
|
|
192
211
|
if (!index.includes(`eos-ems-overview.js?v=${shellTag}`)) fail('EMS overview cache key mismatch');
|
|
193
212
|
if (!index.includes(`eos-ems-overview.css?v=${shellTag}`)) fail('EMS overview CSS cache key mismatch');
|
|
194
|
-
if (!index.includes(`nexowatt-stable-
|
|
195
|
-
if (
|
|
196
|
-
if (index.indexOf(`eos-manual-write-policy.js?v=${shellTag}`) > index.indexOf(`hostInit-${runtime}.js?v=${shellTag}`)) fail('manual-write policy must load before the React runtime');
|
|
213
|
+
if (!index.includes(`nexowatt-stable-v7101.js?v=${shellTag}`)) fail('stable v98 cache key mismatch');
|
|
214
|
+
if (index.indexOf(`eos-manual-write-policy.js?v=${shellTag}`) > index.indexOf(`hostInit-${runtime}.js?v=${runtimeNumber}`)) fail('manual-write policy must load before the React runtime');
|
|
197
215
|
if (!index.includes('class="eos-native-shell"')) fail('native NexoWatt shell class missing');
|
|
198
216
|
for (const legacy of ['eos-branding.js', 'eos-security-ui.js', 'eos-console-quiet.js', 'eos-objects-state-tools.js']) {
|
|
199
217
|
if (index.includes(legacy)) fail(`legacy browser overlay still loaded: ${legacy}`);
|
|
@@ -241,7 +259,7 @@ if (accountManagement.includes("launcher.className = 'eos-account-management-lau
|
|
|
241
259
|
if (accountManagement.includes('new MutationObserver')) fail('account-management runtime adds a second broad DOM observer');
|
|
242
260
|
if (read('src-admin/public/js/eos-account-management.js') !== accountManagement) fail('account-management source/build drift');
|
|
243
261
|
const roleBootstrap = read('adminWww/js/eos-role-bootstrap.js');
|
|
244
|
-
if (
|
|
262
|
+
if (roleBootstrap.includes('installIntegratedFirstLogin(base);') || roleBootstrap.includes('showFirstLoginPassword(resolved, base);')) fail('forced first-login UI must be disabled');
|
|
245
263
|
if (/data-eos-account=|selector\.innerHTML/.test(roleBootstrap)) fail('login role buttons must not enlarge the normal login card');
|
|
246
264
|
if (!roleBootstrap.includes('nexowatt/account/passwordless-status') || !roleBootstrap.includes('eligibility.allowed')) fail('server-checked first-login eligibility is incomplete');
|
|
247
265
|
if (roleBootstrap.includes('installPasswordlessFirstLoginLauncher')) fail('old first-login launcher remains active');
|
|
@@ -254,22 +272,29 @@ if (!mf.includes(`remoteEntry-${runtime}.js`) || !mf.includes(`index-D2ymscJA-${
|
|
|
254
272
|
const webBuild = read('build/lib/web.js');
|
|
255
273
|
if (!webBuild.includes('refreshLifetime: 60 * 60 * 24 * 7')) fail('build/lib/web.js must keep upstream-compatible refresh lifetime');
|
|
256
274
|
if (!webBuild.includes('Follow upstream admin semantics again')) fail('build/lib/web.js lacks session compatibility fix');
|
|
275
|
+
if (!exists('build/lib/eosRequestSecurity.js')) fail('build/lib/eosRequestSecurity.js is missing');
|
|
276
|
+
const autoUpdateSource = read('src/lib/eosAutoUpdate.ts');
|
|
277
|
+
if (autoUpdateSource.includes('extendForeignObjectAsync(this.instanceId')) fail('auto-update runtime must not write the running instance native configuration');
|
|
278
|
+
if (!autoUpdateSource.includes("const ENABLED_STATE_ID = 'info.nexowattStableUpdatesEnabled'")) fail('restart-safe auto-update state storage is missing');
|
|
257
279
|
const mainBuild = read('build/main.js');
|
|
258
280
|
if (!mainBuild.includes('v37 BackItUp/runtime-adapter compatibility')) fail('build/main.js lacks BackItUp compatibility guard');
|
|
259
281
|
|
|
260
282
|
if (!pkg.scripts['nexowatt:patch-built-frontend']) fail('missing nexowatt:patch-built-frontend script');
|
|
261
283
|
if (pkg.scripts['check:eos-esm'] !== 'node tools/nexowatt-esm-syntax-selftest.cjs') fail('check:eos-esm script is missing or incorrect');
|
|
262
284
|
if (pkg.scripts['check:eos-imports'] !== 'node tools/nexowatt-import-integrity-selftest.cjs') fail('check:eos-imports script is missing or incorrect');
|
|
285
|
+
if (pkg.scripts['check:eos-backend-runtime'] !== 'node tools/nexowatt-backend-runtime-selftest.cjs') fail('check:eos-backend-runtime script is missing or incorrect');
|
|
263
286
|
if (pkg.scripts['check:eos-entry'] !== 'node tools/nexowatt-entrypoint-smoke-selftest.cjs') fail('check:eos-entry script is missing or incorrect');
|
|
264
287
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-esm-syntax-selftest.cjs')) fail('ESM syntax selftest is not part of check:eos-stability');
|
|
265
288
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-import-integrity-selftest.cjs')) fail('import integrity selftest is not part of check:eos-stability');
|
|
289
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-backend-runtime-selftest.cjs')) fail('backend runtime selftest is not part of check:eos-stability');
|
|
266
290
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-entrypoint-smoke-selftest.cjs')) fail('entrypoint smoke selftest is not part of check:eos-stability');
|
|
267
291
|
if (pkg.scripts['clean:eos-runtime'] !== 'node tools/nexowatt-clean-legacy-runtime.cjs') fail('clean:eos-runtime script is missing or incorrect');
|
|
268
|
-
if (pkg.scripts.prepack !==
|
|
269
|
-
if (
|
|
292
|
+
if (pkg.scripts.prepack !== canonicalPrepack) fail('prepack must verify the sealed prebuilt artifact without tsc/tsx');
|
|
293
|
+
if (/\b(?:tsc|tsx)\b|build:(?:backend|frontend)|\bnpx\b|npm\s+(?:i|install|ci)\b/i.test(pkg.scripts.prepack || '')) fail('prepack must not require local development dependencies');
|
|
294
|
+
if (pkg.scripts.build !== 'npm run build:frontend && npm run build:backend && npm run clean:eos-runtime && npm run seal:eos-prebuilt-release') fail('build must clean and seal the prebuilt release after compilation');
|
|
270
295
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-role-access-selftest.cjs')) fail('role access selftest is not part of check:eos-stability');
|
|
271
|
-
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-
|
|
272
|
-
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-account-
|
|
296
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-account-password-flow-selftest.cjs')) fail('standard account-password flow selftest is not part of check:eos-stability');
|
|
297
|
+
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-account-password-flow-selftest.cjs')) fail('standard account-password management selftest is not part of check:eos-stability');
|
|
273
298
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-modern-ui-selftest.cjs')) fail('modern-UI selftest is not part of check:eos-stability');
|
|
274
299
|
if (pkg.scripts['test:eos-login-layout'] !== 'node tools/nexowatt-login-layout-selftest.cjs') fail('login-layout selftest script is missing or incorrect');
|
|
275
300
|
if (!pkg.scripts['check:eos-stability']?.includes('nexowatt-login-layout-selftest.cjs')) fail('login-layout selftest is not part of check:eos-stability');
|
|
@@ -24,7 +24,19 @@ try {
|
|
|
24
24
|
const currentPkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
25
25
|
const version = currentPkg.version;
|
|
26
26
|
writeJson('package.json', currentPkg);
|
|
27
|
-
writeJson('package-lock.json', {
|
|
27
|
+
writeJson('package-lock.json', {
|
|
28
|
+
name: currentPkg.name,
|
|
29
|
+
version: '7.9.92',
|
|
30
|
+
packages: {
|
|
31
|
+
'': {
|
|
32
|
+
version: '7.9.92',
|
|
33
|
+
description: 'stale description',
|
|
34
|
+
files: ['README_STABILITY_V7.9.92.md'],
|
|
35
|
+
scripts: { 'check:eos-stable-v92': 'node stale.js' },
|
|
36
|
+
nexowattReleasePolicy: { distTag: 'latest', purpose: 'stale 7.9.92 policy' },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
28
40
|
writeJson('io-package.json', {
|
|
29
41
|
version: '7.9.92',
|
|
30
42
|
common: {
|
|
@@ -75,6 +87,11 @@ try {
|
|
|
75
87
|
]) {
|
|
76
88
|
if (actual !== version) fail(`${label} was not synchronized: ${actual}`);
|
|
77
89
|
}
|
|
90
|
+
for (const key of ['description', 'files', 'scripts', 'nexowattReleasePolicy']) {
|
|
91
|
+
if (JSON.stringify(lock.packages[''][key]) !== JSON.stringify(currentPkg[key])) {
|
|
92
|
+
fail(`package-lock root ${key} was not synchronized`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
78
95
|
if (io.common.meta !== `${expectedBase}/io-package.json`) fail('io-package URL was not synchronized');
|
|
79
96
|
if (entry.meta !== `${expectedBase}/io-package.json`) fail('repository entry URL was not synchronized');
|
|
80
97
|
if (!fs.existsSync(path.join(temp, build.repositoryEntry))) fail('current repository entry was not created');
|
package/INSTALL_TEST_V7.10.0.md
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Installationstest 7.10.0
|
|
2
|
-
|
|
3
|
-
```bash
|
|
4
|
-
cd /opt/iobroker
|
|
5
|
-
iobroker stop eos-admin.0
|
|
6
|
-
npm install --no-save --omit=dev iobroker.eos-admin@7.10.0
|
|
7
|
-
iobroker upload eos-admin
|
|
8
|
-
iobroker restart eos-admin.0
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Danach Browser mit `Strg + F5` vollständig neu laden. Für EMS-Livedaten muss `iobroker.nexowatt-ui` mindestens `0.8.198` installiert und gestartet sein.
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
# NexoWatt EOS Admin 7.10.0 – Merge-Update
|
|
2
|
-
|
|
3
|
-
Die flache Merge-ZIP direkt in den vorhandenen Repository-Ordner entpacken und anschließend `MERGE_UPDATE.cmd` ausführen.
|
|
4
|
-
|
|
5
|
-
Enthalten sind alle Änderungen aus 7.9.96 einschließlich nativer Rollenübersicht, persönlicher Erstkennwortvergabe und EMS-Diagnose sowie die Korrekturen für Login-Geometrie und produktive AdminConnection.
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Stable-Veröffentlichung 7.10.0
|
|
2
|
-
|
|
3
|
-
```powershell
|
|
4
|
-
npm login
|
|
5
|
-
npm whoami
|
|
6
|
-
npm run check:eos-release
|
|
7
|
-
npm publish --dry-run --tag latest
|
|
8
|
-
npm publish --tag latest
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Das geprüfte Tarball kann alternativ direkt veröffentlicht werden:
|
|
12
|
-
|
|
13
|
-
```powershell
|
|
14
|
-
npm publish .\iobroker.eos-admin-7.10.0.tgz --tag latest
|
|
15
|
-
```
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
# NexoWatt EOS Admin 7.10.0 – Stabilität
|
|
2
|
-
|
|
3
|
-
Die native NexoWatt-Autoaktualisierung ist standardmäßig aktiv und kann im Admin-Cockpit deaktiviert werden. Sie setzt ausschließlich für installierte NexoWatt-Adapter aus dem erkannten Stable-Repository die ioBroker-Richtlinie `major`. Fremdadapter bleiben unverändert. Beim Abschalten werden vorherige Richtlinien wiederhergestellt.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Release-Abnahme 7.10.0
|
|
2
|
-
|
|
3
|
-
- [ ] Login-Karte ist ordentlich proportioniert und nur moderat größer als vor 7.9.96.
|
|
4
|
-
- [ ] Normale Anmeldung, falsches Passwort und persönliche Erstkennwortvergabe erzeugen keine innere Scrollleiste.
|
|
5
|
-
- [ ] Erstkennwort `nexowatt` führt zur verpflichtenden persönlichen Kennwortvergabe.
|
|
6
|
-
- [ ] Native Adapterkarten sind bei Admin, Installateur und Endkunde sichtbar, soweit die Rolle sie freigibt.
|
|
7
|
-
- [ ] NexoWatt-UI-Karte ist in der Übersicht vorhanden.
|
|
8
|
-
- [ ] EMS-Kachel zeigt nach Verbindungsaufbau Livewerte aus `nexowatt-ui.*.info.adminOverview.*`.
|
|
9
|
-
- [ ] UI-Version unter `0.8.198` wird verständlich gemeldet.
|
|
10
|
-
- [ ] Die EMS-Kachel enthält keinen Schreibpfad.
|
|
11
|
-
- [ ] `npm run check:eos-release` und `npm publish --dry-run --tag latest` sind vollständig grün.
|
package/RELEASE_NOTES_V7.10.0.md
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# NexoWatt EOS Admin 7.10.0
|
|
2
|
-
|
|
3
|
-
## Korrekturen
|
|
4
|
-
|
|
5
|
-
- Dauerhafter vertikaler Scrollbalken in der Cockpit-/Übersichtsfläche.
|
|
6
|
-
- Login wieder kompakt und sauber ausgerichtet; keine überlappenden Feldbeschriftungen.
|
|
7
|
-
- Erstpasswort und Passwort-Reset verwenden die native ioBroker-Passwortverwaltung mit kanonischer Benutzer-ID und Kompatibilitäts-Fallback.
|
|
8
|
-
- Passwort-Metadaten werden erst nach Hash- und Credential-Prüfung freigegeben.
|
|
9
|
-
- Präzise Fehlermeldungen für nicht gespeicherte oder nicht verifizierte Passwörter.
|
|
10
|
-
- Cache-Tag 7100 und automatische Release-Überwachung gegen gemischte Browserstände.
|
|
11
|
-
- Automatische Stable-Updates für installierte NexoWatt-Adapter bleiben standardmäßig aktiv und abschaltbar.
|
|
12
|
-
|
|
13
|
-
## Unverändert
|
|
14
|
-
|
|
15
|
-
- EMS-Diagnose bleibt rein lesend.
|
|
16
|
-
- Der nicht vorhandene Link zur vollständigen EMS-Diagnose bleibt entfernt.
|
|
17
|
-
- Der Bearbeitungsstift bleibt im unteren Kartenbereich.
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
(() => {
|
|
2
|
-
'use strict';
|
|
3
|
-
const RELEASE = '7.10.0';
|
|
4
|
-
const RELEASE_KEY = 'nexowatt.eos.loadedRelease';
|
|
5
|
-
const RELOAD_KEY = 'nexowatt.eos.reloadTarget';
|
|
6
|
-
const CHECK_MS = 15000;
|
|
7
|
-
let refreshing = false;
|
|
8
|
-
|
|
9
|
-
const normalize = value => String(value || '').trim().replace(/^v/i, '');
|
|
10
|
-
const validRelease = value => /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(normalize(value));
|
|
11
|
-
const reloadUrl = version => {
|
|
12
|
-
const url = new URL(window.location.href);
|
|
13
|
-
url.searchParams.set('_eosRelease', normalize(version) || RELEASE);
|
|
14
|
-
url.searchParams.set('_eosReload', String(Date.now()));
|
|
15
|
-
return url.toString();
|
|
16
|
-
};
|
|
17
|
-
const purgeBrowserCaches = async () => {
|
|
18
|
-
const jobs = [];
|
|
19
|
-
try {
|
|
20
|
-
if ('caches' in window) {
|
|
21
|
-
jobs.push(caches.keys().then(keys => Promise.all(keys.map(key => caches.delete(key)))));
|
|
22
|
-
}
|
|
23
|
-
} catch (_) { /* Cache API is optional */ }
|
|
24
|
-
try {
|
|
25
|
-
if (navigator.serviceWorker?.getRegistrations) {
|
|
26
|
-
jobs.push(navigator.serviceWorker.getRegistrations().then(rows => Promise.all(rows.map(row => row.unregister()))));
|
|
27
|
-
}
|
|
28
|
-
} catch (_) { /* service workers may be unavailable */ }
|
|
29
|
-
await Promise.allSettled(jobs);
|
|
30
|
-
};
|
|
31
|
-
const reloadFor = async version => {
|
|
32
|
-
const target = normalize(version) || RELEASE;
|
|
33
|
-
if (refreshing || sessionStorage.getItem(RELOAD_KEY) === target) return;
|
|
34
|
-
refreshing = true;
|
|
35
|
-
sessionStorage.setItem(RELOAD_KEY, target);
|
|
36
|
-
document.documentElement.classList.add('eos-release-refreshing');
|
|
37
|
-
await purgeBrowserCaches();
|
|
38
|
-
window.location.replace(reloadUrl(target));
|
|
39
|
-
};
|
|
40
|
-
const checkServerVersion = async () => {
|
|
41
|
-
try {
|
|
42
|
-
const endpoint = new URL('./version', window.location.href);
|
|
43
|
-
endpoint.searchParams.set('_eosTs', String(Date.now()));
|
|
44
|
-
const response = await fetch(endpoint, {
|
|
45
|
-
cache: 'no-store',
|
|
46
|
-
credentials: 'same-origin',
|
|
47
|
-
headers: { 'Cache-Control': 'no-cache' },
|
|
48
|
-
});
|
|
49
|
-
if (!response.ok) return;
|
|
50
|
-
const serverVersion = normalize(await response.text());
|
|
51
|
-
if (validRelease(serverVersion) && serverVersion !== RELEASE) {
|
|
52
|
-
await reloadFor(serverVersion);
|
|
53
|
-
}
|
|
54
|
-
} catch (_) { /* adapter restart or temporary network interruption */ }
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
window.NEXOWATT_EOS_RELEASE = RELEASE;
|
|
58
|
-
const previous = normalize(localStorage.getItem(RELEASE_KEY));
|
|
59
|
-
localStorage.setItem(RELEASE_KEY, RELEASE);
|
|
60
|
-
const loadedFor = normalize(new URL(window.location.href).searchParams.get('_eosRelease'));
|
|
61
|
-
if (previous && previous !== RELEASE && loadedFor !== RELEASE) {
|
|
62
|
-
void reloadFor(RELEASE);
|
|
63
|
-
} else {
|
|
64
|
-
sessionStorage.removeItem(RELOAD_KEY);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
window.addEventListener('focus', () => void checkServerVersion());
|
|
68
|
-
document.addEventListener('visibilitychange', () => {
|
|
69
|
-
if (document.visibilityState === 'visible') void checkServerVersion();
|
|
70
|
-
});
|
|
71
|
-
window.setInterval(() => void checkServerVersion(), CHECK_MS);
|
|
72
|
-
window.NEXOWATT_EOS_RELEASE_WATCH = Object.freeze({
|
|
73
|
-
release: RELEASE,
|
|
74
|
-
check: checkServerVersion,
|
|
75
|
-
purge: purgeBrowserCaches,
|
|
76
|
-
});
|
|
77
|
-
})();
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
(() => {
|
|
2
|
-
'use strict';
|
|
3
|
-
const VERSION = 'v7100-scroll-login-auto-update';
|
|
4
|
-
const MANAGED_USERS = new Set(['installer', 'guest', 'user']);
|
|
5
|
-
const normalizeUser = value => String(value || '').trim().toLowerCase().replace(/^system\.user\./, '');
|
|
6
|
-
const INTRO_STYLE_PROPERTIES = [
|
|
7
|
-
'position', 'top', 'right', 'bottom', 'left', 'width', 'height', 'min-height', 'max-height',
|
|
8
|
-
'margin', 'overflow-x', 'overflow-y', 'overscroll-behavior', 'scrollbar-gutter',
|
|
9
|
-
];
|
|
10
|
-
const isIntroRoute = () => {
|
|
11
|
-
const hash = decodeURIComponent(window.location.hash || '').toLowerCase();
|
|
12
|
-
const explicitTab = hash.match(/(?:^|[#/])(tab-[a-z0-9_-]+)(?:[/?&]|$)/)?.[1] || '';
|
|
13
|
-
if (explicitTab) return explicitTab === 'tab-intro';
|
|
14
|
-
return document.documentElement.classList.contains('eos-route-intro')
|
|
15
|
-
|| !hash
|
|
16
|
-
|| hash === '#'
|
|
17
|
-
|| hash === '#/';
|
|
18
|
-
};
|
|
19
|
-
const bindScrollInput = paper => {
|
|
20
|
-
if (paper.dataset.nexowattScrollBound === 'true') return;
|
|
21
|
-
paper.dataset.nexowattScrollBound = 'true';
|
|
22
|
-
paper.addEventListener('wheel', event => {
|
|
23
|
-
if (!event.deltaY || paper.scrollHeight <= paper.clientHeight + 1) return;
|
|
24
|
-
const before = paper.scrollTop;
|
|
25
|
-
paper.scrollTop += event.deltaY;
|
|
26
|
-
if (paper.scrollTop !== before) event.preventDefault();
|
|
27
|
-
}, { passive: false });
|
|
28
|
-
paper.addEventListener('keydown', event => {
|
|
29
|
-
if (paper.scrollHeight <= paper.clientHeight + 1) return;
|
|
30
|
-
const step = Math.max(120, Math.round(paper.clientHeight * .78));
|
|
31
|
-
if (event.key === 'PageDown') paper.scrollTop += step;
|
|
32
|
-
else if (event.key === 'PageUp') paper.scrollTop -= step;
|
|
33
|
-
else if (event.key === 'Home' && event.ctrlKey) paper.scrollTop = 0;
|
|
34
|
-
else if (event.key === 'End' && event.ctrlKey) paper.scrollTop = paper.scrollHeight;
|
|
35
|
-
else return;
|
|
36
|
-
event.preventDefault();
|
|
37
|
-
});
|
|
38
|
-
};
|
|
39
|
-
const disableCockpitScroll = () => {
|
|
40
|
-
const root = document.documentElement;
|
|
41
|
-
root.classList.remove('eos-intro-scroll-enabled');
|
|
42
|
-
const paper = document.getElementById('app-paper');
|
|
43
|
-
if (!paper || paper.dataset.nexowattScrollable !== 'true') return;
|
|
44
|
-
delete paper.dataset.nexowattScrollable;
|
|
45
|
-
for (const property of INTRO_STYLE_PROPERTIES) paper.style.removeProperty(property);
|
|
46
|
-
};
|
|
47
|
-
const ensureCockpitScroll = () => {
|
|
48
|
-
const root = document.documentElement;
|
|
49
|
-
const paper = document.getElementById('app-paper');
|
|
50
|
-
if (!paper || !root.classList.contains('eos-app')) return;
|
|
51
|
-
if (!isIntroRoute()) {
|
|
52
|
-
disableCockpitScroll();
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
// eos-route-* is owned by the native shell; only add our dedicated scroll flag.
|
|
56
|
-
root.classList.add('eos-intro-scroll-enabled');
|
|
57
|
-
paper.dataset.nexowattScrollable = 'true';
|
|
58
|
-
if (paper.tabIndex < 0) paper.tabIndex = 0;
|
|
59
|
-
const styles = {
|
|
60
|
-
position: 'fixed',
|
|
61
|
-
top: 'var(--nx-content-top, 154px)',
|
|
62
|
-
right: 'var(--nx-page-x, 12px)',
|
|
63
|
-
bottom: '8px',
|
|
64
|
-
left: 'var(--nx-page-x, 12px)',
|
|
65
|
-
width: 'auto',
|
|
66
|
-
height: 'auto',
|
|
67
|
-
minHeight: '0',
|
|
68
|
-
maxHeight: 'none',
|
|
69
|
-
margin: '0',
|
|
70
|
-
overflowX: 'hidden',
|
|
71
|
-
overflowY: 'scroll',
|
|
72
|
-
overscrollBehavior: 'contain',
|
|
73
|
-
scrollbarGutter: 'stable',
|
|
74
|
-
};
|
|
75
|
-
for (const [name, value] of Object.entries(styles)) {
|
|
76
|
-
paper.style.setProperty(name.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`), value, 'important');
|
|
77
|
-
}
|
|
78
|
-
bindScrollInput(paper);
|
|
79
|
-
};
|
|
80
|
-
const apply = () => {
|
|
81
|
-
document.documentElement.classList.add('eos-assist-disabled');
|
|
82
|
-
document.querySelectorAll('.eos-assist-root,.eos-assist-header-root,[data-eos-assist-root],.eos-passwordless-launcher')
|
|
83
|
-
.forEach(element => element.remove());
|
|
84
|
-
const username = document.querySelector('input#username,input[name="username"]');
|
|
85
|
-
const password = document.querySelector('input#password,input[name="password"]');
|
|
86
|
-
const submit = document.querySelector('button[type="submit"],input[type="submit"]');
|
|
87
|
-
if (submit && MANAGED_USERS.has(normalizeUser(username?.value)) && !String(password?.value || '')) {
|
|
88
|
-
submit.disabled = true;
|
|
89
|
-
submit.classList.add('Mui-disabled');
|
|
90
|
-
submit.setAttribute('aria-disabled', 'true');
|
|
91
|
-
}
|
|
92
|
-
ensureCockpitScroll();
|
|
93
|
-
};
|
|
94
|
-
let scheduled = false;
|
|
95
|
-
const schedule = () => {
|
|
96
|
-
if (scheduled) return;
|
|
97
|
-
scheduled = true;
|
|
98
|
-
requestAnimationFrame(() => { scheduled = false; apply(); });
|
|
99
|
-
};
|
|
100
|
-
const start = () => {
|
|
101
|
-
apply();
|
|
102
|
-
new MutationObserver(schedule).observe(document.documentElement, { subtree: true, childList: true });
|
|
103
|
-
document.addEventListener('input', schedule, true);
|
|
104
|
-
document.addEventListener('change', schedule, true);
|
|
105
|
-
window.addEventListener('hashchange', schedule);
|
|
106
|
-
window.addEventListener('resize', schedule, { passive: true });
|
|
107
|
-
window.setInterval(ensureCockpitScroll, 750);
|
|
108
|
-
};
|
|
109
|
-
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', start, { once: true }) : start();
|
|
110
|
-
window.NEXOWATT_EOS_STABLE_V7100 = Object.freeze({ version: VERSION, refresh: apply, ensureCockpitScroll, disableCockpitScroll });
|
|
111
|
-
})();
|
package/build/lib/eosPassword.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalizeEosPasswordTarget = normalizeEosPasswordTarget;
|
|
4
|
-
exports.setEosUserPasswordWithVerification = setEosUserPasswordWithVerification;
|
|
5
|
-
exports.verifyEosUserPasswordCredential = verifyEosUserPasswordCredential;
|
|
6
|
-
function normalizeEosPasswordTarget(value) {
|
|
7
|
-
const raw = String(value || '').trim();
|
|
8
|
-
const userId = raw.startsWith('system.user.') ? raw : `system.user.${raw}`;
|
|
9
|
-
const userName = userId.replace(/^system\.user\./, '').trim();
|
|
10
|
-
if (!userName || userName.includes('.') || !/^system\.user\.[^.]+$/.test(userId)) throw new Error('invalidPasswordTarget');
|
|
11
|
-
return { userId, userName };
|
|
12
|
-
}
|
|
13
|
-
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
14
|
-
const accepted = result => result === true || (Array.isArray(result) && result[0] === true);
|
|
15
|
-
async function readPasswordHash(adapter, userId) {
|
|
16
|
-
if (typeof adapter.getForeignObjectAsync !== 'function') return '';
|
|
17
|
-
try {
|
|
18
|
-
const object = await adapter.getForeignObjectAsync(userId);
|
|
19
|
-
return typeof object?.common?.password === 'string' ? object.common.password : '';
|
|
20
|
-
}
|
|
21
|
-
catch { return ''; }
|
|
22
|
-
}
|
|
23
|
-
async function callPasswordApi(adapter, target, password, serviceUser, withOptions) {
|
|
24
|
-
const options = withOptions ? { user: serviceUser } : null;
|
|
25
|
-
if (typeof adapter.setPasswordAsync === 'function') { await adapter.setPasswordAsync(target, password, options); return; }
|
|
26
|
-
if (typeof adapter.setPassword === 'function') {
|
|
27
|
-
await new Promise((resolve, reject) => adapter.setPassword?.(target, password, options, error => error ? reject(error) : resolve()));
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
throw new Error('passwordApiUnavailable');
|
|
31
|
-
}
|
|
32
|
-
async function verifyAfterWrite(adapter, normalized, password, serviceUser) {
|
|
33
|
-
const hasCredentialCheck = typeof adapter.checkPasswordAsync === 'function';
|
|
34
|
-
for (let attempt = 0; attempt < 12; attempt++) {
|
|
35
|
-
if (hasCredentialCheck) {
|
|
36
|
-
for (const candidate of [normalized.userId, normalized.userName]) {
|
|
37
|
-
try {
|
|
38
|
-
if (accepted(await adapter.checkPasswordAsync?.(candidate, password, { user: serviceUser }))) return;
|
|
39
|
-
}
|
|
40
|
-
catch { }
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
else if (await readPasswordHash(adapter, normalized.userId)) return;
|
|
44
|
-
if (attempt < 11) await delay(55 + attempt * 35);
|
|
45
|
-
}
|
|
46
|
-
throw new Error(hasCredentialCheck ? 'passwordVerificationFailed' : 'passwordNotPersisted');
|
|
47
|
-
}
|
|
48
|
-
async function verifyEosUserPasswordCredential(adapter, target, password, serviceUser = 'system.user.admin') {
|
|
49
|
-
const normalized = normalizeEosPasswordTarget(target);
|
|
50
|
-
await verifyAfterWrite(adapter, normalized, password, serviceUser);
|
|
51
|
-
return normalized;
|
|
52
|
-
}
|
|
53
|
-
async function setEosUserPasswordWithVerification(adapter, target, password, serviceUser = 'system.user.admin') {
|
|
54
|
-
const normalized = normalizeEosPasswordTarget(target);
|
|
55
|
-
const attempts = [
|
|
56
|
-
{ apiTarget: normalized.userId, withOptions: true },
|
|
57
|
-
{ apiTarget: normalized.userName, withOptions: true },
|
|
58
|
-
{ apiTarget: normalized.userId, withOptions: false },
|
|
59
|
-
{ apiTarget: normalized.userName, withOptions: false },
|
|
60
|
-
];
|
|
61
|
-
let lastError = null;
|
|
62
|
-
for (const attempt of attempts) {
|
|
63
|
-
try {
|
|
64
|
-
await callPasswordApi(adapter, attempt.apiTarget, password, serviceUser, attempt.withOptions);
|
|
65
|
-
await verifyAfterWrite(adapter, normalized, password, serviceUser);
|
|
66
|
-
return { ...normalized, apiTarget: attempt.apiTarget };
|
|
67
|
-
}
|
|
68
|
-
catch (error) { lastError = error; }
|
|
69
|
-
}
|
|
70
|
-
if (lastError instanceof Error) throw lastError;
|
|
71
|
-
throw new Error('passwordNotPersisted');
|
|
72
|
-
}
|