Skip to content

Commit 158a706

Browse files
Misc updates
1 parent 68b9f55 commit 158a706

5 files changed

Lines changed: 31 additions & 37 deletions

File tree

EssentialCSharp.Chat.Shared/Services/AIChatService.cs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,13 @@ public AIChatService(IOptions<AIOptions> options, AISearchService searchService,
8686
var enrichedPrompt = await EnrichPromptWithContext(prompt, enableContextualSearch, cancellationToken);
8787

8888
// Construct the user input with system context if provided
89-
var systemContext = systemPrompt ?? _Options.SystemPrompt;
89+
var systemContext = !string.IsNullOrWhiteSpace(systemPrompt) ? systemPrompt : _Options.SystemPrompt;
9090

9191
// Create the streaming response using the Responses API
9292
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
93-
List<ResponseItem> responseItems = [ResponseItem.CreateUserMessageItem(enrichedPrompt)];
94-
if (systemContext is not null)
95-
{
96-
responseItems.Add(
97-
ResponseItem.CreateSystemMessageItem(systemContext));
98-
}
93+
List<ResponseItem> responseItems = systemContext is not null
94+
? [ResponseItem.CreateSystemMessageItem(systemContext), ResponseItem.CreateUserMessageItem(enrichedPrompt)]
95+
: [ResponseItem.CreateUserMessageItem(enrichedPrompt)];
9996
#pragma warning restore OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
10097
var streamingUpdates = _ResponseClient.CreateResponseStreamingAsync(
10198
responseItems,
@@ -319,16 +316,13 @@ private static async Task<ResponseCreationOptions> CreateResponseOptionsAsync(
319316
CancellationToken cancellationToken = default)
320317
{
321318
// Construct the user input with system context if provided
322-
var systemContext = systemPrompt ?? _Options.SystemPrompt;
319+
var systemContext = !string.IsNullOrWhiteSpace(systemPrompt) ? systemPrompt : _Options.SystemPrompt;
323320

324321
// Create the streaming response using the Responses API
325322
#pragma warning disable OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
326-
List<ResponseItem> responseItems = [ResponseItem.CreateUserMessageItem(prompt)];
327-
if (systemContext is not null)
328-
{
329-
responseItems.Add(
330-
ResponseItem.CreateSystemMessageItem(systemContext));
331-
}
323+
List<ResponseItem> responseItems = systemContext is not null
324+
? [ResponseItem.CreateSystemMessageItem(systemContext), ResponseItem.CreateUserMessageItem(prompt)]
325+
: [ResponseItem.CreateUserMessageItem(prompt)];
332326
#pragma warning restore OPENAI001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
333327

334328
// Create the response using the Responses API

EssentialCSharp.Web/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public async Task<IActionResult> OnGetCallbackAsync(string? returnUrl = null, st
7171
}
7272

7373
// Sign in the user with this external login provider if the user already has a login.
74+
// bypassTwoFactor: true is intentional — OAuth providers (GitHub, Microsoft) handle their own
75+
// authentication including any provider-side MFA. The app's local TOTP 2FA is designed to protect
76+
// the password-based sign-in path only. If policy changes to require local 2FA for all sign-in
77+
// methods, set bypassTwoFactor to false AND add a RequiresTwoFactor redirect handler here.
7478
Microsoft.AspNetCore.Identity.SignInResult result = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
7579
if (result.Succeeded)
7680
{

EssentialCSharp.Web/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public InputModel Input
2626
public class InputModel
2727
{
2828
[Required]
29-
[StringLength(ValidationMessages.VerificationCodeMaximumLength, ErrorMessage = ValidationMessages.StringLengthErrorMessage, MinimumLength = ValidationMessages.VerificationCodeMaximumLength)]
29+
[StringLength(ValidationMessages.VerificationCodeMaximumLength, ErrorMessage = ValidationMessages.StringLengthErrorMessage, MinimumLength = ValidationMessages.VerificationCodeMinimumLength)]
3030
[DataType(DataType.Text)]
3131
[Display(Name = "Authenticator code")]
3232
public string? TwoFactorCode { get; set; }

EssentialCSharp.Web/Controllers/ChatController.cs

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,17 @@ public ChatController(ILogger<ChatController> logger, AIChatService aiChatServic
2424
[HttpPost("message")]
2525
public async Task<IActionResult> SendMessage([FromBody] ChatMessageRequest request, CancellationToken cancellationToken = default)
2626
{
27-
if (string.IsNullOrWhiteSpace(request.Message))
28-
{
27+
request.Message = request.Message.Trim();
28+
if (string.IsNullOrEmpty(request.Message))
2929
return BadRequest(new { error = "Message cannot be empty." });
30-
}
3130

32-
// Require user authentication for chat
33-
if (!User.Identity?.IsAuthenticated ?? true)
34-
{
35-
return Unauthorized(new { error = "User must be logged in to use chat." });
36-
}
31+
var previousResponseId = string.IsNullOrWhiteSpace(request.PreviousResponseId)
32+
? null
33+
: request.PreviousResponseId.Trim();
3734

3835
var (response, responseId) = await _AiChatService.GetChatCompletion(
3936
prompt: request.Message,
40-
systemPrompt: request.SystemPrompt,
41-
previousResponseId: request.PreviousResponseId,
37+
previousResponseId: previousResponseId,
4238
enableContextualSearch: request.EnableContextualSearch,
4339
cancellationToken: cancellationToken);
4440

@@ -53,20 +49,17 @@ public async Task<IActionResult> SendMessage([FromBody] ChatMessageRequest reque
5349
[HttpPost("stream")]
5450
public async Task StreamMessage([FromBody] ChatMessageRequest request, CancellationToken cancellationToken = default)
5551
{
56-
if (string.IsNullOrWhiteSpace(request.Message))
52+
request.Message = request.Message.Trim();
53+
if (string.IsNullOrEmpty(request.Message))
5754
{
5855
Response.StatusCode = 400;
59-
await Response.WriteAsync(JsonSerializer.Serialize(new { error = "Message cannot be empty." }), cancellationToken);
56+
await Response.WriteAsJsonAsync(new { error = "Message cannot be empty." }, CancellationToken.None);
6057
return;
6158
}
6259

63-
// Require user authentication for chat
64-
if (!User.Identity?.IsAuthenticated ?? true)
65-
{
66-
Response.StatusCode = 401;
67-
await Response.WriteAsync(JsonSerializer.Serialize(new { error = "User must be logged in to use chat." }), cancellationToken);
68-
return;
69-
}
60+
var previousResponseId = string.IsNullOrWhiteSpace(request.PreviousResponseId)
61+
? null
62+
: request.PreviousResponseId.Trim();
7063

7164
Response.ContentType = "text/event-stream";
7265
Response.Headers.CacheControl = "no-cache";
@@ -76,8 +69,7 @@ public async Task StreamMessage([FromBody] ChatMessageRequest request, Cancellat
7669
{
7770
await foreach (var (text, responseId) in _AiChatService.GetChatCompletionStream(
7871
prompt: request.Message,
79-
systemPrompt: request.SystemPrompt,
80-
previousResponseId: request.PreviousResponseId,
72+
previousResponseId: previousResponseId,
8173
enableContextualSearch: request.EnableContextualSearch,
8274
cancellationToken: cancellationToken))
8375
{

EssentialCSharp.Web/Controllers/ChatMessageRequest.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
using System.ComponentModel.DataAnnotations;
2+
13
namespace EssentialCSharp.Web.Controllers;
24

35
public class ChatMessageRequest
46
{
7+
[Required]
8+
[StringLength(500)]
59
public string Message { get; set; } = string.Empty;
6-
public string? SystemPrompt { get; set; }
10+
[StringLength(200)]
711
public string? PreviousResponseId { get; set; }
812
public bool EnableContextualSearch { get; set; } = true;
913
public string? CaptchaResponse { get; set; } // For future captcha implementation

0 commit comments

Comments
 (0)