From 06748d6f834aabd0d24d4e1fd3dfdfb5cf3bc3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=B2=D0=B8=D0=B4=20=D0=A7=D0=B5=D1=80=D0=BD?= =?UTF-8?q?=D0=BE=D0=BF=D1=8F=D1=82=D0=BE=D0=B2?= Date: Tue, 22 Oct 2024 19:25:27 +0300 Subject: [PATCH] 1.5.3 progress - SessionHandler refactored. Now it used as global authorization API - Added semaphore to SessionHandler - WaitLogin dialog flow moved to SessionHandler - MaClient and PortableMaClient authorization logic now separeted and works correctly - Fixed App startup error was not localized and closed immediatly - Fixed code progress bar was freezing due to low Dispatcher priority - Fixed legacy serializer typo error in AccessToken field on write operation --- NebulaAuth/App.xaml.cs | 5 +- NebulaAuth/Model/MAAC/PortableMaClient.cs | 14 +- NebulaAuth/Model/MaClient.cs | 51 +--- NebulaAuth/Model/SessionHandler.cs | 226 +++++++++++++----- NebulaAuth/Model/SessionHandler_API.cs | 49 ++++ NebulaAuth/ViewModel/MainVM.cs | 14 +- NebulaAuth/ViewModel/MainVM_Code.cs | 6 +- NebulaAuth/ViewModel/MainVM_Other.cs | 47 ---- SteamLibForked/Api/Mobile/SteamMobileApi.cs | 5 +- .../Api/Mobile/SteamMobileConfirmationsApi.cs | 8 +- .../Authentication/AdmissionHelper.cs | 2 +- .../SteamAuthenticatorLinker.cs | 2 +- .../Utility/MaFiles/MafileSerializer_Write.cs | 2 +- .../JSON/MobileConfirmationScrapper.cs | 10 +- changelog/1.5.3.html | 3 + 15 files changed, 268 insertions(+), 176 deletions(-) create mode 100644 NebulaAuth/Model/SessionHandler_API.cs delete mode 100644 NebulaAuth/ViewModel/MainVM_Other.cs diff --git a/NebulaAuth/App.xaml.cs b/NebulaAuth/App.xaml.cs index b99aa64..7ea6aea 100644 --- a/NebulaAuth/App.xaml.cs +++ b/NebulaAuth/App.xaml.cs @@ -25,11 +25,12 @@ public partial class App var msg = ex.ToString(); if (ex is CantAlignTimeException) { - msg = Loc.Tr(LocManager.GetCodeBehind("CantAlignTimeError")); + msg = LocManager.Get("CantAlignTimeError"); } - MessageBox.Show(msg); + MessageBox.Show(msg, "Error", MessageBoxButton.OK, MessageBoxImage.Stop, MessageBoxResult.OK, MessageBoxOptions.DefaultDesktopOnly); throw; + } } } diff --git a/NebulaAuth/Model/MAAC/PortableMaClient.cs b/NebulaAuth/Model/MAAC/PortableMaClient.cs index 9a462dd..4c6c087 100644 --- a/NebulaAuth/Model/MAAC/PortableMaClient.cs +++ b/NebulaAuth/Model/MAAC/PortableMaClient.cs @@ -16,6 +16,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.Windows; +using AchiesUtilities.Web.Models; namespace NebulaAuth.Model.MAAC; @@ -80,7 +81,7 @@ public partial class PortableMaClient : ObservableObject, IDisposable } catch (ApplicationException ex) { - Shell.Logger.Warn(ex, "Error GetConf in timer."); + Shell.Logger.Warn(ex, "Timer {accountName}: Error GetConf in timer.", Mafile.AccountName); return 0; } var toConfirm = new List(); @@ -98,13 +99,14 @@ public partial class PortableMaClient : ObservableObject, IDisposable if (toConfirm.Count == 0) return 0; try { - Shell.Logger.Debug("Sending confirmations. Count: {count}", toConfirm.Count); - await HandleTimerRequest(() => SendConfirmations(toConfirm)); + Shell.Logger.Debug("Timer {accountName}: Sending confirmations. Count: {count}", Mafile.AccountName, toConfirm.Count); + var success = await HandleTimerRequest(() => SendConfirmations(toConfirm)); + Shell.Logger.Debug("Timer {accountName}: Confirmation sent: {confirmResult}", Mafile.AccountName, success); return toConfirm.Count; } catch (ApplicationException ex) { - Shell.Logger.Warn(ex, "MultiConf error in Timer."); + Shell.Logger.Warn(ex, "Timer {accountName}: MultiConf error in Timer.", Mafile.AccountName); return 0; } } @@ -125,7 +127,7 @@ public partial class PortableMaClient : ObservableObject, IDisposable Exception innerException; try { - return await SessionHandler.Handle(func, Mafile, GetTimerPrefix()); + return await SessionHandler.Handle(func, Mafile, Chp(), GetTimerPrefix()); } catch (OperationCanceledException ex) { @@ -144,6 +146,8 @@ public partial class PortableMaClient : ObservableObject, IDisposable throw new ApplicationException("Swallowed", innerException); } + private HttpClientHandlerPair Chp() => new(Client, ClientHandler); + private static string GetLocalization(string key) { return LocManager.GetCodeBehindOrDefault(key, LOC_PATH, key); diff --git a/NebulaAuth/Model/MaClient.cs b/NebulaAuth/Model/MaClient.cs index a932073..344eb43 100644 --- a/NebulaAuth/Model/MaClient.cs +++ b/NebulaAuth/Model/MaClient.cs @@ -1,15 +1,11 @@ -using AchiesUtilities.Web.Proxy; +using AchiesUtilities.Web.Models; +using AchiesUtilities.Web.Proxy; using NebulaAuth.Model.Entities; -using SteamLib.Account; -using SteamLib.Api; using SteamLib.Api.Mobile; using SteamLib.Authentication; -using SteamLib.Authentication.LoginV2; -using SteamLib.Core.Enums; using SteamLib.Core.Interfaces; using SteamLib.Exceptions; using SteamLib.ProtoCore.Services; -using SteamLib.SteamMobile; using SteamLib.SteamMobile.Confirmations; using SteamLib.Web; using System; @@ -30,6 +26,7 @@ public static class MaClient private static DynamicProxy Proxy { get; } public static ProxyData? DefaultProxy { get; set; } + public static HttpClientHandlerPair Chp => new(Client, ClientHandler); static MaClient() { @@ -66,50 +63,18 @@ public static class MaClient return SteamMobileConfirmationsApi.GetConfirmations(Client, mafile, mafile.SessionData!.SteamId); } - public static async Task LoginAgain(Mafile mafile, string password, bool savePassword, ICaptchaResolver? resolver) + public static Task LoginAgain(Mafile mafile, string password, bool savePassword, ICaptchaResolver? resolver) { SetProxy(mafile); - var sgGenerator = new SteamGuardCodeGenerator(mafile.SharedSecret); - var options = new LoginV2ExecutorOptions(LoginV2Executor.NullConsumer, Client) - { - Logger = Shell.ExtensionsLogger, - SteamGuardProvider = sgGenerator, - DeviceDetails = LoginV2ExecutorOptions.GetMobileDefaultDevice(), - WebsiteId = "Mobile" - }; - ClientHandler.CookieContainer.ClearMobileSessionCookies(); - var result = await LoginV2Executor.DoLogin(options, mafile.AccountName, password); - AdmissionHelper.TransferCommunityCookies(ClientHandler.CookieContainer); - mafile.SetSessionData((MobileSessionData)result); - if (PHandler.IsPasswordSet) - mafile.Password = (savePassword ? PHandler.Encrypt(password) : null); - Storage.UpdateMafile(mafile); + return SessionHandler.LoginAgain(Chp, mafile, password, savePassword); } - public static async Task RefreshSession(Mafile mafile) + public static Task RefreshSession(Mafile mafile) { ValidateMafile(mafile, true); SetProxy(mafile); - var token = mafile.SessionData!.GetMobileToken(); - if (token == null || token.Value.IsExpired) - { - var sessionToken = await SteamMobileApi.RefreshJwt(Client, mafile.SessionData!.RefreshToken.Token, mafile.SessionData.SteamId.Steam64); - var newToken = SteamTokenHelper.Parse(sessionToken); - mafile.SessionData.SetMobileToken(newToken); - } - - //RETHINK: Do we need this? Mobile token is enough - var communityToken = mafile.SessionData!.GetToken(SteamDomain.Community); - if (communityToken == null || communityToken.Value.IsExpired) - { - var communityTokenString = await SteamGlobalApi.RefreshJwt(Client, SteamDomain.Community); - var newToken = SteamTokenHelper.Parse(communityTokenString); - mafile.SessionData.SetToken(SteamDomain.Community, newToken); - } - - Storage.UpdateMafile(mafile); - ClientHandler.CookieContainer.SetSteamMobileCookiesWithMobileToken(mafile.SessionData); + return SessionHandler.RefreshMobileToken(Chp, mafile); } public static Task SendConfirmation(Mafile mafile, Confirmation confirmation, bool confirm) @@ -122,7 +87,7 @@ public static class MaClient public static Task SendMultipleConfirmation(Mafile mafile, IEnumerable confirmations, bool confirm) { var enumerable = confirmations.ToList(); - if (!enumerable.Any()) + if (enumerable.Count == 0) { return Task.FromResult(result: false); } diff --git a/NebulaAuth/Model/SessionHandler.cs b/NebulaAuth/Model/SessionHandler.cs index 4d4b0fb..1d6dae8 100644 --- a/NebulaAuth/Model/SessionHandler.cs +++ b/NebulaAuth/Model/SessionHandler.cs @@ -1,24 +1,122 @@ -using NebulaAuth.Core; +using AchiesUtilities.Web.Models; +using MaterialDesignThemes.Wpf; +using NebulaAuth.Core; using NebulaAuth.Model.Entities; using SteamLib.Exceptions; using System; +using System.Threading; using System.Threading.Tasks; +using System.Windows; +using NebulaAuth.View.Dialogs; namespace NebulaAuth.Model; -public static class SessionHandler +public static partial class SessionHandler { - public static event EventHandler? LoginStarted; - public static event EventHandler? LoginCompleted; - public static async Task Handle(Func> func, Mafile mafile, string? snackbarPrefix = null) + private static readonly SemaphoreSlim Semaphore = new(1, 1); + + public static async Task Handle(Func> func, Mafile mafile, + HttpClientHandlerPair? chp = null, string? snackbarPrefix = null) + { + chp ??= MaClient.Chp; + await Semaphore.WaitAsync(); + try + { + return await HandleInternal(func, chp.Value, mafile, snackbarPrefix); + } + finally + { + Semaphore.Release(); + } + } + + private static async Task HandleInternal(Func> func, HttpClientHandlerPair chp, Mafile mafile, + string? snackbarPrefix = null) + { + using var scope = Shell.Logger.PushScopeProperty("Scope", "SessionHandler"); + var mobileTokenExpired = MobileTokenExpired(mafile); + var refreshTokenExpired = RefreshTokenExpired(mafile); + var password = GetPassword(mafile); + + if (!mobileTokenExpired) + { + try + { + return await func(); + } + catch (SessionInvalidException ex) + when (refreshTokenExpired == false || password != null) + { + if (ex is SessionPermanentlyExpiredException) + { + Shell.Logger.Debug(ex, "RefreshToken on mafile {name} {steamid} is expired", mafile.AccountName, mafile.SessionData?.SteamId); + refreshTokenExpired = true; + } + else + { + Shell.Logger.Debug(ex, "MobileToken on mafile {name} {steamid} is expired", mafile.AccountName, mafile.SessionData?.SteamId); + } + } + } + + + //State: mobileToken invalid/expired, refreshToken maybe not expired + if (!refreshTokenExpired) + { + var refreshed = await RefreshInternal(chp, mafile); + if (refreshed) + { + SnackbarController.SendSnackbar(snackbarPrefix + LocManager.GetCodeBehindOrDefault("SessionWasRefreshedAutomatically", "SessionHandler", "SessionWasRefreshedAutomatically")); + try + { + return await func(); + } + catch (SessionInvalidException) + when (password != null) + { + + } + } + } + + Shell.Logger.Debug("Session on mafile {name} {steamid} is invalid/expired", mafile.AccountName, mafile.SessionData?.SteamId); + + //State: mobileToken invalid/expired, refreshToken invalid/expired + if (password != null) + { + var logged = await LoginAgainInternal(chp, mafile, password, true); + if (logged) + { + Shell.Logger.Debug("Mafile {name} {steamid} was succesfully auto-relogined", mafile.AccountName, mafile.SessionData?.SteamId); + return await func(); + } + } + + //Nothing to do more, everything is expired + throw new SessionPermanentlyExpiredException(SessionPermanentlyExpiredException.SESSION_EXPIRED_MSG); + } + + + + private static bool MobileTokenExpired(Mafile mafile) + { + var mobileToken = mafile.SessionData?.GetMobileToken(); + return mobileToken == null || mobileToken.Value.IsExpired; + } + + private static bool RefreshTokenExpired(Mafile mafile) + { + return mafile.SessionData?.RefreshToken.IsExpired != false; + } + + private static string? GetPassword(Mafile mafile) { - string? password = null; try { if (PHandler.IsPasswordSet && !string.IsNullOrWhiteSpace(mafile.Password)) { - password = PHandler.Decrypt(mafile.Password); + return PHandler.Decrypt(mafile.Password); } } catch @@ -26,70 +124,74 @@ public static class SessionHandler // ignored } - var refreshed = false; - try - { - return await func(); - } - catch (SessionInvalidException) when (mafile.SessionData is { RefreshToken.IsExpired: false}) - { - Shell.Logger.Debug("Token on mafile {name} {steamid} expired. Trying to refresh", mafile.AccountName, mafile.SessionData?.SteamId); - refreshed = await TryRefresh(mafile); - } - catch (SessionInvalidException) - when (password != null) - { - } - - - if (refreshed) - { - Shell.Logger.Debug("Token on mafile {name} {steamid} refreshed", mafile.AccountName, - mafile.SessionData?.SteamId); - try - { - return await func(); - } - catch (Exception ex3) - when (password != null && ex3 is SessionPermanentlyExpiredException or SessionInvalidException) - { - - } - } - - - if (password == null) - { - throw new SessionInvalidException(); - } - - try - { - LoginStarted?.Invoke(null, EventArgs.Empty); - await MaClient.LoginAgain(mafile, password, savePassword: true, null); - Shell.Logger.Debug("Mafile {name} {steamid} succesfully auto-relogined", mafile.AccountName, - mafile.SessionData?.SteamId); - } - finally - { - LoginCompleted?.Invoke(null, EventArgs.Empty); - } - - return await func(); + return null; } - private static async Task TryRefresh(Mafile mafile, string? snackbarPrefix = null) + + private static async Task RefreshInternal(HttpClientHandlerPair chp, Mafile mafile) { try { - await MaClient.RefreshSession(mafile); - SnackbarController.SendSnackbar(snackbarPrefix + LocManager.GetCodeBehindOrDefault("SessionWasRefreshedAutomatically", "SessionHandler", "SessionWasRefreshedAutomatically")); + await RefreshMobileToken(chp, mafile); return true; } - catch (SessionInvalidException) + catch(Exception ex) { - Shell.Logger.Debug("Token on mafile {name} {steamid} not refreshed", mafile.AccountName, mafile.SessionData?.SteamId); + Shell.Logger.Debug(ex, "Failed to refresh session on mafile {name} {steamid}", mafile.AccountName, mafile.SessionData?.SteamId); return false; } } + + private static async Task LoginAgainInternal(HttpClientHandlerPair chp, Mafile mafile, string password, + bool savePassword) + { + var t = Task.Run(OnLoginStarted); + try + { + + await LoginAgain(chp, mafile, password, savePassword); + return true; + } + catch (Exception ex) + { + Shell.Logger.Debug(ex, "Failed to relogin mafile {name} {steamid}", mafile.AccountName, + mafile.SessionData?.SteamId); + return false; + } + finally + { + OnLoginCompleted(); + await t; + } + } + + private static async Task OnLoginStarted() + { + if (DialogHost.IsDialogOpen(null)) return; + await Application.Current.Dispatcher.BeginInvoke(async () => + { + await DialogHost.Show(new WaitLoginDialog()); + }); + } + + private static void OnLoginCompleted() + { + var currentSession = DialogHost.GetDialogSession(null); + Application.Current.Dispatcher.BeginInvoke(() => + { + if (currentSession is { Content: WaitLoginDialog, IsEnded: false }) + { + try + { + currentSession.Close(); + } + catch + { + //Ignored + } + } + }); + } + + } \ No newline at end of file diff --git a/NebulaAuth/Model/SessionHandler_API.cs b/NebulaAuth/Model/SessionHandler_API.cs new file mode 100644 index 0000000..bfa1574 --- /dev/null +++ b/NebulaAuth/Model/SessionHandler_API.cs @@ -0,0 +1,49 @@ +using AchiesUtilities.Web.Models; +using NebulaAuth.Model.Entities; +using SteamLib.Account; +using SteamLib.Api.Mobile; +using SteamLib.Authentication; +using SteamLib.Authentication.LoginV2; +using SteamLib.Exceptions; +using SteamLib.SteamMobile; +using System.Threading.Tasks; + +namespace NebulaAuth.Model; + +public partial class SessionHandler //API +{ + public static async Task RefreshMobileToken(HttpClientHandlerPair chp, Mafile mafile) + { + if (mafile.SessionData is not { RefreshToken.IsExpired: false }) + throw new SessionPermanentlyExpiredException(SessionInvalidException.SESSION_NULL_MSG); + + var mobileToken = await SteamMobileApi.RefreshJwt(chp.Client, mafile.SessionData.RefreshToken.Token, mafile.SessionData.SteamId); + Shell.Logger.Info("MobileToken on {name} {steamid} successfully refreshed", mafile.AccountName, mafile.SessionData.SteamId); + + var newToken = SteamTokenHelper.Parse(mobileToken); + mafile.SessionData.SetMobileToken(newToken); + mafile.SetSessionData(mafile.SessionData); //Trigger event + Storage.UpdateMafile(mafile); + chp.Handler.CookieContainer.SetSteamMobileCookiesWithMobileToken(mafile.SessionData); + } + + public static async Task LoginAgain(HttpClientHandlerPair chp, Mafile mafile, string password, bool savePassword) + { + var sgGenerator = new SteamGuardCodeGenerator(mafile.SharedSecret); + var options = new LoginV2ExecutorOptions(LoginV2Executor.NullConsumer, chp.Client) + { + Logger = Shell.ExtensionsLogger, + SteamGuardProvider = sgGenerator, + DeviceDetails = LoginV2ExecutorOptions.GetMobileDefaultDevice(), + WebsiteId = "Mobile", + }; + chp.Handler.CookieContainer.ClearMobileSessionCookies(); + var result = await LoginV2Executor.DoLogin(options, mafile.AccountName, password); + Shell.Logger.Info("Logged in again on {name} {steamid}", mafile.AccountName, result.SteamId); + AdmissionHelper.TransferCommunityCookies(chp.Handler.CookieContainer); + mafile.SetSessionData((MobileSessionData)result); + if (PHandler.IsPasswordSet) + mafile.Password = (savePassword ? PHandler.Encrypt(password) : null); + Storage.UpdateMafile(mafile); + } +} \ No newline at end of file diff --git a/NebulaAuth/ViewModel/MainVM.cs b/NebulaAuth/ViewModel/MainVM.cs index abe3917..02ed04d 100644 --- a/NebulaAuth/ViewModel/MainVM.cs +++ b/NebulaAuth/ViewModel/MainVM.cs @@ -1,5 +1,6 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using JetBrains.Annotations; using MaterialDesignThemes.Wpf; using NebulaAuth.Core; using NebulaAuth.Model; @@ -12,7 +13,6 @@ using System; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Linq; -using System.Threading; using System.Threading.Tasks; namespace NebulaAuth.ViewModel; @@ -21,8 +21,9 @@ public partial class MainVM : ObservableObject { [ObservableProperty] private ObservableCollection _maFiles = Storage.MaFiles; - public SnackbarMessageQueue MessageQueue => SnackbarController.MessageQueue; + [UsedImplicitly] + public SnackbarMessageQueue MessageQueue => SnackbarController.MessageQueue; public Mafile? SelectedMafile @@ -42,8 +43,6 @@ public partial class MainVM : ObservableObject new MaProxy(kvp.Key, kvp.Value))); Storage.MaFiles.CollectionChanged += MaFilesOnCollectionChanged; QueryGroups(); - SessionHandler.LoginStarted += SessionHandlerOnLoginStarted; - SessionHandler.LoginCompleted += SessionHandlerOnLoginCompleted; UpdateManager.CheckForUpdates(); if (Storage.DuplicateFound > 0) { @@ -200,4 +199,11 @@ public partial class MainVM : ObservableObject Shell.Logger.Error(ex); } } + + + private static string GetLocalization(string key) + { + const string LOC_PATH = "MainVM"; + return LocManager.GetCodeBehindOrDefault(key, LOC_PATH, key); + } } \ No newline at end of file diff --git a/NebulaAuth/ViewModel/MainVM_Code.cs b/NebulaAuth/ViewModel/MainVM_Code.cs index 2fe953d..17b964b 100644 --- a/NebulaAuth/ViewModel/MainVM_Code.cs +++ b/NebulaAuth/ViewModel/MainVM_Code.cs @@ -30,7 +30,7 @@ public partial class MainVM private void UpdateCode(object? state = null) { var currentTime = TimeAligner.GetSteamTime(); - var untilChange = currentTime - currentTime / 30L * 30L; + var untilChange = currentTime % 30; var codeProgress = untilChange / 30D * 100; string? code = null; @@ -41,12 +41,12 @@ public partial class MainVM if (Application.Current == null) return; - Application.Current.Dispatcher.Invoke((string? c) => + Application.Current.Dispatcher.BeginInvoke((string? c) => { if (Application.Current.MainWindow?.WindowState == WindowState.Minimized) return; CodeProgress = codeProgress; if (c != null) Code = c; - }, DispatcherPriority.Background, code); + }, DispatcherPriority.DataBind, code); } [RelayCommand(AllowConcurrentExecutions = false)] diff --git a/NebulaAuth/ViewModel/MainVM_Other.cs b/NebulaAuth/ViewModel/MainVM_Other.cs deleted file mode 100644 index 8f3d860..0000000 --- a/NebulaAuth/ViewModel/MainVM_Other.cs +++ /dev/null @@ -1,47 +0,0 @@ -using MaterialDesignThemes.Wpf; -using System; -using System.Windows; -using NebulaAuth.View.Dialogs; -using NebulaAuth.Core; - -namespace NebulaAuth.ViewModel; - -public partial class MainVM //Other -{ - - private const string LOC_PATH = "MainVM"; - - private static string GetLocalization(string key) - { - return LocManager.GetCodeBehindOrDefault(key, LOC_PATH, key); - } - - - private void SessionHandlerOnLoginCompleted(object? sender, EventArgs e) - { - var currentSession = DialogHost.GetDialogSession(null); - Application.Current.Dispatcher.BeginInvoke(() => - { - if (currentSession is { Content: WaitLoginDialog, IsEnded: false }) - { - try - { - currentSession.Close(); - } - catch - { - //Ignored - } - } - }); - } - - private async void SessionHandlerOnLoginStarted(object? sender, EventArgs e) - { - if (DialogHost.IsDialogOpen(null)) return; - await Application.Current.Dispatcher.BeginInvoke(async () => - { - await DialogHost.Show(new WaitLoginDialog()); - }); - } -} \ No newline at end of file diff --git a/SteamLibForked/Api/Mobile/SteamMobileApi.cs b/SteamLibForked/Api/Mobile/SteamMobileApi.cs index 0a143fb..16e8076 100644 --- a/SteamLibForked/Api/Mobile/SteamMobileApi.cs +++ b/SteamLibForked/Api/Mobile/SteamMobileApi.cs @@ -7,6 +7,7 @@ using SteamLib.ProtoCore.Enums; using SteamLib.ProtoCore.Exceptions; using SteamLib.ProtoCore.Services; using System.Net; +using SteamLib.Account; namespace SteamLib.Api.Mobile; @@ -28,12 +29,12 @@ public static class SteamMobileApi /// /// Refreshed AccessToken /// - public static async Task RefreshJwt(HttpClient client, string refreshToken, long steamId, CancellationToken cancellationToken = default) + public static async Task RefreshJwt(HttpClient client, string refreshToken, SteamId steamId, CancellationToken cancellationToken = default) { var req = new GenerateAccessTokenForApp_Request { RefreshToken = refreshToken, - SteamId = steamId, + SteamId = steamId.Steam64, TokenRenewalType = true }; diff --git a/SteamLibForked/Api/Mobile/SteamMobileConfirmationsApi.cs b/SteamLibForked/Api/Mobile/SteamMobileConfirmationsApi.cs index 7d1d8fe..e4f8243 100644 --- a/SteamLibForked/Api/Mobile/SteamMobileConfirmationsApi.cs +++ b/SteamLibForked/Api/Mobile/SteamMobileConfirmationsApi.cs @@ -28,12 +28,12 @@ public static class SteamMobileConfirmationsApi var reqMsg = new HttpRequestMessage(HttpMethod.Get, req); var resp = await client.SendAsync(reqMsg, cancellationToken); - var respStr = await resp.Content.ReadAsStringAsync(cancellationToken); + if (resp.StatusCode == HttpStatusCode.Redirect) { - throw new SessionPermanentlyExpiredException("Mobile session expired"); + throw new SessionInvalidException("Mobile session expired"); } - + var respStr = await resp.Content.ReadAsStringAsync(cancellationToken); resp.EnsureSuccessStatusCode(); try @@ -41,7 +41,7 @@ public static class SteamMobileConfirmationsApi return MobileConfirmationScrapper.Scrap(respStr); } catch (Exception ex) - when (ex is not (SessionPermanentlyExpiredException or CantLoadConfirmationsException)) + when (ex is not (SessionInvalidException or CantLoadConfirmationsException)) { SteamLibErrorMonitor.LogErrorResponse(respStr, ex); throw; diff --git a/SteamLibForked/Authentication/AdmissionHelper.cs b/SteamLibForked/Authentication/AdmissionHelper.cs index 36bde8e..fae2743 100644 --- a/SteamLibForked/Authentication/AdmissionHelper.cs +++ b/SteamLibForked/Authentication/AdmissionHelper.cs @@ -79,7 +79,7 @@ public static class AdmissionHelper } /// - /// Clear and set new session. Not recommended. Uses for domain instead of its own cookie. It's okay to use it only for confirmations. But Market, Trading and other pages won't be authenticated + /// Clear and set new session. Not recommended. Uses for domain instead of its own cookie. It's okay to use it only for confirmations. But Market, Trading and other pages won't be authorized /// public static void SetSteamMobileCookiesWithMobileToken(this CookieContainer container, IMobileSessionData mobileSession, string setLanguage = "english") diff --git a/SteamLibForked/SteamMobile/AuthenticatorLinker/SteamAuthenticatorLinker.cs b/SteamLibForked/SteamMobile/AuthenticatorLinker/SteamAuthenticatorLinker.cs index e48bb71..540ee7e 100644 --- a/SteamLibForked/SteamMobile/AuthenticatorLinker/SteamAuthenticatorLinker.cs +++ b/SteamLibForked/SteamMobile/AuthenticatorLinker/SteamAuthenticatorLinker.cs @@ -52,7 +52,7 @@ public class SteamAuthenticatorLinker if (accessToken.Value.Type != SteamAccessTokenType.Mobile) Logger?.LogWarning("Provided access token is not of type Mobile. Actual type: {actualType}", accessToken.Value.Type); - var refreshed = await SteamMobileApi.RefreshJwt(Options.HttpClient, data.RefreshToken.Token, data.RefreshToken.SteamId.Steam64); + var refreshed = await SteamMobileApi.RefreshJwt(Options.HttpClient, data.RefreshToken.Token, data.RefreshToken.SteamId); accessToken = SteamTokenHelper.Parse(refreshed); data.SetMobileToken(accessToken.Value); } diff --git a/SteamLibForked/Utility/MaFiles/MafileSerializer_Write.cs b/SteamLibForked/Utility/MaFiles/MafileSerializer_Write.cs index 29c65ad..dace869 100644 --- a/SteamLibForked/Utility/MaFiles/MafileSerializer_Write.cs +++ b/SteamLibForked/Utility/MaFiles/MafileSerializer_Write.cs @@ -63,7 +63,7 @@ public static partial class MafileSerializer //Write ? null : new { - AccesToken = ext.SessionData?.MobileToken?.Token, + AccessToken = ext.SessionData?.MobileToken?.Token, steamLoginSecure = ext.SessionData?.MobileToken?.SignedToken, RefreshToken = ext.SessionData?.RefreshToken.Token, SteamID = ext.SessionData?.SteamId.Steam64.Id, diff --git a/SteamLibForked/Web/Scrappers/JSON/MobileConfirmationScrapper.cs b/SteamLibForked/Web/Scrappers/JSON/MobileConfirmationScrapper.cs index 2389447..630dca8 100644 --- a/SteamLibForked/Web/Scrappers/JSON/MobileConfirmationScrapper.cs +++ b/SteamLibForked/Web/Scrappers/JSON/MobileConfirmationScrapper.cs @@ -14,6 +14,14 @@ public static class MobileConfirmationScrapper {"You are not set up to receive mobile confirmations", LoadConfirmationsError.NotSetupToReceiveConfirmations} }; + /// + /// + /// + /// + /// + /// + /// + /// public static List Scrap(string response) { ConfirmationsJson conf; @@ -28,7 +36,7 @@ public static class MobileConfirmationScrapper if (conf.NeedAuth) { - throw new SessionPermanentlyExpiredException(); + throw new SessionInvalidException(); } if (conf.Success == false) diff --git a/changelog/1.5.3.html b/changelog/1.5.3.html index 49e8e71..8c2c3a6 100644 --- a/changelog/1.5.3.html +++ b/changelog/1.5.3.html @@ -74,10 +74,13 @@ - UPDATE: Added hyperlink to troubleshooting guide in "Linking" window
- UPDATE: Added socks4, socks5 proxy support (not tested)
- FIX: Now errors in receiving confirmations are localized and displayed correctly.
+ - FIX: Fixed typo in "AccesToken" when serializing in legacy mode
+ - FIX: Fixed application startup error was not shown correctly and had empty message when app wasn't able to align time
- UI: Added "Copy RCode" button after linking account
- UI: Auto-confirm timers now use icons instead of text-chips
- UI: Minor design and localization improvements
- UI: Hyperlink "by achies" now leads to repository instead of "achiez/" user page
+ - UI: Fixed code progress bar was "lagging"
- DEV: Big code clean-ups and refactoring
- DEV: Updated dependency and SteamLib libraries