90 lines
6.8 KiB
Markdown
90 lines
6.8 KiB
Markdown
# Web Login Runtime Mismatch
|
|
|
|
## Metadata
|
|
|
|
- Date: 2026-07-30
|
|
- Status: Resolved; authenticated live runtime verified
|
|
- Scope: Live ARR Web process on port 8766
|
|
- Confidence: Fact
|
|
- Source: Listener/process inspection, Keychain/launcher validation, loopback/LAN HTTP probes, source/config inspection, automated tests and isolated browser verification
|
|
- Last verified: 2026-07-31
|
|
- Stale trigger: Port-8766 process restart, login credential configuration, route/config change or LAN-address change
|
|
|
|
## Finding
|
|
|
|
The first page-failure check found a partial runtime mismatch: PID 37865 was still bound to `0.0.0.0:8766` and returned
|
|
HTTP 200 for `/`, `/h5`, `/api/health` and `/assets/app.js` on loopback and the then-current LAN address
|
|
`192.168.3.48`, while `/login` alone returned 404. The long-lived Python process predated the new login routes but read
|
|
newer static files from disk.
|
|
|
|
The 23:03 recheck found a complete service outage instead. No process listens on 8766, PID 37865 is gone, and `/`,
|
|
`/h5`, `/login`, `/healthz`, `/api/health` and `/assets/styles.css` all fail with connection refused on loopback. The
|
|
workstation's Wi-Fi address has also changed to `192.168.3.103`, where root and login probes likewise fail. No matching
|
|
Web/worker/ngrok process, 8765/8766/8877 listener or launch agent was found. There is no retained process log, so the
|
|
evidence does not prove why PID 37865 exited.
|
|
|
|
The login change was nevertheless relevant to recovery: current source intentionally refuses startup when
|
|
`ARR_WEB_USERNAME` or `ARR_WEB_PASSWORD` is absent. After the operator supplied both values, each was placed in a
|
|
separate macOS Keychain item and a credential-free local launcher restored the prior controlled database, OSS,
|
|
processing, monthly and company-report inputs. Detached Screen session `arr2-web-8766` owns the sole `*:8766` listener.
|
|
|
|
On 2026-07-31 the operator requested a credential rotation. Both values were replaced through interactive no-echo
|
|
Keychain input, the password item was rebuilt under stable non-credential account metadata, and the credential-free
|
|
launcher remained valid. A controlled restart replaced only the resolved Web listener and recreated the same detached
|
|
Screen topology; no credential value is recorded here.
|
|
|
|
## Completed Source Implementation
|
|
|
|
- `arr_web.auth` validates runtime `ARR_WEB_USERNAME` / `ARR_WEB_PASSWORD` with constant-time comparison and a bounded
|
|
per-client attempt ledger. Missing/invalid configuration fails Web startup closed.
|
|
- The authenticated `SessionLedger` issues random server-side sessions and per-session CSRF tokens, expires/revokes
|
|
them and retains `HttpOnly`, `SameSite=Strict` plus optional `Secure` cookie behavior.
|
|
- Login assets, `POST /api/login` and minimal `/healthz` are the only anonymous routes. Desktop/H5 documents redirect
|
|
to an allowlisted login target; all business APIs, detailed health, uploads, traces and downloads reject anonymous access.
|
|
- Desktop and H5 clients redirect expired sessions to login and expose CSRF logout. Logout starts hidden when an old
|
|
anonymous `/api/session` response lacks `username`; this kept PID 37865's mixed-version UI compatible before activation.
|
|
- Caddy Basic Auth was removed; Caddy remains the HTTPS boundary and the Web application owns human authentication.
|
|
|
|
## Verification
|
|
|
|
- Python and all three JavaScript files pass syntax checks.
|
|
- The final focused auth/Web/company/deployment set passes 33 tests. Full discovery passes 317 tests in 97.311 seconds
|
|
with 10 expected environment/fixture skips and no failures/errors.
|
|
- Isolated real-browser verification passed generic wrong-credential feedback, password visibility, successful desktop
|
|
and `/h5` return, desktop/H5 logout, zero console warnings/errors and no horizontal overflow at 375, 768, 1024 and
|
|
1440 CSS pixels.
|
|
- Ruby's standard YAML parser loaded the Compose file and deployment contracts confirm login env/readiness/Caddy
|
|
shape. Docker is unavailable on this workstation, so no live Compose expansion or image build is claimed.
|
|
- Live activation passes anonymous root 303 and business API 401; exact login, hardened cookie/session/CSRF,
|
|
authenticated desktop/H5/history reads, all five readiness flags, logout and post-logout rejection. Loopback and
|
|
`192.168.3.103` return `/healthz` 200; LAN root redirects to login and LAN `/login` returns 200.
|
|
- A 2026-07-31 follow-up found the service still healthy under the same detached Screen process, while DHCP had moved
|
|
the workstation address back to `192.168.3.48`. Loopback and `.48` root return 303 to login, `/healthz` and the login
|
|
document return 200, and the in-app browser rendered the complete login gateway. The prior `.103` URL is now stale.
|
|
- The same-day visual follow-up removed the login page's workflow narrative, numbered steps, duplicate brand placement,
|
|
welcome/access introduction and support disclaimers. The live gateway now presents one `ARR Report` heading, the
|
|
`username` and `password` fields, password visibility and the existing submit/error states. Thirty-three focused
|
|
Web/auth/UI tests pass; browser checks at 390x844 and 1280x720 have no horizontal overflow or console warnings/errors.
|
|
- The credential-rotation acceptance rejects the prior pair and accepts the new pair, then verifies anonymous root/API
|
|
boundaries, hardened cookie/session/CSRF, desktop/H5, logout revocation, all six current detailed readiness flags and
|
|
loopback plus `192.168.3.48` health. Two read-only snapshots remained 30 daily jobs, 4 monthly versions and 4 company
|
|
jobs; latest creation times predate the 15:30 +08 restart. Nine focused auth/deployment tests pass, and literal scans
|
|
of the workspace, launcher, state logs and process list are clean.
|
|
- The initial activation totals were 24 daily jobs, 4 monthly versions and 3 company jobs. No XML upload,
|
|
company-report generation, Booking activation, monthly worker or other business mutation was started by either
|
|
activation or rotation acceptance.
|
|
|
|
## Activation Result and Operating Boundary
|
|
|
|
- Current LAN entry as of 2026-07-31: `http://192.168.3.48:8766/`; DHCP may change this address again.
|
|
- `/Users/chillishark/.local/bin/arr2-web-8766` is owner-executable only and contains paths/Keychain labels, not secret
|
|
values. Its `--check` mode validates required private inputs without printing them.
|
|
- The active Screen session is detached but not a reboot-persistent process manager. A future controlled restart should
|
|
validate the launcher, stop the exact 8766 listener and start one `screen -dmS arr2-web-8766` session.
|
|
- The latest requested values were rotated successfully, but the password still matches the username. A future
|
|
strength rotation should use a distinct high-entropy password, update only Keychain and restart once; never commit the
|
|
value or put it in process arguments.
|
|
|
|
Live login/readiness is complete. A no-PII upload-filename check and one released 5/5 company-report job remain separate
|
|
business-mutation acceptance work.
|