v0.31.3
This commit is contained in:
1 parent
0facfe6f5c
commit
95c55da2ee
39 files changed
+715
-151
No files matched your search
@@ -0,0 +1,43 @@
|
||||
# RustProxy 0.31.3 - Mobile admin session recovery
|
||||
|
||||
## Scope and evidence
|
||||
|
||||
The supplied 0.31.2 source was inspected and executed with a deterministic Node.js VM harness. The original functions permitted two simultaneous `/api/auth/session` requests from `pageshow` and `visibilitychange`. In the reproduced race, one `auth.invalid_origin` response called `location.reload()`, another successful response cleared the reload-protection marker, and a subsequent 403 triggered another reload. The event ordering and client-side failure were reproduced; the original server-side rejection on the reported mobile device remains unexplained because no captured mobile HTTP exchange was provided.
|
||||
|
||||
The dashboard's prior visibility handler also restarted the SSE channel and refresh timers before it checked the session. A full dashboard navigation rejected at the server could return raw JSON as the document, rather than an actionable page.
|
||||
|
||||
## Changes
|
||||
|
||||
- `src/admin/web/app/session-resume.js`: shared in-flight session validation; one visible retry path after 403/network errors, no `location.reload()` on resume; successful checks update CSRF/session display and release polling only if the auth epoch is unchanged. An HTTP 401 keeps the existing login/lock flow.
|
||||
- `src/admin/web/app/refresh.js`: `visibilitychange`, `pagehide`, and BFCache `pageshow` share a resume gate. Pause/abort polling and close SSE before validating; allow background tasks only after success. Repeated callbacks during the same visible period do not initiate another check.
|
||||
- `src/admin/web/app/runtime.js` and `core.js`: initial-startup reload marker is cleared only after successful full activation, including preferences/configuration. Startup errors stop the refresh coordinator and display a visible failure. Session failures show a localized manual retry button.
|
||||
- `src/admin/session.rs`: unchanged Origin matching and `Sec-Fetch-Site` enforcement; 403 from invalid Origin now has bounded structured diagnostics showing method, path (without query), sanitized Origin, Host, expected external scheme/authority, fetch site, trust status, and safe forwarding metadata. No Cookie, Authorization, CSRF token, secret, query parameter or untrusted forwarded Host value is logged. Browser document navigation requesting HTML receives a standalone 403 error/retry page; API responses remain JSON.
|
||||
- Localization (`en_US`, `pl_pl`), versioned panel assets, developer checks and release identity were updated. No schema/config/proxy data-plane or public route change.
|
||||
|
||||
## Test matrix
|
||||
|
||||
| Scenario | Source simulation | Live acceptance still needed |
|
||||
| --- | --- | --- |
|
||||
| Visibility + BFCache in one event sequence | One `/api/auth/session` check | iOS Safari / Android Chrome |
|
||||
| 403 during resume | No automatic reload; error screen; paused SSE and tasks | Capture browser headers and proxy forwarding |
|
||||
| Manual retry after temporary rejection | Single recheck; restored shell/SSE on success | Network interruption/recovery |
|
||||
| HTTP 401 | Existing lock/login behavior | Expired/revoked real session |
|
||||
| Pagehide/restore, 10 repeated cycles | One check per return; no leaked event handlers or parallel SSE | Real BFCache lifecycle |
|
||||
| Stale session response after logout | Ignored without restoring session state | Concurrent logout/restore |
|
||||
| Startup failure | Visible error, recovery marker retained | Missing JS or language/config response |
|
||||
| Foreign Origin / cross-site | Rust regression test added, exact checks retained | Real server test with Rust/Cargo |
|
||||
| Document navigation blocked by Origin | Rust regression test added, 403 HTML response | Mobile top-level navigation |
|
||||
|
||||
The deterministic browser suite uses actual application code and a simulated API. It is *not* a real browser, reverse proxy, or compiled Rust backend test. `Cargo.lock` comes from the prior 0.31.2 candidate, remains unresolved against the current dependency constraints and must be generated by a real Rust 1.99+ Cargo resolution. Do not deploy on the basis of static/source-only testing.
|
||||
|
||||
## Release-host validation
|
||||
|
||||
```bash
|
||||
bash scripts/resolve_dependencies_0312.sh
|
||||
./dev.sh check
|
||||
./dev.sh test
|
||||
./dev.sh release
|
||||
(cd docker-agent && go test ./...)
|
||||
```
|
||||
|
||||
Then verify on a real administrator endpoint with correct trusted reverse-proxy forwarding. Compare the external scheme/authority with `Origin`, `Host`, `Sec-Fetch-Site` and **only trusted** `X-Forwarded-Host` / `X-Forwarded-Proto` in the diagnostic log. Test at least 20 return-to-tab cycles on actual mobile browsers, including BFCache, session expiration, temporary 403 responses and recovery. Confirm that disallowed origins still return 403 and that polling/SSE do not grow across cycles. Do not turn off Origin/CSRF or loosen forwarded-header trust to hide the symptom.
|
||||
+2
-1
@@ -31,6 +31,7 @@ This is the canonical index for the current project documentation. The authentic
|
||||
- [0.26.3 implementation note](V0.26.3_IMPLEMENTATION.md) - global interface scaling, chart themes, square draft dock and Settings navigation polish.
|
||||
- [0.26.2 implementation note](V0.26.2_IMPLEMENTATION.md) - unified Logs navigation, field-query search, dynamic JSON columns and RAW parsing.
|
||||
- [0.26.1 implementation note](V0.26.1_IMPLEMENTATION.md) - historical vhost-aware protocol logging and Stored Logs UX milestone.
|
||||
- [0.31.3 mobile session / invalid-Origin recovery](IMPLEMENTATION_0.31.3.md) - deterministic BFCache and visibility session coordination, 403 diagnostics, recovery and remaining acceptance.
|
||||
- [0.31.1 mobile panel bootstrap](IMPLEMENTATION_0.31.1.md) - panel script readiness, versioned assets, failure recovery and acceptance tests.
|
||||
- [0.31.0 security audit](SECURITY_AUDIT_0.31.0.md) - current API/panel/BAN/PURGE attack-surface review, hardening and remaining runtime verification.
|
||||
- [0.31.0 implementation report](IMPLEMENTATION_0.31.0.md) - consolidated changes, exact file inventory, validation results and outstanding Rust runtime acceptance.
|
||||
@@ -81,7 +82,7 @@ This is the canonical index for the current project documentation. The authentic
|
||||
|
||||
## Historical or version-labelled context
|
||||
|
||||
Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [IMPLEMENTATION_0.31.1.md](IMPLEMENTATION_0.31.1.md); [IMPLEMENTATION_0.31.0.md](IMPLEMENTATION_0.31.0.md) is retained as the previous milestone; [V0.29.1_IMPLEMENTATION.md](V0.29.1_IMPLEMENTATION.md) is retained as historical context, and [V0.29.0_IMPLEMENTATION.md](V0.29.0_IMPLEMENTATION.md) is retained as the prior redirect/health/cache/log milestone; [V0.28.2_IMPLEMENTATION.md](V0.28.2_IMPLEMENTATION.md) is retained as the prior certificate-hardening milestone; [V0.28.1_IMPLEMENTATION.md](V0.28.1_IMPLEMENTATION.md) is retained as the prior external-path milestone; [V0.28.0_IMPLEMENTATION.md](V0.28.0_IMPLEMENTATION.md) is retained as the prior GeoIP/listener/cache milestone, and [V0.27.3_IMPLEMENTATION.md](V0.27.3_IMPLEMENTATION.md) is retained as the prior HTTP/3/cache-maintenance milestone, [V0.27.2_IMPLEMENTATION.md](V0.27.2_IMPLEMENTATION.md) is retained as the prior managed-ACME repair, [V0.27.1_IMPLEMENTATION.md](V0.27.1_IMPLEMENTATION.md) as the prior managed-runtime/list-sorting milestone, and older version notes remain historical evidence. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain available for traceability.
|
||||
Version-labelled `V*.md` files are retained as historical implementation/audit records. Their version number describes the audited milestone. The current release implementation note is [IMPLEMENTATION_0.31.3.md](IMPLEMENTATION_0.31.3.md); [IMPLEMENTATION_0.31.1.md](IMPLEMENTATION_0.31.1.md) is retained as the prior mobile milestone; [IMPLEMENTATION_0.31.0.md](IMPLEMENTATION_0.31.0.md) is retained as the previous milestone; [V0.29.1_IMPLEMENTATION.md](V0.29.1_IMPLEMENTATION.md) is retained as historical context, and [V0.29.0_IMPLEMENTATION.md](V0.29.0_IMPLEMENTATION.md) is retained as the prior redirect/health/cache/log milestone; [V0.28.2_IMPLEMENTATION.md](V0.28.2_IMPLEMENTATION.md) is retained as the prior certificate-hardening milestone; [V0.28.1_IMPLEMENTATION.md](V0.28.1_IMPLEMENTATION.md) is retained as the prior external-path milestone; [V0.28.0_IMPLEMENTATION.md](V0.28.0_IMPLEMENTATION.md) is retained as the prior GeoIP/listener/cache milestone, and [V0.27.3_IMPLEMENTATION.md](V0.27.3_IMPLEMENTATION.md) is retained as the prior HTTP/3/cache-maintenance milestone, [V0.27.2_IMPLEMENTATION.md](V0.27.2_IMPLEMENTATION.md) is retained as the prior managed-ACME repair, [V0.27.1_IMPLEMENTATION.md](V0.27.1_IMPLEMENTATION.md) as the prior managed-runtime/list-sorting milestone, and older version notes remain historical evidence. The latest retained audit is [V0.25.5_AUDIT.md](V0.25.5_AUDIT.md); older audit files remain available for traceability.
|
||||
|
||||
Older context documents such as [INTEGRATIONS_040](INTEGRATIONS_040.md), [MANAGEMENT](MANAGEMENT.md), [SECURITY_AUDIT](SECURITY_AUDIT.md), [ACME_RFC2136](ACME_RFC2136.md) and older version audits remain available for traceability but should not override the current functional/technical documents above.
|
||||
|
||||
|
||||
+13
-1
@@ -1,4 +1,16 @@
|
||||
# Verification report - RustProxy 0.31.2
|
||||
# Verification report - RustProxy 0.31.3
|
||||
|
||||
## 0.31.3 - invalid-Origin resume and mobile panel recovery (2026-10-11)
|
||||
|
||||
- **Source:** the uploaded RustProxy 0.31.2 ZIP plus the user's case description. No remote repository/history or real mobile network capture was provided.
|
||||
- **Reproduced in the original source:** two overlapping session validations; a 403 during return-to-tab caused `location.reload()`; a concurrent successful validation cleared the recovery marker; another 403 could reload again. Separately, refresh tasks and SSE restarted before a resumed session was validated.
|
||||
- **Corrections:** single-flight session verification and coalesced visibility/BFCache events; suspend polling and SSE until verified; visible localized retry on 403/network errors; unchanged login handling on 401; clear the startup recovery marker only after full initialization; stop refresh on startup failure. Invalid-Origin top-level HTML navigation returns an explicit 403 error page rather than raw JSON. Server Origin/CSRF/cross-site enforcement is unchanged; structured diagnostic logging redacts credentials and untrusted forwarding data.
|
||||
- **Regression coverage:** `tools/checks/origin_resume_0313_ui_test.mjs` exercises actual JavaScript source against deterministic session API outcomes, repeated tab cycles, stale auth epoch, SSE suspension/resume, retry, 401 and startup marker. Rust unit/integration tests were added for blocked foreign origins, safe diagnostic values and readable 403 document handling, but cannot run here without Cargo.
|
||||
- **PASS (2026-10-11):** `tools/checks/origin_resume_0313_ui_test.mjs` and all 11 other bundled Node UI tests; actual assembled dashboard bundle parsed by Node; original-source Node reproduction recorded the duplicate request/reload race.
|
||||
- **PASS (2026-10-11):** source/module/version/security/dependency contracts, SQLite schema-9 migration and upgrade smoke (`release_smoke.py`), documentation/Reader (`docs_check.py`), language packs (`langs_check.py`), shell syntax and Go Docker Agent `go test ./...`. Memory workload simulated 300,000 PURGEs; 2,000 HTTP requests targeted a **Python test peer**, not the RustProxy executable.
|
||||
- **NOT VERIFIED:** `./dev.sh check` exits 127 because `cargo`/`rustc` are absent. `./dev.sh test` passed all Rust-independent stages through docs/locales and reached the same missing-Cargo gate; it did not run Rust unit tests. No compiled RustProxy, iOS/Android browser, trusted reverse-proxy trace or production rollout was exercised.
|
||||
- **Verification limit:** the new Rust tests are written but unexecuted; the lockfile is an inherited dependency snapshot, not a resolved 0.31.3 graph. The code has not passed a compiler-enabled release gate.
|
||||
- **Release gate remains OPEN:** the local environment has no rustc/cargo/rustfmt. The inherited lockfile is unresolved for 0.31.2/0.31.3 dependency families. Run Cargo resolution, fmt, clippy, Rust tests and real admin/reverse-proxy/mobile acceptance on a Rust 1.99+ host before production release.
|
||||
|
||||
## 0.31.2 — stable library upgrade candidate (2026-10-10)
|
||||
|
||||
|
||||
Reference in new issue
Block a user