PHP code example of webmonks / laravel-2fa

1. Go to this page and download the library: Download webmonks/laravel-2fa library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

webmonks / laravel-2fa example snippets




namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use WebMonks\Laravel2FA\Contracts\TwoFactorAuthenticatable;
use WebMonks\Laravel2FA\Traits\HasTwoFactorAuthentication;

class User extends Authenticatable implements TwoFactorAuthenticatable
{
    use HasTwoFactorAuthentication;

    // Your existing model code...
}

// Protect routes (in routes/web.php)
Route::group(['middleware' => ['auth', '2fa']], function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/sensitive-data', [DataController::class, 'show']);
});

// Enable 2FA for users (in your controller)
use WebMonks\Laravel2FA\Facades\TwoFactor;

// Email OTP (works immediately - zero configuration needed)
TwoFactor::enable($user, 'email');

// TOTP/Google Authenticator
TwoFactor::enable($user, 'totp');
$qrCodeUrl = TwoFactor::getTotpQrCodeUrl($user); // Show this QR to user

// Day 1: Email OTP (works immediately)
TwoFactor::enable($user, 'email');
TwoFactor::generateCode($user, 'email'); // Sends via Laravel Mail

// Day 30: Add SMS when ready
// .env: TWILIO_SID=xxx TWILIO_TOKEN=yyy TWILIO_FROM=+1234567890
TwoFactor::setPhoneNumber($user, '+15551234567');
TwoFactor::enable($user, 'sms');

// Day 60: Add WhatsApp for global users
TwoFactor::enable($user, 'whatsapp');
TwoFactor::generateCode($user, 'whatsapp');

// Day 90: Add Voice calls for accessibility
TwoFactor::enable($user, 'voice');
TwoFactor::generateCode($user, 'voice'); // Multi-language support

// Day 120: Add Push notifications for mobile apps
TwoFactor::enable($user, 'push');
TwoFactor::registerPushDevice($user, $fcmToken, 'android');

// Day 150: Add TOTP for power users
TwoFactor::enable($user, 'totp');
$qrCode = TwoFactor::getTotpQrCodeUrl($user);

// Day 180: Add device trust and recovery codes
$recoveryCodes = TwoFactor::generateRecoveryCodes($user);
TwoFactor::trustDevice($user, $deviceFingerprint);

use WebMonks\Laravel2FA\Facades\TwoFactor;

// Enable email 2FA (works immediately with Laravel Mail)
TwoFactor::enable($user, 'email');

// Generate and send code
TwoFactor::generateCode($user, 'email');
// User receives: "Your verification code is: 123456"

// Verify code
$isValid = TwoFactor::verifyCode($user, '123456', 'email');

// Check status
$isEnabled = TwoFactor::isEnabled($user, 'email');

// Set user's phone number
TwoFactor::setPhoneNumber($user, '+15551234567');

// Enable SMS 2FA
TwoFactor::enable($user, 'sms');

// Generate and send SMS
$sent = TwoFactor::generateCode($user, 'sms');
if ($sent) {
    return response()->json(['message' => 'SMS sent to your phone']);
}

// Verify SMS code
$isValid = TwoFactor::verifyCode($user, $request->input('code'), 'sms');

// Enable TOTP
TwoFactor::enable($user, 'totp');

// Get QR code URL for setup
$qrCodeUrl = TwoFactor::getTotpQrCodeUrl($user);
// Display this QR code to user for scanning with Google Authenticator

// Get setup key (alternative to QR code)
$setupKey = TwoFactor::getTotpSecretKey($user);

// Verify TOTP code
$isValid = TwoFactor::verifyCode($user, '123456', 'totp');

// Generate recovery codes
$codes = TwoFactor::generateRecoveryCodes($user);
// Returns: ['a1b2c3d4e5', 'f6g7h8i9j0', ...] (8 codes by default)

// Show codes to user for safe storage
foreach ($codes as $code) {
    echo "Recovery code: {$code}\n";
}

// Verify recovery code
$isValid = TwoFactor::verifyRecoveryCode($user, 'a1b2c3d4e5');

// Check remaining recovery codes
$remaining = TwoFactor::getRemainingRecoveryCodes($user);

// Generate device fingerprint (your implementation)
$deviceFingerprint = hash('sha256', $request->ip() . $request->userAgent());

