You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The DOM enrichment script (buildChooserEnrichmentScript in packages/pds-core/src/chooser-enrichment.ts, mounted by createChooserEnrichmentMiddleware and rendered into /oauth/authorize + /account* HTML responses) has three related defects:
1. Wrong scope — only enriches account-chooser rows
The script walks every text node matching a known handle and rewrites the surrounding DOM (inserts <span class="epds-email-label">…</span>, tags the matched span with epds-handle-label). On the consent screen, on the standalone /account* SPA pages, and anywhere else upstream oauth-provider-ui shows the user's handle, the same handle text appears in prose copy — alice.test grants access to ..., headings, account-management cards, etc. Two failure shapes:
Over-enrichment: handle text in prose got mutated, injecting an email span into copy that was not an account row. This was the original symptom; PR fix(pds-core): scope chooser enrichment to account rows #137 narrowed the rewrite to nodes whose closest('[role="button"][tabindex="0"]') resolved (the chooser-row markup oauth-provider-ui 0.4.3 emits).
Under-enrichment: PR fix(pds-core): scope chooser enrichment to account rows #137's narrow scope means the consent screen, /account* cards, and any other page where we do want the email-first presentation now go un-enriched. We need enrichment on every page that shows the user's handle, not only chooser rows.
2. Random-handle mode should hide the handle entirely
epds_handle_mode resolves to one of random, picker, picker-with-random (packages/shared/src/handle.ts). When the active mode is random the handle is an opaque autogenerated string with no user value — surfacing it in the UI is just noise. In that mode the handle span should be hidden (display:none / aria-hidden) and only the email / display name should remain visible.
The other two modes (picker, picker-with-random) still show the handle as today.
3. Tooltip explaining what a handle is
When the handle is hidden (random mode) — and arguably any time we replace handle-prominent UI with email-prominent UI — hovering or focusing the email / account name should reveal a tooltip that:
Shows the underlying handle value.
Includes a short, user-friendly explanation of what an AT Protocol handle is and why we have one (e.g. one or two plain sentences plus optionally a link to docs).
Tooltip needs keyboard + screen-reader access (focus trigger, aria-describedby or live-region equivalent), not pure :hover.
Scope of the fix
Generalise the enrichment walker so it covers every page where upstream renders the handle, not just chooser rows. PR fix(pds-core): scope chooser enrichment to account rows #137's row-scoping needs to be reworked into a positive allowlist of contexts (chooser row, consent paragraph, account-card, etc.) or a negative exclusion list — whichever keeps over-enrichment from coming back.
Plumb the active HandleMode (resolved per-flow already, see auth_flow.handle_mode and resolveHandleMode) through to the injected script so it can branch on random vs picker modes.
Add the tooltip component (HTML + CSS + minimal JS in the same injected script) with copy that explains handles. Coordinate copy with whoever owns user-facing strings.
Regression coverage in packages/pds-core/src/__tests__/chooser-enrichment.test.ts (and equivalent for /account* if not already covered): chooser row, consent prose, multiple account cards, random mode hides handle, picker mode keeps handle, tooltip is reachable by keyboard.
Bugs
The DOM enrichment script (
buildChooserEnrichmentScriptinpackages/pds-core/src/chooser-enrichment.ts, mounted bycreateChooserEnrichmentMiddlewareand rendered into/oauth/authorize+/account*HTML responses) has three related defects:1. Wrong scope — only enriches account-chooser rows
The script walks every text node matching a known handle and rewrites the surrounding DOM (inserts
<span class="epds-email-label">…</span>, tags the matched span withepds-handle-label). On the consent screen, on the standalone/account*SPA pages, and anywhere else upstreamoauth-provider-uishows the user's handle, the same handle text appears in prose copy —alice.test grants access to ..., headings, account-management cards, etc. Two failure shapes:closest('[role="button"][tabindex="0"]')resolved (the chooser-row markup oauth-provider-ui 0.4.3 emits)./account*cards, and any other page where we do want the email-first presentation now go un-enriched. We need enrichment on every page that shows the user's handle, not only chooser rows.2. Random-handle mode should hide the handle entirely
epds_handle_moderesolves to one ofrandom,picker,picker-with-random(packages/shared/src/handle.ts). When the active mode israndomthe handle is an opaque autogenerated string with no user value — surfacing it in the UI is just noise. In that mode the handle span should be hidden (display:none / aria-hidden) and only the email / display name should remain visible.The other two modes (
picker,picker-with-random) still show the handle as today.3. Tooltip explaining what a handle is
When the handle is hidden (random mode) — and arguably any time we replace handle-prominent UI with email-prominent UI — hovering or focusing the email / account name should reveal a tooltip that:
Tooltip needs keyboard + screen-reader access (focus trigger,
aria-describedbyor live-region equivalent), not pure:hover.Scope of the fix
HandleMode(resolved per-flow already, seeauth_flow.handle_modeandresolveHandleMode) through to the injected script so it can branch onrandomvs picker modes.packages/pds-core/src/__tests__/chooser-enrichment.test.ts(and equivalent for/account*if not already covered): chooser row, consent prose, multiple account cards, random mode hides handle, picker mode keeps handle, tooltip is reachable by keyboard.Related