turahe / otp
send OTP to every where
Requires
- php: ^8.2
- giggsey/libphonenumber-for-php: ^9.0
- illuminate/container: ^10.0|^11.0|^12.0
- illuminate/notifications: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^8.0|^9.0|^10.0
This package is auto-updated.
Last update: 2025-07-20 03:26:24 UTC
README
Introduction ๐
A robust Laravel package for generating and validating OTPs (One Time Passwords) with comprehensive test coverage and modern CI/CD pipeline. Perfect for authentication systems, email verification, and secure access control.
Features โจ
- ๐ Secure OTP Generation: 6-digit numeric tokens with configurable expiry
- ๐ง Email Integration: Built-in email sending with customizable templates
- ๐งช Comprehensive Testing: 87+ tests with 100% coverage of core functionality
- ๐ Modern CI/CD: GitHub Actions with PHP 8.2-8.4 and Laravel 10-12 support
- ๐ฑ Flexible Identity: Support for email, phone numbers, or any string identifier
- โฐ Automatic Cleanup: Scheduled cleanup of expired tokens
- ๐จ PSR-12 Compliant: Clean, maintainable code following Laravel best practices
Requirements ๐
- PHP: ^8.2
- Laravel: ^10.0 || ^11.0 || ^12.0
- Database: MySQL, PostgreSQL, SQLite, or SQL Server
Installation ๐ฝ
1. Install via Composer
composer require turahe/otp
2. Add Service Provider
Add to config/app.php
providers array:
'providers' => [ // ... Turahe\Otp\OtpServiceProvider::class, ],
3. Add Facade Alias (Optional)
Add to config/app.php
aliases array:
'aliases' => [ // ... 'Otp' => Turahe\Otp\Facades\Otp::class, ],
4. Publish Configuration (Optional)
php artisan vendor:publish --provider="Turahe\Otp\OtpServiceProvider"
5. Run Migrations
php artisan migrate
Configuration โ๏ธ
The package configuration file (config/otp.php
) allows you to customize:
return [ // Token expiry time in minutes 'expires' => 15, // Database table name 'table' => 'otp_tokens', // Password generator type (string, numeric, numeric-no-0) 'password_generator' => 'numeric', // Default notification channels 'default_channels' => 'mail', ];
Usage ๐งจ
Basic OTP Generation
use Turahe\Otp\Facades\Otp; // Generate OTP for email (default 15 minutes expiry) $otp = Otp::generate('user@example.com'); // Generate OTP with custom expiry (10 minutes) $otp = Otp::generate('user@example.com', 10); // Generate OTP for phone number $otp = Otp::generate('+1234567890', 5);
OTP Validation
// Validate OTP $isValid = Otp::validate('user@example.com', '123456'); if ($isValid) { // OTP is valid and has been consumed echo "OTP verified successfully!"; } else { // OTP is invalid or expired echo "Invalid or expired OTP"; }
Email Integration
use Turahe\Otp\Jobs\SendOtp; // Send OTP via email $otp = Otp::generate('user@example.com'); dispatch(new SendOtp('user@example.com', $otp));
Custom Email Templates
The package includes a default email template at resources/views/emails/otp.blade.php
. You can customize it by publishing the views:
php artisan vendor:publish --tag=otp-views
Cleanup Expired Tokens
# Manual cleanup php artisan otp:clean # Scheduled cleanup (add to app/Console/Kernel.php) protected function schedule(Schedule $schedule) { $schedule->command('otp:clean')->daily(); }
Testing ๐งช
The package includes comprehensive test coverage:
# Run all tests composer test # Run specific test suites composer test tests/HelperTest.php composer test tests/Jobs/SendOtpTest.php composer test tests/Services/TokenTest.php # Run with coverage report composer test -- --coverage-html coverage/
Test Coverage
- Helper Functions: Phone validation, email provider extraction, disposable email detection
- SendOtp Job: Email queuing, parameter handling, edge cases
- Token Service: OTP generation, validation, expiry handling, serialization
- Integration Tests: Full workflow testing with database interactions
CI/CD Pipeline ๐
Continuous Integration
The GitHub Actions workflow runs on every push and pull request:
- Matrix Testing: PHP 8.2, 8.3, 8.4 ร Laravel 10, 11, 12
- Code Quality: PHP CS Fixer (PSR-12) and PHPStan static analysis
- Security: Composer security audit
- Validation: Composer.json validation and lock file checks
Release Management
Automated releases are created when semantic version tags are pushed:
git tag v1.2.0 git push origin v1.2.0
Local Development
Run the same checks locally:
# Code quality checks composer cs-check composer stan # Fix code style composer cs-fix # Security audit composer audit # Full test suite composer test
API Reference ๐
Otp Facade
Method | Parameters | Returns | Description |
---|---|---|---|
generate() |
string $identity, int $expiresAt = 15 |
OtpToken |
Generate new OTP |
validate() |
string $identity, string $token |
bool |
Validate OTP |
Token Service
Method | Parameters | Returns | Description |
---|---|---|---|
identity() |
- | mixed |
Get token identity |
token() |
- | string |
Get token value |
expired() |
- | bool |
Check if token expired |
timeLeft() |
- | int |
Get seconds until expiry |
Helper Functions
Function | Parameters | Returns | Description |
---|---|---|---|
validation_number() |
string $number, string $country = 'ID' |
bool |
Validate phone number |
format_number() |
string $number, string $country = 'ID' |
string |
Format phone number |
get_email_provider() |
string $email |
string |
Extract email provider |
validate_email() |
string $email |
bool |
Check if email is disposable |
Examples ๐
Authentication Flow
// 1. Generate OTP for login $otp = Otp::generate($user->email, 10); // 2. Send OTP via email dispatch(new SendOtp($user->email, $otp)); // 3. User enters OTP $userOtp = request('otp'); // 4. Validate OTP if (Otp::validate($user->email, $userOtp)) { // Login successful Auth::login($user); return redirect()->intended('/dashboard'); } else { // Invalid OTP return back()->withErrors(['otp' => 'Invalid or expired OTP']); }
Phone Number Validation
use Turahe\Otp\Helpers; // Validate Indonesian phone number $phone = '+6281234567890'; if (validation_number($phone, 'ID')) { $formatted = format_number($phone, 'ID'); // +62 812-3456-7890 }
Email Provider Detection
use Turahe\Otp\Helpers; $email = 'user@gmail.com'; $provider = get_email_provider($email); // Returns: 'gmail' // Check if disposable email if (validate_email($email)) { // Email is not disposable } else { // Email is disposable }
Contributing ๐ค
We welcome contributions! Please see our contributing guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
composer test
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Development Setup
# Clone repository git clone https://github.com/turahe/laravel-otp.git cd laravel-otp # Install dependencies composer install # Run tests composer test # Check code quality composer cs-check composer stan
Security ๐
If you discover any security-related issues, please email security@turahe.dev instead of using the issue tracker.
License ๐
This package is open-sourced software licensed under the MIT license.
Support ๐ฌ
- Documentation: GitHub Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Changelog ๐
See CHANGELOG.md for a detailed history of changes.
Made with โค๏ธ by Turahe