// Trust current device
TwoFactor::trustDevice($user, $deviceFingerprint);

// Check if device is trusted
if (TwoFactor::isDeviceTrusted($user, $deviceFingerprint)) {
    // Skip 2FA for trusted device
    return redirect('/dashboard');
}

// Remove trusted device
TwoFactor::removeTrustedDevice($user, $deviceFingerprint);

// Get all trusted devices
$trustedDevices = TwoFactor::getTrustedDevices($user);

use WebMonks\Laravel2FA\Facades\TwoFactor;

// Set user's WhatsApp number
TwoFactor::setPhoneNumber($user, '+15551234567');

// Enable WhatsApp 2FA
TwoFactor::enable($user, 'whatsapp');

// Generate and send WhatsApp code
$sent = TwoFactor::generateCode($user, 'whatsapp');
if ($sent) {
    return response()->json(['message' => 'WhatsApp code sent successfully']);
}

// Verify WhatsApp code
$isValid = TwoFactor::verifyCode($user, $request->input('code'), 'whatsapp');

// Custom message template
$messageTemplate = 'Your *{app_name}* verification code is: *{code}*\n\nExpires in {expiry_minutes} minutes. šŸ”';

// Enable voice call 2FA
TwoFactor::enable($user, 'voice');

// Generate and make voice call
$called = TwoFactor::generateCode($user, 'voice');
if ($called) {
    return response()->json(['message' => 'Voice call initiated']);
}

// Verify voice code
$isValid = TwoFactor::verifyCode($user, $request->input('code'), 'voice');

// Supported languages and voices
$languages = ['en-US', 'es-ES', 'fr-FR', 'de-DE', 'it-IT', 'pt-BR', 'ru-RU', 'ja-JP', 'ko-KR', 'zh-CN'];
$voices = ['woman', 'man', 'alice']; // Alice supports more languages

// config/two-factor.php
'sms' => [
    'driver' => 'twilio',
    'fallback_drivers' => ['vonage', 'aws-sns'], // Fallback order

    // Additional fallback settings
    'fallback_delay' => 30, // Wait 30s before trying fallback
    'max_fallback_attempts' => 2,
],

// Usage remains the same - fallback is automatic
TwoFactor::generateCode($user, 'sms'); // Will try Twilio → Vonage → AWS SNS

// Register user's push device
TwoFactor::registerPushDevice($user, $fcmToken, 'android', [
    'device_name' => 'John\'s iPhone',
    'device_model' => 'iPhone 13',
    'app_version' => '1.2.0',
]);

// Enable push 2FA
TwoFactor::enable($user, 'push');

// Send push notification for approval
$sent = TwoFactor::generateCode($user, 'push');
if ($sent) {
    return response()->json([
        'message' => 'Push notification sent',
        'timeout' => 300, // 5 minutes to approve
    ]);
}

// Check approval status
$isApproved = TwoFactor::isPushApproved($user, $challengeId);

// Approve push notification (from mobile app)
TwoFactor::approvePushChallenge($user, $challengeId, [
    'biometric_used' => true,
    'location' => ['lat' => 37.7749, 'lng' => -122.4194],
    'device_info' => ['battery' => 85, 'network' => 'wifi'],
]);

// Deny push notification
TwoFactor::denyPushChallenge($user, $challengeId, 'User denied');

// Create custom Slack provider
class SlackTwoFactorProvider extends AbstractCustomProvider
{
    public function send(string $to, string $message, array $options = []): bool
    {
        $payload = [
            'channel' => $this->config['channel'] ?? '#security',
            'username' => $this->config['username'] ?? '2FA Bot',
            'text' => "šŸ” 2FA Code for {$to}: `{$message}`",
            'icon_emoji' => ':lock:',
        ];

        return Http::post($this->config['webhook_url'], $payload)->successful();
    }
}

// Register in service provider
$this->app->bind('two-factor.custom.slack', SlackTwoFactorProvider::class);

// Usage
TwoFactor::enableCustomDelivery($user, 'slack', ['channel' => '@john.doe']);
TwoFactor::generateCode($user, 'slack');

