mirror of
https://github.com/RedWizardsLab/EchoHub.git
synced 2026-09-04 08:36:11 +02:00
feat: implement user registration and update SASL authentication handling
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>0.2.7</Version>
|
||||
<Version>0.2.8</Version>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -29,4 +29,5 @@ public interface IChatService
|
||||
Task<UserProfileDto?> GetUserProfileAsync(string username);
|
||||
Task<List<string>> GetChannelsForUserAsync(string username);
|
||||
Task<(Guid UserId, string Username)?> AuthenticateUserAsync(string username, string password);
|
||||
Task<(Guid UserId, string Username)?> RegisterUserAsync(string username, string password);
|
||||
}
|
||||
|
||||
@@ -170,9 +170,13 @@ public sealed class IrcCommandHandler
|
||||
|
||||
var result = await _chatService.AuthenticateUserAsync(username, password);
|
||||
|
||||
// Auth failed — try registering a new account
|
||||
if (result is null)
|
||||
result = await _chatService.RegisterUserAsync(username, password);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
_logger.LogWarning("SASL auth failed for user '{Username}' (connection {Id})",
|
||||
_logger.LogWarning("SASL auth/register failed for user '{Username}' (connection {Id})",
|
||||
username, _conn.ConnectionId);
|
||||
await _conn.SendNumericAsync(ServerName, IrcNumericReply.ERR_SASLFAIL,
|
||||
":SASL authentication failed");
|
||||
@@ -286,10 +290,14 @@ public sealed class IrcCommandHandler
|
||||
|
||||
var result = await _chatService.AuthenticateUserAsync(_conn.Nickname!, _conn.Password);
|
||||
|
||||
// Auth failed — try registering a new account
|
||||
if (result is null)
|
||||
result = await _chatService.RegisterUserAsync(_conn.Nickname!, _conn.Password);
|
||||
|
||||
if (result is null)
|
||||
{
|
||||
await _conn.SendNumericAsync(ServerName, IrcNumericReply.ERR_PASSWDMISMATCH,
|
||||
":Password incorrect or account not found. Register via the EchoHub client first.");
|
||||
":Password incorrect.");
|
||||
await _conn.SendAsync("ERROR :Authentication failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -339,6 +339,38 @@ public class ChatService : IChatService
|
||||
return (user.Id, user.Username);
|
||||
}
|
||||
|
||||
public async Task<(Guid UserId, string Username)?> RegisterUserAsync(string username, string password)
|
||||
{
|
||||
username = username.ToLowerInvariant().Trim();
|
||||
|
||||
if (!ValidationConstants.UsernameRegex().IsMatch(username))
|
||||
return null;
|
||||
|
||||
if (password.Length < 6 || password.Length > ValidationConstants.MaxPasswordLength)
|
||||
return null;
|
||||
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<EchoHubDbContext>();
|
||||
|
||||
if (await db.Users.AnyAsync(u => u.Username == username))
|
||||
return null;
|
||||
|
||||
var isFirstUser = !await db.Users.AnyAsync();
|
||||
|
||||
var user = new User
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Username = username,
|
||||
PasswordHash = BCrypt.Net.BCrypt.HashPassword(password),
|
||||
Role = isFirstUser ? ServerRole.Owner : ServerRole.Member,
|
||||
};
|
||||
|
||||
db.Users.Add(user);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return (user.Id, user.Username);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collapse consecutive newlines and cap total line count to prevent newline spam.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user