Passphrase Gate
A controlled passphrase screen with create and unlock modes — composes the password strength bar and surfaces errors, performing no crypto itself.
Passphrase Gate
The Passphrase Gate is a controlled, presentational unlock/create screen for
a passphrase-protected surface. Create mode renders passphrase + confirmation
fields, enforces a minimum length, and shows strength by composing the
Password Strength Bar from
caller-computed props. Unlock mode renders a single field with a
caller-provided error surface (e.g. "Incorrect passphrase"). Submission emits the
passphrase via onSubmit.
Backend-agnostic. The gate performs no crypto, no storage access, and holds no passphrase beyond its controlled field state — the app derives the key and drives the vault. Works with any backend; the recommended LocalMode hook is
useEncryptedVaultfrom@localmode/react(unlock(passphrase),status,error) — a recommendation, never a requirement.
When to use it: any vault, encrypted-store, or key-derivation form that needs a create-vs-unlock passphrase screen with strength feedback and error handling.
Preview
Installation
pnpm dlx shadcn@latest add @localmode/ui/security-privacy/passphrase-gatenpx shadcn@latest add @localmode/ui/security-privacy/passphrase-gateyarn dlx shadcn@latest add @localmode/ui/security-privacy/passphrase-gatebunx --bun shadcn@latest add @localmode/ui/security-privacy/passphrase-gateDependencies
- Data source: controlled and presentational — emits
onSubmit(passphrase)andonPassphraseChange(value); it never estimates strength or touches crypto. Recommended LocalMode hook:useEncryptedVault(optional). lucide-react— iconsclsx+tailwind-merge— via the sharedcn()util (installed automatically as a registry dependency)- Composes
@localmode/ui/security-privacy/password-strength-bar(installed automatically as a registry dependency)
Files installed
passphrase-gate.tsx— the componentpassword-strength-bar.tsx— the composed strength meterlib/utils.ts— thecn()helper (if not already present)
Props
PassphraseGate
Prop
Type
PassphraseStrength
Prop
Type
Examples
Wiring to an encrypted vault
The app owns the estimator and the vault; the gate only renders and reports intent:
import { useEncryptedVault } from '@localmode/react';
import { PassphraseGate } from '@/components/passphrase-gate';
function estimate(value: string) {
const classes =
(/[a-z]/.test(value) ? 1 : 0) + (/[A-Z]/.test(value) ? 1 : 0) +
(/[0-9]/.test(value) ? 1 : 0) + (/[^a-zA-Z0-9]/.test(value) ? 1 : 0);
const score = Math.round((Math.min(value.length, 16) / 16) * 60 + (classes / 4) * 40);
return { value: score, label: score < 40 ? 'Weak' : score < 70 ? 'Good' : 'Strong',
color: score < 40 ? 'error' : score < 70 ? 'warning' : 'success' } as const;
}
export function VaultGate() {
const { status, error, unlock } = useEncryptedVault({ name: 'notes' });
const [strength, setStrength] = useState({ value: 0 });
return (
<PassphraseGate
mode={status === 'uninitialized' ? 'create' : 'unlock'}
onSubmit={unlock}
onPassphraseChange={(v) => setStrength(estimate(v))}
strength={strength}
error={error?.name === 'VaultPassphraseError' ? 'Incorrect passphrase' : undefined}
/>
);
}Unlock mode with a busy state
<PassphraseGate mode="unlock" isBusy={isDeriving} onSubmit={unlock} error={lastError} />Customization
Create mode gates submission until the passphrase reaches minLength (default 8)
and the confirmation matches; the strength bar renders only when you pass
strength. Unlock mode shows a single field plus the error surface. Because you
own the copied file, every threshold, label, and class is yours to change — swap
the composed strength bar, add a "show passphrase" toggle, or wire your own
key-derivation flow.
Differential Privacy Controls
A collapsible DP settings panel (enable toggle, epsilon slider, privacy-budget bar) plus a compact "DP Applied" provenance badge — driven by the app's DP-middleware state.
Vault Item Card
A lock-state-aware card for an encrypted note or document — masked while locked, decrypt-on-view when unlocked. Never receives ciphertext or keys.