- fix: profiles token refresh now
This commit is contained in:
@@ -62,6 +62,7 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
_logger = DebugService.GetLogger(this);
|
_logger = DebugService.GetLogger(this);
|
||||||
Credentials = new AuthTokenCredentialsVar(this);
|
Credentials = new AuthTokenCredentialsVar(this);
|
||||||
Task.Run(ReadAuthConfig);
|
Task.Run(ReadAuthConfig);
|
||||||
|
Credentials.Value = Credentials.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DoAuth(string? code = null)
|
public void DoAuth(string? code = null)
|
||||||
@@ -81,13 +82,15 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
Exception? exception = null;
|
Exception? exception = null;
|
||||||
AuthTokenCredentials? credentials = null;
|
|
||||||
|
|
||||||
foreach (var server in serverCandidates)
|
foreach (var server in serverCandidates)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
credentials = await AuthService.Auth(CurrentLogin, CurrentPassword, server, code);
|
await CatchAuthError(async() =>
|
||||||
|
{
|
||||||
|
Credentials.Value = await AuthService.Auth(CurrentLogin, CurrentPassword, server, code);
|
||||||
|
}, ()=> message.Dispose());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -98,13 +101,10 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
|
|
||||||
message.Dispose();
|
message.Dispose();
|
||||||
|
|
||||||
if (credentials is null)
|
if (exception != null)
|
||||||
{
|
{
|
||||||
PopupMessageService.Popup(exception ?? new Exception(LocalisationService.GetString("auth-error")));
|
PopupMessageService.Popup(new Exception("Error while auth", exception));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Credentials.Value = credentials;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +124,6 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
case AuthenticateDenyCode.TfaRequired:
|
case AuthenticateDenyCode.TfaRequired:
|
||||||
case AuthenticateDenyCode.TfaInvalid:
|
case AuthenticateDenyCode.TfaInvalid:
|
||||||
var p = ViewHelperService.GetViewModel<TfaViewModel>();
|
var p = ViewHelperService.GetViewModel<TfaViewModel>();
|
||||||
p.OnTfaEntered += OnTfaEntered;
|
|
||||||
PopupMessageService.Popup(p);
|
PopupMessageService.Popup(p);
|
||||||
_logger.Log("TFA required");
|
_logger.Log("TFA required");
|
||||||
break;
|
break;
|
||||||
@@ -242,7 +241,7 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
Accounts.Add(alpm);
|
Accounts.Add(alpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ReadAuthConfig()
|
private async Task ReadAuthConfig()
|
||||||
{
|
{
|
||||||
var message = ViewHelperService.GetViewModel<InfoPopupViewModel>();
|
var message = ViewHelperService.GetViewModel<InfoPopupViewModel>();
|
||||||
message.InfoText = LocalisationService.GetString("auth-config-read");
|
message.InfoText = LocalisationService.GetString("auth-config-read");
|
||||||
@@ -290,20 +289,27 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
{
|
{
|
||||||
if(authTokenCredentials is null)
|
if(authTokenCredentials is null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
var daysLeft = (int)(authTokenCredentials.Token.ExpireTime - DateTime.Now).TotalDays;
|
||||||
|
|
||||||
if (authTokenCredentials.Token.ExpireTime < DateTime.Now.AddDays(2))
|
if(daysLeft >= 4)
|
||||||
|
{
|
||||||
|
_logger.Log("Token " + authTokenCredentials.Login + " is active, "+daysLeft+" days left, undo renewing!");
|
||||||
return authTokenCredentials;
|
return authTokenCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.Log($"Renewing token for {authTokenCredentials.Login}");
|
_logger.Log($"Renewing token for {authTokenCredentials.Login}");
|
||||||
return await AuthService.Refresh(authTokenCredentials);
|
return await ExceptionHelper.TryRun(() => AuthService.Refresh(authTokenCredentials),3, (attempt, e) =>
|
||||||
|
{
|
||||||
|
_logger.Error(new Exception("Error while renewing, attempts: " + attempt, e));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
var unexpectedError = new Exception(LocalisationService.GetString("auth-error"), e);
|
var unexpectedError = new Exception(LocalisationService.GetString("auth-error"), e);
|
||||||
_logger.Error(unexpectedError);
|
_logger.Error(unexpectedError);
|
||||||
//PopupMessageService.Popup(unexpectedError);
|
|
||||||
return authTokenCredentials;
|
return authTokenCredentials;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,7 +382,19 @@ public partial class AccountInfoViewModel : ViewModelBase
|
|||||||
|
|
||||||
var errorRun = false;
|
var errorRun = false;
|
||||||
|
|
||||||
//currProfile = await CheckOrRenewToken(currProfile);
|
currProfile = await accountInfoViewModel.CheckOrRenewToken(currProfile);
|
||||||
|
|
||||||
|
if (currProfile is null)
|
||||||
|
{
|
||||||
|
message.Dispose();
|
||||||
|
|
||||||
|
accountInfoViewModel._logger.Log("profile credentials update required!");
|
||||||
|
|
||||||
|
accountInfoViewModel.PopupMessageService.Popup("profile credentials update required!");
|
||||||
|
|
||||||
|
accountInfoViewModel.IsLogged = false;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ public abstract class PopupViewModelBase : ViewModelBase, IDisposable
|
|||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
OnDispose();
|
||||||
PopupMessageService.ClosePopup(this);
|
PopupMessageService.ClosePopup(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnDispose(){}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Nebula.Launcher.Services;
|
using Nebula.Launcher.Services;
|
||||||
|
using Nebula.Launcher.ViewModels.Pages;
|
||||||
using Nebula.Launcher.Views.Popup;
|
using Nebula.Launcher.Views.Popup;
|
||||||
using Nebula.Shared.Services;
|
using Nebula.Shared.Services;
|
||||||
using Nebula.Shared.ViewHelper;
|
using Nebula.Shared.ViewHelper;
|
||||||
@@ -9,7 +10,10 @@ namespace Nebula.Launcher.ViewModels.Popup;
|
|||||||
[ConstructGenerator, ViewModelRegister(typeof(TfaView))]
|
[ConstructGenerator, ViewModelRegister(typeof(TfaView))]
|
||||||
public partial class TfaViewModel : PopupViewModelBase
|
public partial class TfaViewModel : PopupViewModelBase
|
||||||
{
|
{
|
||||||
public Action<string>? OnTfaEntered;
|
[GenerateProperty] public override PopupMessageService PopupMessageService { get; }
|
||||||
|
[GenerateProperty] public AccountInfoViewModel AccountInfo { get; }
|
||||||
|
public override string Title => LocalisationService.GetString("popup-twofa");
|
||||||
|
public override bool IsClosable => true;
|
||||||
|
|
||||||
protected override void InitialiseInDesignMode()
|
protected override void InitialiseInDesignMode()
|
||||||
{
|
{
|
||||||
@@ -21,11 +25,7 @@ public partial class TfaViewModel : PopupViewModelBase
|
|||||||
|
|
||||||
public void OnTfaEnter(string code)
|
public void OnTfaEnter(string code)
|
||||||
{
|
{
|
||||||
OnTfaEntered?.Invoke(code);
|
AccountInfo.DoAuth(code);
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[GenerateProperty] public override PopupMessageService PopupMessageService { get; }
|
|
||||||
public override string Title => LocalisationService.GetString("popup-twofa");
|
|
||||||
public override bool IsClosable => true;
|
|
||||||
}
|
}
|
||||||
@@ -74,6 +74,19 @@ public sealed record AuthDenyError(string[] Errors, AuthenticateDenyCode Code);
|
|||||||
public sealed class AuthException(AuthDenyError error) : Exception
|
public sealed class AuthException(AuthDenyError error) : Exception
|
||||||
{
|
{
|
||||||
public AuthDenyError Error { get; } = error;
|
public AuthDenyError Error { get; } = error;
|
||||||
|
|
||||||
|
public override string Message
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var str = "Error while logging in. Please try again. " + Error.Code;
|
||||||
|
foreach (var error in Error.Errors)
|
||||||
|
{
|
||||||
|
str += "\n" + error;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||||
|
|||||||
@@ -32,20 +32,6 @@ public class RestService
|
|||||||
var response = await _client.GetAsync(uri, cancellationToken);
|
var response = await _client.GetAsync(uri, cancellationToken);
|
||||||
return await ReadResult<T>(response, cancellationToken, uri);
|
return await ReadResult<T>(response, cancellationToken, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Pure]
|
|
||||||
public async Task<T> GetAsyncDefault<T>(Uri uri, T defaultValue, CancellationToken cancellationToken) where T : notnull
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return await GetAsync<T>(uri, cancellationToken);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(e);
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<K> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken) where K : notnull
|
public async Task<K> PostAsync<K, T>(T information, Uri uri, CancellationToken cancellationToken) where K : notnull
|
||||||
{
|
{
|
||||||
@@ -71,6 +57,20 @@ public class RestService
|
|||||||
var response = await _client.DeleteAsync(uri, cancellationToken);
|
var response = await _client.DeleteAsync(uri, cancellationToken);
|
||||||
return await ReadResult<T>(response, cancellationToken, uri);
|
return await ReadResult<T>(response, cancellationToken, uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Pure]
|
||||||
|
public async Task<T> GetAsyncDefault<T>(Uri uri, T defaultValue, CancellationToken cancellationToken) where T : notnull
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await GetAsync<T>(uri, cancellationToken);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(e);
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Pure]
|
[Pure]
|
||||||
private async Task<T> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken, Uri uri) where T : notnull
|
private async Task<T> ReadResult<T>(HttpResponseMessage response, CancellationToken cancellationToken, Uri uri) where T : notnull
|
||||||
|
|||||||
19
Nebula.Shared/Utils/ExceptionHelper.cs
Normal file
19
Nebula.Shared/Utils/ExceptionHelper.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
namespace Nebula.Shared.Utils;
|
||||||
|
|
||||||
|
public static class ExceptionHelper
|
||||||
|
{
|
||||||
|
public static Task<T> TryRun<T>(Func<Task<T>> func, int attempts = 3, Action<int, Exception>? attemptsCallback = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return func.Invoke();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (attempts <= 0) throw new("Attempts was expired! ", e);
|
||||||
|
attempts--;
|
||||||
|
attemptsCallback?.Invoke(attempts, e);
|
||||||
|
return TryRun(func, attempts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user