makaveli / laravel-accept-code
Advanced Accept Code for Laravel
Requires
- php: ^8.2
- laravel/framework: ^10.10|^11.0|^12.0
- makaveli/laravel-core: ^1.0.3
- makaveli/laravel-crudler: ^1.1.19
- makaveli/laravel-jwt-auth: ^1.1.4
- makaveli/laravel-logger: ^1.1.4
- makaveli/laravel-login-history: ^1.1.4
README
🌍 Languages
- 🇺🇸 English (default)
- 🇷🇺 Русская версия
Table of Contents
- Introduction
- Requirements
- Installation
- Configuration
- Core Components
- Usage
- Extending the Package
- Recommendations
- Useful Links
Introduction
makaveli/laravel-accept-code is a package for managing one‑time verification codes (OTP) in Laravel. It implements typical scenarios: login by code (password‑less), registration with confirmation, and password reset. The package uses the makaveli ecosystem (JWT authentication, logging, CRUD layers) and can be easily integrated into any project.
Key features:
- Generation and sending of verification codes (email/SMS).
- Code validity checks with TTL and resend delay.
- Ready‑to‑use DTOs and requests for typical actions.
- Integration with
laravel-jwt-authto issue tokens after successful confirmation. - Integration with
laravel-loggerfor logging actions. - Integration with
laravel-login-historyto record login history. - Flexible configuration via callbacks (user lookup, notification sending, permission checks).
Requirements
- PHP 8.2 or higher
- Laravel 10.10, 11.0 or 12.0
- makaveli/laravel-core (^1.0.3)
- makaveli/laravel-logger (^1.1.4)
- makaveli/laravel-login-history (^1.1.4)
- makaveli/laravel-jwt-auth (^1.1.4)
- makaveli/laravel-crudler (^1.1.18)
Installation
-
Install the package via Composer:
composer require makaveli/laravel-accept-code
-
Run the migrations to create the
accept_codestable:php artisan migrate:accept-code
-
(Optional) Publish the configuration file to adjust settings:
php artisan vendor:publish --tag=accept-code-config
This will create the file
config/accept-code.php.
Configuration
The config/accept-code.php file contains the main settings. All callbacks are specified as arrays [class, method] or closures.
| Parameter | Description | Default |
|---|---|---|
accept_code_slugs |
List of allowed slugs | ['login', 'registration', 'reset-password'] |
get_user_by_phone |
Callback to find a user by phone number | [\App\Modules\User\Repositories\UserRepository::class, 'getByPhone'] |
get_user_by_email |
Callback to find a user by email | similar |
get_user_role_id |
Callback to get the user's role ID | – |
check_permission_to_auth |
Callback to check permissions for authentication | – |
verified_user |
Callback to set the is_verified flag |
– |
change_password |
Callback to change the password | – |
logger_slugs |
Slugs for logging | – |
email |
Callbacks for sending email | – |
phone |
Callbacks for sending SMS | – |
accept_code_delay_repeat_ttl |
Delay between resends (seconds) | 90 |
accept_code_ttl |
Code lifetime (seconds) | 43200 (12 hours) |
phone_validation_rule |
Phone validation rule | ValidPhone::create() |
password_validation_rule |
Password validation rule | ValidPassword::create() |
Example configuration:
return [ 'get_user_by_phone' => [\App\Modules\User\Repositories\UserRepository::class, 'getByPhone'], 'get_user_by_email' => [\App\Modules\User\Repositories\UserRepository::class, 'getByEmail'], 'verified_user' => [\App\Modules\Auth\Services\AuthService::class, 'verifiedUser'], 'email' => [ 'send_verification_notification' => [\App\Modules\Email\Actions\EmailSenderActions::class, 'sendVerificationNotification'], ], 'phone' => [ 'send_login_code' => [\App\Modules\Phone\Actions\MTCActions::class, 'sendLoginCode'], ], // ... ];
Core Components
Actions
The package provides three groups of actions:
LoginAcceptCodeActions– sending and confirming a code for login.RegistrationAcceptCodeActions– sending and confirming a code for registration.ResetPasswordAcceptCodeActions– sending, verifying, and confirming a code for password reset.
Each class inherits from AcceptCodeActions, which contains common methods (transactions, logging, JWT generation, login history recording).
DTO
-
AcceptCodeDTO– a universal DTO for passing data between request and action. Contains fields:login,isPortal,code,type,captchaToken,password,request.
Static methods:fromRegistrationSendRequest,fromRegistrationAcceptAccountRequest,fromLoginSendRequest,fromLoginAcceptRequest,fromPasswordResetSendRequest,fromPasswordResetVerifyRequest,fromPasswordResetSetNewRequest. -
AcceptCodeFormDTO– a DTO for creating/updating a code record. Contains:userId,credetinal,slug,type,userVerified.
Static methods:fromCredetinalsPhone,fromCredetinals.
Repository
AcceptCodeRepository extends BaseRepository and contains methods for working with codes:
getSendAcceptCodeByUserId– get the last sent code for a user.getSendAcceptCode– get a code by credentials and slug.checkDelayIsOver– checks whether a new code can be sent (delay not exceeded).acceptCodeIsValid– checks whether the code has not expired.getAcceptCode– generic method to fetch a code with existence and TTL checks.canSendLoginAcceptCode,canSendPasswordResetCode,canSendRegistrationAcceptCode– checks whether sending is allowed.
Service
AcceptCodeService extends BaseService and is responsible for creating/updating code records:
_create(AcceptCodeFormDTO $dto)– creates a new record with a random 4‑digit code.createOrUpdate(AcceptCodeFormDTO $dto)– updates an existing record or creates a new one.
Requests
The package includes ready‑made FormRequests for each endpoint:
LoginSendCodeRequestLoginAcceptCodeRequestRegistrationSendCodeRequestRegistrationAcceptAccountRequestPasswordResetSendRequestPasswordResetVerifyRequestPasswordResetSetNewRequest
All of them extend FormRequest and use validation rules from the configuration.
Model
AcceptCode – Eloquent model with fields user_id, credetinal, code, type, slug. Used to store codes.
Console Commands
php artisan migrate:accept-code– runs the package migrations.
Usage
Login by Code
- Send code
use AcceptCode\Actions\LoginAcceptCodeActions; use AcceptCode\DTO\AcceptCodeDTO; $actions = new LoginAcceptCodeActions(); $dto = AcceptCodeDTO::fromLoginSendRequest($request); $actions->sendLoginCode($dto); // returns true or throws an exception
- Confirm code and authenticate
[$accessToken, $refreshToken, $user] = $actions->acceptLoginCodeAndAuth( AcceptCodeDTO::fromLoginAcceptRequest($request) ); // You can return the tokens and user data in the response
Registration with Confirmation
- Send registration code
use AcceptCode\Actions\RegistrationAcceptCodeActions; $actions = new RegistrationAcceptCodeActions(); $dto = AcceptCodeDTO::fromRegistrationSendRequest($request); $actions->sendRegistrationCode($dto);
- Confirm code and generate tokens
[$accessToken, $refreshToken, $user] = $actions->acceptRegistrationCode( AcceptCodeDTO::fromRegistrationAcceptAccountRequest($request) );
Password Reset
- Send password reset code
use AcceptCode\Actions\ResetPasswordAcceptCodeActions; $actions = new ResetPasswordAcceptCodeActions(); $dto = AcceptCodeDTO::fromPasswordResetSendRequest($request); $actions->sendResetPasswordCode($dto);
- Verify code (optional step)
$actions->verifyResetPasswordCode( AcceptCodeDTO::fromPasswordResetVerifyRequest($request) ); // if the code is invalid or expired, an exception will be thrown
- Set new password
$user = $actions->acceptResetPasswordCode( AcceptCodeDTO::fromPasswordResetSetNewRequest($request) );
Extending the Package
You can replace any part of the package by overriding:
- Model – create your own model extending
AcceptCode, and change$tableif needed. - Repository – extend
AcceptCodeRepositoryand override methods for custom logic. - Service – extend
AcceptCodeServiceand override_createorcreateOrUpdate. - Actions – create your own classes extending
AcceptCodeActionsand override the necessary methods. - DTO and Request – use them directly or create your own by extending the base classes.
All dependencies (logging, JWT, login history) are placed in traits that can be overridden in your own action.
Recommendations
- Configure the callbacks in the config file – specify your own methods for user lookup, sending notifications, and permission checks.
- Use asynchronous logging – actions already use
successAsyncLoganderrorAsyncLogvia theAsyncLoggertrait. - Set reasonable TTLs – adjust
accept_code_ttlandaccept_code_delay_repeat_ttlaccording to your security requirements. - Protect endpoints from spam – add a captcha (e.g.,
captchaTokenis already present in the DTO) and configure rate limits. - For email confirmation – set up email notifications in the
emailsection. - For SMS confirmation – specify your SMS services in the
phonesection.