liberusoftware/two-factor-authentication-api
A Laravel package that adds a ready-made API layer for two-factor authentication, letting you enrol users, verify codes, and manage 2FA settings over clean JSON endpoints.
This package is a presentation adapter: expect it to expose HTTP endpoints/resources for a two-factor authentication domain module rather than implement TOTP, recovery codes, or persistence itself. With zero stars, zero dependents, a NOASSERTION license, and a release date in the future, treat the repository as an internal/early-stage module and verify everything against the source before adopting it.
Minimal setup:
Require the package and inspect what it pulls in:
composer require liberusoftware/two-factor-authentication-api
composer show liberusoftware/two-factor-authentication-api
Check composer.json for the core 2FA/domain dependency. If no core implementation is required, this adapter may be incomplete on its own.
Check auto-discovery and publishable assets:
php artisan about
php artisan vendor:publish --provider="LiberuSoftware\TwoFactorAuthenticationApi\TwoFactorAuthenticationApiServiceProvider"
php artisan route:list --path=two-factor
Look first at the package's src/, routes/, config/, and README.md. Confirm which service provider is registered and whether routes are under api middleware, auth:sanctum, or another guard.
Confirm the required domain services are bound:
php artisan tinker
>>> app()->bound(\LiberuSoftware\TwoFactorAuthentication\Contracts\TwoFactorService::class);
Exact contracts will differ; inspect constructor type-hints in the adapter's controllers/actions.
First use case: authenticated user enrols in 2FA, confirms a code, and receives recovery codes. Exercise it with a real request before wiring a frontend:
curl -X POST https://app.test/api/two-factor/enable \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json"
Do not build UI until you have confirmed the endpoint paths, request payloads, response shapes, and whether the adapter expects session state or stateless API tokens.
Treat the adapter as an HTTP boundary. Keep your application's own service/action layer around it so you can swap or remove the package later. Controllers should call your TwoFactorEnrollmentService, which may delegate to the package's domain service, and API resources should map package responses into your public contract.
Typical API flow. Most adapters of this shape expose endpoints equivalent to:
POST /two-factor/enable — create a pending secret and return provisioning data (QR URI/secret).POST /two-factor/confirm — verify the first TOTP code and activate 2FA.POST /two-factor/verify — complete a login challenge with a TOTP or recovery code.POST /two-factor/disable — usually requires password and/or a valid code.GET/POST /two-factor/recovery-codes — view or regenerate one-time recovery codes.Verify actual route names with php artisan route:list. Prefer generating URLs via route names in tests rather than hard-coding paths.
Login challenge pattern. Don't mark a user fully authenticated immediately after password validation when 2FA is enabled. Use a short-lived challenge token or session flag, then require /two-factor/verify before issuing the real API token:
// Pseudocode: adapt to the package's actual guard/challenge mechanism.
if ($user->hasTwoFactorEnabled()) {
return response()->json([
'two_factor_required' => true,
'challenge_token' => $challenge,
], 202);
}
For SPAs/mobile, prefer stateless challenge tokens (Sanctum or signed temporary URLs) over relying on session middleware. For Blade apps, a session-based challenge is simpler but must be cleared correctly after success or failure.
Middleware and route protection. Apply the package's 2FA middleware to sensitive route groups, but keep authentication and 2FA as separate concerns. A common pattern is:
Route::middleware(['auth:sanctum', 'two-factor'])->group(function () {
// sensitive endpoints
});
Confirm the middleware alias in the service provider. If the package does not register one, implement your own middleware that checks the user's 2FA state and challenge status.
Enrolment workflow. Store pending secrets separately from active secrets. Do not activate 2FA until the user proves possession of the device with a valid code. Only then reveal recovery codes, and show them exactly once.
Recovery codes. Treat them as passwords: hash at rest, return plaintext only at generation time, invalidate on use, and provide a regeneration path. If the adapter returns plaintext lists, keep that response out of logs and error trackers.
Testing. Use Laravel's HTTP testing around the adapter endpoints, plus unit tests for your wrapper:
$this->actingAs($user, 'sanctum')
->postJson('/api/two-factor/enable')
->assertOk();
Fake time-sensitive code generation in tests rather than relying on real TOTP windows. Assert that a used recovery code cannot be reused and that a disabled user cannot pass the 2FA middleware.
Frontend integration. Return a provisioning URI (otpauth://) or secret in a consistent shape, and document whether the secret is base32. For QR rendering, let the frontend generate the image from the URI; don't have the API return a QR PNG unless that is explicitly supported.
NOASSERTION means you cannot assume MIT/Apache rights. Get legal review before shipping this in a commercial product; otherwise you may need to fork or replace it.composer.json, review the diff between releases, and avoid ^ ranges until you trust the upgrade path.route:list and verify middleware, throttling, CORS, and auth guards. Add throttle:two-factor or similar to verification endpoints to slow brute force.encrypted cast or equivalent. Never log request payloads containing TOTP codes, secrets, or recovery codes; audit Log::info calls and exception handlers.config/two-factor-authentication.php exists, publish it and diff against the package default after upgrades. Cached config (php artisan config:cache) can hide new keys.route:list, then inspect the package's form requests for validation rules and its exception handler for response codes. Use php artisan tinker to resolve the adapter's services and confirm container bindings. If routes 404, check provider discovery and route caching (php artisan route:clear).TwoFactorEnabled, TwoFactorVerified, RecoveryCodesGenerated), and container bindings before editing vendor code. Bind your own implementation of the adapter's interfaces in a service provider if you need custom behavior.How can I help you explore Laravel packages today?