Passed
Push — master ( 5e1c69...957702 )
by Artem
01:39
created

Authenticator::createPhoneChallenge()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 11
nc 2
nop 1
dl 0
loc 19
rs 9.9
c 1
b 0
f 0
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 string $deviceId;
27
28
    public function __construct(RequestBuilder $requestBuilder, HttpClient $httpClient, string $deviceId)
29
    {
30
        $this->requestBuilder = $requestBuilder;
31
        $this->httpClient = $httpClient;
32
        $this->deviceId = $deviceId;
33
    }
34
35
    /**
36
     * @throws ClientExceptionInterface
37
     * @throws \JsonException
38
     * @throws DomainException
39
     */
40
    public function createAccessToken(string $username, string $password): ?string
41
    {
42
        $request = $this->requestBuilder->create('POST', '/auth/lkfl', [
43
            'Referrer' => 'https://lknpd.nalog.ru/',
44
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
45
        ], \json_encode([
46
            'username' => $username,
47
            'password' => $password,
48
            'deviceInfo' => new DeviceInfo($this->deviceId),
49
        ]));
50
51
        $response = $this->httpClient->sendRequest($request);
52
53
        if ($response->getStatusCode() >= 400) {
54
            (new ErrorHandler())->handleResponse($response);
55
        }
56
57
        $this->accessToken = (string)$response->getBody();
58
59
        return $this->accessToken;
60
    }
61
62
    /**
63
     * @throws ClientExceptionInterface
64
     * @throws \JsonException
65
     */
66
    public function createAccessTokenByPhone(string $phone, string $challengeToken, string $verificationCode): ?string
67
    {
68
        $request = $this->requestBuilder->create('POST', '/auth/challenge/sms/verify', [
69
            'Referrer' => 'https://lknpd.nalog.ru/',
70
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
71
        ], \json_encode([
72
            'phone' => $phone,
73
            'code' => $verificationCode,
74
            'challengeToken' => $challengeToken,
75
            'deviceInfo' => new DeviceInfo($this->deviceId),
76
        ]));
77
78
        $response = $this->httpClient->sendRequest($request);
79
80
        if ($response->getStatusCode() >= 400) {
81
            (new ErrorHandler())->handleResponse($response);
82
        }
83
84
        $this->accessToken = (string)$response->getBody();
85
86
        return $this->accessToken;
87
    }
88
89
    /**
90
     * @throws ClientExceptionInterface
91
     * @throws \JsonException
92
     * @return array{challengeToken: string, expireDate: string, expireIn: int}
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
112
        return JSON::decode($response);
113
    }
114
115
    /**
116
     * @throws ClientExceptionInterface
117
     * @throws \JsonException
118
     */
119
    public function refreshAccessToken(string $refreshToken): ?string
120
    {
121
        $request = $this->requestBuilder->create('POST', '/auth/token', [
122
            'Referrer' => 'https://lknpd.nalog.ru/sales',
123
            'Referrer-Policy' => 'strict-origin-when-cross-origin',
124
        ], JSON::encode([
125
            'deviceInfo' => new DeviceInfo($this->deviceId),
126
            'refreshToken' => $refreshToken,
127
        ]));
128
129
        $response = $this->httpClient->sendRequest($request);
130
        if ($response->getStatusCode() !== 200) {
131
            return null;
132
        }
133
134
        $this->accessToken = (string)$response->getBody();
135
136
        return $this->accessToken;
137
    }
138
139
    public function setAccessToken(string $accessToken): void
140
    {
141
        $this->accessToken = $accessToken;
142
    }
143
144
    public function getAccessToken(): ?string
145
    {
146
        return $this->accessToken;
147
    }
148
}
149