diff --git a/CHANGELOG.md b/CHANGELOG.md index bce46f1..5c512c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # GameVault App Changelog -##1.17.1 +## 1.17.2 +Recommended Gamevault Server Version: `v15.0.2` +### Changes +- Added authorization to the admin panel’s registration action, allowing administrators to register users even when server-side registration is disabled. +- Extended the existing installation overwrite warning to allow users to continue the installation at their own risk. +- Performance optimization in the community tab +- Bug fix: OAuth access token expiration was not calculated correctly under certain circumstances. + +## 1.17.1 Recommended Gamevault Server Version: `v15.0.2` ### Changes - User registration has also been added to the Admin Panel. diff --git a/gamevault/AssemblyInfo.cs b/gamevault/AssemblyInfo.cs index 525d34e..bfb06b5 100644 --- a/gamevault/AssemblyInfo.cs +++ b/gamevault/AssemblyInfo.cs @@ -11,7 +11,7 @@ //(used if a resource is not found in the page, // app, or any theme specific resource dictionaries) )] -[assembly: AssemblyVersion("1.17.1.0")] +[assembly: AssemblyVersion("1.17.2.0")] [assembly: AssemblyCopyright("© Phalcode™. All Rights Reserved.")] #if DEBUG [assembly: XmlnsDefinition("debug-mode", "Namespace")] diff --git a/gamevault/Helper/LoginManager.cs b/gamevault/Helper/LoginManager.cs index 6aed09e..4f8995d 100644 --- a/gamevault/Helper/LoginManager.cs +++ b/gamevault/Helper/LoginManager.cs @@ -72,7 +72,7 @@ public string GetServerLoginResponseMessage() public void SwitchToOfflineMode() { MainWindowViewModel.Instance.OnlineState = System.Windows.Visibility.Visible; - m_User = null; + m_User = null; } public UserProfile GetUserProfile() { @@ -385,12 +385,20 @@ public void PhalcodeLogout() } - public async Task Register(LoginUser user) + public async Task Register(LoginUser user, bool useOAuth = false) { try { string userObject = JsonSerializer.Serialize(new User { Username = user.Username, Password = user.Password, EMail = user.EMail, FirstName = user.FirstName, LastName = user.LastName, BirthDate = user.BirthDate }); - string newUser = await WebHelper.BasePostAsync($"{user.ServerUrl}/api/auth/basic/register", userObject); + string newUser = ""; + if (useOAuth) + { + newUser = await WebHelper.PostAsync($"{user.ServerUrl}/api/auth/basic/register", userObject); + } + else + { + newUser = await WebHelper.BasePostAsync($"{user.ServerUrl}/api/auth/basic/register", userObject); + } User newUserObject = JsonSerializer.Deserialize(newUser); if (newUserObject!.Activated != true) { diff --git a/gamevault/Helper/VisualHelper.cs b/gamevault/Helper/VisualHelper.cs index 4e2e364..e53eae8 100644 --- a/gamevault/Helper/VisualHelper.cs +++ b/gamevault/Helper/VisualHelper.cs @@ -23,6 +23,25 @@ internal static T FindNextParentByType(DependencyObject child) while (parentDepObj != null); return default; } + internal static IEnumerable FindVisualChildren(DependencyObject depObj) where T : DependencyObject + { + if (depObj != null) + { + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) + { + DependencyObject child = VisualTreeHelper.GetChild(depObj, i); + if (child is T t) + { + yield return t; + } + + foreach (T childOfChild in FindVisualChildren(child)) + { + yield return childOfChild; + } + } + } + } internal static void AdjustWindowChrome(MetroWindow window) { try @@ -47,7 +66,7 @@ internal static void HideWindow(Window window) internal static void RestoreHiddenWindow(Window window, int height, int width) { window.Width = width; - window.Height = height; + window.Height = height; window.ShowInTaskbar = true; double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth; double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight; diff --git a/gamevault/Helper/Web/OAuthHttpClient.cs b/gamevault/Helper/Web/OAuthHttpClient.cs index 5342b4e..f4f8da9 100644 --- a/gamevault/Helper/Web/OAuthHttpClient.cs +++ b/gamevault/Helper/Web/OAuthHttpClient.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Text.Json; using gamevault.Models; +using System.Diagnostics; namespace gamevault.Helper { @@ -66,7 +67,7 @@ private async Task SendAsync(HttpRequestMessage request, Re await LoginBasicAuthAsync(UserName, Password); } - if (IsTokenExpired(_accessToken) && !await RefreshTokenAsync()) + if (IsTokenExpired() && !await RefreshTokenAsync()) throw new InvalidOperationException("Failed to refresh token."); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken); @@ -106,20 +107,30 @@ private async Task RefreshTokenAsync() _accessToken = json?.AccessToken; _refreshToken = json?.RefreshToken; - + nextTokenRefresh = GetNextTokenRefresh(_accessToken); + //Debug.WriteLine($"Token refreshed. Next refresh at: {nextTokenRefresh}"); return true; } - - private bool IsTokenExpired(string token) + DateTimeOffset nextTokenRefresh; + private bool IsTokenExpired() + { + return nextTokenRefresh <= DateTimeOffset.UtcNow.AddMinutes(1); + } + private DateTimeOffset GetNextTokenRefresh(string token) { var parts = token.Split('.'); - if (parts.Length != 3) return true; + if (parts.Length != 3) return DateTimeOffset.UtcNow; var payload = parts[1]; var jsonBytes = Convert.FromBase64String(Base64UrlDecode(payload)); - - var json = JsonSerializer.Deserialize(Encoding.UTF8.GetString(jsonBytes)); - return json?.Exp == null || DateTimeOffset.FromUnixTimeSeconds(json.Exp) <= DateTimeOffset.UtcNow.AddMinutes(1); + var json = JsonSerializer.Deserialize(Encoding.UTF8.GetString(jsonBytes)); + if (json?.Exp == null) + { + return DateTimeOffset.UtcNow; + } + var expTimestamp = DateTimeOffset.FromUnixTimeSeconds(json.Exp); + var creationTimestamp = DateTimeOffset.FromUnixTimeSeconds(json.Creation); + return DateTimeOffset.UtcNow + (expTimestamp - creationTimestamp); } private string Base64UrlDecode(string input) @@ -140,6 +151,8 @@ public class AuthResponse public class JwtPayload { + [JsonPropertyName("iat")] + public long Creation { get; set; } [JsonPropertyName("exp")] public long Exp { get; set; } } diff --git a/gamevault/UserControls/CommunityUserControl.xaml b/gamevault/UserControls/CommunityUserControl.xaml index 1b24e85..5d9dfaa 100644 --- a/gamevault/UserControls/CommunityUserControl.xaml +++ b/gamevault/UserControls/CommunityUserControl.xaml @@ -67,7 +67,7 @@ - +