diff --git a/RelayCore/Endpoints/AuthEndpoints.cs b/RelayCore/Endpoints/AuthEndpoints.cs index 6e35234..0be2123 100644 --- a/RelayCore/Endpoints/AuthEndpoints.cs +++ b/RelayCore/Endpoints/AuthEndpoints.cs @@ -1,4 +1,5 @@ -using RelayCore.Services; +using Microsoft.Extensions.Primitives; +using RelayCore.Services; namespace RelayCore.Endpoints; @@ -8,19 +9,29 @@ public static class AuthEndpoints { app.MapPost("/user/signin", async (AuthSignin request, APIAuthService service, HttpContext context) => { - var ip = context.Connection.RemoteIpAddress?.MapToIPv4().ToString(); + string ip = ""; + StringValues userAgent = ""; + if (context != null) + { + ip = context.Connection.RemoteIpAddress?.MapToIPv4().ToString(); + context.Request.Headers.TryGetValue("User-Agent", out userAgent); + } + + var token = await service.UserSigninAsync(request, ip, userAgent.ToString()); + + return token != null ? Results.Ok(token) : Results.Unauthorized(); + }); + app.MapGet("/users", async (APIAuthService service) => + { + return Results.Ok(service.GetUsersAsync()); + }); + app.MapPost("/user/register", async (AuthRegister request, APIAuthService service, HttpContext context) => + { + var ip = context.Connection.RemoteIpAddress?.MapToIPv4().ToString(); context.Request.Headers.TryGetValue("User-Agent", out var userAgent); - Console.WriteLine($"IP:{ip}\nUserAgent:{userAgent}"); - // var token = await service.UserSigninAsync(request, ip, userAgent); - - // return token != null ? Results.Ok(token) : Results.Unauthorized(); - return Results.Ok(); - }); - app.MapPost("/user/register", async (AuthRegister request, APIAuthService service) => - { - var token = await service.UserRegisterAsync(request); - return token != null ? Results.Ok(token) : Results.Unauthorized(); + var token = await service.UserRegisterAsync(request, ip, userAgent); + return token != null ? Results.Ok(token) : Results.Ok("Username or Email already exists!"); }); app.MapPost("/server/verify/user", async (AuthUserVerify request, APIAuthService service) => { diff --git a/RelayCore/Models/Users.cs b/RelayCore/Models/Users.cs index 893b6e3..dd8312f 100644 --- a/RelayCore/Models/Users.cs +++ b/RelayCore/Models/Users.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Serialization; using SurrealDb.Net.Models; namespace RelayCore.Models; diff --git a/RelayCore/Services/APIAuthService.cs b/RelayCore/Services/APIAuthService.cs index e271ff5..8bcf2ed 100644 --- a/RelayCore/Services/APIAuthService.cs +++ b/RelayCore/Services/APIAuthService.cs @@ -1,4 +1,5 @@ -using RelayCore.Endpoints; +using Newtonsoft.Json; +using RelayCore.Endpoints; using RelayCore.Models; using SurrealDb.Net; using SurrealDb.Net.Models; @@ -8,21 +9,25 @@ namespace RelayCore.Services; public class APIAuthService(SurrealDbClient _db) { - public async Task UserSigninAsync(AuthSignin request) + public async Task UserSigninAsync(AuthSignin request, string ip, string userAgent) { var hasher = new PasswordHasher(); var users = await _db.Select("auth_users"); - var user = users.FirstOrDefault(x => (x.Username == request.UserName || x.Email == request.UserName) - && hasher.VerifyPassword(request.Password, x.Password)); + var user = users.FirstOrDefault(x => (x.Username == request.UserName || x.Email == request.UserName) ); + // && hasher.VerifyPassword(request.Password, x.Password)); + if (user == null) + return null; var tokens = await _db.Select("auth_sessions"); - var token = tokens.Where(x => x.UserId == user.Id && !x.Revoked).OrderByDescending(x => x.ExpiresAt).FirstOrDefault(); - if (token.ExpiresAt > DateTime.UtcNow) - return token.TokenHash; + var token = tokens.Where(x => x.UserId == user.Id && x.IpAddress == ip && x.UserAgent == userAgent && !x.Revoked) + .OrderByDescending(x => x.ExpiresAt).FirstOrDefault(); + if (token != null) + if (token.ExpiresAt > DateTime.UtcNow) + return token.TokenHash; //TODO: Generate TOKEN - var newToken = hasher.HashPassword($"{user.Email}{user.Username}{user.Password}"); + var newToken = hasher.HashPassword($"{request.UserName}{userAgent}"); //TODO: Store TOKEN and Username for verification - var sessionId = await _db.Create(new Sessions + var sessionId = await _db.Create("auth_sessions", new Sessions { UserId = user.Id, TokenHash = newToken, @@ -30,20 +35,46 @@ public class APIAuthService(SurrealDbClient _db) ExpiresAt = DateTime.UtcNow.AddDays(30), DeviceName = "", Revoked = false, - IpAddress = "", - UserAgent = "" + IpAddress = ip, + UserAgent = userAgent }); //TODO: Add invalidation to TOKENs return newToken; } - public async Task UserRegisterAsync(AuthRegister request) + public async Task> GetUsersAsync() { - throw new NotImplementedException(); + var users = await _db.Select("auth_users"); + return users.Where(x => x.Username is not null).OrderByDescending(x=>x.CreatedAt).ToList(); + } + + public async Task UserRegisterAsync(AuthRegister request, string ip, string userAgent) + { + var hasher = new PasswordHasher(); + var users = await _db.Select("auth_users"); + var user = users.FirstOrDefault(x => x.Username == request.Username || x.Email == request.Username); + Console.WriteLine($"Register User found in DB: {user.Username}"); + if (user == null) + { + return await UserSigninAsync(new AuthSignin{UserName=request.Username, Password = request.Password}, ip, userAgent); + } + + return null; } public async Task ServerVerifyUser(AuthUserVerify request) { - throw new NotImplementedException(); + var users = await _db.Select("auth_users"); + var user = users.FirstOrDefault(x => x.Username == request.Username); + + if (user == null) + return false; + + var sessions = await _db.Select("auth_sessions"); + var session = sessions.FirstOrDefault(x => x.TokenHash == request.Token && x.UserId == user.Id); + if (session == null) + return false; + + return true; } } \ No newline at end of file