From 9ea92e9fe42c2fda559c419d1e8d7ff779a2f55d Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Fri, 7 Aug 2026 00:33:33 -0700 Subject: [PATCH 1/2] fix(chat): accept long hcaptcha tokens --- .../ChatRequestValidationTests.cs | 36 +++++++++++++++++++ .../Controllers/ChatMessageRequest.cs | 1 - 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs diff --git a/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs b/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs new file mode 100644 index 00000000..0674a557 --- /dev/null +++ b/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs @@ -0,0 +1,36 @@ +using System.Net; +using System.Net.Http.Json; +using System.Text.Json; + +namespace EssentialCSharp.Web.Tests; + +public class ChatRequestValidationTests : IntegrationTestBase +{ + [Test] + public async Task ChatStream_WhenCaptchaTokenExceedsTwoThousandCharacters_DoesNotFailModelValidation() + { + HttpClient client = McpTestHelper.CreateClient(Factory); + + string userId = await McpTestHelper.CreateUserAsync(Factory, "chat-validation-user"); + (string cookieName, string cookieValue) = await McpTestHelper.CreateIdentityApplicationCookieAsync(Factory, userId); + + string longCaptchaToken = new('a', 2500); + + using var request = new HttpRequestMessage(HttpMethod.Post, "/api/chat/stream") + { + Content = JsonContent.Create(new + { + message = "Hello", + enableContextualSearch = false, + captchaResponse = longCaptchaToken + }) + }; + McpTestHelper.AddCookie(request, cookieName, cookieValue); + + using HttpResponseMessage response = await client.SendAsync(request); + await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.ServiceUnavailable); + + using JsonDocument payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); + await Assert.That(payload.RootElement.GetProperty("errorCode").GetString()).IsEqualTo("chat_unavailable"); + } +} diff --git a/EssentialCSharp.Web/Controllers/ChatMessageRequest.cs b/EssentialCSharp.Web/Controllers/ChatMessageRequest.cs index ca05d5ee..b0ca12c7 100644 --- a/EssentialCSharp.Web/Controllers/ChatMessageRequest.cs +++ b/EssentialCSharp.Web/Controllers/ChatMessageRequest.cs @@ -14,6 +14,5 @@ public class ChatMessageRequest /// hCaptcha token obtained from the client-side invisible widget. /// Required when CaptchaOptions.SecretKey is configured; ignored otherwise. /// - [StringLength(2000)] public string? CaptchaResponse { get; set; } } From 37a4439b851fe8b987f591cf84eccb10c9836387 Mon Sep 17 00:00:00 2001 From: Benjamin Michaelis Date: Fri, 7 Aug 2026 00:34:38 -0700 Subject: [PATCH 2/2] Delete EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs --- .../ChatRequestValidationTests.cs | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs diff --git a/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs b/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs deleted file mode 100644 index 0674a557..00000000 --- a/EssentialCSharp.Web.Tests/ChatRequestValidationTests.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Net; -using System.Net.Http.Json; -using System.Text.Json; - -namespace EssentialCSharp.Web.Tests; - -public class ChatRequestValidationTests : IntegrationTestBase -{ - [Test] - public async Task ChatStream_WhenCaptchaTokenExceedsTwoThousandCharacters_DoesNotFailModelValidation() - { - HttpClient client = McpTestHelper.CreateClient(Factory); - - string userId = await McpTestHelper.CreateUserAsync(Factory, "chat-validation-user"); - (string cookieName, string cookieValue) = await McpTestHelper.CreateIdentityApplicationCookieAsync(Factory, userId); - - string longCaptchaToken = new('a', 2500); - - using var request = new HttpRequestMessage(HttpMethod.Post, "/api/chat/stream") - { - Content = JsonContent.Create(new - { - message = "Hello", - enableContextualSearch = false, - captchaResponse = longCaptchaToken - }) - }; - McpTestHelper.AddCookie(request, cookieName, cookieValue); - - using HttpResponseMessage response = await client.SendAsync(request); - await Assert.That(response.StatusCode).IsEqualTo(HttpStatusCode.ServiceUnavailable); - - using JsonDocument payload = JsonDocument.Parse(await response.Content.ReadAsStringAsync()); - await Assert.That(payload.RootElement.GetProperty("errorCode").GetString()).IsEqualTo("chat_unavailable"); - } -}