diff --git a/CollabVMAuthServer/Database.cs b/CollabVMAuthServer/Database.cs index 6d14d34..4b76a65 100644 --- a/CollabVMAuthServer/Database.cs +++ b/CollabVMAuthServer/Database.cs @@ -30,6 +30,7 @@ public class Database username VARCHAR(20) NOT NULL UNIQUE KEY, password TEXT NOT NULL, email TEXT NOT NULL UNIQUE KEY, + date_of_birth DATE NOT NULL, email_verified BOOLEAN NOT NULL DEFAULT 0, email_verification_code CHAR(8) DEFAULT NULL, cvm_rank INT UNSIGNED NOT NULL DEFAULT 1, @@ -77,6 +78,7 @@ public class Database Username = reader.GetString("username"), Password = reader.GetString("password"), Email = reader.GetString("email"), + DateOfBirth = reader.GetDateOnly("date_of_birth"), EmailVerified = reader.GetBoolean("email_verified"), EmailVerificationCode = reader.GetString("email_verification_code"), Rank = (Rank)reader.GetUInt32("cvm_rank"), @@ -85,7 +87,7 @@ public class Database }; } - public async Task RegisterAccount(string username, string email, string password, bool verified, IPAddress ip, + public async Task RegisterAccount(string username, string email, DateOnly dateOfBirth, string password, bool verified, IPAddress ip, string? verificationcode = null) { await using var db = new MySqlConnection(connectionString); @@ -93,13 +95,14 @@ public class Database await using var cmd = db.CreateCommand(); cmd.CommandText = """ INSERT INTO users - (username, password, email, email_verified, email_verification_code, registration_ip) + (username, password, email, date_of_birth, email_verified, email_verification_code, registration_ip) VALUES - (@username, @password, @email, @email_verified, @email_verification_code, @registration_ip) + (@username, @password, @email @date_of_birth, @email_verified, @email_verification_code, @registration_ip) """; cmd.Parameters.AddWithValue("@username", username); cmd.Parameters.AddWithValue("@password", Argon2.Hash(password)); cmd.Parameters.AddWithValue("@email", email); + cmd.Parameters.AddWithValue("@date_of_birth", dateOfBirth); cmd.Parameters.AddWithValue("@email_verified", verified); cmd.Parameters.AddWithValue("@email_verification_code", verificationcode); cmd.Parameters.AddWithValue("@registration_ip", ip.GetAddressBytes()); diff --git a/CollabVMAuthServer/HTTP/Payloads/RegisterPayload.cs b/CollabVMAuthServer/HTTP/Payloads/RegisterPayload.cs index e24f0df..6666b03 100644 --- a/CollabVMAuthServer/HTTP/Payloads/RegisterPayload.cs +++ b/CollabVMAuthServer/HTTP/Payloads/RegisterPayload.cs @@ -6,4 +6,5 @@ public class RegisterPayload public string password { get; set; } public string email { get; set; } public string? captchaToken { get; set; } + public string dateOfBirth { get; set; } } \ No newline at end of file diff --git a/CollabVMAuthServer/Routes.cs b/CollabVMAuthServer/Routes.cs index 5e158a1..0005d2a 100644 --- a/CollabVMAuthServer/Routes.cs +++ b/CollabVMAuthServer/Routes.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; using System.Net; +using System.Runtime.InteropServices.JavaScript; using System.Text.Json; using System.Text.Json.Serialization; using Computernewb.CollabVMAuthServer.HTTP.Payloads; @@ -524,7 +525,7 @@ public static class Routes }, Utilities.JsonSerializerOptions); } var payload = await context.Request.ReadFromJsonAsync(); - if (payload == null || string.IsNullOrWhiteSpace(payload.username) || string.IsNullOrWhiteSpace(payload.password) || string.IsNullOrWhiteSpace(payload.email)) + if (payload == null || string.IsNullOrWhiteSpace(payload.username) || string.IsNullOrWhiteSpace(payload.password) || string.IsNullOrWhiteSpace(payload.email) || string.IsNullOrWhiteSpace(payload.dateOfBirth)) { context.Response.StatusCode = 400; return Results.Json(new RegisterResponse @@ -628,11 +629,31 @@ public static class Routes error = "That password is commonly used and is not allowed." }, Utilities.JsonSerializerOptions); } + // Validate date of birth + if (!DateOnly.TryParseExact(payload.dateOfBirth, "yyyy-MM-dd", out var dob)) + { + context.Response.StatusCode = 400; + return Results.Json(new RegisterResponse + { + success = false, + error = "Invalid date of birth" + }, Utilities.JsonSerializerOptions); + } + + if (dob.AddYears(13) > DateOnly.FromDateTime(DateTime.Now)) + { + context.Response.StatusCode = 400; + return Results.Json(new RegisterResponse + { + success = false, + error = "You must be at least 13 years old to register." + }, Utilities.JsonSerializerOptions); + } // Create the account if (Program.Config.Registration.EmailVerificationRequired) { var code = Program.Random.Next(10000000, 99999999).ToString(); - await Program.Database.RegisterAccount(payload.username, payload.email, payload.password, false, ip,code); + await Program.Database.RegisterAccount(payload.username, payload.email, dob, payload.password, false, ip,code); await Program.Mailer.SendVerificationCode(payload.username, payload.email, code); return Results.Json(new RegisterResponse { @@ -644,7 +665,7 @@ public static class Routes } else { - await Program.Database.RegisterAccount(payload.username, payload.email, payload.password, true, null); + await Program.Database.RegisterAccount(payload.username, payload.email, dob, payload.password, true, null); var token = Utilities.RandomString(32); await Program.Database.CreateSession(user.Username, token, ip); return Results.Json(new RegisterResponse diff --git a/CollabVMAuthServer/User.cs b/CollabVMAuthServer/User.cs index e21bb89..72d0e5b 100644 --- a/CollabVMAuthServer/User.cs +++ b/CollabVMAuthServer/User.cs @@ -8,6 +8,7 @@ public class User public string Username { get; set; } public string Password { get; set; } public string Email { get; set; } + public DateOnly DateOfBirth { get; set; } public bool EmailVerified { get; set; } public string EmailVerificationCode { get; set; } public Rank Rank { get; set; }