Reauth Gate

Asks the user to re-confirm with a passkey, password or PIN before a sensitive action, so an unattended signed-in screen is harder to misuse.

StopsHelps prevent a sensitive action on an unattended signed-in screen

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/reauth-gate.json

The files land in your project. They're yours to edit.

What it catches

  • Sensitive action started without a recent re-confirmation
  • Names the exact action and the reason before asking
  • Runs the queued action right after a successful verify
  • Shows how long the unlock lasts, with a button to end it early
  • Wrong credential or a rejected verify shows an error and keeps the action queued

Props

ReauthGate props
PropTypeDefault
verify* (required)

Check the credential. Resolve true to unlock; false (or a rejection) counts as a wrong attempt.

(credential: ReauthCredential) => boolean | Promise<boolean>—
methods

Offered methods, preferred first.

ReauthMethod[]["passkey", "password"]
duration

How long a confirmation is remembered, in ms. Every protected action resets it.

number5 * 60_000
reason

Why this area asks again, shown in the prompt.

string"This changes who can get into your account, so we check …
children* (required)

Render the protected UI. Call `protect(label, action)` from sensitive buttons.

(protect: Protect, state: { unlocked: boolean }) => React.ReactNode—
promptText

Templates: `{action}`, `{time}` are filled in.

string"Confirm it's you to {action}."
rememberText

Shown after confirming. `{time}` is how long the unlock lasts.

string"You won't be asked again for {time}."
wrongText

Shown when verify returns false or rejects.

string"That didn't match. Try again."
cancelledText

Shown when the user cancels the prompt.

string"Cancelled. Nothing was changed."
chipText

Countdown chip text. `{time}` is filled in.

string"Confirmed · {time}"
endLabel

Label of the button that ends the unlock early.

string"End now"

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Prompt is a labelled region (role=region with aria-labelledby); focus moves to its first control when it opens
  • Escape cancels the prompt
  • Method switch uses aria-pressed buttons in a labelled group
  • Credential input has a sr-only label, aria-invalid on a wrong attempt, and a polite live message
  • Countdown chip is role=timer with an aria-label; its progress animation is skipped under reduced motion

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Re-check the credential and a server-side recent-auth timestamp on every sensitive endpoint, and rate-limit verify; the client window is only a convenience.

  • The unlock window lives in component state only; a reload, another tab or a direct API call is not covered
  • Security depends entirely on your verify function and your server
  • No attempt limit or lockout; rate-limit verification on the server
  • Passkey mode calls verify with no secret; you run the WebAuthn ceremony inside verify

What it stops

Helps prevent a sensitive action on an unattended signed-in screen

Also known as

sudo mode · re-authenticate · confirm password · passkey · pin · step-up auth · verify identity · mpin

Field type

Dependencies

Pairs well with