✨ Basic auth
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using NodaTime;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
using Org.BouncyCastle.Security;
|
||||
|
||||
namespace DysonNetwork.Sphere.Account;
|
||||
|
||||
@@ -12,9 +9,12 @@ public class Account : BaseModel
|
||||
public long Id { get; set; }
|
||||
[MaxLength(256)] public string Name { get; set; } = string.Empty;
|
||||
[MaxLength(256)] public string Nick { get; set; } = string.Empty;
|
||||
|
||||
|
||||
public ICollection<AccountContact> Contacts { get; set; } = new List<AccountContact>();
|
||||
public ICollection<AccountAuthFactor> AuthFactors { get; set; } = new List<AccountAuthFactor>();
|
||||
|
||||
[JsonIgnore] public ICollection<AccountAuthFactor> AuthFactors { get; set; } = new List<AccountAuthFactor>();
|
||||
[JsonIgnore] public ICollection<Auth.Session> Sessions { get; set; } = new List<Auth.Session>();
|
||||
[JsonIgnore] public ICollection<Auth.Challenge> Challenges { get; set; } = new List<Auth.Challenge>();
|
||||
}
|
||||
|
||||
public class AccountContact : BaseModel
|
||||
@@ -23,13 +23,15 @@ public class AccountContact : BaseModel
|
||||
public AccountContactType Type { get; set; }
|
||||
public Instant? VerifiedAt { get; set; }
|
||||
[MaxLength(1024)] public string Content { get; set; } = string.Empty;
|
||||
|
||||
|
||||
[JsonIgnore] public Account Account { get; set; } = null!;
|
||||
}
|
||||
|
||||
public enum AccountContactType
|
||||
{
|
||||
Email, PhoneNumber, Address
|
||||
Email,
|
||||
PhoneNumber,
|
||||
Address
|
||||
}
|
||||
|
||||
public class AccountAuthFactor : BaseModel
|
||||
@@ -37,25 +39,28 @@ public class AccountAuthFactor : BaseModel
|
||||
public long Id { get; set; }
|
||||
public AccountAuthFactorType Type { get; set; }
|
||||
public string? Secret { get; set; } = null;
|
||||
|
||||
|
||||
[JsonIgnore] public Account Account { get; set; } = null!;
|
||||
|
||||
public AccountAuthFactor HashSecret(int cost = 12)
|
||||
{
|
||||
if(Secret == null) return this;
|
||||
|
||||
var passwordBytes = Encoding.UTF8.GetBytes(Secret);
|
||||
var random = new SecureRandom();
|
||||
var salt = new byte[16];
|
||||
random.NextBytes(salt);
|
||||
var hashed = BCrypt.Generate(passwordBytes, salt, cost);
|
||||
Secret = Convert.ToBase64String(hashed);
|
||||
|
||||
if (Secret == null) return this;
|
||||
Secret = BCrypt.Net.BCrypt.HashPassword(Secret, workFactor: cost);
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool VerifyPassword(string password)
|
||||
{
|
||||
if (Secret == null)
|
||||
throw new InvalidOperationException("Auth factor with no secret cannot be verified with password.");
|
||||
return BCrypt.Net.BCrypt.Verify(password, Secret);
|
||||
}
|
||||
}
|
||||
|
||||
public enum AccountAuthFactorType
|
||||
{
|
||||
Password, EmailCode, InAppCode, TimedCode
|
||||
Password,
|
||||
EmailCode,
|
||||
InAppCode,
|
||||
TimedCode
|
||||
}
|
Reference in New Issue
Block a user