• 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

0.0
/src/Controllers/ForcePasswordResetController.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\Controllers;
15

16
use CodeIgniter\HTTP\RedirectResponse;
17
use CodeIgniter\HTTP\ResponseInterface;
18
use Daycry\Auth\Authentication\Passwords;
19
use Daycry\Auth\Models\UserModel;
20
use Daycry\Auth\Services\AuditLogger;
21
use Daycry\Auth\Services\PasswordChangeRecorder;
22

23
/**
24
 * Handles forced password resets for logged-in users
25
 * whose accounts have been flagged for a mandatory password change.
26
 *
27
 * The ForcePasswordResetFilter redirects users here when
28
 * $user->requiresPasswordReset() returns true.
29
 */
30
class ForcePasswordResetController extends BaseAuthController
31
{
32
    /**
33
     * Displays the force password reset form.
34
     */
35
    public function showView(): ResponseInterface
×
36
    {
37
        if (! auth()->loggedIn()) {
×
38
            return redirect()->route('login');
×
39
        }
40

41
        $content = $this->view(setting('Auth.views')['force-password-reset']);
×
42

43
        return $this->response->setBody($content);
×
44
    }
45

46
    /**
47
     * Handles the force password reset form submission.
48
     */
49
    public function resetAction(): RedirectResponse
×
50
    {
51
        if (! auth()->loggedIn()) {
×
52
            return redirect()->route('login');
×
53
        }
54

55
        $rules = $this->getValidationRules();
×
56

57
        $postData = $this->request->getPost();
×
58

59
        if (! $this->validateRequest($postData, $rules)) {
×
60
            return $this->handleValidationError(config('Auth')->forcePasswordResetRedirect());
×
61
        }
62

63
        $user            = auth()->user();
×
64
        $currentPassword = $this->request->getPost('current_password');
×
65
        $newPassword     = $this->request->getPost('new_password');
×
66

67
        // Verify the current password
68
        /** @var Passwords $passwords */
69
        $passwords = service('passwords');
×
70

71
        if (! $passwords->verify($currentPassword, $user->getPasswordHash())) {
×
72
            return $this->handleError(
×
73
                config('Auth')->forcePasswordResetRedirect(),
×
74
                lang('Auth.invalidCurrentPassword'),
×
75
            );
×
76
        }
77

78
        // Capture the previous hash for password-history bookkeeping.
NEW
79
        $previousHash = $user->password_hash ?? null;
×
80

81
        // Update the password
82
        $user->setPassword($newPassword);
×
83

84
        /** @var UserModel $userModel */
85
        $userModel = model(UserModel::class);
×
86
        $userModel->save($user);
×
87

NEW
88
        (new PasswordChangeRecorder())->record($user, $previousHash);
×
89

90
        // Clear the force reset flag
91
        $user->undoForcePasswordReset();
×
92

NEW
93
        (new AuditLogger())->record(AuditLogger::EVENT_PASSWORD_CHANGED, (int) $user->id, [
×
NEW
94
            'forced' => true,
×
NEW
95
        ]);
×
96

97
        return $this->handleSuccess(
×
98
            config('Auth')->loginRedirect(),
×
99
            lang('Auth.forceResetSuccess'),
×
100
        );
×
101
    }
102

103
    /**
104
     * Returns the rules that should be used for validation.
105
     *
106
     * @return array<string, string>
107
     */
108
    protected function getValidationRules(): array
×
109
    {
110
        return [
×
111
            'current_password'     => 'required',
×
112
            'new_password'         => 'required|min_length[8]',
×
113
            'new_password_confirm' => 'required|matches[new_password]',
×
114
        ];
×
115
    }
116
}
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