class DiscordTwoFactorProvider extends AbstractCustomProvider
{
    public function send(string $to, string $message, array $options = []): bool
    {
        $payload = [
            'username' => $this->config['username'] ?? '2FA Bot',
            'content' => "šŸ”’ **2FA Verification Code**\nUser: {$to}\nCode: `{$message}`\nā° Expires in 10 minutes",
            'embeds' => [[
                'color' => 0x00ff00,
                'title' => 'šŸ” Two-Factor Authentication',
                'description' => "Your verification code: **{$message}**",
                'timestamp' => now()->toISOString(),
            ]],
        ];

        return Http::post($this->config['webhook_url'], $payload)->successful();
    }
}

class TelegramTwoFactorProvider extends AbstractCustomProvider
{
    public function send(string $to, string $message, array $options = []): bool
    {
        $payload = [
            'chat_id' => $this->config['chat_id'],
            'text' => "šŸ” *2FA Verification Code*\n\nUser: {$to}\nCode: `{$message}`\n\nā° Expires in 10 minutes",
            'parse_mode' => 'Markdown',
            'reply_markup' => json_encode([
                'inline_keyboard' => [[
                    ['text' => 'āœ… Approved', 'callback_data' => "approve_{$message}"],
                    ['text' => 'āŒ Deny', 'callback_data' => "deny_{$message}"],
                ]],
            ]),
        ];

        $url = "https://api.telegram.org/bot{$this->config['bot_token']}/sendMessage";
        return Http::post($url, $payload)->successful();
    }
}

// config/two-factor.php
'custom_delivery' => [
    'fallback_chain' => [
        'enabled' => true,
        'primary_to_fallback_delay' => 30, // seconds
        'chains' => [
            // SMS fallback chain
            'sms_fallback' => ['sms', 'whatsapp', 'voice', 'email'],

            // Email fallback chain
            'email_fallback' => ['email', 'push'],

            // Push fallback chain
            'push_fallback' => ['push', 'sms', 'email'],

            // Custom enterprise chain
            'enterprise_fallback' => ['push', 'whatsapp', 'voice', 'slack', 'email'],
        ],
    ],
],

// Automatic fallback usage
TwoFactor::enableFallbackChain($user, 'enterprise_fallback');
TwoFactor::generateCode($user, 'sms'); // Will try entire enterprise chain if needed

// config/two-factor.php
'guards' => [
    'web' => [
        'enabled' => true,
        'model' => \App\Models\User::class,
        'routes' => [
            'challenge' => '/two-factor/challenge',
            'verify' => '/two-factor/verify',
        ],
    ],
    'admin' => [
        'enabled' => true,
        'model' => \App\Models\Admin::class,
        'routes' => [
            'challenge' => '/admin/two-factor/challenge',
            'verify' => '/admin/two-factor/verify',
        ],
    ],
    'api' => [
        'enabled' => true,
        'model' => \App\Models\User::class,
        'stateless' => true, // No sessions for API
    ],
    'customer' => [
        'enabled' => true,
        'model' => \App\Models\Customer::class,
        'routes' => [
            'challenge' => '/customer/two-factor/challenge',
            'verify' => '/customer/two-factor/verify',
        ],
    ],
],

// Enable 2FA for different guards
TwoFactor::enable($user, 'email', 'web');
TwoFactor::enable($admin, 'totp', 'admin');
TwoFactor::enable($customer, 'sms', 'customer');

// Guard-specific middleware
Route::group(['middleware' => ['auth:admin', '2fa:admin']], function () {
    Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
});

Route::group(['middleware' => ['auth:customer', '2fa:customer']], function () {
    Route::get('/customer/profile', [CustomerController::class, 'profile']);
});

// API routes with stateless 2FA
Route::middleware(['auth:sanctum', '2fa:api'])->group(function () {
    Route::get('/api/user', function (Request $request) {
        return $request->user();
    });
});

// Verify codes with specific guard
$isValid = TwoFactor::verifyCode($admin, $code, 'totp', 'admin');
$isValid = TwoFactor::verifyCode($user, $code, 'email', 'api');

// Built-in rate limiting (configurable)
'rate_limiting' => [
    'enabled' => true,
    'max_attempts' => 5,           // 5 attempts
    'decay_minutes' => 15,         // per 15 minutes
],

// SMS-specific rate limiting
'sms' => [
    'rate_limiting' => [
        'per_phone_number' => [
            'max_attempts' => 10,      // 10 SMS per phone
            'decay_minutes' => 60,     // per hour
        ],
        'global' => [
            'max_attempts' => 1000,    // 1000 SMS total
            'decay_minutes' => 60,     // per hour
        ],
    ],
],

