diff --git a/src/NebulaAuth/Components/HintBox.xaml.cs b/src/NebulaAuth/Components/HintBox.xaml.cs index 38d84d1..8943147 100644 --- a/src/NebulaAuth/Components/HintBox.xaml.cs +++ b/src/NebulaAuth/Components/HintBox.xaml.cs @@ -77,6 +77,10 @@ public partial class HintBox : UserControl IconKind = PackIconKind.ErrorOutline; IconBrush = (Brush) Application.Current.FindResource("ErrorBrush")!; break; + case HintBoxSeverity.Warning: + IconKind = PackIconKind.WarningOutline; + IconBrush = (Brush) Application.Current.FindResource("WarningBrush")!; + break; default: IconKind = PackIconKind.InfoCircleOutline; IconBrush = (Brush) Application.Current.FindResource("InfoBrush")!; @@ -94,5 +98,6 @@ public partial class HintBox : UserControl public enum HintBoxSeverity { Info, + Warning, Error } \ No newline at end of file diff --git a/src/NebulaAuth/Core/DialogsController.cs b/src/NebulaAuth/Core/DialogsController.cs index 2e25ba8..2fe5ae8 100644 --- a/src/NebulaAuth/Core/DialogsController.cs +++ b/src/NebulaAuth/Core/DialogsController.cs @@ -15,13 +15,15 @@ namespace NebulaAuth.Core; public static class DialogsController { - public static async Task ShowLoginAgainDialog(string username, string? currentPassword = null) + public static async Task ShowLoginAgainDialog(string username, string? currentPassword = null, + bool showNoProxyWarning = false) { var vm = new LoginAgainVM { UserName = username, Password = currentPassword ?? string.Empty, - SavePassword = PHandler.IsPasswordSet + SavePassword = PHandler.IsPasswordSet, + ShowNoProxyWarning = showNoProxyWarning }; var content = new LoginAgainDialog { diff --git a/src/NebulaAuth/Localization/dialogs.loginagain.loc.json b/src/NebulaAuth/Localization/dialogs.loginagain.loc.json index c8cade7..20ace34 100644 --- a/src/NebulaAuth/Localization/dialogs.loginagain.loc.json +++ b/src/NebulaAuth/Localization/dialogs.loginagain.loc.json @@ -79,6 +79,16 @@ "es": "Pulsa 'DEL' para eliminar", "tr": "Silmek için 'DEL' tuşuna bas", "kk": "Жою үшін 'DEL' пернесін басыңыз" + }, + "NoProxyWarning": { + "en": "No proxy is assigned", + "ru": "Прокси не установлен", + "zh": "未分配代理", + "uk": "Проксі не призначено", + "fr": "Aucun proxy assigné", + "es": "No hay ningún proxy asignado", + "tr": "Proxy atanmamış", + "kk": "Прокси тағайындалмаған" } } } \ No newline at end of file diff --git a/src/NebulaAuth/Model/MAAC/MAACRequestHandler.cs b/src/NebulaAuth/Model/MAAC/MAACRequestHandler.cs index bf3f5e6..68e71a3 100644 --- a/src/NebulaAuth/Model/MAAC/MAACRequestHandler.cs +++ b/src/NebulaAuth/Model/MAAC/MAACRequestHandler.cs @@ -82,7 +82,7 @@ public static class MAACRequestHandler { return withSessionHandler ? Result.Success(await SessionHandler.Handle(req, client.Mafile, client.Chp(), - GetTimerPrefix(client.Mafile))) + GetTimerPrefix(client.Mafile), false)) : Result.Success(await req()); } catch (SessionInvalidException ex) diff --git a/src/NebulaAuth/Model/SessionHandler/SessionHandler.cs b/src/NebulaAuth/Model/SessionHandler/SessionHandler.cs index b1c9979..46fa778 100644 --- a/src/NebulaAuth/Model/SessionHandler/SessionHandler.cs +++ b/src/NebulaAuth/Model/SessionHandler/SessionHandler.cs @@ -6,7 +6,9 @@ using AchiesUtilities.Web.Models; using MaterialDesignThemes.Wpf; using NebulaAuth.Core; using NebulaAuth.Model.Entities; +using NebulaAuth.Utility; using NebulaAuth.View.Dialogs; +using NebulaAuth.ViewModel.Other; using SteamLib.Exceptions.Authorization; namespace NebulaAuth.Model; @@ -16,13 +18,13 @@ public static partial class SessionHandler private static readonly SemaphoreSlim Semaphore = new(1, 1); public static async Task Handle(Func> func, Mafile mafile, - HttpClientHandlerPair? chp = null, string? snackbarPrefix = null) + HttpClientHandlerPair? chp = null, string? snackbarPrefix = null, bool allowInteractiveLogin = true) { chp ??= MaClient.GetHttpClientHandlerPair(mafile); await Semaphore.WaitAsync(); try { - return await HandleInternal(func, chp.Value, mafile, snackbarPrefix); + return await HandleInternal(func, chp.Value, mafile, snackbarPrefix, allowInteractiveLogin); } finally { @@ -31,7 +33,7 @@ public static partial class SessionHandler } private static async Task HandleInternal(Func> func, HttpClientHandlerPair chp, Mafile mafile, - string? snackbarPrefix = null) + string? snackbarPrefix = null, bool allowInteractiveLogin = true) { using var scope = Shell.Logger.PushScopeProperty("Scope", "SessionHandler"); Exception? currentException = null; @@ -86,6 +88,32 @@ public static partial class SessionHandler } } + if (allowInteractiveLogin && !DialogHost.IsDialogOpen(null)) + { + var noProxy = mafile.Proxy == null && MaClient.DefaultProxy == null; + var currentPassword = GetPassword(mafile); + + Task dialogTask = null!; + Application.Current.Dispatcher.Invoke(() => + { + dialogTask = DialogsController.ShowLoginAgainDialog(mafile.AccountName, currentPassword, noProxy); + }); + + var vm = await dialogTask; + if (vm != null) + { + Shell.Logger.Info("User provided credentials interactively for {name}, attempting login", + mafile.AccountName); + var logged = await LoginAgainInternal(chp, mafile, vm.Password, vm.SavePassword); + if (logged) + { + Shell.Logger.Debug("Interactive login for {name} succeeded, retrying operation", + mafile.AccountName); + return await func(); + } + } + } + throw new SessionPermanentlyExpiredException(SessionPermanentlyExpiredException.SESSION_EXPIRED_MSG, currentException); } @@ -118,6 +146,7 @@ public static partial class SessionHandler { Shell.Logger.Debug(ex, "Failed to relogin mafile {name} {steamid}", mafile.AccountName, mafile.SessionData?.SteamId); + ExceptionHandler.Handle(ex); return false; } finally diff --git a/src/NebulaAuth/Utility/ExceptionHandler.cs b/src/NebulaAuth/Utility/ExceptionHandler.cs index 6198906..c0e6c0c 100644 --- a/src/NebulaAuth/Utility/ExceptionHandler.cs +++ b/src/NebulaAuth/Utility/ExceptionHandler.cs @@ -93,7 +93,7 @@ public static class ExceptionHandler } case LoginException e: { - return "LoginException".GetCodeBehindLocalization() + ": " + + return "LoginException".GetCodeBehindLocalization() + ErrorTranslatorHelper.TranslateLoginError(e.Error); } case UnsupportedAuthTypeException e: diff --git a/src/NebulaAuth/View/Dialogs/LoginAgainDialog.xaml b/src/NebulaAuth/View/Dialogs/LoginAgainDialog.xaml index 3689a47..f0d05bd 100644 --- a/src/NebulaAuth/View/Dialogs/LoginAgainDialog.xaml +++ b/src/NebulaAuth/View/Dialogs/LoginAgainDialog.xaml @@ -25,24 +25,30 @@ + - + - - + diff --git a/src/NebulaAuth/ViewModel/Other/LoginAgainVM.cs b/src/NebulaAuth/ViewModel/Other/LoginAgainVM.cs index 3698bd3..c4a5636 100644 --- a/src/NebulaAuth/ViewModel/Other/LoginAgainVM.cs +++ b/src/NebulaAuth/ViewModel/Other/LoginAgainVM.cs @@ -11,5 +11,7 @@ public partial class LoginAgainVM : ObservableObject [ObservableProperty] private bool _savePassword; + [ObservableProperty] private bool _showNoProxyWarning; + [ObservableProperty] private string _userName = null!; } \ No newline at end of file