88 lines
2.1 KiB
PHP
88 lines
2.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Support\Str;
|
|
|
|
class ImpersonationToken extends Model
|
|
{
|
|
protected $fillable = [
|
|
'admin_id',
|
|
'target_user_id',
|
|
'token',
|
|
'expires_at',
|
|
'used_at',
|
|
'ip_address',
|
|
];
|
|
|
|
protected $casts = [
|
|
'expires_at' => 'datetime',
|
|
'used_at' => 'datetime',
|
|
];
|
|
|
|
public function admin(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'admin_id');
|
|
}
|
|
|
|
public function targetUser(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'target_user_id');
|
|
}
|
|
|
|
public static function createForUser(User $admin, User $targetUser, ?string $ipAddress = null): self
|
|
{
|
|
// Clean up old tokens for this admin/user combination
|
|
static::where('admin_id', $admin->id)
|
|
->where('target_user_id', $targetUser->id)
|
|
->delete();
|
|
|
|
return static::create([
|
|
'admin_id' => $admin->id,
|
|
'target_user_id' => $targetUser->id,
|
|
'token' => Str::random(64),
|
|
'expires_at' => now()->addMinutes(5),
|
|
'ip_address' => $ipAddress,
|
|
]);
|
|
}
|
|
|
|
public function isValid(): bool
|
|
{
|
|
return $this->expires_at->isFuture() && $this->used_at === null;
|
|
}
|
|
|
|
public function markAsUsed(): void
|
|
{
|
|
$this->update(['used_at' => now()]);
|
|
}
|
|
|
|
public static function findValidToken(string $token, ?string $ipAddress = null): ?self
|
|
{
|
|
$record = static::where('token', $token)
|
|
->where('expires_at', '>', now())
|
|
->whereNull('used_at')
|
|
->first();
|
|
|
|
if (! $record) {
|
|
return null;
|
|
}
|
|
|
|
if ($ipAddress && $record->ip_address && $record->ip_address !== $ipAddress) {
|
|
return null;
|
|
}
|
|
|
|
return $record;
|
|
}
|
|
|
|
public static function cleanupExpired(): int
|
|
{
|
|
return static::where('expires_at', '<', now())
|
|
->orWhereNotNull('used_at')
|
|
->delete();
|
|
}
|
|
}
|