Passed
Pull Request — master (#23)
by
unknown
11:09
created

Authenticator   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 59
dl 0
loc 127
rs 10
c 2
b 0
f 0
wmc 11

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setAccessToken() 0 3 1
A createPhoneChallenge() 0 20 2
A getAccessToken() 0 3 1
A createAccessTokenByPhone() 0 21 2
A createAccessToken() 0 20 2
A __construct() 0 5 1
A refreshAccessToken() 0 18 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoman4eg\Nalog\Http;
5
6
use Http\Client\HttpClient;
7
use Psr\Http\Client\ClientExceptionInterface;
8
use Shoman4eg\Nalog\DTO\DeviceInfo;
9
use Shoman4eg\Nalog\ErrorHandler;
10
use Shoman4eg\Nalog\Exception\DomainException;
11
use Shoman4eg\Nalog\RequestBuilder;
12
use Shoman4eg\Nalog\Util\JSON;
13
14
/**
15
 * Helper class to get access tokens.
16
 *
17
 * @author Artem Dubinin <[email protected]>
18
 *
19
 * @internal this class should not be used outside of the API Client, it is not part of the BC promise
20
 */
21
final class Authenticator
22
{
23
    private RequestBuilder $requestBuilder;
24
    private HttpClient $httpClient;
25
    private ?string $accessToken;
26
    private array $challenge;
27
    private string $deviceId;
28
29
    public function __construct(RequestBuilder $requestBuilder, HttpClient $httpClient, string $deviceId)
30
    {
31
        $this->requestBuilder = $requestBuilder;
32
        $this->httpClient = $httpClient;
33
        $this->deviceId = $deviceId;
34
    }
35
36
    /**
37
     * @throws ClientExceptionInterface
38
     * @throws \JsonException
39
     * @throws DomainException
40
     */
41
    public function createAccessToken(string $username, string $password): ?string
42
    {
43
        $request = $this->requestBuilder->create('POST', '/auth/lkfl', [
44
            'Referrer' => 'https://lknpd.nalog.ru/',
45
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
46
        ], \json_encode([
47
            'username' => $username,
48
            'password' => $password,
49
            'deviceInfo' => new DeviceInfo($this->deviceId),
50
        ]));
51
52
        $response = $this->httpClient->sendRequest($request);
53
54
        if ($response->getStatusCode() >= 400) {
55
            (new ErrorHandler())->handleResponse($response);
56
        }
57
58
        $this->accessToken = (string)$response->getBody();
59
60
        return $this->accessToken;
61
    }
62
63
    /**
64
     * @throws ClientExceptionInterface
65
     * @throws \JsonException
66
     */
67
    public function createAccessTokenByPhone(string $phone, string $challengeToken, string $verificationCode): ?string
68
    {
69
        $request = $this->requestBuilder->create('POST', '/auth/challenge/sms/verify', [
70
            'Referrer' => 'https://lknpd.nalog.ru/',
71
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
72
        ], \json_encode([
73
            'phone' => $phone,
74
            'code' => $verificationCode,
75
            'challengeToken' => $challengeToken,
76
            'deviceInfo' => new DeviceInfo($this->deviceId),
77
        ]));
78
79
        $response = $this->httpClient->sendRequest($request);
80
81
        if ($response->getStatusCode() >= 400) {
82
            (new ErrorHandler())->handleResponse($response);
83
        }
84
85
        $this->accessToken = (string)$response->getBody();
86
87
        return $this->accessToken;
88
    }
89
90
    /**
91
     * @throws ClientExceptionInterface
92
     * @throws \JsonException
93
     */
94
    public function createPhoneChallenge(string $phone): array
95
    {
96
        $request = $this->requestBuilder->create('POST', '/auth/challenge/sms/start', [
97
            'Referrer' => 'https://lknpd.nalog.ru/',
98
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
99
        ], \json_encode([
100
            'phone' => $phone,
101
            'requireTpToBeActive' => true,
102
        ]));
103
104
        $response = $this->httpClient->sendRequest($request);
105
106
        if ($response->getStatusCode() >= 400) {
107
            (new ErrorHandler())->handleResponse($response);
108
        }
109
110
        $response = (string)$response->getBody();
111
        $this->challenge = JSON::decode($response);
112
113
        return $this->challenge;
114
    }
115
116
    /**
117
     * @throws ClientExceptionInterface
118
     * @throws \JsonException
119
     */
120
    public function refreshAccessToken(string $refreshToken): ?string
121
    {
122
        $request = $this->requestBuilder->create('POST', '/auth/token', [
123
            'Referrer' => 'https://lknpd.nalog.ru/sales',
124
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
125
        ], JSON::encode([
126
            'deviceInfo' => new DeviceInfo($this->deviceId),
127
            'refreshToken' => $refreshToken,
128
        ]));
129
130
        $response = $this->httpClient->sendRequest($request);
131
        if ($response->getStatusCode() !== 200) {
132
            return null;
133
        }
134
135
        $this->accessToken = (string)$response->getBody();
136
137
        return $this->accessToken;
138
    }
139
140
    public function setAccessToken(string $accessToken): void
141
    {
142
        $this->accessToken = $accessToken;
143
    }
144
145
    public function getAccessToken(): ?string
146
    {
147
        return $this->accessToken;
148
    }
149
}
150