mercator / totp2fa
TOTP-based 2FA for Winter CMS backend users with one-time recovery code display.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:winter-plugin
pkg:composer/mercator/totp2fa
Requires
- php: >=8.2
- bacon/bacon-qr-code: ^3.0
- pragmarx/google2fa: ^8.0
This package is auto-updated.
Last update: 2026-02-13 22:11:16 UTC
README
TOTP-based two-factor authentication (2FA) for Winter CMS backend users, with one-time display of recovery codes.
Goals (behaviour)
- Backend decides which users must enroll (Off / All / Roles).
- If a user must use 2FA but has none:
- user is forced into enrollment
- recovery codes are shown once, immediately after enrollment
- Recovery codes are never shown in the backend user management form.
- Users can regenerate recovery codes themselves
- New codes are shown once immediately after regeneration
- Recovery codes are stored encrypted in the database.
Requirements
- Winter CMS 1.3 (Laravel 12)
- PHP >= 8.2
- Composer:
- pragmarx/google2fa
- bacon/bacon-qr-code
Install
-
Copy to
plugins/mercator/totp2fa -
Install dependencies:
composer require pragmarx/google2fa bacon/bacon-qr-code
- Run plugin migrations:
php artisan winter:up
Configure enforcement
Backend → Settings → Security → Backend 2FA (TOTP)
- Off / All users / Selected roles (comma-separated role codes or names)
User flow
- If required and not enrolled →
/mercator/totp2fa/challenge/setup - If enrolled but not verified this session →
/mercator/totp2fa/challenge - After successful enrollment or regeneration →
/mercator/totp2fa/challenge/recovery(codes shown once) - Users can regenerate codes at
/mercator/totp2fa/challenge/manage
Security notes
backend.page.beforeDisplayandbackend.ajax.beforeRunHandlerare both enforced (prevents AJAX bypass).- Secrets + recovery codes are encrypted using Laravel
Crypt. - Recovery codes are displayed only when a one-time session flag is present, and then require an acknowledgement to mark them as shown.