Add versioned legal consent to authentication
This commit is contained in:
@@ -21,13 +21,18 @@ public class AuthController : ControllerBase
|
||||
private readonly BlacklistService _blacklist;
|
||||
private readonly IHttpClientFactory _httpClients;
|
||||
private readonly JwtTokenService _tokens;
|
||||
private readonly LegalPolicy _legal;
|
||||
|
||||
public AuthController(UserService users, IConfiguration cfg, BlacklistService blacklist,
|
||||
IHttpClientFactory httpClients, JwtTokenService tokens)
|
||||
IHttpClientFactory httpClients, JwtTokenService tokens, LegalPolicy legal)
|
||||
{
|
||||
_users = users; _cfg = cfg; _blacklist = blacklist; _httpClients = httpClients; _tokens = tokens;
|
||||
_users = users; _cfg = cfg; _blacklist = blacklist; _httpClients = httpClients; _tokens = tokens; _legal = legal;
|
||||
}
|
||||
|
||||
[HttpGet("legal")]
|
||||
[AllowAnonymous]
|
||||
public IActionResult Legal() => Ok(_legal.Status());
|
||||
|
||||
[HttpPost("register")]
|
||||
public async Task<IActionResult> Register([FromBody] RegisterRequest req)
|
||||
{
|
||||
@@ -35,6 +40,9 @@ public class AuthController : ControllerBase
|
||||
var password = req.Password ?? "";
|
||||
var email = req.Email?.Trim() ?? "";
|
||||
|
||||
if (!req.AcceptLegal)
|
||||
return BadRequest("You must agree to the Terms of Service and acknowledge the Privacy Policy");
|
||||
|
||||
if (!Regex.IsMatch(username, "^[A-Za-z0-9_]{3,24}$"))
|
||||
return BadRequest("Username must be 3-24 characters using only letters, numbers, or underscores");
|
||||
if (password.Length < 8)
|
||||
@@ -48,6 +56,7 @@ public class AuthController : ControllerBase
|
||||
|
||||
var hash = BCrypt.Net.BCrypt.HashPassword(password);
|
||||
var user = new User { Username = username, PasswordHash = hash, Role = "USER", Email = email, CreatedUtc = DateTime.UtcNow };
|
||||
_legal.Accept(user, "password_registration");
|
||||
try
|
||||
{
|
||||
await _users.CreateAsync(user);
|
||||
@@ -72,7 +81,7 @@ public class AuthController : ControllerBase
|
||||
user.RefreshTokenExpiry = DateTime.UtcNow.AddDays(7);
|
||||
await _users.UpdateAsync(user);
|
||||
|
||||
return Ok(new { accessToken, refreshToken = user.RefreshToken, user.Username, user.Role, jti, exp = expUtc });
|
||||
return Ok(SessionResponse(user, accessToken, expUtc, jti, user.RefreshToken));
|
||||
}
|
||||
|
||||
[HttpPost("refresh")]
|
||||
@@ -83,7 +92,7 @@ public class AuthController : ControllerBase
|
||||
return Unauthorized("Invalid or expired refresh token");
|
||||
|
||||
var (accessToken, _, expUtc) = _tokens.Generate(user);
|
||||
return Ok(new { accessToken, exp = expUtc });
|
||||
return Ok(SessionResponse(user, accessToken, expUtc));
|
||||
}
|
||||
|
||||
[HttpPost("logout")]
|
||||
@@ -105,6 +114,18 @@ public class AuthController : ControllerBase
|
||||
return user is null ? Unauthorized() : Ok(ProfileResponse(user));
|
||||
}
|
||||
|
||||
[HttpPost("legal/accept")]
|
||||
[Authorize(Roles = "USER,SUPER")]
|
||||
public async Task<IActionResult> AcceptLegal([FromBody] AcceptLegalRequest req)
|
||||
{
|
||||
if (!req.Accept) return BadRequest("Legal acceptance is required.");
|
||||
var user = await CurrentUserAsync();
|
||||
if (user is null) return Unauthorized();
|
||||
_legal.Accept(user, "existing_user_prompt");
|
||||
await _users.UpdateAsync(user);
|
||||
return Ok(_legal.Status(user));
|
||||
}
|
||||
|
||||
[HttpPatch("me")]
|
||||
[Authorize(Roles = "USER,SUPER")]
|
||||
public async Task<IActionResult> UpdateProfile([FromBody] UpdateProfileRequest req)
|
||||
@@ -204,14 +225,27 @@ public class AuthController : ControllerBase
|
||||
return ObjectId.TryParse(user.Id, out var id) ? id.CreationTime : DateTime.UtcNow;
|
||||
}
|
||||
|
||||
private static object ProfileResponse(User user) => new
|
||||
private object ProfileResponse(User user) => new
|
||||
{
|
||||
userId = user.Id,
|
||||
user.Username,
|
||||
user.DisplayName,
|
||||
user.Email,
|
||||
user.Role,
|
||||
createdUtc = user.CreatedUtc ?? CreationDate(user)
|
||||
createdUtc = user.CreatedUtc ?? CreationDate(user),
|
||||
legal = _legal.Status(user)
|
||||
};
|
||||
|
||||
private object SessionResponse(User user, string accessToken, DateTime expUtc,
|
||||
string? jti = null, string? refreshToken = null) => new
|
||||
{
|
||||
accessToken,
|
||||
refreshToken,
|
||||
user.Username,
|
||||
user.Role,
|
||||
jti,
|
||||
exp = expUtc,
|
||||
legal = _legal.Status(user)
|
||||
};
|
||||
|
||||
private async Task RevokeCurrentTokenAsync()
|
||||
|
||||
@@ -19,10 +19,11 @@ public class SteamAuthController : ControllerBase
|
||||
private readonly JwtTokenService _tokens;
|
||||
private readonly IConfiguration _cfg;
|
||||
private readonly ILogger<SteamAuthController> _logger;
|
||||
private readonly LegalPolicy _legal;
|
||||
|
||||
public SteamAuthController(UserService users, SteamAuthTransactionService transactions,
|
||||
SteamOpenIdService openId, JwtTokenService tokens, IConfiguration cfg,
|
||||
ILogger<SteamAuthController> logger)
|
||||
ILogger<SteamAuthController> logger, LegalPolicy legal)
|
||||
{
|
||||
_users = users;
|
||||
_transactions = transactions;
|
||||
@@ -30,6 +31,7 @@ public class SteamAuthController : ControllerBase
|
||||
_tokens = tokens;
|
||||
_cfg = cfg;
|
||||
_logger = logger;
|
||||
_legal = legal;
|
||||
}
|
||||
|
||||
[HttpPost("start")]
|
||||
@@ -115,7 +117,8 @@ public class SteamAuthController : ControllerBase
|
||||
user.Username,
|
||||
user.Role,
|
||||
jti,
|
||||
exp
|
||||
exp,
|
||||
legal = _legal.Status(user)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -133,6 +136,8 @@ public class SteamAuthController : ControllerBase
|
||||
var createdUser = false;
|
||||
if (request.Action == "create")
|
||||
{
|
||||
if (!request.AcceptLegal)
|
||||
return BadRequest(new { message = "You must agree to the Terms of Service and acknowledge the Privacy Policy." });
|
||||
var validation = ValidateNewAccount(request);
|
||||
if (validation is not null)
|
||||
return BadRequest(new { message = validation });
|
||||
@@ -149,6 +154,7 @@ public class SteamAuthController : ControllerBase
|
||||
RefreshToken = NewRefreshToken(),
|
||||
RefreshTokenExpiry = DateTime.UtcNow.AddDays(7)
|
||||
};
|
||||
_legal.Accept(user, "steam_registration");
|
||||
try
|
||||
{
|
||||
await _users.CreateAsync(user);
|
||||
|
||||
Reference in New Issue
Block a user