AccessCode::getResponseAccessCodeFromForm()   A
last analyzed

Complexity

Conditions 4
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 11
c 1
b 0
f 1
dl 0
loc 20
rs 9.9
cc 4
nc 2
nop 0
1
<?php
2
3
namespace MagicLink;
4
5
use Illuminate\Contracts\Encryption\DecryptException;
6
use Illuminate\Support\Arr;
7
use Illuminate\Support\Facades\Hash;
8
9
trait AccessCode
10
{
11
    abstract protected function getAccessCode();
12
13
    abstract protected function getMagikLinkId();
14
15
    protected $cookieName = 'magic-link-access-code';
16
17
    public function getResponseAccessCode()
18
    {
19
        $responseFromForm = $this->getResponseAccessCodeFromForm();
20
21
        return $responseFromForm
22
            ? $responseFromForm
23
            : $this->getResponseAccessCodeFromCookie();
24
    }
25
26
    /**
27
     * Check if access code is right.
28
     */
29
    private function checkAccessCode(?string $accessCode): bool
30
    {
31
        if ($accessCode === null) {
32
            return false;
33
        }
34
35
        return Hash::check($accessCode, $this->getAccessCode());
36
    }
37
38
    /**
39
     * The action was protected with an access code.
40
     */
41
    private function protectedWithAccessCode(): bool
42
    {
43
        return ! is_null($this->getAccessCode() ?? null);
44
    }
45
46
    private function getResponseAccessCodeFromForm()
47
    {
48
        $accessCode = $this->getAccessCodeFromForm();
49
50
        if (
51
            $this->protectedWithAccessCode()
52
            && $accessCode
53
            && $this->checkAccessCode($accessCode)
54
        ) {
55
            return redirect(request()->url())->withCookie(
56
                cookie(
57
                    $this->cookieName,
58
                    encrypt($this->getMagikLinkId().'|'.$accessCode),
59
                    0,
60
                    '/'
61
                )
62
            );
63
        }
64
65
        return null;
66
    }
67
68
    private function getResponseAccessCodeFromCookie()
69
    {
70
        if ($this->protectedWithAccessCode()) {
71
            if ($this->getAccessCodeFromCookie()) {
72
                if ($this->checkAccessCode($this->getAccessCodeFromCookie())) {
73
                    return null;
74
                }
75
            }
76
77
            return response()->view(
78
                config('magiclink.access-code.view', 'magiclink::ask-for-access-code-form'),
79
                [],
80
                403
81
            );
82
        }
83
84
        return null;
85
    }
86
87
    private function getAccessCodeFromForm()
88
    {
89
        return request()->get('access-code');
90
    }
91
92
    private function getAccessCodeFromCookie()
93
    {
94
        $accessCodeCookies = request()->cookie($this->cookieName);
95
96
        if (! $accessCodeCookies) {
97
            return null;
98
        }
99
100
        try {
101
            $cookie = Arr::last((array) $accessCodeCookies);
102
103
            [$magiclinkId, $accessCode] = explode('|', decrypt($cookie));
104
105
            if ($magiclinkId === $this->getMagikLinkId()) {
106
                return $accessCode;
107
            }
108
        } catch (DecryptException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
109
        }
110
111
        return null;
112
    }
113
}
114