using System.Security.Authentication; using YandexMusic.API.Models.Account; using YandexMusic.API.Requests.Account; namespace YandexMusic.API; /// API для работы с пользователем и авторизации. public class YAuthAPI : YCommonAPI { public YAuthAPI(YandexMusicApi api) : base(api) { } /// Авторизация по готовому музыкальному токену (OAuth). 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); } /// Авторизация по паспортному токену (полученному, например, после QR-входа). 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); } /// Получение информации о текущем аккаунте. public Task GetUserAuthAsync() => new YGetAuthInfoBuilder(Api).ExecuteAsync(null!); /// Создание сессии авторизации (получение доступных методов входа). public async Task 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; } /// Получение капчи. public Task GetCaptchaAsync() { if (Api.Storage.AuthToken == null) throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием"); return new YGetAuthCaptchaBuilder(Api).ExecuteAsync(null!); } /// Авторизация по капче. public Task AuthorizeByCaptchaAsync(string captchaValue) { if (Api.Storage.AuthToken == null) throw new AuthenticationException("Выполните CreateAuthSessionAsync перед использованием"); return new YGetAuthLoginCaptchaBuilder(Api).ExecuteAsync(captchaValue); } /// Отправить письмо для авторизации. public Task GetAuthLetterAsync() => new YGetAuthLetterBuilder(Api).ExecuteAsync(null!); /// Подтверждение входа по письму и получение музыкального токена. public async Task 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; } /// Авторизация по паролю приложения Яндекс. public async Task 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; } /// Получение информации о пользователе через логин. public Task GetLoginInfoAsync() => new YGetLoginInfoBuilder(Api).ExecuteAsync(null!); }