# Security & Auth Conventions

## OAuth2 PKCE Flow

Auth lives in `src/components/security/`. The library implements OAuth2 Authorization Code + PKCE against an OpenStack IDP.

### Key Modules

| File | Purpose |
|------|---------|
| `methods.js` | Core auth: `doLogin`, `initLogOut`, `getAccessToken`, `storeAuthInfo`, token refresh with mutex (SuperTokensLock) |
| `actions.js` | Redux actions: `onUserAuth`, `getUserInfo`, `doLogout` |
| `reducers.js` | Auth state: `loggedUserState` with `member`, `sessionState` |
| `constants.js` | Error code constants (`AUTH_ERROR_*`) |
| `abstract-auth-callback-route.js` | Route component for OAuth callback handling (v1) |
| `abstract-auth-callback-route-v2.js` | OAuth callback with PKCE verifier exchange (v2) |
| `session-checker/op-session-checker.js` | Session iframe checker for silent re-auth |

### Token Management

- Access tokens stored via `storeAuthInfo()` in localStorage
- Refresh uses `SuperTokensLock` (browser-tabs-lock) for cross-tab mutex
- ID token validated with `idtoken-verifier`
- PKCE: SHA256 code challenge via `src/utils/crypto.js` (`getSHA256`, `getRandomBytes`)

### Auth Error Handling

`authErrorHandler` in `utils/actions.js` handles HTTP errors:
- **401:** Triggers `initLogin()` → redirects to IDP (with session-clearing guard to prevent loops)
- **403:** Shows "not authorized" message
- **412:** Shows server-provided validation errors
- **Other:** Generic error with optional `res.body.message`

### Conventions

- Auth methods imported from `security/methods` — never call IDP directly
- Access token passed as query param `access_token` (not Bearer header) in `getRequest`/`putRequest` helpers
- `getAllowedUserGroups()` reads from env/config to restrict access by group membership
- Consumer apps must provide `loggedUserState` in their Redux store
