add date of birth

This commit is contained in:
Elijah R 2024-04-05 15:50:18 -04:00
parent 788d11f39a
commit 0b1ec748da
4 changed files with 32 additions and 6 deletions

View file

@ -30,6 +30,7 @@ public class Database
username VARCHAR(20) NOT NULL UNIQUE KEY, username VARCHAR(20) NOT NULL UNIQUE KEY,
password TEXT NOT NULL, password TEXT NOT NULL,
email TEXT NOT NULL UNIQUE KEY, email TEXT NOT NULL UNIQUE KEY,
date_of_birth DATE NOT NULL,
email_verified BOOLEAN NOT NULL DEFAULT 0, email_verified BOOLEAN NOT NULL DEFAULT 0,
email_verification_code CHAR(8) DEFAULT NULL, email_verification_code CHAR(8) DEFAULT NULL,
cvm_rank INT UNSIGNED NOT NULL DEFAULT 1, cvm_rank INT UNSIGNED NOT NULL DEFAULT 1,
@ -77,6 +78,7 @@ public class Database
Username = reader.GetString("username"), Username = reader.GetString("username"),
Password = reader.GetString("password"), Password = reader.GetString("password"),
Email = reader.GetString("email"), Email = reader.GetString("email"),
DateOfBirth = reader.GetDateOnly("date_of_birth"),
EmailVerified = reader.GetBoolean("email_verified"), EmailVerified = reader.GetBoolean("email_verified"),
EmailVerificationCode = reader.GetString("email_verification_code"), EmailVerificationCode = reader.GetString("email_verification_code"),
Rank = (Rank)reader.GetUInt32("cvm_rank"), 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) string? verificationcode = null)
{ {
await using var db = new MySqlConnection(connectionString); await using var db = new MySqlConnection(connectionString);
@ -93,13 +95,14 @@ public class Database
await using var cmd = db.CreateCommand(); await using var cmd = db.CreateCommand();
cmd.CommandText = """ cmd.CommandText = """
INSERT INTO users 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 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("@username", username);
cmd.Parameters.AddWithValue("@password", Argon2.Hash(password)); cmd.Parameters.AddWithValue("@password", Argon2.Hash(password));
cmd.Parameters.AddWithValue("@email", email); cmd.Parameters.AddWithValue("@email", email);
cmd.Parameters.AddWithValue("@date_of_birth", dateOfBirth);
cmd.Parameters.AddWithValue("@email_verified", verified); cmd.Parameters.AddWithValue("@email_verified", verified);
cmd.Parameters.AddWithValue("@email_verification_code", verificationcode); cmd.Parameters.AddWithValue("@email_verification_code", verificationcode);
cmd.Parameters.AddWithValue("@registration_ip", ip.GetAddressBytes()); cmd.Parameters.AddWithValue("@registration_ip", ip.GetAddressBytes());

View file

@ -6,4 +6,5 @@ public class RegisterPayload
public string password { get; set; } public string password { get; set; }
public string email { get; set; } public string email { get; set; }
public string? captchaToken { get; set; } public string? captchaToken { get; set; }
public string dateOfBirth { get; set; }
} }

View file

@ -1,5 +1,6 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Net; using System.Net;
using System.Runtime.InteropServices.JavaScript;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Computernewb.CollabVMAuthServer.HTTP.Payloads; using Computernewb.CollabVMAuthServer.HTTP.Payloads;
@ -524,7 +525,7 @@ public static class Routes
}, Utilities.JsonSerializerOptions); }, Utilities.JsonSerializerOptions);
} }
var payload = await context.Request.ReadFromJsonAsync<RegisterPayload>(); var payload = await context.Request.ReadFromJsonAsync<RegisterPayload>();
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; context.Response.StatusCode = 400;
return Results.Json(new RegisterResponse return Results.Json(new RegisterResponse
@ -628,11 +629,31 @@ public static class Routes
error = "That password is commonly used and is not allowed." error = "That password is commonly used and is not allowed."
}, Utilities.JsonSerializerOptions); }, 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 // Create the account
if (Program.Config.Registration.EmailVerificationRequired) if (Program.Config.Registration.EmailVerificationRequired)
{ {
var code = Program.Random.Next(10000000, 99999999).ToString(); 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); await Program.Mailer.SendVerificationCode(payload.username, payload.email, code);
return Results.Json(new RegisterResponse return Results.Json(new RegisterResponse
{ {
@ -644,7 +665,7 @@ public static class Routes
} }
else 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); var token = Utilities.RandomString(32);
await Program.Database.CreateSession(user.Username, token, ip); await Program.Database.CreateSession(user.Username, token, ip);
return Results.Json(new RegisterResponse return Results.Json(new RegisterResponse

View file

@ -8,6 +8,7 @@ public class User
public string Username { get; set; } public string Username { get; set; }
public string Password { get; set; } public string Password { get; set; }
public string Email { get; set; } public string Email { get; set; }
public DateOnly DateOfBirth { get; set; }
public bool EmailVerified { get; set; } public bool EmailVerified { get; set; }
public string EmailVerificationCode { get; set; } public string EmailVerificationCode { get; set; }
public Rank Rank { get; set; } public Rank Rank { get; set; }