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.
129 lines
4.2 KiB
C#
129 lines
4.2 KiB
C#
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" });
|
|
}
|
|
}
|