Authenticator::getAccessToken()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoman4eg\Nalog\Http;
5
6
use Psr\Http\Client\ClientExceptionInterface;
7
use Psr\Http\Client\ClientInterface;
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 the API Client, it is not part of the BC promise
20
 */
21
final class Authenticator
22
{
23
    private RequestBuilder $requestBuilder;
24
    private ClientInterface $httpClient;
25
    private ?string $accessToken;
26
    private string $deviceId;
27
    private array $defaultHeaders = [
28
        'Referrer' => 'https://lknpd.nalog.ru/auth/login',
29
    ];
30
31
    public function __construct(RequestBuilder $requestBuilder, ClientInterface $httpClient, string $deviceId)
32
    {
33
        $this->requestBuilder = $requestBuilder;
34
        $this->httpClient = $httpClient;
35
        $this->deviceId = $deviceId;
36
    }
37
38
    /**
39
     * @throws \JsonException
40
     * @throws ClientExceptionInterface
41
     * @throws DomainException
42
     */
43
    public function createAccessToken(string $username, string $password): ?string
44
    {
45
        $request = $this->requestBuilder->create(
46
            'POST',
47
            '/auth/lkfl',
48
            $this->defaultHeaders,
49
            JSON::encode([
50
                'username' => $username,
51
                'password' => $password,
52
                'deviceInfo' => new DeviceInfo($this->deviceId),
53
            ])
54
        );
55
56
        $response = $this->httpClient->sendRequest($request);
57
58
        if ($response->getStatusCode() >= 400) {
59
            (new ErrorHandler())->handleResponse($response);
60
        }
61
62
        $this->accessToken = (string)$response->getBody();
63
64
        return $this->accessToken;
65
    }
66
67
    /**
68
     * @throws \JsonException
69
     * @throws ClientExceptionInterface
70
     */
71
    public function createAccessTokenByPhone(string $phone, string $challengeToken, string $verificationCode): ?string
72
    {
73
        $request = $this->requestBuilder->create(
74
            'POST',
75
            '/auth/challenge/sms/verify',
76
            $this->defaultHeaders,
77
            JSON::encode([
78
                'phone' => $phone,
79
                'code' => $verificationCode,
80
                'challengeToken' => $challengeToken,
81
                'deviceInfo' => new DeviceInfo($this->deviceId),
82
            ])
83
        );
84
85
        $response = $this->httpClient->sendRequest($request);
86
87
        if ($response->getStatusCode() >= 400) {
88
            (new ErrorHandler())->handleResponse($response);
89
        }
90
91
        $this->accessToken = (string)$response->getBody();
92
93
        return $this->accessToken;
94
    }
95
96
    /**
97
     * @return array{challengeToken: string, expireDate: string, expireIn: int}
98
     *
99
     * @throws \JsonException
100
     * @throws ClientExceptionInterface
101
     * @throws DomainException
102
     */
103
    public function createPhoneChallenge(string $phone): array
104
    {
105
        $request = $this->requestBuilder->create(
106
            'POST',
107
            '/auth/challenge/sms/start',
108
            $this->defaultHeaders,
109
            JSON::encode([
110
                'phone' => $phone,
111
                'requireTpToBeActive' => true,
112
            ])
113
        );
114
115
        $response = $this->httpClient->sendRequest($request);
116
117
        if ($response->getStatusCode() >= 400) {
118
            (new ErrorHandler())->handleResponse($response);
119
        }
120
121
        $response = (string)$response->getBody();
122
123
        return JSON::decode($response);
124
    }
125
126
    /**
127
     * @throws \JsonException
128
     * @throws ClientExceptionInterface
129
     */
130
    public function refreshAccessToken(string $refreshToken): ?string
131
    {
132
        $request = $this->requestBuilder->create(
133
            'POST',
134
            '/auth/token',
135
            $this->defaultHeaders,
136
            JSON::encode([
137
                'deviceInfo' => new DeviceInfo($this->deviceId),
138
                'refreshToken' => $refreshToken,
139
            ])
140
        );
141
142
        $response = $this->httpClient->sendRequest($request);
143
        if ($response->getStatusCode() !== 200) {
144
            return null;
145
        }
146
147
        $this->accessToken = (string)$response->getBody();
148
149
        return $this->accessToken;
150
    }
151
152
    public function setAccessToken(string $accessToken): void
153
    {
154
        $this->accessToken = $accessToken;
155
    }
156
157
    public function getAccessToken(): ?string
158
    {
159
        return $this->accessToken;
160
    }
161
}
162