&НаКлиенте
Процедура ПолучитьСМСДляМойНалог(Команда)
Если Не ЗначениеЗаполнено(Объект.НомерТелефонаМойНалог) или СтрДлина(Объект.НомерТелефонаМойНалог) < 11 Тогда
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = "Введите в Настройках номер телефона для доступа к порталу 'Мой налог'";
Сообщение.Сообщить();
Иначе
СтруктураОтвета = ПолучитьДанныеАвторизацииНаПорталеМойНалог(Истина);
Если Не СтруктураОтвета = Неопределено Тогда
Объект.challengeToken = СтруктураОтвета.challengeToken;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция УстановкаJSON(ТекСтруктура, ПараметрЗаписи = "") Экспорт
ЗаписьJSON = Новый ЗаписьJSON;
Если ПараметрЗаписи = "" Тогда
ЗаписьJSON.УстановитьСтроку();
Иначе
ЗаписьJSON.УстановитьСтроку(ПараметрЗаписи);
КонецЕсли;
ЗаписатьJSON(ЗаписьJSON,ТекСтруктура,Новый НастройкиСериализацииJSON,"ПреобразованиеJSON");
Возврат ЗаписьJSON.Закрыть();
КонецФункции
&НаСервере
Функция ПрочитатьОтветВJSON(ТекОтветJSON) Экспорт
Попытка
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекОтветJSON);
Структура = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Возврат Структура;
Исключение
Сообщение = Новый СообщениеПользователю();
Сообщение.Текст = ОписаниеОшибки();
Сообщение.Сообщить();
Возврат Неопределено;
КонецПопытки;
КонецФункции
&НаСервере
Функция ПолучитьДанныеАвторизацииНаПорталеМойНалог(ТолькоСМС) Экспорт
Если ТолькоСМС Тогда
Возврат ЗапрашиваемСМС_challengeToken();
Иначе
Если Не ЗначениеЗаполнено(Объект.refreshToken) Тогда
Возврат Получаем_accessToken();
Иначе
Возврат Обновляем_accessToken_Через_refreshToken();
КонецЕсли;
КонецЕсли;
КонецФункции
&НаСервере
Функция ПодготовитьЗаголовкиДляМойНалог(РасширенныеЗаголовки = Ложь, НужнаАвторизация = Ложь)
Заголовки = Новый Соответствие;
Заголовки.Вставить("Connection", "keep-alive");
Заголовки.Вставить("Accept", "application/json, text/plain, */*");
Заголовки.Вставить("Content-Type", "application/json");
Заголовки.Вставить("Cookie", "_ym_uid=1666736533300201951; _ym_d=1666746533; _ym_isad=2; _ym_visorc=w");
Если РасширенныеЗаголовки Тогда
Заголовки.Вставить("Accept-Language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
Если НужнаАвторизация Тогда
Заголовки.Вставить("Authorization", "Bearer" + " " + Объект.accessToken);
Иначе
Заголовки.Вставить("Authorization", "");
КонецЕсли;
Заголовки.Вставить("Origin", "https://" + Объект.АдресСервисаМойНалог);
Заголовки.Вставить("Referer", "https://" + Объект.АдресСервисаМойНалог + "/auth/login");
Заголовки.Вставить("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
КонецЕсли;
Возврат Заголовки;
КонецФункции
&НаСервере
Функция ЗапрашиваемСМС_challengeToken()
SSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
HTTPСоединение = Новый HTTPСоединение(Объект.АдресСервисаМойНалог, , , , ,Объект.Таймаут,SSL);
// Устанавливаем заголовки
ЗаголовкиДляМойНалог = ПодготовитьЗаголовкиДляМойНалог();
HTTPЗапрос = Новый HTTPЗапрос("/api/v2/auth/challenge/sms/start", ЗаголовкиДляМойНалог);
// Формируем тело запроса в JSON
ТелоСтруктура = Новый Структура;
ТелоСтруктура.Вставить("phone", СокрЛП(Объект.НомерТелефонаМойНалог));
ТелоСтруктура.Вставить("requireTpToBeActive", Истина);
// Сериализация в JSON
ТелоJSON = УстановкаJSON(ТелоСтруктура);
// Устанавливаем тело запроса
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8);
// Отправляем запрос
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтруктураОтвета = Неопределено;
// Проверяем код ответа
Если HTTPОтвет.КодСостояния = 200 Тогда
СтруктураОтвета = ПрочитатьОтветВJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
Возврат СтруктураОтвета; // challengeToken
Иначе
ВызватьИсключение "Ошибка HTTP запроса: " + Формат(HTTPОтвет.КодСостояния);
КонецЕсли;
Возврат СтруктураОтвета;
КонецФункции
&НаСервере
Функция Получаем_accessToken() Экспорт
SSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
HTTPСоединение = Новый HTTPСоединение(Объект.АдресСервисаМойНалог, , , , ,Объект.Таймаут,SSL);
// Устанавливаем заголовки
ЗаголовкиДляМойНалог = ПодготовитьЗаголовкиДляМойНалог(Истина);
HTTPЗапрос = Новый HTTPЗапрос("/api/v1/auth/challenge/sms/verify",ЗаголовкиДляМойНалог);
// Формируем тело запроса в JSON
ТелоСтруктура = Новый Структура;
ТелоСтруктура.Вставить("phone", СокрЛП(Объект.НомерТелефонаМойНалог));
ТелоСтруктура.Вставить("code", СокрЛП(Объект.КодСМСМойНалог));
ТелоСтруктура.Вставить("challengeToken", Объект.challengeToken);
//// Формируем тело deviceInfo
deviceInfoСтруктура = Новый Структура;
deviceInfoСтруктура.Вставить("sourceType", "WEB");
sourceDeviceId = Новый УникальныйИдентификатор;
sourceDeviceIdBase64 = НРег(Лев(Base64Строка(ПолучитьДвоичныеДанныеИзСтроки(СокрЛП(sourceDeviceId))),21));
deviceInfoСтруктура.Вставить("sourceDeviceId", sourceDeviceIdBase64);
deviceInfoСтруктура.Вставить("appVersion", "1.0.0");
metaDetails = Новый Структура;
metaDetails.Вставить("userAgent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
deviceInfoСтруктура.Вставить("metaDetails", metaDetails);
ТелоСтруктура.Вставить("deviceInfo", deviceInfoСтруктура);
// Сериализация в JSON
ТелоJSON = УстановкаJSON(ТелоСтруктура);
// Устанавливаем тело запроса
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8);
// Отправляем запрос
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтруктураОтвета = Неопределено;
// Проверяем код ответа
Если HTTPОтвет.КодСостояния = 200 Тогда
СтруктураОтвета = ПрочитатьОтветВJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
СтруктураОтвета.Вставить("sourceDeviceIdBase64",sourceDeviceIdBase64);
Возврат СтруктураОтвета; //token, refreshToken
Иначе
ТекстОшибки = ПрочитатьОтветВJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
ВызватьИсключение("Ошибка HTTP запроса: " + Формат(HTTPОтвет.КодСостояния) + " Тело: " + ТекстОшибки);
КонецЕсли;
Возврат СтруктураОтвета;
КонецФункции
&НаСервере
Функция Обновляем_accessToken_Через_refreshToken() Экспорт
SSL = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Неопределено);
HTTPСоединение = Новый HTTPСоединение(Объект.АдресСервисаМойНалог, , , , ,Объект.Таймаут,SSL);
// Устанавливаем заголовки
ЗаголовкиДляМойНалог = ПодготовитьЗаголовкиДляМойНалог(Истина);
// обновляем accessToken с помощью refreshToken
HTTPЗапрос = Новый HTTPЗапрос("/api/v1/auth/token", ЗаголовкиДляМойНалог);
// Формируем тело deviceInfo
deviceInfoСтруктура = Новый Структура;
deviceInfoСтруктура.Вставить("sourceType", "WEB");
deviceInfoСтруктура.Вставить("sourceDeviceId", Объект.sourceDeviceIdBase64);
deviceInfoСтруктура.Вставить("appVersion", "1.0.0");
metaDetails = Новый Структура;
metaDetails.Вставить("userAgent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36");
deviceInfoСтруктура.Вставить("metaDetails", metaDetails);
// Формируем тело запроса в JSON
ТелоСтруктура = Новый Структура;
ТелоСтруктура.Вставить("deviceInfo", deviceInfoСтруктура);
ТелоСтруктура.Вставить("refreshToken", Объект.refreshToken);
// Сериализация в JSON
ТелоJSON = УстановкаJSON(ТелоСтруктура);
// Устанавливаем тело запроса
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8);
// Отправляем запрос
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
СтруктураОтвета = Неопределено;
// Проверяем код ответа
Если HTTPОтвет.КодСостояния = 200 Тогда
СтруктураОтвета = ПрочитатьОтветВJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
Возврат СтруктураОтвета; //token, refreshToken
Иначе
ТекстОшибки = ПрочитатьОтветВJSON(HTTPОтвет.ПолучитьТелоКакСтроку());
ВызватьИсключение("Ошибка HTTP запроса: " + Формат(HTTPОтвет.КодСостояния) + " Тело: " + ТекстОшибки);
КонецЕсли;
Возврат СтруктураОтвета;
КонецФункции
&НаКлиенте
Процедура АвторизацияНаМойНалог(Команда)
Сообщение = Новый СообщениеПользователю();
Если Не ЗначениеЗаполнено(Объект.НомерТелефонаМойНалог) ИЛИ Не ЗначениеЗаполнено(Объект.КодСМСМойНалог) или СтрДлина(Объект.НомерТелефонаМойНалог) < 11 или СтрДлина(Объект.КодСМСМойНалог) < 6 Тогда
Сообщение.Текст = "Введите номер телефона и код для доступа к порталу 'Мой налог'";
ИначеЕсли Не ЗначениеЗаполнено(Объект.challengeToken) Тогда
Сообщение.Текст = "Получите заново и введите код для доступа к порталу 'Мой налог'";
Иначе
СтруктураОтвета = Неопределено;
СтруктураОтвета = АвторизацияНаМойНалогНаСервере();
Если Не СтруктураОтвета = Неопределено Тогда
Объект.accessToken = СтруктураОтвета.token;
Объект.refreshToken = СтруктураОтвета.refreshToken;
Если СтруктураОтвета.Свойство("sourceDeviceIdBase64") Тогда
Объект.sourceDeviceIdBase64 = СтруктураОтвета.sourceDeviceIdBase64;
КонецЕсли;
Сообщение.Текст = "Авторизация на портале 'Мой налог' прошла успешно!";
Объект.УспешнаяАвторизацияНаМойНалог = Истина;
Иначе
Сообщение.Текст = "НЕ ПРОЙДЕНА авторизация на портале 'Мой налог'!";
Объект.УспешнаяАвторизацияНаМойНалог = Ложь;
КонецЕсли;
КонецЕсли;
Сообщение.Сообщить();
КонецПроцедуры
&НаСервере
Функция АвторизацияНаМойНалогНаСервере()
Возврат ПолучитьДанныеАвторизацииНаПорталеМойНалог(Ложь);
КонецФункции