Add Login Module

This commit is contained in:
Thanakarn Klangkasame
2025-10-02 11:18:44 +07:00
parent f505e31cfd
commit 563a341a99
52 changed files with 1127 additions and 2036 deletions

View File

@@ -4,9 +4,11 @@ using AMREZ.EOP.Contracts.DTOs.Authentications.AddEmailIdentity;
using AMREZ.EOP.Contracts.DTOs.Authentications.ChangePassword;
using AMREZ.EOP.Contracts.DTOs.Authentications.DisableMfa;
using AMREZ.EOP.Contracts.DTOs.Authentications.EnableTotp;
using AMREZ.EOP.Contracts.DTOs.Authentications.IssueTokenPair;
using AMREZ.EOP.Contracts.DTOs.Authentications.Login;
using AMREZ.EOP.Contracts.DTOs.Authentications.Logout;
using AMREZ.EOP.Contracts.DTOs.Authentications.LogoutAll;
using AMREZ.EOP.Contracts.DTOs.Authentications.Refresh;
using AMREZ.EOP.Contracts.DTOs.Authentications.Register;
using AMREZ.EOP.Contracts.DTOs.Authentications.VerifyEmail;
using AMREZ.EOP.Domain.Shared.Contracts;
@@ -32,14 +34,33 @@ public class AuthenticationController : ControllerBase
private readonly ILogoutUseCase _logout;
private readonly ILogoutAllUseCase _logoutAll;
private readonly IIssueTokenPairUseCase _issueTokens;
private readonly IRefreshUseCase _refresh;
public AuthenticationController(
ILoginUseCase login,
IRegisterUseCase register,
IChangePasswordUseCase changePassword)
IChangePasswordUseCase changePassword,
IAddEmailIdentityUseCase addEmail,
IVerifyEmailUseCase verifyEmail,
IEnableTotpUseCase enableTotp,
IDisableMfaUseCase disableMfa,
ILogoutUseCase logout,
ILogoutAllUseCase logoutAll,
IIssueTokenPairUseCase issueTokens,
IRefreshUseCase refresh)
{
_login = login;
_register = register;
_changePassword = changePassword;
_addEmail = addEmail;
_verifyEmail = verifyEmail;
_enableTotp = enableTotp;
_disableMfa = disableMfa;
_logout = logout;
_logoutAll = logoutAll;
_issueTokens = issueTokens;
_refresh = refresh;
}
[HttpPost("login")]
@@ -51,7 +72,7 @@ public class AuthenticationController : ControllerBase
var claims = new List<Claim>
{
new(ClaimTypes.NameIdentifier, res.UserId.ToString()),
new(ClaimTypes.Name, string.IsNullOrWhiteSpace(res.DisplayName) ? res.Email : res.DisplayName),
new(ClaimTypes.Name, res.Email),
new(ClaimTypes.Email, res.Email),
new("tenant", res.TenantId)
};
@@ -59,9 +80,71 @@ public class AuthenticationController : ControllerBase
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, AuthPolicies.Scheme));
await HttpContext.SignInAsync(AuthPolicies.Scheme, principal);
return Ok(res);
var tokenPair = await _issueTokens.ExecuteAsync(new IssueTokenPairRequest()
{
UserId = res.UserId,
Tenant = res.TenantId,
Email = res.Email
}, ct);
if (!string.IsNullOrWhiteSpace(tokenPair.RefreshToken))
{
Response.Cookies.Append(
"refresh_token",
tokenPair.RefreshToken!,
new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Expires = tokenPair.RefreshExpiresAt?.UtcDateTime
});
}
return Ok(new
{
user = res,
access_token = tokenPair.AccessToken,
token_type = "Bearer",
expires_at = tokenPair.AccessExpiresAt
});
}
[HttpPost("refresh")]
public async Task<IActionResult> Refresh([FromBody] RefreshRequest body, CancellationToken ct)
{
var raw = string.IsNullOrWhiteSpace(body.RefreshToken)
? Request.Cookies["refresh_token"]
: body.RefreshToken;
if (string.IsNullOrWhiteSpace(raw))
return Unauthorized(new { message = "Missing refresh token" });
var res = await _refresh.ExecuteAsync(body, ct);
if (res is null) return Unauthorized(new { message = "Invalid/expired refresh token" });
if (!string.IsNullOrWhiteSpace(res.RefreshToken))
{
Response.Cookies.Append(
"refresh_token",
res.RefreshToken!,
new CookieOptions
{
HttpOnly = true,
Secure = true,
SameSite = SameSiteMode.Strict,
Expires = res.RefreshExpiresAt?.UtcDateTime
});
}
return Ok(new
{
access_token = res.AccessToken,
token_type = "Bearer",
expires_at = res.AccessExpiresAt
});
}
[HttpPost("register")]
public async Task<IActionResult> Register([FromBody] RegisterRequest body, CancellationToken ct)
{