// Enable comprehensive logging
'logging' => [
    'enabled' => true,
    'channel' => 'stack', // Uses Laravel's logging
    'events' => [
        'enabled' => true,      // Log when 2FA enabled
        'disabled' => true,     // Log when 2FA disabled
        'verified' => true,     // Log successful verifications
        'failed' => true,       // Log failed attempts
        'recovery_used' => true, // Log recovery code usage
    ],
],

// Publish views for customization
php artisan vendor:publish --tag=two-factor-views

// Customize email templates in:
// resources/views/vendor/two-factor/emails/code.blade.php
// resources/views/vendor/two-factor/emails/code-text.blade.php



namespace App\Providers\Sms;

use WebMonks\Laravel2FA\Contracts\SmsProvider;
use WebMonks\Laravel2FA\Providers\Sms\AbstractSmsProvider;

class CustomSmsProvider extends AbstractSmsProvider
{
    public function send(string $to, string $message, array $options = []): bool
    {
        // Your custom SMS logic here
        $response = Http::post('https://api.yoursms.com/send', [
            'api_key' => $this->config['api_key'],
            'to' => $to,
            'message' => $message,
        ]);

        return $response->successful();
    }

    public function getName(): string
    {
        return 'custom';
    }

    public function getMaxMessageLength(): int
    {
        return 160;
    }

    public function getRequiredConfig(): array
    {
        return ['api_key', 'api_secret'];
    }
}

// AppServiceProvider.php
public function register()
{
    $this->app->bind('two-factor.sms.custom', function ($app) {
        $config = config('two-factor.sms.drivers.custom', []);
        return new CustomSmsProvider($config);
    });
}

Route::middleware(['auth:sanctum', '2fa:api'])->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });

    Route::post('/sensitive-action', [ApiController::class, 'sensitiveAction']);
});

// Generate codes via API
POST /api/two-factor/generate
{
    "method": "email" // or "sms", "whatsapp", "voice", "push", "totp"
}

// Verify codes via API
POST /api/two-factor/verify
{
    "code": "123456",
    "method": "email"
}

// Push notification approval API
POST /api/two-factor/push/approve
{
    "challenge_id": "uuid-challenge-id",
    "approved": true,
    "biometric_used": true
}

// Get user 2FA status
GET /api/two-factor/status

use Illuminate\Support\Facades\Notification;
use WebMonks\Laravel2FA\Notifications\TwoFactorSmsCode;
use WebMonks\Laravel2FA\Facades\TwoFactor;

public function test_email_otp_flow()
{
    Mail::fake();

    // Enable email 2FA
    TwoFactor::enable($this->user, 'email');

    // Generate code
    TwoFactor::generateCode($this->user, 'email');

    // Assert email was sent
    Mail::assertSent(TwoFactorCodeMail::class);

    // Verify code works
    $code = TwoFactor::getLastGeneratedCode($this->user, 'email');
    $this->assertTrue(TwoFactor::verifyCode($this->user, $code, 'email'));
}

public function test_sms_otp_flow()
{
    Notification::fake();

    // Setup SMS
    TwoFactor::setPhoneNumber($this->user, '+15551234567');
    TwoFactor::enable($this->user, 'sms');

    // Generate SMS code
    TwoFactor::generateCode($this->user, 'sms');

    // Assert SMS notification sent
    Notification::assertSentTo($this->user, TwoFactorSmsCode::class);
}

// config/two-factor.php

'default_method' => 'email',

'enabled_methods' => [
    'email' => true,            // Email OTP (zero config)
    'sms' => false,             // SMS OTP (xpire_minutes' => 10,     // Code expiration
    'throttle_minutes' => 1,    // Send throttling
    'max_attempts' => 5,        // Max verification attempts
    'queue' => 'default',       // Queue for sending emails
],

'sms' => [
    'length' => 6,
    'expire_minutes' => 10,
    'driver' => 'twilio',       // SMS provider
    'message_template' => 'Your {app_name} code: {code}',
],

'totp' => [
    'issuer' => 'YourApp',      // App name in authenticator
    'algorithm' => 'sha1',      // TOTP algorithm
    'digits' => 6,              // Code digits
    'period' => 30,             // Code validity period
    'window' => 1,              // Time window tolerance
],

