Skip to content

feat(auth): print the OTP banner on client demand, with expiry and requester info - #368

Merged
antfu merged 8 commits into
mainfrom
feat/otp-banner-on-demand
Sep 8, 2026
Merged

feat(auth): print the OTP banner on client demand, with expiry and requester info#368
antfu merged 8 commits into
mainfrom
feat/otp-banner-on-demand

Conversation

@antfubot

@antfubot antfubot commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

What

Makes the interactive-auth code/magic-link banner on demand: it prints only when an untrusted browser client actually needs a code, never on plain page loads. Opening a page that is already authorized prints nothing.

  • New anonymous:devframe:auth:request-code RPC (client: rpc.requestAuthCode(options?)): asks the server to print its banner. reissue: true rotates the code first, so the manual action always yields a freshly-valid code; a plain request prints each code at most once (per-code dedupe).
  • AuthBannerFunction now receives { code, url, expireAt, requester? }requester is the asking browser's parsed UA label + origin — and the built-in createAuthBanner box renders the expiry and requester rows.
  • Banner triggers are now exactly: the hub-ui ViewBuiltinClientAuthNotice view on first mount, its new “Re-issue one-time password” button, a user's custom auth UI calling requestAuthCode() (both custom hub examples updated, at parity), the native-prompt fallback, or a host calling auth.printBanner() directly.
  • The instance shell no longer auto-prints on the first served request, and a code exchange no longer reprints the rotated code.
  • An expired code is rotated before printing, so a requested banner always shows a redeemable code.

Why

The banner previously printed on the first request that reached the server — including pages already trusted by a stored token — and gave the user no way to get a fresh code printed when theirs expired or rotated away.

Docs (security guide, client guide, initiate adapter, interactive-auth + node-api references) and API snapshots updated; origin-adoption tests reworked to trigger printing over the new RPC.


Created with the help of an agent.

…quester info

