• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daycry / auth / 16343465380

17 Jul 2025 11:07AM UTC coverage: 59.224% (-0.6%) from 59.854%
16343465380

push

github

web-flow
Merge pull request #23 from daycry/development

Improvements

57 of 292 new or added lines in 16 files covered. (19.52%)

6 existing lines in 4 files now uncovered.

1939 of 3274 relevant lines covered (59.22%)

22.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

8.33
/src/Services/AttemptHandler.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Auth.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Auth\Services;
15

16
use CodeIgniter\HTTP\RequestInterface;
17
use CodeIgniter\HTTP\ResponseInterface;
18
use Daycry\Auth\Models\AttemptModel;
19
use Daycry\Auth\Validators\AttemptValidator;
20

21
/**
22
 * Service for handling invalid login attempts
23
 *
24
 * Extracts attempt handling logic from BaseControllerTrait
25
 */
26
class AttemptHandler
27
{
28
    protected AttemptModel $attemptModel;
29
    protected bool $isEnabled;
30

31
    public function __construct()
32
    {
33
        $this->attemptModel = new AttemptModel();
15✔
34
        $this->isEnabled    = service('settings')->get('Auth.enableInvalidAttempts') === true;
15✔
35
    }
36

37
    /**
38
     * Check if attempts validation is enabled and validate if needed
39
     */
40
    public function validateAttempts(ResponseInterface $response): void
41
    {
NEW
42
        if (! $this->isEnabled) {
×
NEW
43
            return;
×
44
        }
45

NEW
46
        AttemptValidator::check($response);
×
47
    }
48

49
    /**
50
     * Handle invalid attempts by updating the attempts counter
51
     */
52
    public function handleInvalidAttempt(RequestInterface $request): void
53
    {
NEW
54
        if (! $this->isEnabled) {
×
NEW
55
            return;
×
56
        }
57

NEW
58
        $ipAddress = $request->getIPAddress();
×
NEW
59
        $attempt   = $this->attemptModel->where('ip_address', $ipAddress)->first();
×
60

NEW
61
        if ($attempt === null) {
×
NEW
62
            $this->createNewAttempt($ipAddress);
×
NEW
63
        } elseif ($attempt->attempts < service('settings')->get('Auth.maxAttempts')) {
×
NEW
64
            $this->incrementAttempt($attempt);
×
65
        }
66
    }
67

68
    /**
69
     * Create a new attempt record
70
     */
71
    private function createNewAttempt(string $ipAddress): void
72
    {
NEW
73
        $attempt = [
×
NEW
74
            'user_id'      => auth()->user()?->id,
×
NEW
75
            'ip_address'   => $ipAddress,
×
NEW
76
            'attempts'     => 1,
×
NEW
77
            'hour_started' => time(),
×
NEW
78
        ];
×
79

NEW
80
        $this->attemptModel->save($attempt);
×
81
    }
82

83
    /**
84
     * Increment existing attempt counter
85
     */
86
    private function incrementAttempt(object $attempt): void
87
    {
NEW
88
        $attempt->attempts++;
×
NEW
89
        $this->attemptModel->save($attempt);
×
90
    }
91

92
    /**
93
     * Check if attempts handling is enabled
94
     */
95
    public function isEnabled(): bool
96
    {
NEW
97
        return $this->isEnabled;
×
98
    }
99

100
    /**
101
     * Static method to get a new instance
102
     */
103
    public static function getInstance(): self
104
    {
NEW
105
        return new self();
×
106
    }
107
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc