Commit Graph
6 Commits
Author SHA1 Message Date
Lucas Berger 982438dc10 style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
2026-06-11 20:35:18 -04:00
Lucas Berger 2c8f1a28af fix(auth): self-healing displayName; drop synthetic Member<sub> from storage
The legend showed 'Member 972be1a3' because Authelia does not emit
name/preferred_username/email in the ID TOKEN (only at the userinfo endpoint),
and @hono/oidc-auth reads ID-token claims only. The real fix is an Authelia
claims_policy adding those claims to id_token for the familysync client.

App-side robustness so it self-heals once Authelia is fixed (no DB surgery):
- deriveDisplayName now returns null (not a synthetic 'Member <sub>') when no
  real claim is present, so we never persist an ugly sub string; the UI degrades
  to a generic 'Member'.
- upsertUser now tracks the IdP name authoritatively: a non-null displayName that
  differs from the stored value updates the row (blank/stale 'Member …'/email →
  real name on next login). A null value never overwrites a good stored name.
2026-06-07 16:17:17 -04:00
Lucas Berger a99ef1daae refactor(260607-l6l): extract shared deriveDisplayName helper (BUG 2 DRY)
The displayName claim-preference logic (name → preferred_username → email →
sub fallback) was duplicated verbatim in me.ts and events.ts resolveUserId.
Extract it to auth/user.ts as deriveDisplayName and use it in both call sites,
so the rule has one definition. Update the events.test.ts user.js mock to keep
the real helper (spread importActual) while stubbing only upsertUser.
2026-06-07 15:37:18 -04:00
Lucas Berger 23c8bb3402 fix(260607-l6l): derive displayName from OIDC claims in me.ts + resolveUserId
BUG 2: Both me.ts and events.ts resolveUserId were passing email (often
absent) as displayName to upsertUser, resulting in blank legend names.
Also, upsertUser returned existing rows unchanged even when displayName
was null and a better value was now available.

- me.ts: derive displayName via name → preferred_username → email →
  "Member <sub-prefix>" fallback, checked defensively. Updated JSDoc.
- events.ts resolveUserId: same derivation so write-path upserts don't
  re-blank a correctly-set displayName.
- user.ts: when existing row has null displayName and caller supplies one,
  issue an UPDATE so already-existing blank rows are corrected on next login.

Authelia-side emission of name/preferred_username is an operator concern
(claim mappings / userinfo scope in authelia config) — out of scope here.
The code now reads whatever claims are present and falls back sensibly.
2026-06-07 15:27:40 -04:00
Lucas Berger 4b34b16f02 fix(02): dev-auth bypass no longer blocked by oidcAuthMiddleware
- index.ts: compute devBypassActive at startup; skip app.use(oidcAuthMiddleware)
  entirely when active so the OIDC guard never runs in local dev
- routes/me.ts: read c.get('user') first; return dev identity directly when
  devAuthBypass injected it, bypassing getAuth() and the DB upsert
- auth/devBypass.ts: add ContextVariableMap augmentation for 'user' key;
  correct stale comment that claimed getAuth/401 path was still active
2026-06-05 13:48:00 -04:00
Lucas Berger 668ed9be0d feat(01-02): wire OIDC middleware, /api/me route, and authenticated PWA shell
- src/auth/middleware.ts: re-exports oidcAuthMiddleware, processOAuthCallback,
  getAuth from @hono/oidc-auth; documents required env vars and AUTH-02
  refresh-token rotation (no iframe, D-12)
- src/routes/me.ts: GET / calls getAuth → upsertUser(iss, sub, email) →
  returns { user: { id, displayName, color } }; identity keyed on iss+sub
- src/index.ts: /callback registered before oidcAuthMiddleware; /api/*
  guarded; /health remains unauthenticated; /api/me mounted
- apps/pwa/src/api/client.ts: typed fetchMe() with credentials: 'include'
- apps/pwa/src/App.tsx: useQuery(['me'], fetchMe); renders member name and
  color swatch; retains /health stack indicator from Plan 01
- tsc --noEmit: clean; all tests pass
2026-06-04 10:22:46 -04:00