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

daycry / auth / 25518434194

07 May 2026 07:49PM UTC coverage: 58.608% (-6.4%) from 64.989%
25518434194

push

github

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

Implement security enhancements and new account features

277 of 1030 new or added lines in 55 files covered. (26.89%)

11 existing lines in 6 files now uncovered.

3544 of 6047 relevant lines covered (58.61%)

47.97 hits per line

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

26.67
/src/Authentication/Services/DeviceSessionRecorder.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\Authentication\Services;
15

16
use CodeIgniter\HTTP\IncomingRequest;
17
use Daycry\Auth\Entities\User;
18
use Daycry\Auth\Models\DeviceSessionModel;
19
use Throwable;
20

21
/**
22
 * Handles creation and termination of device session records.
23
 *
24
 * Extracted from Session authenticator to isolate device-tracking
25
 * concerns from the core authentication flow.
26
 *
27
 * DB failures here are logged but **never** propagate — device tracking
28
 * is a non-critical feature and must not break login/logout.
29
 */
30
class DeviceSessionRecorder
31
{
32
    /**
33
     * Creates a device session record for the given user.
34
     *
35
     * Silently returns if there is no active PHP session (e.g. in testing).
36
     */
37
    public function recordSession(User $user, string $ipAddress): void
34✔
38
    {
39
        $sessionId = session_id();
34✔
40

41
        // No active session (e.g. testing environment without a real session)
42
        if ($sessionId === '' || $sessionId === false) {
34✔
43
            return;
34✔
44
        }
45

46
        try {
47
            /** @var DeviceSessionModel $deviceSessionModel */
NEW
48
            $deviceSessionModel = model(DeviceSessionModel::class);
×
49

50
            // Enforce per-user concurrent session limit (terminates oldest excess
51
            // sessions before creating the new one). 0 = unlimited.
NEW
52
            $limit = (int) (setting('Auth.maxConcurrentSessions') ?? 0);
×
53

NEW
54
            if ($limit > 0) {
×
NEW
55
                $deviceSessionModel->enforceConcurrentSessionLimit($user, $limit);
×
56
            }
57

58
            /** @var IncomingRequest $incomingRequest */
NEW
59
            $incomingRequest = service('request');
×
NEW
60
            $userAgent       = (string) $incomingRequest->getUserAgent();
×
61

NEW
62
            $deviceSessionModel->createSession(
×
NEW
63
                $user,
×
NEW
64
                $sessionId,
×
NEW
65
                $ipAddress,
×
NEW
66
                $userAgent !== '' ? $userAgent : null,
×
NEW
67
            );
×
NEW
68
        } catch (Throwable $e) {
×
NEW
69
            log_message('error', 'DeviceSessionRecorder::recordSession failed: {message}', [
×
NEW
70
                'message' => $e->getMessage(),
×
NEW
71
            ]);
×
72
        }
73
    }
74

75
    /**
76
     * Terminates the current device session.
77
     */
78
    public function terminateCurrentSession(): void
4✔
79
    {
80
        $sessionId = session_id();
4✔
81

82
        if ($sessionId === '' || $sessionId === false) {
4✔
83
            return;
4✔
84
        }
85

86
        try {
87
            /** @var DeviceSessionModel $deviceSessionModel */
NEW
88
            $deviceSessionModel = model(DeviceSessionModel::class);
×
NEW
89
            $deviceSessionModel->terminateSession($sessionId);
×
NEW
90
        } catch (Throwable $e) {
×
NEW
91
            log_message('error', 'DeviceSessionRecorder::terminateCurrentSession failed: {message}', [
×
NEW
92
                'message' => $e->getMessage(),
×
NEW
93
            ]);
×
94
        }
95
    }
96
}
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