← All @molecule/* packages · App templates
@molecule/api-two-factor-otplibProvider bond · two-factor · API (Node) · v1.0.1 · Apache-2.0
Two-factor provider using otplib for molecule.dev
npm install @molecule/api-two-factor-otplibnpm · Source on GitHub · Implements @molecule/api-two-factor
@molecule/api-two-factor-otplib is a provider bond on the API (Node) side: it implements the two-factor core interface (@molecule/api-two-factor) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
Works with: @molecule/api-two-factor
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Two-factor authentication provider using otplib for molecule.dev.
provider
npm install @molecule/api-two-factor-otplib @molecule/api-two-factor otplib qrcode
npm install -D @types/qrcode
providerTwo-factor authentication provider backed by otplib and qrcode.
const provider: TwoFactorProvider
Implements @molecule/api-two-factor interface.
Setup function to register this provider with the core interface:
import { setProvider } from '@molecule/api-two-factor'
import { provider } from '@molecule/api-two-factor-otplib'
export function setupTwoFactorOtplib(): void {
setProvider(provider)
}
Peer dependencies:
@molecule/api-two-factor ^1.0.1@molecule/api-two-factorotplibqrcodeTesting the flow end-to-end without an authenticator app. A TOTP feature
is only verified when a real code passes the challenge — and no phone is
needed for that: generate the current code from the stored base32 secret
with otplib itself (this bond's own dependency, already installed):
node -e "import('otplib').then(async o => console.log(await o.generate({ secret: process.argv[1] })))" <base32-secret>
(otplib v13 exposes `generate({ secret })` — the v12 `authenticator.generate()`
was removed and will throw.)
Use the secret returned by generateSecret() during setup (or read it back
from wherever the app stored it) to complete the enable + challenge steps in
a browser walkthrough or an integration test. Codes rotate every 30 seconds
— generate immediately before submitting. Never mock verify() to test the
flow; a generated real code exercises the same path a user's app does.
Integration checklist — drive the app's REAL UI as the user would (in molecule.dev: navigate_preview → read_preview_ui → interact_preview, targeting elements by data-mol-id), adapt to this app's actual auth/settings screens, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
000000 must FAIL.
COUNTERPARTY: the secret is shown on screen during setup — compute the current
6-digit code from it with the preinstalled otplib (v13: await generate({ secret });
both otplib's generate() and this package's verify() are async). NEVER add
an endpoint that leaks the stored secret to the client to obtain the code.@example) so the
lifecycle stays covered on every later build.