Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion docs/architecture/keycloak-spa-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ Without this, `keycloak-js` has nowhere to redirect to.

## Local development

For frontend development you do not need access to the DLS identity server. A self-contained Keycloak mock lives under `keycloak-mock/` in this repository and provides a `dls` realm with a pre-configured `SmartEM` client and seeded users.
For frontend development you do not need access to the DLS identity server. A self-contained Keycloak mock lives under `keycloak-mock/` in this repository and provides a `dls` realm with a pre-configured `SmartEM_User` client and seeded users.

See [Local Keycloak for SmartEM frontend dev](../development/local-keycloak.md) for setup and integration with the frontend.

### Mock mode

There is also a second local-dev path that bypasses Keycloak entirely: `npm run dev:smartem:mock` (which sets `VITE_ENABLE_MOCKS=true`) swaps the real `KeycloakAuthProvider` for a `MockAuthProvider` that emits a hardcoded user identity and a synthetic `Bearer mock-token`. MSW intercepts every `/api/` request in the browser, so neither Keycloak nor the backend is contacted. `/config.json` is not fetched either.

This mode is for visual UI demo only — `login()` and `logout()` are no-ops, the mock identity is fixed, and the synthetic token is never validated. Anything that needs a real session lifecycle has to use the full Keycloak path (with the local mock or DLS realm). Mock mode is distinct from the "Keycloak is unreachable" error state, which the real provider handles by rendering the sign-in screen with a connection-error message.
21 changes: 15 additions & 6 deletions docs/development/local-keycloak.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,22 +91,31 @@ Edit `smartem-frontend/apps/smartem/public/config.json`:
"url": "http://localhost:30090",
"realm": "dls",
"clientId": "SmartEM_User"
},
"authEnabled": true
}
}
```

Use `http://localhost:30090` for the k3s NodePort. For docker-compose Keycloak or a port-forwarded pod, use `http://localhost:8080`. If Vite runs on a host other than the one with the cluster, use `http://<node-ip>:30090`.

The config is fetched with `cache: 'no-store'` and applied before the SPA mounts, so a browser reload picks up edits without restarting Vite.

## Disabling auth entirely (Vite dev only, with caveat)
## Mock mode (no Keycloak, no backend)

Set `authEnabled: false` in `apps/smartem/public/config.json` and the `AuthGate` (`apps/smartem/src/auth/AuthGate.tsx`) short-circuits — the SPA renders without contacting Keycloak at all. Useful for pure UI iteration.
For pure UI iteration without bringing up Keycloak or the backend, run the SPA in mock mode:

**Caveat:** the backend (`smartem-decisions`) always enforces Bearer-token validation on non-exempt requests since smartem-decisions#285 — there is no opt-out. With `authEnabled: false` the SPA renders, but every `/api/` call returns 401. This mode is only useful when paired with MSW (`VITE_ENABLE_MOCKS=true` in `apps/smartem/.env.local`), or for views that don't fetch from the backend.
```bash
cd smartem-frontend
npm run dev:smartem:mock
```

This sets `VITE_ENABLE_MOCKS=true` at build time, which has two effects:

- MSW intercepts every `/api/` request in the browser and answers from generated faker fixtures (`packages/api/src/generated/default/default.msw.ts`).
- The `AuthGate` swaps `KeycloakAuthProvider` for a `MockAuthProvider` that emits a hardcoded user identity (`Mock User`, `mock@example.diamond.ac.uk`, fedId `mock001`) and a synthetic `Bearer mock-token`. Keycloak is never contacted; `/config.json` is not fetched.

`login()` and `logout()` are no-ops in mock mode — there is no session to end. The mock provider is intentionally narrow: it lets the dashboard and any auth-conditional UI render in a logged-in state for visual demo, nothing more. Anything that needs a real token, real claims, or real session lifecycle has to use the full Keycloak path above.

This is a deliberately separate path from "Keycloak is unavailable" — the latter is an error state to recover from, the former is a dev convenience for offline/mocked UI work.
The mock mode is a separate, parallel path from "Keycloak is unreachable" — the latter is an error state the SPA recovers from by showing the sign-in screen with a connection-error message.

## Editing the realm

Expand Down
11 changes: 5 additions & 6 deletions k8s/environments/development/smartem-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@ metadata:
namespace: smartem-decisions
data:
# Fetched at SPA boot from /config.json. The URL must be browser-reachable;
# NodePort 30090 maps to the in-cluster keycloak-service:8080. authEnabled
# is true because the backend always enforces Bearer-token validation
# (smartem-decisions#285 removed the KEYCLOAK_AUTH_REQUIRED escape hatch);
# the SPA must complete the login ceremony to talk to /api/.
# NodePort 30090 maps to the in-cluster keycloak-service:8080. Auth is
# always on at the SPA level (smartem-frontend#101 dropped the authEnabled
# toggle); the backend likewise enforces Bearer-token validation
# unconditionally (smartem-decisions#285).
config.json: |
{
"keycloak": {
"url": "http://localhost:30090",
"realm": "dls",
"clientId": "SmartEM_User"
},
"authEnabled": true
}
}

---
Expand Down
3 changes: 1 addition & 2 deletions k8s/environments/production/smartem-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ data:
"url": "https://identity.diamond.ac.uk",
"realm": "dls",
"clientId": "SmartEM_User"
},
"authEnabled": true
}
}

---
Expand Down
3 changes: 1 addition & 2 deletions k8s/environments/staging/smartem-frontend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ data:
"url": "https://identity-test.diamond.ac.uk",
"realm": "dls",
"clientId": "SmartEM_User"
},
"authEnabled": true
}
}

---
Expand Down
3 changes: 1 addition & 2 deletions keycloak-mock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ Edit `smartem-frontend/apps/smartem/public/config.json`:
"url": "http://localhost:30090",
"realm": "dls",
"clientId": "SmartEM_User"
},
"authEnabled": true
}
}
```

Expand Down
Loading