feat: Refactor authentication and token management

- Updated EchoHubConnection to use ApiClient for token retrieval.
- Introduced ValidationConstants for common validation patterns and limits.
- Enhanced AuthDtos with refresh token support and expiration details.
- Added new ChatDtos for channel creation and topic updates.
- Created CommonDtos for error and paginated responses.
- Implemented RefreshToken model for managing refresh tokens.
- Modified JwtTokenService to generate and hash refresh tokens.
- Updated AuthController to handle registration, login, token refresh, and logout with improved error handling.
- Enhanced ChannelsController with channel creation, topic updates, and pagination for channel retrieval.
- Added FilesController for file management with rate limiting.
- Improved UsersController for profile updates and avatar uploads with validation.
- Integrated rate limiting across controllers to manage request load.
- Introduced FileValidationHelper for validating uploaded image files.
- Updated database context to include RefreshToken and enforce unique constraints.
- Enhanced ChatHub for improved channel and message handling with validation.
- Updated Program.cs to configure rate limiting and CORS policies.
This commit is contained in:
HueByte
2026-02-19 03:25:01 +01:00
parent ed1bf13302
commit 287270b26d
18 changed files with 669 additions and 96 deletions
@@ -0,0 +1,26 @@
using System.Text.RegularExpressions;
namespace EchoHub.Core.Constants;
public static partial class ValidationConstants
{
public const string UsernamePattern = @"^[a-zA-Z0-9_-]{3,50}$";
public const string ChannelNamePattern = @"^[a-zA-Z0-9_-]{2,100}$";
public const string HexColorPattern = @"^#[0-9a-fA-F]{6}$";
public const int MaxPasswordLength = 128;
public const int MaxDisplayNameLength = 100;
public const int MaxBioLength = 500;
public const int MaxStatusMessageLength = 100;
public const int MaxChannelTopicLength = 500;
public const int MaxHistoryCount = 100;
[GeneratedRegex(UsernamePattern)]
public static partial Regex UsernameRegex();
[GeneratedRegex(ChannelNamePattern)]
public static partial Regex ChannelNameRegex();
[GeneratedRegex(HexColorPattern)]
public static partial Regex HexColorRegex();
}
+9 -1
View File
@@ -4,4 +4,12 @@ public record RegisterRequest(string Username, string Password, string? DisplayN
public record LoginRequest(string Username, string Password);
public record LoginResponse(string Token, string Username, string? DisplayName, string? NicknameColor);
public record LoginResponse(
string Token,
string RefreshToken,
DateTimeOffset ExpiresAt,
string Username,
string? DisplayName,
string? NicknameColor);
public record RefreshRequest(string RefreshToken);
+4
View File
@@ -29,3 +29,7 @@ public record UserDto(
DateTimeOffset LastSeenAt);
public record SendMessageRequest(string ChannelName, string Content);
public record CreateChannelRequest(string Name, string? Topic = null);
public record UpdateTopicRequest(string? Topic);
+5
View File
@@ -0,0 +1,5 @@
namespace EchoHub.Core.DTOs;
public record ErrorResponse(string Error, string? Detail = null);
public record PaginatedResponse<T>(List<T> Items, int Total, int Offset, int Limit);
+2
View File
@@ -29,3 +29,5 @@ public record UserPresenceDto(
string? NicknameColor,
UserStatus Status,
string? StatusMessage);
public record AvatarUploadResponse(string AvatarAscii);
+17
View File
@@ -0,0 +1,17 @@
namespace EchoHub.Core.Models;
public class RefreshToken
{
public Guid Id { get; set; }
public required string TokenHash { get; set; }
public Guid UserId { get; set; }
public DateTimeOffset ExpiresAt { get; set; }
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? RevokedAt { get; set; }
public bool IsExpired => DateTimeOffset.UtcNow >= ExpiresAt;
public bool IsRevoked => RevokedAt is not null;
public bool IsActive => !IsExpired && !IsRevoked;
public User? User { get; set; }
}