Files
rr3-server/RR3CommunityServer/Models/AccountModels.cs
Daniel Elliott a6bab92282 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.
2026-02-19 15:00:16 -08:00

114 lines
3.5 KiB
C#

using RR3CommunityServer.Data;
namespace RR3CommunityServer.Models;
// Account entity with authentication
public class Account
{
public int Id { get; set; }
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string PasswordHash { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime? LastLoginAt { get; set; }
public bool IsActive { get; set; } = true;
public bool EmailVerified { get; set; } = false;
public string? EmailVerificationToken { get; set; }
public string? PasswordResetToken { get; set; }
public DateTime? PasswordResetExpiry { get; set; }
// Link to game user data
public int? UserId { get; set; }
public User? User { get; set; }
// Multiple devices can be linked to one account
public List<DeviceAccount> LinkedDevices { get; set; } = new();
}
// Join table for account-device relationship
public class DeviceAccount
{
public int Id { get; set; }
public int AccountId { get; set; }
public Account Account { get; set; } = null!;
public string DeviceId { get; set; } = string.Empty;
public string? DeviceName { get; set; }
public DateTime LinkedAt { get; set; } = DateTime.UtcNow;
public DateTime LastUsedAt { get; set; } = DateTime.UtcNow;
}
// Request/Response DTOs for authentication
public class RegisterRequest
{
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string ConfirmPassword { get; set; } = string.Empty;
}
public class LoginRequest
{
public string UsernameOrEmail { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string? DeviceId { get; set; }
}
public class LoginResponse
{
public string Token { get; set; } = string.Empty;
public int AccountId { get; set; }
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public DateTime ExpiresAt { get; set; }
}
public class ChangePasswordRequest
{
public string CurrentPassword { get; set; } = string.Empty;
public string NewPassword { get; set; } = string.Empty;
public string ConfirmPassword { get; set; } = string.Empty;
}
public class ForgotPasswordRequest
{
public string Email { get; set; } = string.Empty;
}
public class ResetPasswordRequest
{
public string Token { get; set; } = string.Empty;
public string NewPassword { get; set; } = string.Empty;
public string ConfirmPassword { get; set; } = string.Empty;
}
public class LinkDeviceRequest
{
public string DeviceId { get; set; } = string.Empty;
public string? DeviceName { get; set; }
}
public class AccountSettingsResponse
{
public int AccountId { get; set; }
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public bool EmailVerified { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? LastLoginAt { get; set; }
public List<LinkedDeviceInfo> LinkedDevices { get; set; } = new();
// Game progress
public int? Gold { get; set; }
public int? Cash { get; set; }
public int? Level { get; set; }
public int? CarsOwned { get; set; }
}
public class LinkedDeviceInfo
{
public string DeviceId { get; set; } = string.Empty;
public string? DeviceName { get; set; }
public DateTime LinkedAt { get; set; }
public DateTime LastUsedAt { get; set; }
}