diff --git a/apps/server/AliasVault.Client/Auth/Components/InputTextField.razor b/apps/server/AliasVault.Client/Auth/Components/InputTextField.razor
index a85ed93dd..84619e2e2 100644
--- a/apps/server/AliasVault.Client/Auth/Components/InputTextField.razor
+++ b/apps/server/AliasVault.Client/Auth/Components/InputTextField.razor
@@ -1,12 +1,14 @@
@using System.Linq.Expressions
-
+@* Thin styled wrapper around InputTextOnInput so the auth forms get consistent styling without repeating the long
+ Tailwind class list. The actual bind-on-input logic lives in InputTextOnInput. *@
+
@code {
///
diff --git a/apps/server/AliasVault.Client/Auth/Pages/Login.razor b/apps/server/AliasVault.Client/Auth/Pages/Login.razor
index 2076c8e26..7efa7230e 100644
--- a/apps/server/AliasVault.Client/Auth/Pages/Login.razor
+++ b/apps/server/AliasVault.Client/Auth/Pages/Login.razor
@@ -68,7 +68,7 @@ else if (_showLoginWithRecoveryCodeStep)
-
diff --git a/apps/server/AliasVault.Client/Shared/Components/InputTextOnInput.razor b/apps/server/AliasVault.Client/Shared/Components/InputTextOnInput.razor
new file mode 100644
index 000000000..24a9bc480
--- /dev/null
+++ b/apps/server/AliasVault.Client/Shared/Components/InputTextOnInput.razor
@@ -0,0 +1,30 @@
+@using System.Diagnostics.CodeAnalysis
+@using Microsoft.AspNetCore.Components.Forms
+@inherits InputBase
+
+@* A drop-in replacement for Blazor's built-in that updates the bound value on the `oninput` event
+ instead of `onchange`. The built-in component only commits the value on blur, which means programmatically filled
+ values (e.g. password-manager autofill) that never receive a blur are not bound, which can result in a
+ a "required" validation error on submit. *@
+
+
+@code {
+ ///
+ /// Commits the new value to the EditContext on every input event so autofilled values are captured immediately.
+ ///
+ private void OnInput(ChangeEventArgs e)
+ {
+ CurrentValueAsString = e.Value?.ToString();
+ }
+
+ ///
+ protected override bool TryParseValueFromString(string? value, out string? result, [NotNullWhen(false)] out string? validationErrorMessage)
+ {
+ result = value;
+ validationErrorMessage = null;
+ return true;
+ }
+}
diff --git a/apps/server/AliasVault.Client/_Imports.razor b/apps/server/AliasVault.Client/_Imports.razor
index bafbb7ab1..9e59e5eee 100644
--- a/apps/server/AliasVault.Client/_Imports.razor
+++ b/apps/server/AliasVault.Client/_Imports.razor
@@ -28,6 +28,7 @@
@using AliasVault.Client.Services.Auth
@using AliasVault.Client.Services.Database
@using AliasVault.Client.Services.JsInterop;
+@using AliasVault.Client.Shared.Components
@using AliasVault.RazorComponents
@using AliasVault.RazorComponents.Alerts
@using AliasVault.RazorComponents.Buttons