First round of refinements on the login system...

There's a lot more to do on the to-do list
This commit is contained in:
Dan Baker 2026-02-22 20:02:09 +00:00
parent 82ed2e3ce2
commit 1b241aeddb
7 changed files with 390 additions and 219 deletions

View file

@ -2,6 +2,7 @@
namespace App\Models;
use App\DTOs\MagicTokenResult;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@ -20,9 +21,7 @@ class MagicLoginToken extends Model
protected $fillable = [
'email_hash',
'token_hash',
'plain_token',
'code_hash',
'plain_code',
'expires_at',
'ip_address',
'user_agent',
@ -44,23 +43,23 @@ class MagicLoginToken extends Model
/**
* Generate a new magic login token for the given email.
* Plain token and code are returned in the DTO but never persisted.
*/
public static function generate(string $email, ?string $ip = null, ?string $ua = null): self
public static function generate(string $email, ?string $ip = null, ?string $ua = null): MagicTokenResult
{
$emailHash = User::hashEmail($email);
$token = Str::random(64);
$code = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);
$plainToken = Str::random(64);
$plainCode = str_pad((string) random_int(0, 999999), 6, '0', STR_PAD_LEFT);
return self::create([
'email_hash' => $emailHash,
'token_hash' => Hash::make($token),
'plain_token' => $token,
'code_hash' => Hash::make($code),
'plain_code' => $code,
$model = self::create([
'email_hash' => User::hashEmail($email),
'token_hash' => hash('sha256', $plainToken),
'code_hash' => Hash::make($plainCode),
'expires_at' => now()->addMinutes(15),
'ip_address' => $ip,
'user_agent' => $ua,
]);
return new MagicTokenResult($model, $plainToken, $plainCode);
}
/**
@ -79,14 +78,6 @@ class MagicLoginToken extends Model
$this->update(['used_at' => now()]);
}
/**
* Verify the provided token matches the plain token.
*/
public function verifyToken(string $token): bool
{
return $this->plain_token === $token;
}
/**
* Verify the provided code matches the hashed code.
*/