'recovery_codes' => [
    'count' => 8,               // Number of recovery codes
    'length' => 10,             // Recovery code length
],

// Email & SMS can be queued for better performance
'email' => [
    'queue' => true,
    'queue_name' => 'notifications',
],

'sms' => [
    'queue' => true,
    'queue_name' => 'sms',
],

// Add indexes for better performance (ion (Blueprint $table) {
    $table->index(['user_id', 'user_type']);
    $table->index(['expires_at']);
    $table->index(['created_at']);
});

// Cache TOTP secrets and settings for performance
'totp' => [
    'cache_enabled' => true,
    'cache_ttl' => 3600, // 1 hour
],

// Multi-layer rate limiting
'rate_limiting' => [
    'global' => [
        'max_attempts' => 1000,     // Global limit
        'decay_minutes' => 60,
    ],
    'per_user' => [
        'max_attempts' => 10,       // Per user limit
        'decay_minutes' => 60,
    ],
    'per_ip' => [
        'max_attempts' => 50,       // Per IP limit
        'decay_minutes' => 60,
    ],
],

// Check Laravel Mail configuration
php artisan config:cache
php artisan queue:work

// Test Laravel Mail directly
Mail::to('[email protected]')->send(new TestMail());

// Check 2FA logs
tail -f storage/logs/laravel.log | grep "2fa"

// Verify SMS provider credentials
php artisan tinker
> config('two-factor.sms.drivers.twilio')

// Test provider connection
> TwoFactor::testSmsProvider('twilio')

// Check phone number format
> PhoneNumberFormatter::format('+1-555-123-4567', 'US')

// Increase time window tolerance
'totp' => [
    'window' => 2, // Allow ±2 time periods (±60 seconds)
],

// Check server time synchronization
date_default_timezone_set('UTC');

// Test WhatsApp provider credentials
php artisan tinker
> config('two-factor.whatsapp.drivers.twilio')

// Check WhatsApp sandbox setup (Twilio)
> TwoFactor::testWhatsAppProvider('twilio')

// Verify WhatsApp Business API credentials
> Http::get('https://graph.facebook.com/v18.0/{phone-number-id}', [
    'access_token' => config('two-factor.whatsapp.drivers.whatsapp_business.access_token')
]);

// Test voice provider
> TwoFactor::testVoiceProvider('twilio')

// Check voice capabilities for phone number
> TwoFactor::checkVoiceCapabilities('+15551234567')

// Test TwiML generation
> TwoFactor::generateVoiceTwiML('123456', ['language' => 'en-US'])

// Test FCM credentials
> TwoFactor::testFCMProvider()

// Test APNS connection
> TwoFactor::testAPNSProvider()

// Check device registration
> TwoFactor::checkPushDeviceRegistration($user, $deviceToken)

// Validate push payload
> TwoFactor::validatePushPayload($payload)

// Test fallback chain
> TwoFactor::testSMSFallbackChain(['twilio', 'vonage', 'aws-sns'])

// Check provider status
> TwoFactor::checkProviderStatus('vonage')
> TwoFactor::checkProviderStatus('aws-sns')

// View fallback logs
> TwoFactor::getFallbackLogs($user, 'sms')

// Test Slack webhook
> Http::post(config('two-factor.custom_delivery.providers.slack.webhook_url'), [
    'text' => 'Test message from Laravel 2FA'
]);

// Test Discord webhook
> TwoFactor::testCustomProvider('discord')

// Test Telegram bot
> TwoFactor::testTelegramBot()

// Monitor delivery success rates
$stats = TwoFactor::getDeliveryStats($user, 'last_30_days');

// Track provider performance
$performance = TwoFactor::getProviderPerformance(['twilio', 'vonage', 'fcm']);

// Get fallback usage statistics
$fallbackStats = TwoFactor::getFallbackStatistics();

// Monitor costs (if cost tracking enabled)
$costs = TwoFactor::getCostAnalysis('this_month');
bash
composer two-factor:install
php artisan migrate
bash
# Install the package
composer fig, migrations)
php artisan two-factor:install

# Run migrations
php artisan migrate
bash
# Publish config for customization (optional)
php artisan vendor:publish --tag=two-factor-config

# Publish views for UI customization (optional)
php artisan vendor:publish --tag=two-factor-views
bash
composer 
bash
composer two-factor:install
php artisan migrate