Commit MWS backend source tree

The ASP.NET Core solution (mws.api/mws.application/mws.domain/
mws.infrastructure) existed only as untracked working files. Adding
it to version control, plus a .gitignore for build output and local
tooling directories, so the CQRS/mediator refactor plan has a real
git history to branch and diff against.
This commit is contained in:
2026-08-13 23:10:22 +07:00
parent 96944ad2c3
commit f72aaa2329
94 changed files with 7758 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
using AutoMapper;
using Mws.Application.Common;
namespace Mws.Application.Auth;
public interface IAuthService
{
Task<LoginResponse> LoginAsync(LoginRequest request, CancellationToken cancellationToken = default);
}
public class AuthService(IUnitOfWork uow, IPasswordHasher passwordHasher, ITokenService tokenService, IMapper mapper)
: IAuthService
{
public async Task<LoginResponse> LoginAsync(LoginRequest request, CancellationToken cancellationToken = default)
{
var username = request.Username.Trim();
var user = await uow.Users.GetByUsernameWithRoleAsync(username, cancellationToken);
if (user is null || !passwordHasher.Verify(request.Password, user.PasswordHash))
{
throw new UnauthorizedException("Invalid username or password");
}
if (!user.IsActive)
{
throw new ForbiddenException("Account disabled");
}
return new LoginResponse
{
Token = tokenService.CreateToken(user.Id, user.Username),
User = mapper.Map<UserDto>(user),
};
}
}
+33
View File
@@ -0,0 +1,33 @@
namespace Mws.Application.Auth;
public class LoginRequest
{
public string Username { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
}
public class UserDto
{
public Guid Id { get; set; }
public string Username { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty;
public Guid RoleId { get; set; }
public string RoleName { get; set; } = string.Empty;
}
public class LoginResponse
{
public string Token { get; set; } = string.Empty;
public UserDto User { get; set; } = null!;
}
public interface IPasswordHasher
{
string Hash(string password);
bool Verify(string password, string hash);
}
public interface ITokenService
{
string CreateToken(Guid userId, string username);
}