83 lines
2.5 KiB
PHP
83 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace Paymenter\Extensions\Others\Security\Services;
|
|
|
|
use App\Models\User;
|
|
use Paymenter\Extensions\Others\Security\Models\SuspendedAccount;
|
|
use Paymenter\Extensions\Others\Security\Models\LoginAttempt;
|
|
use Illuminate\Support\Facades\Auth;
|
|
|
|
class FraudDetectionService
|
|
{
|
|
public static function checkAndSuspendForFraud(User $user): bool
|
|
{
|
|
$extension = app(\Paymenter\Extensions\Others\Security\Security::class);
|
|
$config = $extension->getConfig();
|
|
|
|
$autoSuspend = false;
|
|
foreach ($config as $setting) {
|
|
if ($setting['name'] === 'auto_suspend_fraud') {
|
|
$autoSuspend = $setting['default'] ?? false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$autoSuspend) {
|
|
return false;
|
|
}
|
|
|
|
$fraudScore = static::calculateFraudScore($user);
|
|
|
|
if ($fraudScore >= 70) {
|
|
SuspendedAccount::suspendUser(
|
|
$user->id,
|
|
"Auto-suspended due to suspected fraudulent activity (Score: {$fraudScore})",
|
|
Auth::id() ?? 1,
|
|
false,
|
|
now()->addDays(7),
|
|
"Automated fraud detection triggered suspension"
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected static function calculateFraudScore(User $user): int
|
|
{
|
|
$score = 0;
|
|
|
|
$recentFailedLogins = LoginAttempt::where('email', $user->email)
|
|
->where('successful', false)
|
|
->where('attempted_at', '>', now()->subDay())
|
|
->count();
|
|
|
|
if ($recentFailedLogins > 10) $score += 30;
|
|
elseif ($recentFailedLogins > 5) $score += 15;
|
|
|
|
$recentIPs = LoginAttempt::where('email', $user->email)
|
|
->where('attempted_at', '>', now()->subHours(2))
|
|
->distinct('ip_address')
|
|
->count();
|
|
|
|
if ($recentIPs > 3) $score += 25;
|
|
elseif ($recentIPs > 2) $score += 10;
|
|
|
|
$rapidLogins = LoginAttempt::where('email', $user->email)
|
|
->where('attempted_at', '>', now()->subMinutes(10))
|
|
->count();
|
|
|
|
if ($rapidLogins > 10) $score += 35;
|
|
elseif ($rapidLogins > 5) $score += 20;
|
|
|
|
return min($score, 100);
|
|
}
|
|
|
|
public static function shouldFlagForReview(User $user): bool
|
|
{
|
|
$fraudScore = static::calculateFraudScore($user);
|
|
return $fraudScore >= 40 && $fraudScore < 70;
|
|
}
|
|
}
|