Add user authentication and account management system
Features:
- User registration with username, email, password
- Login with JWT token authentication
- Password hashing with BCrypt
- Account settings & management
- Device linking to accounts
- Change password & password reset
- Account-User relationship (1-to-1 with game data)
Database entities:
- Account: User accounts with credentials
- DeviceAccount: Link devices to accounts (many-to-many)
API endpoints:
- POST /api/auth/register
- POST /api/auth/login
- POST /api/auth/change-password
- POST /api/auth/forgot-password
- POST /api/auth/reset-password
- GET /api/auth/me
- POST /api/auth/link-device
- DELETE /api/auth/unlink-device/{deviceId}
Starting resources for new accounts:
- 100,000 Gold
- 500,000 Cash
- Level 1
Ready for VPS deployment with HTTPS.
This commit is contained in:
128
RR3CommunityServer/Controllers/AuthController.cs
Normal file
128
RR3CommunityServer/Controllers/AuthController.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using RR3CommunityServer.Models;
|
||||
using RR3CommunityServer.Services;
|
||||
|
||||
namespace RR3CommunityServer.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class AuthController : ControllerBase
|
||||
{
|
||||
private readonly IAuthService _authService;
|
||||
private readonly ILogger<AuthController> _logger;
|
||||
|
||||
public AuthController(IAuthService authService, ILogger<AuthController> logger)
|
||||
{
|
||||
_authService = authService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost("register")]
|
||||
public async Task<ActionResult> Register([FromBody] RegisterRequest request)
|
||||
{
|
||||
var (success, token, error) = await _authService.RegisterAsync(request);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Account created successfully", token });
|
||||
}
|
||||
|
||||
[HttpPost("login")]
|
||||
public async Task<ActionResult> Login([FromBody] LoginRequest request)
|
||||
{
|
||||
var (success, response, error) = await _authService.LoginAsync(request);
|
||||
|
||||
if (!success)
|
||||
return Unauthorized(new { message = error });
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("change-password")]
|
||||
public async Task<ActionResult> ChangePassword([FromBody] ChangePasswordRequest request)
|
||||
{
|
||||
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
||||
var account = await _authService.ValidateTokenAsync(token);
|
||||
|
||||
if (account == null)
|
||||
return Unauthorized(new { message = "Invalid or expired token" });
|
||||
|
||||
var (success, error) = await _authService.ChangePasswordAsync(account.Id, request);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Password changed successfully" });
|
||||
}
|
||||
|
||||
[HttpPost("forgot-password")]
|
||||
public async Task<ActionResult> ForgotPassword([FromBody] ForgotPasswordRequest request)
|
||||
{
|
||||
var (success, error) = await _authService.ForgotPasswordAsync(request);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Password reset instructions sent to your email" });
|
||||
}
|
||||
|
||||
[HttpPost("reset-password")]
|
||||
public async Task<ActionResult> ResetPassword([FromBody] ResetPasswordRequest request)
|
||||
{
|
||||
var (success, error) = await _authService.ResetPasswordAsync(request);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Password reset successfully" });
|
||||
}
|
||||
|
||||
[HttpGet("me")]
|
||||
public async Task<ActionResult> GetCurrentUser()
|
||||
{
|
||||
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
||||
var account = await _authService.ValidateTokenAsync(token);
|
||||
|
||||
if (account == null)
|
||||
return Unauthorized(new { message = "Invalid or expired token" });
|
||||
|
||||
var settings = await _authService.GetAccountSettingsAsync(account.Id);
|
||||
|
||||
return Ok(settings);
|
||||
}
|
||||
|
||||
[HttpPost("link-device")]
|
||||
public async Task<ActionResult> LinkDevice([FromBody] LinkDeviceRequest request)
|
||||
{
|
||||
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
||||
var account = await _authService.ValidateTokenAsync(token);
|
||||
|
||||
if (account == null)
|
||||
return Unauthorized(new { message = "Invalid or expired token" });
|
||||
|
||||
var (success, error) = await _authService.LinkDeviceAsync(account.Id, request);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Device linked successfully" });
|
||||
}
|
||||
|
||||
[HttpDelete("unlink-device/{deviceId}")]
|
||||
public async Task<ActionResult> UnlinkDevice(string deviceId)
|
||||
{
|
||||
var token = Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
||||
var account = await _authService.ValidateTokenAsync(token);
|
||||
|
||||
if (account == null)
|
||||
return Unauthorized(new { message = "Invalid or expired token" });
|
||||
|
||||
var (success, error) = await _authService.UnlinkDeviceAsync(account.Id, deviceId);
|
||||
|
||||
if (!success)
|
||||
return BadRequest(new { message = error });
|
||||
|
||||
return Ok(new { message = "Device unlinked successfully" });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user