Authentication is where a web framework's promises get tested, because every entry point of it is a door. A password form, a verification link in a mail, a reset link, a "continue with GitHub" button and a six-digit code from a phone all end in the same sentence - "this session belongs to that user".

This guide builds one application with all of those doors on it, from punk new to a passing test suite, using four pieces of the Punk ecosystem: Punk::Auth for the identity and the single-use tokens, Punk::Plugin::Mailer to send the tokens through Resend, Punk::Plugin::TOTP for the second factor, and Punk::Plugin::OAuth2 for GitHub and Google.

What you are building

Twenty routes, and this is all of them:

GET /login/totp native handler