# goi-web client Vite + React front end for JWT authentication using **HttpOnly cookies**, intended to run against a **Spring Boot** backend. This is the standalone client extracted from the original monorepo (the Express `apps/server` and monorepo wrapper were removed). ## Run ```bash npm install npm run dev # http://localhost:5173 ``` The dev server proxies API calls to the backend, so make sure your Spring Boot app is running (default `http://localhost:8080`). ## How requests are routed (CORS-free dev) `.env` uses **relative** base URLs: ``` VITE_AUTH_SERVICE_URL=/auth-service VITE_OPR_API_URL=/opr-rest-api ``` `vite.config.js` proxies those prefixes to the backend: ``` /auth-service/* -> http://localhost:8080/auth-service/* /opr-rest-api/* -> http://localhost:8083/opr-rest-api/* ``` Because the browser only ever talks to `localhost:5173` (same origin), **there is no CORS in development** and the HttpOnly cookies attach normally. Change the `BACKEND` constant in `vite.config.js` if your backend port differs. If you prefer to call the backend **directly** (no proxy), switch `.env` to absolute URLs (commented examples are in the file) and configure CORS on the backend: `allowCredentials = true` with an **explicit** origin (`http://localhost:5173`) — `*` is not allowed together with credentials. ## auth vs data calls - `src/lib/endpoints.js` exposes `authUrl()` and `oprUrl()`. - Auth calls (`/auth/login`, `/auth/me`, `/auth/logout`, `/auth/token/refresh`) go through `authUrl()` → auth service. - Data calls go through `oprUrl()` → opr/data service. See `src/features/products/ProductsPage.jsx` for an example. Never fetch data from the auth URL. ## Backend contract the client expects - `POST /auth-service/auth/login` — sets HttpOnly cookies, returns the user object. - `GET /auth-service/auth/me` — returns `{ authenticated: true, role, firstName, lastName, ... }` when logged in. `role` drives the client-side role checks. - `POST /auth-service/auth/logout` — clears cookies. - `POST /auth-service/auth/token/refresh` — rotates the access token (called automatically on 401). - `GET /opr-rest-api/products` (example) — returns `{ status, created, data: [...] }`. ## Role-based access (RBAC) - `src/auth/authGuard.jsx` provides `RequireAuth` and `RequireRole`. - `` (or an array of roles) guards a route; the sidebar shows the Admin link only to admins. - **The front-end guard is UX only.** Always enforce roles on the server too (e.g. Spring Security `@PreAuthorize("hasRole('ADMIN')")`). The client can be tampered with. ## Notes - Match the `role` strings to whatever your backend returns (the reference uses lowercase `"user"` / `"admin"`). - The dead `App.css` (Vite starter leftover) was removed.