Полный рефакторинг api. Вынесено отдельно api passport
This commit is contained in:
111
YandexMusic.API/API/YAuthAPI.cs
Normal file
111
YandexMusic.API/API/YAuthAPI.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using System.Security.Authentication;
|
||||
using YandexMusic.API.Models.Account;
|
||||
using YandexMusic.API.Requests.Account;
|
||||
|
||||
namespace YandexMusic.API;
|
||||
|
||||
/// <summary>API для работы с пользователем и авторизации.</summary>
|
||||
public class YAuthAPI : YCommonAPI
|
||||
{
|
||||
public YAuthAPI(YandexMusicApi api) : base(api) { }
|
||||
|
||||
/// <summary>Авторизация по готовому музыкальному токену (OAuth).</summary>
|
||||
public async Task AuthorizeAsync(string musicToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(musicToken))
|
||||
throw new ArgumentException("Токен не может быть пустым", nameof(musicToken));
|
||||
|
||||
Api.Storage.Token = musicToken;
|
||||
var authInfo = await new YGetAuthInfoBuilder(Api).ExecuteAsync(null!);
|
||||
if (authInfo?.Account?.Uid == null)
|
||||
throw new Exception("Пользователь не авторизован");
|
||||
|
||||
Api.Storage.SetAuthorized(authInfo.Account, musicToken);
|
||||
}
|
||||
|
||||
/// <summary>Авторизация по паспортному токену (полученному, например, после QR-входа).</summary>
|
||||
public async Task AuthorizeByPassportTokenAsync(string passportToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(passportToken))
|
||||
throw new ArgumentException("Паспортный токен не может быть пустым", nameof(passportToken));
|
||||
|
||||
var musicToken = await Api.Passport.GetMusicTokenByPassportTokenAsync(passportToken);
|
||||
if (musicToken?.AccessToken == null)
|
||||
throw new Exception("Не удалось обменять паспортный токен на музыкальный");
|
||||
|
||||
await AuthorizeAsync(musicToken.AccessToken);
|
||||
}
|
||||
|
||||
/// <summary>Получение информации о текущем аккаунте.</summary>
|
||||
public Task<YAccountResult?> GetUserAuthAsync()
|
||||
=> new YGetAuthInfoBuilder(Api).ExecuteAsync(null!);
|
||||
|
||||
/// <summary>Создание сессии авторизации (получение доступных методов входа).</summary>
|
||||
public async Task<YAuthTypes?> CreateAuthSessionAsync(string userName)
|
||||
{
|
||||
if (!await Api.Passport.GetCsrfTokenAsync()) // вместо InitSessionAsync
|
||||
throw new Exception("Не удалось инициализировать сессию");
|
||||
|
||||
var result = await new YGetAuthLoginUserBuilder(Api).ExecuteAsync((Api.Storage.AuthToken.CsfrToken, userName));
|
||||
if (result?.TrackId != null)
|
||||
Api.Storage.AuthToken.TrackId = result.TrackId;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Получение капчи.</summary>
|
||||
public Task<YAuthCaptcha?> GetCaptchaAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
return new YGetAuthCaptchaBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
/// <summary>Авторизация по капче.</summary>
|
||||
public Task<YAuthBase?> AuthorizeByCaptchaAsync(string captchaValue)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
return new YGetAuthLoginCaptchaBuilder(Api).ExecuteAsync(captchaValue);
|
||||
}
|
||||
|
||||
/// <summary>Отправить письмо для авторизации.</summary>
|
||||
public Task<YAuthLetter?> GetAuthLetterAsync()
|
||||
=> new YGetAuthLetterBuilder(Api).ExecuteAsync(null!);
|
||||
|
||||
/// <summary>Подтверждение входа по письму и получение музыкального токена.</summary>
|
||||
public async Task<bool> AuthorizeByLetterAsync()
|
||||
{
|
||||
var status = await new YGetAuthLoginLetterBuilder(Api).ExecuteAsync(null!);
|
||||
if (status?.Status != YAuthStatus.Ok || !status.MagicLinkConfirmed)
|
||||
throw new Exception("Письмо не подтверждено");
|
||||
|
||||
var musicToken = await Api.Passport.GetMusicTokenByCookiesAsync();
|
||||
if (musicToken?.AccessToken == null)
|
||||
throw new Exception("Не удалось получить музыкальный токен после подтверждения письма");
|
||||
|
||||
await AuthorizeAsync(musicToken.AccessToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>Авторизация по паролю приложения Яндекс.</summary>
|
||||
public async Task<YAuthBase?> AuthorizeByAppPasswordAsync(string password)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
|
||||
var result = await new YGetAuthAppPasswordBuilder(Api).ExecuteAsync(password);
|
||||
if (result?.Status != YAuthStatus.Ok)
|
||||
throw new AuthenticationException("Ошибка авторизации по паролю");
|
||||
|
||||
var musicToken = await Api.Passport.GetMusicTokenByCookiesAsync();
|
||||
if (musicToken?.AccessToken == null)
|
||||
throw new Exception("Не удалось получить музыкальный токен после ввода пароля");
|
||||
|
||||
await AuthorizeAsync(musicToken.AccessToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Получение информации о пользователе через логин.</summary>
|
||||
public Task<YLoginInfo?> GetLoginInfoAsync()
|
||||
=> new YGetLoginInfoBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
230
YandexMusic.API/API/YPassportAPI.cs
Normal file
230
YandexMusic.API/API/YPassportAPI.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
using System.Security.Authentication;
|
||||
using System.Text.RegularExpressions;
|
||||
using YandexMusic.API.Models.Account;
|
||||
using YandexMusic.API.Models.Passport;
|
||||
using YandexMusic.API.Requests.Account;
|
||||
using YandexMusic.API.Requests.Passport;
|
||||
|
||||
namespace YandexMusic.API;
|
||||
|
||||
/// <summary>API для работы с яндекс паспортом</summary>
|
||||
public class YPassportAPI : YCommonAPI
|
||||
{
|
||||
public YPassportAPI(YandexMusicApi api) : base(api) { }
|
||||
|
||||
public async Task<YAccessToken?> GetMusicTokenByCookiesAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Api.Storage.AuthToken.TrackId))
|
||||
{
|
||||
if (!await GetCsrfTokenAsync())
|
||||
throw new Exception("Не удалось инициализировать сессию");
|
||||
await CreateTrackAsync(); // ваш приватный метод создания track_id
|
||||
}
|
||||
return await new YGetAuthCookiesBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
public async Task<YAccessToken?> GetMusicTokenByPassportTokenAsync(string passportToken)
|
||||
=> await GetAccessTokenAsync(passportToken);
|
||||
|
||||
public async Task<string?> GetAuthQRLinkAsync()
|
||||
{
|
||||
if (!await GetCsrfTokenAsync())
|
||||
throw new Exception("Не удалось инициализировать сессию");
|
||||
|
||||
await CreateTrackAsync();
|
||||
|
||||
return $"https://passport.yandex.ru/auth/magic/code/?track_id={Api.Storage.AuthToken.TrackId}";
|
||||
}
|
||||
|
||||
public async Task<YAuthQRStatus?> CheckQRStatusAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
|
||||
var status = await new YGetQrStatus(Api).ExecuteAsync(null!);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status?.TrackId))
|
||||
{
|
||||
Api.Storage.AuthToken.SessionTrackId = status.TrackId;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public async Task<YAuthQrSession?> AuthorizeByQRAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Api.Storage.AuthToken.SessionTrackId))
|
||||
throw new Exception("Токен сессии не инициализирован");
|
||||
|
||||
var status = await new YGetAuthLoginQRBuilder(Api).ExecuteAsync(null!);
|
||||
if (status != null && status.DefaultUid != 0 && await LoginByCookiesAsync())
|
||||
return status;
|
||||
throw new AuthenticationException("Ошибка авторизации по QR");
|
||||
}
|
||||
|
||||
/// <summary>Многоступенчатая авторизация: начало (передача логина).</summary>
|
||||
public async Task<YMultistepStart?> MultistepStartAsync(string login)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована. Вызовите GetAuthQRLinkAsync или CreateTrackAsync");
|
||||
return await new YMultistepStartBuilder(Api).ExecuteAsync(login);
|
||||
}
|
||||
|
||||
/// <summary>Многоступенчатая авторизация: ввод пароля.</summary>
|
||||
public async Task<YPassportUser?> MultistepPasswordAsync(string password)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YMultiStepPasswordBuilder(Api).ExecuteAsync(password);
|
||||
}
|
||||
|
||||
/// <summary>Авторизация с помощью RFC OTP.</summary>
|
||||
public async Task<YPassportUser?> RfcOtpPasswordAsync(string rfcOtp)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YRfcOtpBuilder(Api).ExecuteAsync(rfcOtp);
|
||||
}
|
||||
|
||||
/// <summary>Создание сессии пользователя.</summary>
|
||||
public async Task<YPassportSession?> CreateUserSessionAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YGetSessionBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
/// <summary>Проверка состояния сессии.</summary>
|
||||
public async Task<YPassportSessionStatus?> GetSessionStateAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YCheckSessionBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
/// <summary>Проверка номера телефона (валидация).</summary>
|
||||
public async Task<YValidatePhoneNumberResult?> ValidatePhoneNumberAsync(string phone)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YValidatePhoneNumberBuilder(Api).ExecuteAsync(phone);
|
||||
}
|
||||
|
||||
/// <summary>Проверка доступности номера.</summary>
|
||||
public async Task<YCheckAvailabilityResult?> CheckPhoneAvailabilityAsync(string phone)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YCheckPhoneAvailabilityBuilder(Api).ExecuteAsync(phone);
|
||||
}
|
||||
|
||||
/// <summary>Запрос на отправку push-уведомления.</summary>
|
||||
public async Task<YSendPushResult?> SuggestSendPushAsync(string phone)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YSendPushBuilder(Api).ExecuteAsync(phone);
|
||||
}
|
||||
|
||||
/// <summary>Проверка push-кода.</summary>
|
||||
public async Task CheckPushCodeAsync(string code)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
await new YCheckPushCodeBuilder(Api).ExecuteAsync(code);
|
||||
}
|
||||
|
||||
/// <summary>Проверка на "сквоттера" (захват номера).</summary>
|
||||
public async Task<YValidateSquatter?> ValidateSquatterAsync(string phone)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YValidateSquatterBuilder(Api).ExecuteAsync(phone);
|
||||
}
|
||||
|
||||
/// <summary>Получение списка аккаунтов по номеру телефона.</summary>
|
||||
public async Task<YSuggestByPhoneResult?> SuggestByPhoneAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
return await new YSuggestByPhoneBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
/// <summary>Вход по паролю (упрощённый, если не нужна многоступенчатость).</summary>
|
||||
public async Task<YPassportUser?> LoginByPasswordAsync(string password)
|
||||
{
|
||||
// Сначала запускаем мультистеп (если track_id уже есть)
|
||||
if (string.IsNullOrEmpty(Api.Storage.AuthToken.TrackId))
|
||||
throw new Exception("TrackId не найден. Вызовите MultistepStartAsync сначала.");
|
||||
return await MultistepPasswordAsync(password);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private async Task CreateTrackAsync()
|
||||
{
|
||||
if (!await GetCsrfTokenAsync())
|
||||
throw new Exception("Невозможно инициализировать сессию входа.");
|
||||
|
||||
var track = await new YCreateTrackBuilder(Api).ExecuteAsync(null!);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(track?.TrackId) || string.IsNullOrWhiteSpace(track?.CsrfToken))
|
||||
throw new Exception("Не удалось создать трек паспорта.");
|
||||
|
||||
Api.Storage.AuthToken.TrackId = track.TrackId;
|
||||
Api.Storage.AuthToken.CsfrToken = track.CsrfToken;
|
||||
}
|
||||
|
||||
internal async Task<bool> GetCsrfTokenAsync()
|
||||
{
|
||||
using var response = await new YGetAuthMethodsBuilder(Api).ExecuteRawAsync(null!);
|
||||
if (response == null || !response.IsSuccessStatusCode)
|
||||
throw new HttpRequestException("Не удалось получить CSRF-токен");
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
var csrfMatch = Regex.Match(content, @"window\.__CSRF__\s*=\s*""([^""]+)""");
|
||||
var processMatch = Regex.Match(content, @"'process_uuid'\s*:\s*'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})'");
|
||||
|
||||
if (!csrfMatch.Success || !processMatch.Success)
|
||||
return false;
|
||||
|
||||
Api.Storage.HeaderToken = new YAuthToken
|
||||
{
|
||||
CsfrToken = csrfMatch.Groups[1].Value,
|
||||
ProcessUuid = processMatch.Groups[1].Value
|
||||
};
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal async Task<YAccessToken?> GetAccessTokenAsync(string passportToken)
|
||||
{
|
||||
if (string.IsNullOrEmpty(passportToken))
|
||||
throw new Exception("Сессия не инициализована");
|
||||
|
||||
var token = await new YGetMusicTokenBuilder(Api).ExecuteAsync(passportToken);
|
||||
if (token?.AccessToken != null)
|
||||
Api.Storage.Token = token.AccessToken;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
internal async Task<bool> LoginByCookiesAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Сессия входа не инициализирована");
|
||||
|
||||
var accessToken = await new YGetAuthCookiesBuilder(Api).ExecuteAsync(null!);
|
||||
if (accessToken == null || string.IsNullOrEmpty(accessToken.AccessToken))
|
||||
return false;
|
||||
|
||||
await GetAccessTokenAsync(accessToken.AccessToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
using System.Security.Authentication;
|
||||
using System.Text.RegularExpressions;
|
||||
using YandexMusic.API.Models.Account;
|
||||
using YandexMusic.API.Requests.Account;
|
||||
|
||||
namespace YandexMusic.API;
|
||||
|
||||
/// <summary>API для работы с пользователем и авторизации.</summary>
|
||||
public class YUserAPI : YCommonAPI
|
||||
{
|
||||
public YUserAPI(YandexMusicApi api) : base(api) { }
|
||||
|
||||
private async Task<bool> GetCsrfTokenAsync()
|
||||
{
|
||||
using var response = await new YGetAuthMethodsBuilder(Api).ExecuteRawAsync(null!);
|
||||
if (response == null || !response.IsSuccessStatusCode)
|
||||
throw new HttpRequestException("Не удалось получить CSRF-токен");
|
||||
|
||||
var content = await response.Content.ReadAsStringAsync();
|
||||
var csrfMatch = Regex.Match(content, @"window\.__CSRF__\s*=\s*""([^""]+)""");
|
||||
var processMatch = Regex.Match(content, @"'process_uuid'\s*:\s*'([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})'");
|
||||
|
||||
if (!csrfMatch.Success || !processMatch.Success)
|
||||
return false;
|
||||
|
||||
Api.Storage.HeaderToken = new YAuthToken
|
||||
{
|
||||
CsfrToken = csrfMatch.Groups[1].Value,
|
||||
ProcessUuid = processMatch.Groups[1].Value
|
||||
};
|
||||
|
||||
await new YPostAuthStats(Api).ExecuteAsync(null!);
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task<bool> LoginByCookiesAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Сессия входа не инициализирована");
|
||||
|
||||
var accessToken = await new YGetAuthCookiesBuilder(Api).ExecuteAsync(null!);
|
||||
if (accessToken == null || string.IsNullOrEmpty(accessToken.AccessToken))
|
||||
return false;
|
||||
|
||||
Api.Storage.AccessToken = accessToken;
|
||||
Api.Storage.Token = accessToken.AccessToken;
|
||||
|
||||
await AuthorizeByPassportAsync(accessToken.AccessToken);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task AuthorizeAsync(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
throw new Exception("Токен не может быть пустым");
|
||||
|
||||
Api.Storage.Token = token;
|
||||
var authInfo = await new YGetAuthInfoBuilder(Api).ExecuteAsync(null!);
|
||||
if (authInfo?.Account?.Uid == null)
|
||||
throw new Exception("Пользователь не авторизован");
|
||||
|
||||
Api.Storage.SetAuthorized(authInfo.Account, token);
|
||||
}
|
||||
|
||||
public async Task AuthorizeByPassportAsync(string token)
|
||||
{
|
||||
if (string.IsNullOrEmpty(token))
|
||||
throw new Exception("Токен не может быть пустым");
|
||||
|
||||
Api.Storage.Token = token;
|
||||
await GetAccessTokenAsync();
|
||||
await AuthorizeAsync(Api.Storage.Token);
|
||||
}
|
||||
|
||||
public Task<YAccountResult?> GetUserAuthAsync()
|
||||
=> new YGetAuthInfoBuilder(Api).ExecuteAsync(null!);
|
||||
|
||||
public async Task<YAuthTypes?> CreateAuthSessionAsync(string userName)
|
||||
{
|
||||
if (!await GetCsrfTokenAsync())
|
||||
throw new Exception("Не удалось инициализировать сессию");
|
||||
|
||||
var result = await new YGetAuthLoginUserBuilder(Api).ExecuteAsync((Api.Storage.AuthToken.CsfrToken, userName));
|
||||
if (result?.TrackId != null)
|
||||
Api.Storage.AuthToken.TrackId = result.TrackId;
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<string?> GetAuthQRLinkAsync()
|
||||
{
|
||||
if (!await GetCsrfTokenAsync())
|
||||
throw new Exception("Не удалось инициализировать сессию");
|
||||
|
||||
var qr = await new YGetAuthQRBuilder(Api).ExecuteAsync(null!);
|
||||
if (qr?.Status != YAuthStatus.Ok || string.IsNullOrEmpty(qr.TrackId))
|
||||
return null;
|
||||
|
||||
Api.Storage.AuthToken = new YAuthToken
|
||||
{
|
||||
TrackId = qr.TrackId,
|
||||
CsfrToken = qr.CsrfToken
|
||||
};
|
||||
return $"https://passport.yandex.ru/auth/magic/code/?track_id={qr.TrackId}";
|
||||
}
|
||||
|
||||
public async Task<YAuthQRStatus?> CheckQRStatusAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
|
||||
var status = await new YPostQrStatus(Api).ExecuteAsync(null!);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(status?.TrackId))
|
||||
{
|
||||
Api.Storage.AuthToken.SessionTrackId = status.TrackId;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public async Task<YAuthQRSession?> AuthorizeByQRAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализирована");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Api.Storage.AuthToken.SessionTrackId))
|
||||
throw new Exception("Токен сессии не инициализирован");
|
||||
|
||||
var status = await new YGetAuthLoginQRBuilder(Api).ExecuteAsync(null!);
|
||||
if (status != null && status.DefaultUid != 0 && await LoginByCookiesAsync())
|
||||
return status;
|
||||
throw new AuthenticationException("Ошибка авторизации по QR");
|
||||
}
|
||||
|
||||
public Task<YAuthCaptcha?> GetCaptchaAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
return new YGetAuthCaptchaBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
|
||||
public Task<YAuthBase?> AuthorizeByCaptchaAsync(string captchaValue)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
return new YGetAuthLoginCaptchaBuilder(Api).ExecuteAsync(captchaValue);
|
||||
}
|
||||
|
||||
public Task<YAuthLetter?> GetAuthLetterAsync()
|
||||
=> new YGetAuthLetterBuilder(Api).ExecuteAsync(null!);
|
||||
|
||||
public async Task<bool> AuthorizeByLetterAsync()
|
||||
{
|
||||
var status = await new YGetAuthLoginLetterBuilder(Api).ExecuteAsync(null!);
|
||||
if (status?.Status != YAuthStatus.Ok || !status.MagicLinkConfirmed)
|
||||
throw new Exception("Письмо не подтверждено");
|
||||
return await LoginByCookiesAsync();
|
||||
}
|
||||
|
||||
public async Task<YAuthBase?> AuthorizeByAppPasswordAsync(string password)
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием");
|
||||
|
||||
var result = await new YGetAuthAppPasswordBuilder(Api).ExecuteAsync(password);
|
||||
if (result?.Status == YAuthStatus.Ok && await LoginByCookiesAsync())
|
||||
return result;
|
||||
throw new AuthenticationException("Ошибка авторизации по паролю");
|
||||
}
|
||||
|
||||
public async Task<YAccessToken?> GetAccessTokenAsync()
|
||||
{
|
||||
if (Api.Storage.AuthToken == null)
|
||||
throw new Exception("Сессия не инициализована");
|
||||
|
||||
var token = await new YGetMusicTokenBuilder(Api).ExecuteAsync(null!);
|
||||
if (token?.AccessToken != null)
|
||||
Api.Storage.Token = token.AccessToken;
|
||||
return token;
|
||||
}
|
||||
|
||||
public Task<YLoginInfo?> GetLoginInfoAsync()
|
||||
=> new YGetLoginInfoBuilder(Api).ExecuteAsync(null!);
|
||||
}
|
||||
Reference in New Issue
Block a user