Refactor authentication payloads and services for registration and login processes

This commit is contained in:
Aaron Po
2026-02-16 00:02:07 -05:00
parent f4a76a365b
commit 86fa272c84
7 changed files with 77 additions and 29 deletions

View File

@@ -3,9 +3,17 @@ using Org.BouncyCastle.Asn1.Cms;
namespace API.Core.Contracts.Auth; namespace API.Core.Contracts.Auth;
public record AuthPayload( public record LoginPayload(
Guid UserAccountId, Guid UserAccountId,
string Username, string Username,
string RefreshToken, string RefreshToken,
string AccessToken string AccessToken
); );
public record RegistrationPayload(
Guid UserAccountId,
string Username,
string RefreshToken,
string AccessToken,
bool ConfirmationEmailSent
);

View File

@@ -16,7 +16,7 @@ namespace API.Core.Controllers
[FromBody] RegisterRequest req [FromBody] RegisterRequest req
) )
{ {
AuthServiceReturn rtn = await register.RegisterAsync( var rtn = await register.RegisterAsync(
new UserAccount new UserAccount
{ {
UserAccountId = Guid.Empty, UserAccountId = Guid.Empty,
@@ -29,15 +29,12 @@ namespace API.Core.Controllers
req.Password req.Password
); );
var response = new ResponseBody<AuthPayload> var response = new ResponseBody<RegistrationPayload>
{ {
Message = "User registered successfully.", Message = "User registered successfully.",
Payload = new AuthPayload( Payload = new RegistrationPayload(rtn.UserAccount.UserAccountId, rtn.UserAccount.Username,
rtn.UserAccount.UserAccountId,
rtn.UserAccount.Username,
rtn.RefreshToken, rtn.RefreshToken,
rtn.AccessToken rtn.AccessToken, rtn.EmailSent),
),
}; };
return Created("/", response); return Created("/", response);
} }
@@ -48,10 +45,10 @@ namespace API.Core.Controllers
var rtn = await login.LoginAsync(req.Username, req.Password); var rtn = await login.LoginAsync(req.Username, req.Password);
return Ok( return Ok(
new ResponseBody<AuthPayload> new ResponseBody<LoginPayload>
{ {
Message = "Logged in successfully.", Message = "Logged in successfully.",
Payload = new AuthPayload( Payload = new LoginPayload(
rtn.UserAccount.UserAccountId, rtn.UserAccount.UserAccountId,
rtn.UserAccount.Username, rtn.UserAccount.Username,
rtn.RefreshToken, rtn.RefreshToken,

View File

@@ -7,6 +7,7 @@ using Moq;
namespace Service.Auth.Tests; namespace Service.Auth.Tests;
public class LoginServiceTest public class LoginServiceTest
{ {
private readonly Mock<IAuthRepository> _authRepoMock; private readonly Mock<IAuthRepository> _authRepoMock;

View File

@@ -4,5 +4,5 @@ namespace Service.Auth;
public interface ILoginService public interface ILoginService
{ {
Task<AuthServiceReturn> LoginAsync(string username, string password); Task<LoginServiceReturn> LoginAsync(string username, string password);
} }

View File

@@ -2,15 +2,33 @@ using Domain.Entities;
namespace Service.Auth; namespace Service.Auth;
public record AuthServiceReturn( public record RegisterServiceReturn
UserAccount UserAccount, {
string RefreshToken, public bool IsAuthenticated { get; init; }
string AccessToken public bool EmailSent { get; init; }
); public UserAccount UserAccount { get; init; }
public string AccessToken { get; init; } = string.Empty;
public string RefreshToken { get; init; } = string.Empty;
public RegisterServiceReturn(UserAccount userAccount, string accessToken, string refreshToken, bool emailSent)
{
IsAuthenticated = true;
UserAccount = userAccount;
AccessToken = accessToken;
RefreshToken = refreshToken;
EmailSent = true;
}
public RegisterServiceReturn(UserAccount userAccount)
{
IsAuthenticated = false;
UserAccount = userAccount;
}
}
public interface IRegisterService public interface IRegisterService
{ {
Task<AuthServiceReturn> RegisterAsync( Task<RegisterServiceReturn> RegisterAsync(
UserAccount userAccount, UserAccount userAccount,
string password string password
); );

View File

@@ -5,13 +5,19 @@ using Infrastructure.Repository.Auth;
namespace Service.Auth; namespace Service.Auth;
public record LoginServiceReturn(
UserAccount UserAccount,
string RefreshToken,
string AccessToken
);
public class LoginService( public class LoginService(
IAuthRepository authRepo, IAuthRepository authRepo,
IPasswordInfrastructure passwordInfrastructure, IPasswordInfrastructure passwordInfrastructure,
ITokenService tokenService ITokenService tokenService
) : ILoginService ) : ILoginService
{ {
public async Task<AuthServiceReturn> LoginAsync( public async Task<LoginServiceReturn> LoginAsync(
string username, string username,
string password string password
) )
@@ -35,6 +41,6 @@ public class LoginService(
string accessToken = tokenService.GenerateAccessToken(user); string accessToken = tokenService.GenerateAccessToken(user);
string refreshToken = tokenService.GenerateRefreshToken(user); string refreshToken = tokenService.GenerateRefreshToken(user);
return new AuthServiceReturn(user, refreshToken, accessToken); return new LoginServiceReturn(user, refreshToken, accessToken);
} }
} }

View File

@@ -4,6 +4,7 @@ using Infrastructure.Email;
using Infrastructure.Email.Templates.Rendering; using Infrastructure.Email.Templates.Rendering;
using Infrastructure.PasswordHashing; using Infrastructure.PasswordHashing;
using Infrastructure.Repository.Auth; using Infrastructure.Repository.Auth;
using Microsoft.Extensions.Logging;
using Service.Emails; using Service.Emails;
namespace Service.Auth; namespace Service.Auth;
@@ -31,7 +32,7 @@ public class RegisterService(
} }
} }
public async Task<AuthServiceReturn> RegisterAsync( public async Task<RegisterServiceReturn> RegisterAsync(
UserAccount userAccount, UserAccount userAccount,
string password string password
) )
@@ -53,12 +54,29 @@ public class RegisterService(
var accessToken = tokenService.GenerateAccessToken(createdUser); var accessToken = tokenService.GenerateAccessToken(createdUser);
var refreshToken = tokenService.GenerateRefreshToken(createdUser); var refreshToken = tokenService.GenerateRefreshToken(createdUser);
if (string.IsNullOrEmpty(accessToken) || string.IsNullOrEmpty(refreshToken))
{
return new RegisterServiceReturn(createdUser);
}
bool emailSent = false;
try
{
// send confirmation email // send confirmation email
await emailService.SendRegistrationEmailAsync( await emailService.SendRegistrationEmailAsync(
createdUser, createdUser,
"some-confirmation-token" "some-confirmation-token"
); );
return new AuthServiceReturn(createdUser, refreshToken, accessToken); emailSent = true;
}
catch
{
// ignored
}
return new RegisterServiceReturn(createdUser, accessToken, refreshToken, emailSent);
} }
} }