Passed
Push — master ( 5deb44...ec8b22 )
by Darko
08:20
created

Google2FAAuthenticator::isDeviceTrusted()   A

Complexity

Conditions 6
Paths 9

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 14
c 1
b 1
f 0
dl 0
loc 30
rs 9.2222
cc 6
nc 9
nop 0
1
<?php
2
3
namespace App\Support;
4
5
use PragmaRX\Google2FALaravel\Exceptions\InvalidSecretKey;
6
use PragmaRX\Google2FALaravel\Support\Authenticator;
7
8
class Google2FAAuthenticator extends Authenticator
9
{
10
    protected function canPassWithoutCheckingOTP(): bool
11
    {
12
        if (! $this->getUser()->passwordSecurity) {
13
            return true;
14
        }
15
16
        return
17
            ! $this->getUser()->passwordSecurity->google2fa_enable ||
18
            ! $this->isEnabled() ||
19
            $this->noUserIsAuthenticated() ||
20
            $this->twoFactorAuthStillValid() ||
21
            $this->isDeviceTrusted();
22
    }
23
24
    /**
25
     * Check if current device is trusted
26
     */
27
    protected function isDeviceTrusted(): bool
28
    {
29
        $cookie = request()->cookie('2fa_trusted_device');
30
31
        if (! $cookie) {
32
            return false;
33
        }
34
35
        try {
36
            $data = json_decode($cookie, true);
0 ignored issues
show
Bug introduced by
It seems like $cookie can also be of type array; however, parameter $json of json_decode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

36
            $data = json_decode(/** @scrutinizer ignore-type */ $cookie, true);
Loading history...
37
38
            // Check if cookie contains the required data
39
            if (! isset($data['user_id'], $data['token'], $data['expires_at'])) {
40
                return false;
41
            }
42
43
            // Check if the token belongs to the current user
44
            if ((int) $data['user_id'] !== (int) $this->getUser()->id) {
45
                return false;
46
            }
47
48
            // Check if the token is expired
49
            if (time() > $data['expires_at']) {
50
                return false;
51
            }
52
53
            // Device is trusted and token is valid
54
            return true;
55
        } catch (\Exception $e) {
56
            return false;
57
        }
58
    }
59
60
    /**
61
     * @return mixed
62
     *
63
     * @throws InvalidSecretKey
64
     */
65
    protected function getGoogle2FASecretKey()
66
    {
67
        $secret = $this->getUser()->passwordSecurity->{$this->config('otp_secret_column')};
68
69
        if (empty($secret)) {
70
            throw new InvalidSecretKey('Secret key cannot be empty.');
71
        }
72
73
        return $secret;
74
    }
75
}
76