62 lines
1.4 KiB
PHP
62 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Auth;
|
|
|
|
use App\Models\OtpCode;
|
|
use Carbon\Carbon;
|
|
|
|
class OtpService
|
|
{
|
|
/**
|
|
* Generate and save an OTP code for an identifier.
|
|
*/
|
|
public function generate(string $identifier, int $expiryMinutes = 10): string
|
|
{
|
|
// Delete old unexpired codes for this identifier to avoid clutter
|
|
OtpCode::where('identifier', $identifier)
|
|
->whereNull('verified_at')
|
|
->delete();
|
|
|
|
$code = (string) random_int(100000, 999999);
|
|
|
|
OtpCode::create([
|
|
'identifier' => $identifier,
|
|
'code' => $code,
|
|
'expires_at' => Carbon::now()->addMinutes($expiryMinutes),
|
|
]);
|
|
|
|
return $code;
|
|
}
|
|
|
|
/**
|
|
* Verify the OTP code.
|
|
*/
|
|
public function verify(string $identifier, string $code): bool
|
|
{
|
|
$otp = OtpCode::where('identifier', $identifier)
|
|
->where('code', $code)
|
|
->whereNull('verified_at')
|
|
->where('expires_at', '>', Carbon::now())
|
|
->latest()
|
|
->first();
|
|
|
|
if ($otp) {
|
|
$otp->update(['verified_at' => Carbon::now()]);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Clear expired codes.
|
|
*/
|
|
public function cleanup(): void
|
|
{
|
|
OtpCode::where('expires_at', '<', Carbon::now())
|
|
->whereNull('verified_at')
|
|
->delete();
|
|
}
|
|
}
|