Bläddra i källkod

Timeout changes

Krzysztof Krysiński 4 månader sedan
förälder
incheckning
18f8c9d409

+ 5 - 0
src/PixiEditor.IdentityProvider.PixiAuth/PixiAuthIdentityProvider.cs

@@ -82,6 +82,11 @@ public class PixiAuthIdentityProvider : IIdentityProvider
         {
             Error("CONNECTION_TIMEOUT");
         }
+        catch (TooManyRequestsException tooManyRequestsException)
+        {
+            Error(tooManyRequestsException.Message, tooManyRequestsException.TimeLeft);
+            LoginTimeout?.Invoke(tooManyRequestsException.TimeLeft);
+        }
     }
 
     public async Task ResendActivation(string email)

+ 16 - 36
src/PixiEditor.PixiAuth/PixiAuthClient.cs

@@ -47,6 +47,16 @@ public class PixiAuthClient
         {
             throw new InternalServerErrorException("INTERNAL_SERVER_ERROR");
         }
+        else if (response.StatusCode == HttpStatusCode.TooManyRequests)
+        {
+            if (response.Headers.TryGetValues("Retry-After", out var values))
+            {
+                if (int.TryParse(values.FirstOrDefault(), out int retryAfter))
+                {
+                    throw new TooManyRequestsException("TOO_MANY_REQUESTS", retryAfter / 1000d);
+                }
+            }
+        }
 
         return null;
     }
@@ -161,46 +171,15 @@ public class PixiAuthClient
     {
         var response = await httpClient.PostAsJsonAsync("/session/resendActivation", userSessionId);
 
-        if (response.StatusCode == HttpStatusCode.BadRequest)
+        if (response.StatusCode == HttpStatusCode.TooManyRequests)
         {
-            string responseString = await response.Content.ReadAsStringAsync();
-            try
+            if (response.Headers.TryGetValues("Retry-After", out var values))
             {
-                Dictionary<string, object> responseData =
-                    System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(responseString);
-                if (responseData != null && responseData.TryGetValue("error", out object? error))
+                if (int.TryParse(values.FirstOrDefault(), out int retryAfter))
                 {
-                    if (error is JsonElement errorElement)
-                    {
-                        error = errorElement.GetString();
-                    }
-
-
-                    if (error is string errorString and "TOO_MANY_REQUESTS")
-                    {
-                        if (responseData.TryGetValue("timeLeft", out object? timeLeft))
-                        {
-                            if (timeLeft is JsonElement timeLeftElement)
-                            {
-                                timeLeft = timeLeftElement.GetDouble();
-                            }
-
-                            if (timeLeft is double timeLeftDouble)
-                            {
-                                double seconds = double.Round(timeLeftDouble / 1000);
-                                throw new TooManyRequestsException(errorString, seconds);
-                            }
-                        }
-
-                        throw new BadRequestException(errorString);
-                    }
+                    throw new TooManyRequestsException("TOO_MANY_REQUESTS", retryAfter / 1000d);
                 }
             }
-            catch (JsonException)
-            {
-                // Handle JSON parsing error
-                throw new BadRequestException(responseString);
-            }
         }
         else if (response.StatusCode == HttpStatusCode.InternalServerError)
         {
@@ -281,7 +260,8 @@ public class PixiAuthClient
 
     public async Task<Stream> DownloadProduct(string token, string productId)
     {
-        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $"/content/downloadProduct?productId={productId}");
+        HttpRequestMessage request =
+            new HttpRequestMessage(HttpMethod.Get, $"/content/downloadProduct?productId={productId}");
         request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
         request.Content = JsonContent.Create(productId);
 

+ 14 - 1
src/PixiEditor/ViewModels/SubViewModels/UserViewModel.cs

@@ -186,7 +186,8 @@ internal class UserViewModel : SubViewModel<ViewModelMain>
 
     public bool CanRequestLogin(string email)
     {
-        return IdentityProvider is PixiAuthIdentityProvider && !string.IsNullOrEmpty(email) && email.Contains('@');
+        return IdentityProvider is PixiAuthIdentityProvider && !string.IsNullOrEmpty(email) && email.Contains('@') &&
+               !HasTimeout();
     }
 
     public async Task ResendActivation(string email)
@@ -205,12 +206,23 @@ internal class UserViewModel : SubViewModel<ViewModelMain>
         }
     }
 
+    public bool HasTimeout()
+    {
+        if (TimeToEndTimeout != null)
+        {
+            return DateTime.Now < TimeToEndTimeout;
+        }
+
+        return false;
+    }
+
     private void RunTimeoutTimers(double timeLeft)
     {
         DispatcherTimer.RunOnce(
             () =>
             {
                 TimeToEndTimeout = null;
+                LastError = null;
                 NotifyProperties();
             },
             TimeSpan.FromSeconds(timeLeft));
@@ -368,5 +380,6 @@ internal class UserViewModel : SubViewModel<ViewModelMain>
         OnPropertyChanged(nameof(OwnedProducts));
         OnPropertyChanged(nameof(AnyUpdateAvailable));
         ResendActivationCommand.NotifyCanExecuteChanged();
+        RequestLoginCommand.NotifyCanExecuteChanged();
     }
 }

+ 7 - 3
src/PixiEditor/Views/Auth/LoginForm.axaml

@@ -17,7 +17,7 @@
         <StackPanel IsVisible="{Binding !IsLoggedIn}" VerticalAlignment="Top" Spacing="12">
             <TextBox Text="{Binding CurrentEmail, Mode=TwoWay}" Watermark="{ui:Translate Key=ENTER_EMAIL}" Name="Email"
                      IsVisible="{Binding !IsLoggedIn}" />
-            <Button Name="LoginButton" ui:Translator.Key="LOGIN_LINK"
+            <Button Name="LoginButton"
                     IsDefault="True"
                     Command="{Binding RequestLoginCommand}"
                     CommandParameter="{Binding ElementName=Email, Path=Text}">
@@ -27,6 +27,10 @@
                         <Binding Path="!EmailEqualsLastSentMail" />
                     </MultiBinding>
                 </Button.IsVisible>
+                <TextBlock>
+                    <Run ui:Translator.Key="LOGIN_LINK" />
+                    <Run Text="{Binding TimeToEndTimeoutString}" />
+                </TextBlock>
             </Button>
             <Button Command="{Binding Path=ResendActivationCommand}"
                     CommandParameter="{Binding ElementName=Email, Path=Text}">
@@ -87,8 +91,8 @@
                 <Run Text="{Binding Username}" />
             </TextBlock>
             <Button IsVisible="{Binding IdentityProvider.AllowsLogout}"
-                Content="{ui:Translate Key=LOGOUT}"
-                Command="{Binding LogoutCommand}" />
+                    Content="{ui:Translate Key=LOGOUT}"
+                    Command="{Binding LogoutCommand}" />
         </StackPanel>
     </Panel>
 </UserControl>