The interactive-auth banner now prints only when an untrusted browser
client asks for a code (auth notice view mount, its new re-issue button,
or a custom UI via the client's requestAuthCode()), instead of on the
first served request - opening an already-authorized page prints nothing.

- new anonymous:devframe:auth:request-code RPC; reissue: true rotates
  the code first so the manual button always yields a fresh code
- AuthBannerFunction now receives { code, url, expireAt, requester? }
  and the built-in banner renders the expiry and requesting browser
- the code exchange no longer reprints the rotated code
- hub-ui auth notice requests the banner on mount and gains a
  "Re-issue one-time password" button; both custom hub examples request
  it when their auth overlay shows
@coldtea-pr-lens

coldtea-pr-lens Bot commented Sep 8, 2026

Copy link
Copy Markdown

◈ PR Lens

🟢 +0 new · 🟠 ~10 changed · 🔴 -0 removed · 2 flows · 7 files · commit 576ba27


Architecture

Architecture diagram for devframes/devframe at 576ba27

10 components touched across 3 lanes.

Open the interactive canvas


Inside the changed components — 2 views

Component view — Server Auth Recipe and State

Internal components of Devframe handling on-demand banner formatting, code rotation, and origin derivation

Architecture view of Component view — Server Auth Recipe and State in devframes/devframe

Component view — Client Auth UI and RPC Dispatch

Client UI notice and RPC transport methods requesting terminal banner prints

Architecture view of Component view — Client Auth UI and RPC Dispatch in devframes/devframe

Data flow

Data flow diagram for devframes/devframe at 576ba27

On-demand auth code request and exchange · Re-issuing OTP code on demand

Open the interactive canvas


The other flows — 1 sequence

Re-issuing OTP code on demand

Sequence diagram of Re-issuing OTP code on demand in devframes/devframe

Drill down
Client Runtimes & UI — 5 components
🟡 CHANGED Dock UI & Auth Notice

Built-in dock UI that triggers code request on mounting the auth view and provides a re-issue button.

🟡 CHANGED Browser RPC Client

RPC client runtime providing requestAuthCode() to ask the server to print or re-issue the OTP banner.

🟡 CHANGED Auth Notice View

Auth notice view requesting code banner on mount and offering a re-issue button.

🟡 CHANGED Live RPC Client Mode

Live RPC client transport invoking the anonymous request-code method with client UA and origin.

🟡 CHANGED Simple Auth Prompt

Headless fallback prompt that requests a code before presenting native browser prompt.

Framework Kits & Hosts — 1 component
🟡 CHANGED Host & Build Adapters

Host adapters managing origin adoption and binding without eager banner printing on request.

Devframe Core Engine — 4 components
🟡 CHANGED Single-Tool Instance Shell

Devframe server instance shell and auth handler coordinating on-demand banner printing and code rotation.

🟡 CHANGED Interactive Auth Recipe

Registers the anonymous request-code RPC method, formats terminal banner with requester and expiry info, and dedupes prints per code.

🟡 CHANGED OTP Auth State

Manages OTP code lifecycle, expiration timestamps, rotation on reissue, and UA string parsing.

🟡 CHANGED Instance Shell

Derives public origin on first request without printing startup banners eagerly.


View

  • Architecture lens
  • Data flow lens
  • Expand every detail
  • Show unchanged neighbours

Tip

Show unchanged neighbours lists the components this change did not touch alongside the ones it did, so the drill-down shows what the changed code sits next to.

🪧 More tips
  • Run PR Lens on your own machine: npx skills add coldteadotai/pr-lens installs the agent skill. Then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Draw a diff before it is even a pull request: npx @coldtea/pr-lens-cli analyze --base origin/main reads the diff with your own model key, and npx @coldtea/pr-lens-cli render .pr-lens/graph.json draws the same lenses on your machine.
  • The boxes under View are live. Tick Architecture lens or Data flow lens to choose which diagrams appear, or Expand every detail to open every drill-down at once. The comment redraws in place a few seconds later.
  • GitHub will not let you zoom an image in a comment. The link under each diagram opens it on an interactive canvas, where you can zoom, pan and step through the flow.
  • The CLI's render picks up .github/pr-lens.yml automatically and applies your corrections (renames, exclusions, lane pins) at draw time.
  • Would you rather run it from CI on a key of your own? Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and a model key in your repository secrets, say GEMINI_API_KEY. The Action asks Gemini by default, or OpenAI and any endpoint speaking /chat/completions through its provider input.
  • PR Lens is free for open source. A star on the repository is what keeps it going.
  • Push a new commit and the whole comment re-renders for the new head. An older run never overwrites a newer one, so a slow render cannot put a stale diagram back.
  • The diagrams follow your GitHub theme, so dark mode gets the dark render and light mode the light one, and the moving dots show this pull request's data in motion.

◈ Rendered by PR Lens · crafted with ❤️ by the Coldtea team · Come say hi on Discord

@vercel

vercel Bot commented Sep 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
devframe Ready Ready Preview Sep 8, 2026 4:37am UTC

- `@unocss/inspector` 66.10 imports `@devframes/vite/single` at module
  load, and pnpm links it to the workspace package, so the two example
  builds that load `unocss/vite` in their vite config now declare a turbo
  edge on `@devframes/vite#build` instead of racing it
- dedupe the auto-installed `@unocss/core` peer to 66.10.0 (the stale
  66.8.1 copy made `design/uno.config.ts` fail typecheck)
- capture the DP_MESSAGES_0001 warning in a plain array: vitest 5 clears
  spy call history recorded during `beforeAll`
- refresh the a11y client-script API snapshot for tsnapi 1.4.2's default
  export rendering
Its SPA vite config loads unocss/vite, which since unocss 66.10 eagerly
imports the workspace-linked @devframes/vite; every unocss/vite-loading
build task now reaches @devframes/vite#build transitively.
Windows runners check *.patch out with CRLF (autocrlf), which pnpm 12's
patch parser rejects with ERR_PNPM_INVALID_PATCH.
@antfu
antfu merged commit e27579b into main Sep 8, 2026
14 checks passed
@antfu
antfu deleted the feat/otp-banner-on-demand branch September 8, 2026 04:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants