using Microsoft.AspNetCore.Mvc; using Microsoft.Data.SqlClient; using Hasher; using System.Linq; using Models; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; using System.Security.Cryptography; namespace backend.Controllers { [Route("api/login")] [ApiController] public class Login : ControllerBase { private readonly IConfiguration _config; public Login(IConfiguration config) { _config = config; } [HttpPost] public void ProcessLogin([FromBody] dynamic requestBody) { string email = requestBody.username; string password = requestBody.password; string clientPublicKey = requestBody.client_verification_key; // Try to get a name from the database using (var db = new MyDbContext()) { User user = db.Users.FirstOrDefault(u => u.Email.ToLower() == email.ToLower()); if (user != null) { int userId = user.UserId; string passwordHash = user.PasswordHash; // Check the hash if (Argon2dHasher.VerifyArgon2Hash(password, passwordHash)) { // Get the user authorizations List auths = db.Auths.Where((auth) => auth.UserId == userId).ToList(); // Generate a random string for fingerprinting var fingerprint = GenerateRandomString(32); //Create a JWT // Claims: [userId, clientPublicKey, auths] var claims = new[] { // Add the user ID as a subject claim new Claim(JwtRegisteredClaimNames.Sub, userId.ToString()), // Add the client public key as a custom claim new Claim("ClientPublicKey", clientPublicKey) // Add the fingerprint as a hashed custom claim new Claim("Fingerprint", HashFingerprint(fingerprint)) }; // Add the user authorizations as custom claims foreach (var auth in auths) { claims.Append(new Claim("Auth", auth.AuthId.ToString())); } } } else { //TODO Handle case where no user was found with the given email } } } // Helper function to generate a random string public static string GetRandomString(int length) { var r = new Random(); return new String(Enumerable.Range(0, length).Select(n => (Char)(r.Next(32, 127))).ToArray()); } // Helper function to hash the fingerprint using SHA-256 private string HashFingerprint(string fingerprint) { using var sha256 = SHA256.Create(); var hashedFingerprint = sha256.ComputeHash(Encoding.UTF8.GetBytes(fingerprint)); return Convert.ToBase64String(hashedFingerprint); } } }