PR #1093 fixed the chroot anon→Keycloak bug for routes that mounted under SovereignConsoleLayout. Iter-2 of the routing matrix surfaced 7 routes that BYPASS the layout, still hitting Keycloak's hosted login on anon visit: /app/$componentId (TC-R-058) /users/$userId (TC-R-059) /dashboard/ trailing slash (TC-R-069) /Dashboard capital case (TC-R-070) //dashboard double slash (TC-R-093) /apps + network filter (TC-R-075, TC-R-076) Fix: lift the auth gate from SovereignConsoleLayout (per-route layer) to rootRoute.beforeLoad (universal). The new gate runs BEFORE every route's own beforeLoad, so no route can bypass it. Two responsibilities of rootBeforeLoad: 1. Path canonicalisation — collapse //+ → /, strip trailing /, lowercase. Malformed variants redirect to canonical via hard navigation (preserves search + hash byte-for-byte). This catches the trailing-slash / capital / double-slash edges in one rule. 2. Sovereign-mode auth gate — when no session is detected and the canonical path is NOT in PUBLIC_PATH_PREFIXES, redirect to /login?next=<canonical>. Public allow-list is path-prefix matched: /login, /signup, /forgot, /auth/{handover,handover-error,callback}, /readyz, /healthz, /sovereignty/preview, /designs, /api/ Helpers (canonicalisePath, isPublicPath, hasCatalystSession) extracted to src/app/auth-gate.ts so they can be unit-tested without booting the router. 24 unit tests cover canonicalisation rules, public-path matching (including prefix-collision rejection like /loginz), session detection, and an .each() integration block over all 7 bypass routes. SovereignConsoleLayout sets sessionStorage['catalyst:authed']='1' after a successful /whoami probe so the rootRoute gate is permissive for already-authed users (the HttpOnly catalyst_session cookie is invisible to JS). Anti-regression: TC-R-002 (/dashboard) and TC-R-049 (network filter on /dashboard) — already PASSING in iter-2, must continue to PASS. Mothership routing (catalyst-zero mode) is a no-op in the new gate; provisionAuthGuard / wizardAuthGuard continue to handle their own routes via Fix #B (PR #1091). Co-authored-by: Hati Yildiz <hati.yildiz@openova.io> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| .pr-evidence | ||
| e2e | ||
| public | ||
| scripts | ||
| src | ||
| .gitignore | ||
| Containerfile | ||
| eslint.config.js | ||
| index.html | ||
| nginx.conf | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| README.md | ||
| tsconfig.app.json | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Oxc
- @vitejs/plugin-react-swc uses SWC
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])