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.
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
|
||||
import { Hono } from 'hono'
|
||||
import { getAuth } from '../auth/middleware.js'
|
||||
import { upsertUser } from '../auth/user.js'
|
||||
import { upsertUser, deriveDisplayName } from '../auth/user.js'
|
||||
// Side-effect import: brings in the ContextVariableMap augmentation for c.get('user')
|
||||
import '../auth/devBypass.js'
|
||||
|
||||
@@ -53,22 +53,10 @@ meRouter.get('/', async (c) => {
|
||||
const iss = (auth.iss as string | undefined) ?? ''
|
||||
const sub = auth.sub ?? ''
|
||||
|
||||
// Derive the best available display name from OIDC claims, in preference order:
|
||||
// 1. name — full name set by the IdP (most human-friendly)
|
||||
// 2. preferred_username — often the login handle; still readable
|
||||
// 3. email — readable but reveals contact info; acceptable fallback
|
||||
// 4. sub — always present; not human-friendly but never blank
|
||||
//
|
||||
// Each candidate is tested defensively — Authelia may omit or blank-out any claim.
|
||||
// Whether Authelia emits name/preferred_username is an operator configuration concern
|
||||
// (e.g. userinfo scope, claim mappings in authelia config) — out of scope here.
|
||||
const claimStr = (v: unknown): string | undefined =>
|
||||
typeof v === 'string' && v.trim() !== '' ? v.trim() : undefined
|
||||
const displayName =
|
||||
claimStr(auth.name) ??
|
||||
claimStr(auth.preferred_username) ??
|
||||
claimStr(auth.email) ??
|
||||
`Member ${String(sub).slice(0, 8)}`
|
||||
// Derive the best available display name from OIDC claims (name →
|
||||
// preferred_username → email → sub fallback). Shared helper keeps every
|
||||
// upsert call site in agreement (see deriveDisplayName).
|
||||
const displayName = deriveDisplayName(auth, sub)
|
||||
|
||||
const user = await upsertUser(iss, sub, displayName)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user