---
module: profile.display
title: Display
tab: Internal
order: 20
audience: internal
---

Ops/support view of **Profile → Display** (items-per-page, date format, time format, timezone). These are **per-user, self-service** preferences — there is no admin override screen and no "manage another user's display settings" path.

## Who can change what
- **Not admin-gated.** The backend maps `/auth/api/users/me/**` under `.anyRequest().authenticated()` in `hiveops-auth` `SecurityConfig`. Any authenticated principal (CUSTOMER, ADMIN, MSP_ADMIN, BCOS_ADMIN) edits **only their own** preferences — the endpoint keys off the JWT subject (`@AuthenticationPrincipal` email), never a path/user id.
- There is **no** `hasAnyRole('MSP_ADMIN','BCOS_ADMIN')` on these routes. If someone asks "how do I set a user's timezone for them" — you can't from the UI; it requires a DB edit (see below).
- Preferences are **personal and isolated** — changing one user's Display settings never affects a teammate (matches the Overview "personal to your account" note).

## What actually gets stored
- One JSONB blob per user: `users.preferences` in DB **`hiveiq_auth`**. The four Display fields live alongside notification/appearance/security prefs in the same object.
- Display defaults (server-side, `UserPreferences` entity): `itemsPerPage=25`, `dateFormat=MM/DD/YYYY`, `timeFormat=12-hour`, `timezone=America/New_York`.
- A brand-new user (or one migrated before V9) has `preferences = '{}'` — the service returns entity defaults, so the UI shows defaults even though the column is effectively empty until first Save.

## First things to check when it misbehaves
1. **"My display settings won't save / revert after reload"** → the save is a `PUT /auth/api/users/me/preferences` to **hiveops-auth (port 8082)**. Confirm the request 200s. A 401 = expired/missing bearer token (localStorage `token`); 403 = CORS/gateway, not authorization.
2. **CORS on profile.bcos.cloud** → `hiveops-auth` requires the frontend origin in `CORS_ALLOWED_ORIGINS` (env). `https://profile.bcos.cloud` must be present; a missing origin surfaces as a browser CORS failure, not a server error.
3. **"Save button stays greyed out"** → by design: Save is disabled until a field changes (`unsaved` flag). Not a bug.
4. **"Dates still show US format everywhere"** → Display prefs are **read and applied by each consuming SPA**, not enforced centrally. If one app ignores the pref, that app isn't calling `GET /auth/api/users/me/preferences` — it's an app-side bug, not an auth/profile bug.
5. **Settings load but are wrong per user** → look at the JWT: the wrong `sub`/email = wrong user row. Verify the token, not the preferences.

## Manual fix (support-side)
Read or reset one user's Display prefs directly (auth DB is on the database VM — ProxyJump, not the services VM):
```sql
-- inspect
SELECT email, preferences FROM users WHERE email = 'user@example.com';
-- reset just the display fields to defaults
UPDATE users
SET preferences = preferences
    || '{"itemsPerPage":25,"dateFormat":"MM/DD/YYYY","timeFormat":"12-hour","timezone":"America/New_York"}'::jsonb
WHERE email = 'user@example.com';
```

## Common failure modes → fix
| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| Save returns 401 | Expired bearer token | Re-login (refresh access token) |
| Save/GET blocked in browser (CORS) | Origin not in `CORS_ALLOWED_ORIGINS` | Add `https://profile.bcos.cloud` to hiveops-auth env, restart |
| `itemsPerPage` rejected (400) | Value out of `1..500` bound | Frontend only offers 10/25/50/100; a custom PUT outside range is validation-rejected |
| Prefs empty for old user | Pre-V9 row / `'{}'` | Harmless — defaults returned; populated on first Save |
| One app ignores format | That SPA not reading prefs | App-side bug; not hiveops-auth |
