Repository navigation
otp vault
alizeinodin edited this page Sep 11, 2026
·
2 revisions
Optional module: generate → HMAC-SHA256 store → deliver → check.
php artisan smsapi:install otpSMSAPI_OTP_VAULT_ENABLED=true
SMSAPI_OTP_LENGTH=5
SMSAPI_OTP_TTL=300
SMSAPI_OTP_MAX_ATTEMPTS=5
# SMSAPI_OTP_VAULT_STORE=database # or cache
# SMSAPI_OTP_PEPPER= # defaults to APP_KEYuse Alizeinodin\SmsApi\Facades\Sms;
// purpose = vault namespace ("login"); template = SMS/mail template name
Sms::challenge('login')
->template('otp-login')
->to($user)
->send();
Sms::challenge('login')->check($user, $request->input('code'));
$result = Sms::challenge('login')->check($user, $code, throw: false);
if ($result->ok()) {
// …
}| Rule | Behavior |
|---|---|
| Storage | HMAC only — never plaintext in DB |
| Binding | Hash includes recipient + purpose + code |
| Consume | Atomic — second concurrent success fails |
| Attempts | Incremented on mismatch; lock after max |
| TTL | Expired challenges rejected |
| Re-issue | Invalidates previous active challenge |
| Throttle | Per recipient (+ purpose) on issue |
| Sync default | Avoids putting CODE on the queue |
SMSAPI_OTP_VAULT_ALLOW_QUEUE=trueSms::challenge('login')->template('otp-login')->to($user)->queue('otp')->send();If the job permanently fails, the challenge is invalidated via SendMessageJob::failed().
Danger: Queued vault sends still serialize
CODEinto the job payload. Prefer sync for production OTP.
| API | Meaning |
|---|---|
Sms::otp('tpl') |
Deliver template (you provide CODE) |
Sms::challenge('purpose') |
Vault lifecycle |
Sms::otpVault() |
Low-level vault service |