From 5be63dd71d04f212da59e28f85e02aae00636c8a Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Sun, 19 Apr 2026 21:36:45 +0200 Subject: [PATCH] Update tests (#1940) --- .../Tests/Client/Shard4/AuthTests.cs | 71 --------------- .../Shard4/RegistrationRateLimitTests.cs | 90 +++++++++++++++++++ 2 files changed, 90 insertions(+), 71 deletions(-) create mode 100644 apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/RegistrationRateLimitTests.cs diff --git a/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/AuthTests.cs b/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/AuthTests.cs index 2a5e52bc4..cc7cc153b 100644 --- a/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/AuthTests.cs +++ b/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/AuthTests.cs @@ -323,75 +323,4 @@ public class AuthTests : ClientPlaywrightTest Assert.That(authLogEntry.Client, Does.Contain("web-" + currentVersion), "Auth log client header does not contain expected value."); }); } - - /// - /// Test that registration rate limiting works correctly. - /// - /// Async task. - [Test] - [Order(8)] - public async Task RegistrationRateLimitingTest() - { - // Set the registration rate limit to 2 accounts per IP per 24 hours - await ApiServerSettings.SetSettingAsync("MaxRegistrationsPerIpPer24Hours", "2"); - - // Logout the current test user - await Logout(); - - // Register first account - var user1 = "ratelimit1@example.com"; - await Register(checkForSuccess: true, username: user1); - await Logout(); - - // Register second account - var user2 = "ratelimit2@example.com"; - await Register(checkForSuccess: true, username: user2); - await Logout(); - - // Attempt to register third account - should be blocked by rate limit - var user3 = "ratelimit3@example.com"; - await NavigateToRegistration(); - - var emailField = await WaitForAndGetElement("input[id='email']"); - var passwordField = await WaitForAndGetElement("input[id='password']"); - var confirmPasswordField = await WaitForAndGetElement("input[id='confirm-password']"); - - await emailField.FillAsync(user3); - await passwordField.FillAsync(TestUserPassword); - await confirmPasswordField.FillAsync(TestUserPassword); - - var registerButton = await WaitForAndGetElement("button[type='submit']"); - await registerButton.ClickAsync(); - - // Wait for rate limit error message - await Task.Delay(1000); - var pageContent = await Page.TextContentAsync("body"); - - // Check that registration was blocked (should still be on registration page with error) - Assert.That(await Page.UrlAsync(), Does.Contain("user/register"), "Should still be on registration page after rate limit exceeded."); - - // Verify that the auth log contains a failed registration with the rate limit exceeded reason - var failedRegistration = await ApiDbContext.AuthLogs.FirstOrDefaultAsync(x => - x.Username == user3 && - x.EventType == AuthEventType.Register && - !x.IsSuccess && - x.FailureReason == AuthFailureReason.RegistrationRateLimitExceeded); - - Assert.That(failedRegistration, Is.Not.Null, "Failed registration auth log entry with rate limit exceeded reason not found."); - - // Verify only 2 successful registrations were recorded - var successfulRegistrations = await ApiDbContext.AuthLogs.CountAsync(x => - (x.Username == user1 || x.Username == user2 || x.Username == user3) && - x.EventType == AuthEventType.Register && - x.IsSuccess); - - Assert.That(successfulRegistrations, Is.EqualTo(2), "Expected exactly 2 successful registrations."); - - // Reset the rate limit setting back to default - await ApiServerSettings.SetSettingAsync("MaxRegistrationsPerIpPer24Hours", "5"); - - // Re-login as the original test user for subsequent tests - await NavigateToLogin(); - await Login(); - } } diff --git a/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/RegistrationRateLimitTests.cs b/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/RegistrationRateLimitTests.cs new file mode 100644 index 000000000..7757f731a --- /dev/null +++ b/apps/server/Tests/AliasVault.E2ETests/Tests/Client/Shard4/RegistrationRateLimitTests.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) aliasvault. All rights reserved. +// Licensed under the AGPLv3 license. See LICENSE.md file in the project root for full license information. +// +//----------------------------------------------------------------------- + +namespace AliasVault.E2ETests.Tests.Client.Shard4; + +using AliasVault.Auth; +using AliasVault.Shared.Models.Enums; +using Microsoft.EntityFrameworkCore; + +/// +/// End-to-end tests for registration rate limiting. +/// +[Parallelizable(ParallelScope.Self)] +[Category("ClientTests")] +[TestFixture] +public class RegistrationRateLimitTests : ClientPlaywrightTest +{ + /// + /// Test that registration rate limiting works correctly. + /// + /// Async task. + [Test] + public async Task RegistrationRateLimitingTest() + { + // Set the registration rate limit to 2 accounts per IP per 24 hours + // Note: The test user account was already created during test setup, so that's 1/2 accounts used + await ApiServerSettings.SetSettingAsync("MaxRegistrationsPerIpPer24Hours", "2"); + + // Logout the current test user + await Logout(); + + // Register the second account (first one was created during test setup) + var user1 = "ratelimit1@example.com"; + await Register(checkForSuccess: true, username: user1); + await Logout(); + + // Attempt to register third account - should be blocked by rate limit + // since we've now hit the limit of 2 registrations (test user + user1) + var user2 = "ratelimit2@example.com"; + + // Navigate to registration page + await Page.GotoAsync(AppBaseUrl); + await WaitForUrlAsync("user/start", "Log in with"); + await NavigateUsingBlazorRouter("user/register"); + await WaitForUrlAsync("user/register", "Create account"); + + var emailField = await WaitForAndGetElement("input[id='email']"); + var passwordField = await WaitForAndGetElement("input[id='password']"); + var password2Field = await WaitForAndGetElement("input[id='password2']"); + + await emailField.FillAsync(user2); + await passwordField.FillAsync(TestUserPassword); + await password2Field.FillAsync(TestUserPassword); + + // Click somewhere to hide auto-popup and check terms checkbox + await Page.ClickAsync("body"); + var termsCheckbox = await WaitForAndGetElement("input[id='terms']"); + await termsCheckbox.CheckAsync(); + + var submitButton = await WaitForAndGetElement("button[type='submit']"); + await submitButton.ClickAsync(); + + // Wait for rate limit error message + await Task.Delay(1000); + + // Check that registration was blocked (should still be on registration page with error) + Assert.That(Page.Url, Does.Contain("user/register"), "Should still be on registration page after rate limit exceeded."); + + // Verify that the auth log contains a failed registration with the rate limit exceeded reason + var failedRegistration = await ApiDbContext.AuthLogs.FirstOrDefaultAsync(x => + x.Username == user2 && + x.EventType == AuthEventType.Register && + !x.IsSuccess && + x.FailureReason == AliasServerDb.AuthFailureReason.RegistrationRateLimitExceeded); + + Assert.That(failedRegistration, Is.Not.Null, "Failed registration auth log entry with rate limit exceeded reason not found."); + + // Verify only 2 successful registrations were recorded (test user + user1) + var successfulRegistrations = await ApiDbContext.AuthLogs.CountAsync(x => + (x.Username == TestUserUsername || x.Username == user1 || x.Username == user2) && + x.EventType == AuthEventType.Register && + x.IsSuccess); + + Assert.That(successfulRegistrations, Is.EqualTo(2), "Expected exactly 2 successful registrations (test user + user1)."); + } +}