Files
jobtrackingapp/docs/redesign/phase-5/p5-15/p5-15-01/analytics-auth-repair/README.md
T

5.3 KiB

P5-15-01R-03 — Analytics authentication return-path repair

Source: 339e3ba591c91dcd3590d4cbc451ad31268f1aec, development codex/ui-redesign-phase4. This checkpoint owns AUTH-01 and directly related return-target validation only. Production main remains unchanged and NO-GO. No Analytics data model, saved-search/Rules implementation, P5-15-02, P5-13, Docker, B07 or deployment work is authorized here.

Before-fix native evidence and demonstrated cause

The unchanged original functional-acceptance.spec.ts anonymous case was rerun against the disposable Development/SQLite API and actual local sign-in on 2026-10-10. All route census steps complete; the assertion at line154 fails: requested /analytics?months=6, returned /analytics. The native run has zero passes/one failure, zero skipped/flaky/retries. The trace, screenshot and JSON are retained under ignored .artifacts/p5-15-01R-03/browser/auth-original-red*; portable final evidence follows validation. This is the original desired-state assertion, not a weakened replacement.

App.Shell defines path = location.pathname and sends only that value as state.from when redirecting to the public landing page. Search and hash are lost at this boundary, before sign-in. Landing forwards the same router state to Login. Login already uses the supplied string for local, two-factor, Google and Microsoft completion; Analytics receives a query-free destination and chooses its existing twelve-month default. Its only supported reporting query is months:6 or24, otherwise12. No date/status/view controls are invented.

The original Login slash-only validation also permits raw control characters, malformed encoded paths and normalized auth-entry destinations. Local URL normalization shows the literal-tab target /\t/evil.example can become a different origin; this is a demonstrated validation gap, not a demonstrated native external redirect or tenant exposure. Installed router replace handling may reject it with a history SecurityError. The bounded repair must choose the existing safe dashboard fallback instead.

Before application changes, the Login component regression run has 17passing/12failing out of29. Sixteen cases are new:12 untrusted target variants plus valid encoded URL, valid existing Jobs context, unsafe nested context and account-disposal entry. Existing Login cases remain passing; failures demonstrate missing safe fallback/context handling. JSON and log are retained separately; the initial shell wrapper incorrectly reported exit0, so the test JSON/failed assertions, not that wrapper exit, are authoritative RED evidence.

Bounded execution and invariants

  1. Retain the genuine native RED and add browser/local return-boundary regressions; commit/push this independently before application edits.
  2. Preserve pathname/search/hash and valid existing Jobs return context at the existing App/Login owners. Validate untrusted destinations before every existing completion path; no new persistent redirect store or provider contract.
  3. Exercise native Analytics periods/encoding/defaults/refresh/history, failed-login retry, expiry/logout, owned/foreign resources and unsafe client state. Keep saved searches, Rules, P2-D01, revision/fidelity and Production withholding green.
  4. Run full fresh validation, reconcile57 groups without promoting incomplete groups to PASS, record evidence and immediately commit/push each completed unit.

Existing session/account invalidation intentionally disposes the previous page/providers and replaces with /login?sessionChanged=1; previous-account private context must remain discarded. Backend ownership and role checks remain authoritative. Synthetic accounts/disposable SQLite only; no real external identity provider or production data.

Bounded implementation checkpoint

App.Shell now carries pathname/search/hash plus the existing navigation context through the same landing/sign-in state. safeAuthReturnPath rejects external/protocol-relative targets, controls/backslashes, malformed encoding, recursively encoded unsafe paths and normalized authentication-entry loops, including case variants. It returns valid internal strings unchanged. Login uses that validated destination across local, two-factor, Google and Microsoft completion, replaying only validated existing Jobs return context. Account-disposal entries explicitly abandon old destinations. No URL storage, Analytics aggregation, authentication API or provider changes.

Final application changes have fresh 1,033/1,033 backend, 490/490 frontend, 31/31 focused Login, the unchanged original native AUTH-01 1/1, and new native return/security journeys 5/5 passing. TypeScript, lint and both builds pass. The case-insensitive login-loop gap also has separate RED evidence before correction: two failures, two selected passes and27 not selected; final31 cases pass. External identity callbacks/two-factor are component fixtures, not live provider acceptance.

The complete browser/security/fidelity reconciliation is still running. Current checkpoint status: IN PROGRESS, with the demonstrated AUTH-01 repaired but no final acceptance claim yet. P5-15-02 and production are not cleared. Broader human/device/font qualification, historical preference500 causes, the CV Unsaved intermittent observation and P5-13 deferral remain open.