v0.32.5
This commit is contained in:
1 parent
4a3e4bcf8f
commit
a3d183bd4b
8 files changed
+367
-694
No files matched your search
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
## 0.32.5
|
## 0.32.5
|
||||||
|
|
||||||
|
- Fix the administration panel startup `ReferenceError: Cannot access 'i18n' before initialization` in the new DNS/DDNS ACL editor. Define its localization helper before creating the DNS hint; preserve all ACL settings and translations. Add a JavaScript startup regression test to the release checks.
|
||||||
- Fix Rust `E0505` during dynamic ACL DNS resolution: give `lookup_host` an independently owned hostname, while returning the original normalized cache key. The resolver timeout, allowlist expiration and fail-closed behavior are unchanged.
|
- Fix Rust `E0505` during dynamic ACL DNS resolution: give `lookup_host` an independently owned hostname, while returning the original normalized cache key. The resolver timeout, allowlist expiration and fail-closed behavior are unchanged.
|
||||||
- Add bounded DNS/DDNS hostnames as **allow-only** client ACL rules in reusable
|
- Add bounded DNS/DDNS hostnames as **allow-only** client ACL rules in reusable
|
||||||
profiles, host policies, vhosts, locations and Docker ACL assignments.
|
profiles, host policies, vhosts, locations and Docker ACL assignments.
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ streaming HTTP/TLS/WebSocket forwarding, raw TCP/UDP stream hosts, IP-bound vhos
|
|||||||
|
|
||||||
## What changed in 0.32.5
|
## What changed in 0.32.5
|
||||||
|
|
||||||
|
- **ACL editor startup hotfix:** fix the JavaScript `i18n` initialization order
|
||||||
|
that could prevent the entire administration UI from loading. This does not
|
||||||
|
change stored configuration or DNS ACL behavior.
|
||||||
- **Dynamic DNS/DDNS ACL allow rules:** reusable ACL profiles, host policies,
|
- **Dynamic DNS/DDNS ACL allow rules:** reusable ACL profiles, host policies,
|
||||||
inline vhost/location ACLs, and Docker ACL assignments now accept `allow
|
inline vhost/location ACLs, and Docker ACL assignments now accept `allow
|
||||||
office.example.ddns.net` in place of a static client IP/CIDR. Existing IP,
|
office.example.ddns.net` in place of a static client IP/CIDR. Existing IP,
|
||||||
|
|||||||
+6
-5
@@ -2,17 +2,17 @@
|
|||||||
4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example
|
4140a2956264b44f259e6a37fc00ba02097bbe68b09296e04d3d243c1287129b .env.example
|
||||||
9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore
|
9e6356475bf587091bab72246ec9e325b498f7e48a6220e9a18baa50d0a385a6 .gitignore
|
||||||
ad0382153576411fb19861072635c02bdf33de740d6f122d8f27bd9c52ce112a AGENTS.md
|
ad0382153576411fb19861072635c02bdf33de740d6f122d8f27bd9c52ce112a AGENTS.md
|
||||||
d304d9da32d28b866176383b3b274e6ab020a54316d7e8ffe85cecd08e150f93 CHANGELOG.md
|
4a58695f0ef64344228cb43caf2a78aeba724cf0cc573a6a8745da847681aeed CHANGELOG.md
|
||||||
2f1de87bae58761fc8690ec7225520e3a16213c77cbbb5981e34f12a95810668 Cargo.lock
|
2f1de87bae58761fc8690ec7225520e3a16213c77cbbb5981e34f12a95810668 Cargo.lock
|
||||||
8c76ffaf4adba93df26e30f3dd163e0e5e201d069d1ae69c071ca42d7fc7264e Cargo.toml
|
8c76ffaf4adba93df26e30f3dd163e0e5e201d069d1ae69c071ca42d7fc7264e Cargo.toml
|
||||||
25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c Dockerfile
|
25c7f3c8162cbf5cc156439774118a81dae9fdc52b611ec7e40c230fc99a772c Dockerfile
|
||||||
31e13d43d5432731ca7f1bfd29d73eb2b62b8d23fe8678205f712f0daf9908c6 README.md
|
4ee3c626d1e5da5079fe65c6343f085cbb8bb53c2f2fa97e354f9633e8d415b3 README.md
|
||||||
fc03a8d19055642313f0b34bcd22e1cce17efc4d91be7fe7e4819e33b91c531d ROADMAP.md
|
fc03a8d19055642313f0b34bcd22e1cce17efc4d91be7fe7e4819e33b91c531d ROADMAP.md
|
||||||
da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml
|
da8311e3db945290666324a2f24bf4521b365272d7ac3f862ded1be993eea646 UPDATE_CHECK.toml
|
||||||
f645f218dd062bf6cb54a8ee634290562cad364a4cccf09f16e3c8303582af8c build.rs
|
f645f218dd062bf6cb54a8ee634290562cad364a4cccf09f16e3c8303582af8c build.rs
|
||||||
ea8d091843f86f4c66a5c76b20268b2feb397070851b6e05c5bc7d7a8d9157eb deploy/README.md
|
ea8d091843f86f4c66a5c76b20268b2feb397070851b6e05c5bc7d7a8d9157eb deploy/README.md
|
||||||
4834c278430ddf3bf842995735195368f1ac2c3b5c1d749df4f9238caf1e2b25 deploy/rustproxy.service
|
4834c278430ddf3bf842995735195368f1ac2c3b5c1d749df4f9238caf1e2b25 deploy/rustproxy.service
|
||||||
3e709b09ddf4e2c17497c66b416d07e1423eeeb5f29a9100b06c8d3d5cacc36a dev.sh
|
4d9baf35c70d9f5cfb10f8bd4caab543772fdda1e979ff74c17f1e3ebc8e3cd0 dev.sh
|
||||||
5f51efe621f45512a466fa7f2656867c6502a135ca040f4bfeec06a6919b39b6 docker-agent/README.md
|
5f51efe621f45512a466fa7f2656867c6502a135ca040f4bfeec06a6919b39b6 docker-agent/README.md
|
||||||
7fee7d51a7deb67e73e53a0bdff3aa4630aea9bab9b23a0f9b8001b2169892b1 docker-agent/certificate.go
|
7fee7d51a7deb67e73e53a0bdff3aa4630aea9bab9b23a0f9b8001b2169892b1 docker-agent/certificate.go
|
||||||
5e4f565c3c9de4dba897af2e801ea646a83395e72eae4717a6d502dff2fcec10 docker-agent/docker-agent.env.example
|
5e4f565c3c9de4dba897af2e801ea646a83395e72eae4717a6d502dff2fcec10 docker-agent/docker-agent.env.example
|
||||||
@@ -63,7 +63,7 @@ ec7e32fd19e6ba6ed1732f1f3dd92ac0860609e8c0bbd3c1998840cdfb24bf54 docs/SECURITY.
|
|||||||
007537ee971463072b2482dfa4fdcf1955f837ced0b711d4eef3b6267d16d4f6 docs/SECURITY_AUDIT_0.31.0.md
|
007537ee971463072b2482dfa4fdcf1955f837ced0b711d4eef3b6267d16d4f6 docs/SECURITY_AUDIT_0.31.0.md
|
||||||
25a06e7ddbb95d286e849b2fc5ba4adeedbddba0bad948e55bd91d962fd606de docs/SETTINGS.md
|
25a06e7ddbb95d286e849b2fc5ba4adeedbddba0bad948e55bd91d962fd606de docs/SETTINGS.md
|
||||||
8fc112cb45a2f35ef5b0dd4371aa6f43aca4df85db62c6ae02e56d74a3b702ae docs/STREAMS.md
|
8fc112cb45a2f35ef5b0dd4371aa6f43aca4df85db62c6ae02e56d74a3b702ae docs/STREAMS.md
|
||||||
9cf4c4e27ba11f40143f5a158f91d72b6c88a0a612a448390428d7103bbedfb3 docs/TEST_REPORT.md
|
97299efb6288ee29493eb7df243055d1ff76e8d0faf04bd195e184bce2e8bb67 docs/TEST_REPORT.md
|
||||||
cfb452d8496839e832b5fbacdd4e52525b0ecc3112fbb62340c1e580bd5c1717 docs/TODO.md
|
cfb452d8496839e832b5fbacdd4e52525b0ecc3112fbb62340c1e580bd5c1717 docs/TODO.md
|
||||||
751c9b13b47d0959a8575d6e82bdecba988b950a374ba0b084fbba08b4b65ebe docs/TRANSFORM.md
|
751c9b13b47d0959a8575d6e82bdecba988b950a374ba0b084fbba08b4b65ebe docs/TRANSFORM.md
|
||||||
fe3ec6ca16ff933239c12dacf39dd7b45717c0551a8b9f6ce601bf78136c9e37 docs/TRANSPORT.md
|
fe3ec6ca16ff933239c12dacf39dd7b45717c0551a8b9f6ce601bf78136c9e37 docs/TRANSPORT.md
|
||||||
@@ -217,7 +217,7 @@ c24411dd62afaecfc631682554d4a037c7dd27100d817e9901ccdfd505c2ed5b src/admin/web/
|
|||||||
7a12f020fc587205694978ab41b660e9a80487d413fbf6e34fc525eabc58308f src/admin/web/login-keys.json
|
7a12f020fc587205694978ab41b660e9a80487d413fbf6e34fc525eabc58308f src/admin/web/login-keys.json
|
||||||
cbd41678eadd994dc5252628ee8ef9551fa9f7d8694ca5abd206240d9a96ad30 src/admin/web/login.html
|
cbd41678eadd994dc5252628ee8ef9551fa9f7d8694ca5abd206240d9a96ad30 src/admin/web/login.html
|
||||||
c2e5f554810b8e34fb47361fb90a01073a2e332ee26d82e030956fad3ec1f83e src/admin/web/login.js
|
c2e5f554810b8e34fb47361fb90a01073a2e332ee26d82e030956fad3ec1f83e src/admin/web/login.js
|
||||||
0d0ec350d713aaf32a33607b2ddf0a8bb1858f2fd31c8396042cec4c84aee6ef src/admin/web/management.js
|
097fdb41aa1cd526c4d9bc65e502b05a62e664ef9fff8e69f706b93b0b124dc2 src/admin/web/management.js
|
||||||
90d9a0836662135b79fb6f183c4f3eff60f8a64392d6c5795ccf1d8ef6862263 src/admin/web/redirects.js
|
90d9a0836662135b79fb6f183c4f3eff60f8a64392d6c5795ccf1d8ef6862263 src/admin/web/redirects.js
|
||||||
c28f4254ddc1f720d62646ee0f0b590b60a89c0bf447e8ec74ff3dde0c7635ba src/admin/web/settings.js
|
c28f4254ddc1f720d62646ee0f0b590b60a89c0bf447e8ec74ff3dde0c7635ba src/admin/web/settings.js
|
||||||
8eadbada619b15087783dcfa0e889a81f88e78034d084c5ab616f7912b835940 src/admin/web/status_200.html
|
8eadbada619b15087783dcfa0e889a81f88e78034d084c5ab616f7912b835940 src/admin/web/status_200.html
|
||||||
@@ -513,6 +513,7 @@ f6a6d12275bc8ba627b4616a546d075511094bb064cd9058231cc86ca489743e tools/checks/d
|
|||||||
38e35bed4faf984932b39bb5a00819fadc664387e8050a803ff4b5348b31369f tools/checks/docker_startup_0318_ui_test.mjs
|
38e35bed4faf984932b39bb5a00819fadc664387e8050a803ff4b5348b31369f tools/checks/docker_startup_0318_ui_test.mjs
|
||||||
3396e5a510787e70e2ad8d1fad90356af461a88fd84429525d56fa82113da0f3 tools/checks/docs_check.py
|
3396e5a510787e70e2ad8d1fad90356af461a88fd84429525d56fa82113da0f3 tools/checks/docs_check.py
|
||||||
3fc765a7c2723ec783f269cfebc29ad2c09a90f33ea4af58285f883a026c4fa2 tools/checks/dynamic_acl_0325.py
|
3fc765a7c2723ec783f269cfebc29ad2c09a90f33ea4af58285f883a026c4fa2 tools/checks/dynamic_acl_0325.py
|
||||||
|
9c77764561b6ebfeecbc228f43ea29a0dd9f44121ad773c2e4299b92758e45c2 tools/checks/dynamic_acl_startup_0325_ui_test.mjs
|
||||||
5bf26d9c883704e5ac85670bbcb7fb0bbad5d01779ab50407ff4fd5f3022a9cb tools/checks/file_logs_tabs_0315_ui_test.mjs
|
5bf26d9c883704e5ac85670bbcb7fb0bbad5d01779ab50407ff4fd5f3022a9cb tools/checks/file_logs_tabs_0315_ui_test.mjs
|
||||||
72f3c4e3274d33e02d46646395bc0cd18a8f723f8747969fc81997c7a7259e76 tools/checks/h3_cache_mobile_0315_test.mjs
|
72f3c4e3274d33e02d46646395bc0cd18a8f723f8747969fc81997c7a7259e76 tools/checks/h3_cache_mobile_0315_test.mjs
|
||||||
1b5ead59bb2ea0e1ff32bf085f791018149cb9cc29b071fae4fb98ea80010824 tools/checks/h3_navigation_0316.py
|
1b5ead59bb2ea0e1ff32bf085f791018149cb9cc29b071fae4fb98ea80010824 tools/checks/h3_navigation_0316.py
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ if [[ "$mode" == "test" ]]; then
|
|||||||
node tools/checks/stream_0320_ui_test.mjs
|
node tools/checks/stream_0320_ui_test.mjs
|
||||||
node tools/checks/stream_0320_visibility_regression.mjs
|
node tools/checks/stream_0320_visibility_regression.mjs
|
||||||
node tools/checks/overview_registry_0323_ui_test.mjs
|
node tools/checks/overview_registry_0323_ui_test.mjs
|
||||||
|
node tools/checks/dynamic_acl_startup_0325_ui_test.mjs
|
||||||
node tools/checks/preserve_host_0324_ui_test.mjs
|
node tools/checks/preserve_host_0324_ui_test.mjs
|
||||||
node tools/checks/backend_dashboard_0323_ui_test.mjs
|
node tools/checks/backend_dashboard_0323_ui_test.mjs
|
||||||
node tools/checks/dashboard_layout_editor_0323_ui_test.mjs
|
node tools/checks/dashboard_layout_editor_0323_ui_test.mjs
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# Verification report - RustProxy 0.32.5
|
||||||
|
|
||||||
|
## Verification performed for this source package
|
||||||
|
|
||||||
|
- **0.32.5 administration UI startup fix:** the DNS ACL translation helper in
|
||||||
|
`src/admin/web/management.js` is now initialized before the DDNS hint uses
|
||||||
|
it. `tools/checks/dynamic_acl_startup_0325_ui_test.mjs` executes the real ACL
|
||||||
|
editor initializer with a simulated DOM and verifies that it completes and
|
||||||
|
renders the translatable DNS hint. The test reproduced the user-reported
|
||||||
|
`ReferenceError` against the unmodified 0.32.5 source before the fix.
|
||||||
|
**36/36 JavaScript checks passed** after adding this test to `dev.sh`.
|
||||||
|
The assembled JavaScript bundle passed `node --check`. The source/version,
|
||||||
|
admin surface, security, docs and language checks passed. `release_smoke.py`
|
||||||
|
exceeded the available execution timeout; the Rust compiler and live server
|
||||||
|
remain unavailable, so full release/runtime acceptance is not claimed.
|
||||||
|
- **0.32.5 build correction:** fix reported Rust `E0505` in `src/acl/dynamic.rs` by cloning the hostname into `lookup_name` for `lookup_host`. The original `name` is returned as the cache key. Added a source-contract regression check; Rust compilation is still required to confirm the correction.
|
||||||
|
- `tools/checks/dynamic_acl_0325.py`: **15/15 static source contracts passed**.
|
||||||
|
- JavaScript dashboard/settings regression scripts: **36/36 passed** (35 existing and one new startup regression).
|
||||||
|
- `tools/checks/check_source.py`, `rust_module_contracts.py`,
|
||||||
|
`docs_check.py`, `langs_check.py`, `security_contracts.py`, and
|
||||||
|
`admin_surface_audit_0310.py`: passed.
|
||||||
|
- The full `./dev.sh test` was interrupted by the environment time limit while
|
||||||
|
running expensive pre-Cargo release simulations. It was **not** a full pass.
|
||||||
|
- Cargo/rustc are unavailable here. Dynamic DNS Rust unit tests, integration
|
||||||
|
tests, real resolver timeouts/rotation and production acceptance **not run**.
|
||||||
|
|
||||||
|
## 0.32.5 dynamic DNS ACL changes
|
||||||
|
|
||||||
|
This build extends existing ACL `Rule.network` entries with allow-only DNS/DDNS
|
||||||
|
hostname support. Resolution is background-only and bounded (60s cadence,
|
||||||
|
4s timeout, max 8 concurrent lookups, max 128 unique names / 32 IPs per name).
|
||||||
|
Initial, expired and failed resolution states deny dynamic host authorization.
|
||||||
|
Existing numeric IP/CIDR and explicit-deny precedence remain unchanged.
|
||||||
|
|
||||||
|
A Rust compiler and real DNS peer were not available in this environment.
|
||||||
|
The Rust tests in `src/acl/tests.rs` and `src/acl/dynamic.rs` **have not been
|
||||||
|
executed** here. Before rollout, run `cargo fmt --all -- --check`,
|
||||||
|
`cargo check --locked --all-targets` and `cargo test --locked`, then confirm
|
||||||
|
live DDNS rotation and fail-closed DNS outages on staging.
|
||||||
|
|
||||||
|
## Previous 0.32.4 scope
|
||||||
|
|
||||||
|
Review of the supplied RustProxy 0.32.3 source and patch to 0.32.4:
|
||||||
|
HTTP Host / HTTP/2 authority parity, explicit TCP/DNS destination and TLS/SNI
|
||||||
|
isolation, relaxed HTTPS-by-IP troubleshooting hint, and uniform Overview gutters.
|
||||||
|
Follow-up patch to the first 0.32.4 archive:
|
||||||
|
- Fix reported `E0382` in `src/proxy/types.rs`: `Request::builder().uri(uri)`
|
||||||
|
moved `uri` before `upstream_request_target(&uri, ...)` could borrow it.
|
||||||
|
`.uri(uri.clone())` preserves the original URI for authority selection.
|
||||||
|
- Make normal Overview gutters uniformly 4px (dense 3px, comfortable 12px).
|
||||||
|
Resolve the higher-specificity `html[data-dashboard-density] .stats-grid`
|
||||||
|
rule which otherwise overrode the aligned grid and kept the larger gaps.
|
||||||
|
Existing database/configuration schemas and retry/transport policies are
|
||||||
|
unchanged. Only compiling Rust and live protocol tests prove runtime behavior.
|
||||||
|
|
||||||
|
## Available checks
|
||||||
|
|
||||||
|
- `./dev.sh test`: **all pre-Cargo checks passed**, including source/security,
|
||||||
|
SQLite migration/upgrade/backup simulations, memory-model scripts and **35
|
||||||
|
Node.js UI/behavior test scripts**. The command then exited **127** because
|
||||||
|
Rust/Cargo is not installed; this is **not** a passing Rust test run.
|
||||||
|
- New `preserve_host_0324.py` and `preserve_host_0324_ui_test.mjs` passed:
|
||||||
|
authority/destination split source contracts, four protocol selectors,
|
||||||
|
verified/unencrypted origin warnings, explicit diagnostics preset.
|
||||||
|
- Expanded Chromium CSS fixture `tools/checks/overview_gutters_0324_browser.py`:
|
||||||
|
**27 checks passed** (3 container widths x 3 UI density modes x 3 Dashboard
|
||||||
|
densities), checking horizontal/vertical gutters, equally high rows and
|
||||||
|
numeric-to-large-card transition. Normal/dense/comfortable gaps measured
|
||||||
|
**4/3/12px** and the outer grid bottom margin remained `0px`.
|
||||||
|
The older `overview_grid_spacing_0323_browser.py` also passed with all
|
||||||
|
62 blocks, responsive breakpoints and browser zoom 90%-130%.
|
||||||
|
These are simulated layout tests, not a live administrator session.
|
||||||
|
- `preserve_host_0324.py` now guards against moving `uri` before its final
|
||||||
|
authority adjustment, in addition to the backend/transport source contracts.
|
||||||
|
The existing Rust unit test for retry authority remains in the source.
|
||||||
|
- Version consistency: Cargo manifest, package root in existing lockfile,
|
||||||
|
OpenAPI, README, release notes and static assertion fixtures updated to 0.32.4.
|
||||||
|
External Cargo dependency resolutions have **not** been regenerated.
|
||||||
|
|
||||||
|
## Rust validation not performed (blocking for production)
|
||||||
|
|
||||||
|
The user's Rust compiler reported `error[E0382]: borrow of moved value: uri`
|
||||||
|
from the first 0.32.4 archive. This has been corrected in source, but **the
|
||||||
|
corrected code has not been compiled here**: no Cargo or Rust compiler is
|
||||||
|
available in the source-editing environment.
|
||||||
|
Do not treat static tests or the simulated TLS-peer tests added to Rust source
|
||||||
|
as evidence that RustProxy builds or that an actual Angie backend accepts the
|
||||||
|
corrected requests. Run, on a Rust 1.99+ host:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo check --locked --all-targets
|
||||||
|
cargo test --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
Then validate on staging with HTTPS-by-IP and `preserve_host: true` for
|
||||||
|
HTTP/1.1, Auto (H2 and H1 ALPN), compatible HTTP/2 and strict H2; check
|
||||||
|
`:authority` vs `Host`, SNI, certificate verification, WebSockets, H2C and
|
||||||
|
HTTP health probe `host` overrides. Inspect Angie response/error logs for
|
||||||
|
400 responses and verify backend connectivity through pool rotation/retry.
|
||||||
|
No claim of universal backend compatibility or measured throughput is made.
|
||||||
@@ -222,9 +222,9 @@
|
|||||||
const addButton = $("acl-profile-rule-add"), importButton = $("acl-profile-import-rules");
|
const addButton = $("acl-profile-rule-add"), importButton = $("acl-profile-import-rules");
|
||||||
const previewDefault = $("acl-profile-preview-default"), previewFlow = $("acl-profile-preview-flow"), previewNote = $("acl-profile-preview-note");
|
const previewDefault = $("acl-profile-preview-default"), previewFlow = $("acl-profile-preview-flow"), previewNote = $("acl-profile-preview-note");
|
||||||
const countryHelp = $("acl-profile-country-help"), countryLabel = $("acl-profile-country-label"), ipHelp = $("acl-profile-ip-help");
|
const countryHelp = $("acl-profile-country-help"), countryLabel = $("acl-profile-country-label"), ipHelp = $("acl-profile-ip-help");
|
||||||
|
const i18n = (tag, key, cls) => { const node = el(tag, t(key), cls); node.dataset.i18n = key; return node; };
|
||||||
const dnsHint = i18n("p", "aclDnsHelp", "fine"); ipHelp?.after(dnsHint);
|
const dnsHint = i18n("p", "aclDnsHelp", "fine"); ipHelp?.after(dnsHint);
|
||||||
const modeInputs = [...form.querySelectorAll('input[name="acl-profile-mode"]')];
|
const modeInputs = [...form.querySelectorAll('input[name="acl-profile-mode"]')];
|
||||||
const i18n = (tag, key, cls) => { const node = el(tag, t(key), cls); node.dataset.i18n = key; return node; };
|
|
||||||
const selectedMode = () => modeInputs.find(node => node.checked)?.value || "allow_exceptions";
|
const selectedMode = () => modeInputs.find(node => node.checked)?.value || "allow_exceptions";
|
||||||
const setMode = value => { for (const node of modeInputs) node.checked = node.value === value; };
|
const setMode = value => { for (const node of modeInputs) node.checked = node.value === value; };
|
||||||
const guidedAction = mode => mode === "allow_exceptions" ? "allow" : "deny";
|
const guidedAction = mode => mode === "allow_exceptions" ? "allow" : "deny";
|
||||||
|
|||||||
+203
-688
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,51 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
// Execute the real ACL editor initializer, not just parse it: an uninitialized
|
||||||
|
// i18n helper used to stop the entire fingerprinted dashboard bundle at load.
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import { runInNewContext } from 'node:vm';
|
||||||
|
|
||||||
|
const source = readFileSync('src/admin/web/management.js', 'utf8');
|
||||||
|
const start = source.lastIndexOf('(() => {');
|
||||||
|
assert(start > 0 && source.slice(start).includes('window.rustProxyAclProfiles ='), 'ACL editor IIFE not found');
|
||||||
|
|
||||||
|
function element(tag = 'div') {
|
||||||
|
return {
|
||||||
|
tag, children: [], dataset: {}, value: '', checked: false, hidden: false,
|
||||||
|
classList: { add() {}, remove() {}, toggle() {} },
|
||||||
|
append(...nodes) { this.children.push(...nodes); },
|
||||||
|
after(...nodes) { this.insertedAfter = nodes; },
|
||||||
|
replaceChildren(...nodes) { this.children = nodes; },
|
||||||
|
addEventListener() {},
|
||||||
|
reset() {},
|
||||||
|
querySelector() { return element(); },
|
||||||
|
querySelectorAll() { return []; },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const nodes = new Map();
|
||||||
|
const get = id => {
|
||||||
|
if (!nodes.has(id)) nodes.set(id, element());
|
||||||
|
return nodes.get(id);
|
||||||
|
};
|
||||||
|
const modes = ['allow_exceptions', 'block_exceptions', 'custom'].map((value, i) => ({ value, checked: i === 0 }));
|
||||||
|
get('acl-profile-form').querySelectorAll = selector => selector === 'input[name="acl-profile-mode"]' ? modes : [];
|
||||||
|
const window = {};
|
||||||
|
const context = {
|
||||||
|
$: get, window, envelope: null,
|
||||||
|
t: key => `localized:${key}`,
|
||||||
|
el: (tag, text, cls) => {
|
||||||
|
const node = element(tag);
|
||||||
|
if (text !== undefined) node.textContent = text;
|
||||||
|
if (cls) node.className = cls;
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
runInNewContext(source.slice(start), context, { filename: 'src/admin/web/management.js' });
|
||||||
|
assert.equal(typeof window.rustProxyAclProfiles?.render, 'function', 'ACL panel initializer must finish');
|
||||||
|
assert.equal(typeof window.rustProxyAclProfiles?.refreshTranslations, 'function');
|
||||||
|
const hint = get('acl-profile-ip-help').insertedAfter?.[0];
|
||||||
|
assert.equal(hint?.tag, 'p', 'DDNS hint must be rendered');
|
||||||
|
assert.equal(hint?.dataset.i18n, 'aclDnsHelp', 'DDNS hint must remain translatable');
|
||||||
|
assert.equal(hint?.textContent, 'localized:aclDnsHelp');
|
||||||
|
window.rustProxyAclProfiles.reset();
|
||||||
|
console.log('PASS: ACL/DDNS real initializer runs without i18n temporal dead zone');
|
||||||
Reference in new issue
Block a user