feat: tg/ws/security/
This commit is contained in:
@@ -17,6 +17,8 @@ class User extends Authenticatable
|
||||
'auto_transfer_threshold_bnb',
|
||||
'album_storage_default',
|
||||
'can_reveal_mnemonics',
|
||||
'login_attempts',
|
||||
'locked_at',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
@@ -46,6 +48,8 @@ class User extends Authenticatable
|
||||
'album_storage_default' => 'boolean',
|
||||
'can_reveal_mnemonics' => 'boolean',
|
||||
'google_auth_open' => 'integer',
|
||||
'login_attempts' => 'integer',
|
||||
'locked_at' => 'datetime',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -59,6 +63,42 @@ class User extends Authenticatable
|
||||
return (int) $this->status === 1;
|
||||
}
|
||||
|
||||
public function isLocked(): bool
|
||||
{
|
||||
return $this->locked_at !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the consecutive failed-login counter; auto-lock when the
|
||||
* count reaches $maxAttempts (default 5). Returns true when the call
|
||||
* triggers a lock.
|
||||
*/
|
||||
public function recordFailedLogin(int $maxAttempts = 5): bool
|
||||
{
|
||||
$this->login_attempts = (int) $this->login_attempts + 1;
|
||||
$justLocked = false;
|
||||
if ($this->login_attempts >= $maxAttempts && ! $this->isLocked()) {
|
||||
$this->locked_at = now();
|
||||
$justLocked = true;
|
||||
}
|
||||
$this->save();
|
||||
|
||||
return $justLocked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the failed-login counter (called after a successful login or
|
||||
* when an admin manually unlocks the account).
|
||||
*/
|
||||
public function clearLoginAttempts(): void
|
||||
{
|
||||
if ((int) $this->login_attempts !== 0 || $this->locked_at !== null) {
|
||||
$this->login_attempts = 0;
|
||||
$this->locked_at = null;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function channels(): HasMany
|
||||
{
|
||||
return $this->hasMany(Channel::class, 'user_id');
|
||||
|
||||
Reference in New Issue
Block a user