- fix: profiles token refresh now

This commit is contained in:
2025-08-17 21:02:45 +03:00
parent 6c967efd85
commit b86b65fd66
6 changed files with 86 additions and 33 deletions

View File

@@ -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
{ {

View File

@@ -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(){}
} }

View File

@@ -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;
} }

View File

@@ -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))]

View File

@@ -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

View 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);
}
}
}