Refactoring, database structure changed
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
|
||||
public class AccountFilterQuery : IFilterQuery<Database.Model.Accounts.Account>
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
[FromQuery(Name = "username")]
|
||||
public string? Username { get; set; }
|
||||
|
||||
[FromQuery(Name = "email")]
|
||||
public string? Email { get; set; }
|
||||
|
||||
[FromQuery(Name = "is_admin")]
|
||||
public bool? IsAdmin { get; set; }
|
||||
|
||||
[FromQuery(Name = "active_date_from")]
|
||||
public DateOnly? ActiveDateFrom { get; set; }
|
||||
|
||||
[FromQuery(Name = "active_date_to")]
|
||||
public DateOnly? ActiveDateTo { get; set; }
|
||||
|
||||
[FromQuery(Name = "join_date_from")]
|
||||
public DateOnly? JoinDateFrom { get; set; }
|
||||
|
||||
[FromQuery(Name = "join_date_to")]
|
||||
public DateOnly? JoinDateTo { get; set; }
|
||||
|
||||
[FromQuery(Name = "description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
[FromQuery(Name = "gender_id")]
|
||||
public short? GenderId { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region PUBLIC METHODS
|
||||
|
||||
public IEnumerable<Filter<Database.Model.Accounts.Account>> GetFilters() =>
|
||||
[
|
||||
new AccountUsernameFilter(Username),
|
||||
new AccountEmailFilter(Email),
|
||||
new AccountIsAdminFilter(IsAdmin),
|
||||
new AccountActiveDateFromFilter(ActiveDateFrom),
|
||||
new AccountActiveDateToFilter(ActiveDateTo),
|
||||
new AccountJoinDateFromFilter(JoinDateFrom),
|
||||
new AccountJoinDateToFilter(JoinDateTo),
|
||||
new AccountDescriptionFilter(Description),
|
||||
new AccountGenderIdFilter(GenderId),
|
||||
];
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
|
||||
public static class AccountOrderKeys
|
||||
{
|
||||
public static readonly Dictionary<string, Expression<Func<Database.Model.Accounts.Account, object?>>> Base = new Dictionary<string, Expression<Func<Database.Model.Accounts.Account, object?>>>
|
||||
{
|
||||
{ "id", x => x.Id },
|
||||
{ "username", x => x.Username },
|
||||
{ "email", x => x.Email },
|
||||
{ "is_admin", x => x.IsAdmin },
|
||||
{ "active_date", x => x.ActiveDate },
|
||||
{ "join_date", x => x.JoinDate },
|
||||
{ "description", x => x.Description },
|
||||
{ "gender", x => x.Gender != null ? x.Gender.Name : null },
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
|
||||
public class AccountRequest : IPasswordEditRequest
|
||||
{
|
||||
public string Username { get; set; } = null!;
|
||||
public string Email { get; set; } = null!;
|
||||
public string Password { get; set; } = null!;
|
||||
public string PasswordConfirmation { get; set; } = null!;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using FluentValidation;
|
||||
using WatchIt.Database;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
|
||||
public class AccountRequestValidator : AbstractValidator<AccountRequest>
|
||||
{
|
||||
public AccountRequestValidator(DatabaseContext database)
|
||||
{
|
||||
Include(new PasswordEditRequestValidator());
|
||||
RuleFor(x => x.Username).MinimumLength(5)
|
||||
.MaximumLength(50)
|
||||
.CannotBeIn(database.Accounts, x => x.Username).WithMessage("Username was already used");
|
||||
RuleFor(x => x.Email).EmailAddress()
|
||||
.CannotBeIn(database.Accounts, x => x.Email).WithMessage("Email was already used");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using WatchIt.DTO.Models.Controllers.Genders.Gender;
|
||||
using WatchIt.DTO.Models.Generics.Image;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
|
||||
public class AccountResponse
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string Username { get; set; } = null!;
|
||||
public string Email { get; set; } = null!;
|
||||
public bool IsAdmin { get; set; }
|
||||
public DateTimeOffset ActiveDate { get; set; }
|
||||
public DateTimeOffset JoinDate { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public GenderResponse? Gender { get; set; }
|
||||
public ImageResponse? ProfilePicture { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountActiveDateFromFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountActiveDateFromFilter(DateOnly? query) : base(x =>
|
||||
(
|
||||
query == null
|
||||
||
|
||||
x.ActiveDate.UtcDateTime.CompareTo(query.Value) >= 0
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountActiveDateToFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountActiveDateToFilter(DateOnly? query) : base(x =>
|
||||
(
|
||||
query == null
|
||||
||
|
||||
x.ActiveDate.UtcDateTime.CompareTo(query.Value) <= 0
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountDescriptionFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountDescriptionFilter(string? descriptionRegex) : base(x =>
|
||||
(
|
||||
string.IsNullOrWhiteSpace(descriptionRegex)
|
||||
||
|
||||
(
|
||||
!string.IsNullOrWhiteSpace(x.Description)
|
||||
&&
|
||||
Regex.IsMatch(x.Description, descriptionRegex, RegexOptions.IgnoreCase)
|
||||
)
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountEmailFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountEmailFilter(string? emailRegex) : base(x =>
|
||||
(
|
||||
string.IsNullOrWhiteSpace(emailRegex)
|
||||
||
|
||||
(
|
||||
!string.IsNullOrWhiteSpace(x.Username)
|
||||
&&
|
||||
Regex.IsMatch(x.Username, emailRegex, RegexOptions.IgnoreCase)
|
||||
)
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountGenderIdFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountGenderIdFilter(short? genderId) : base(x =>
|
||||
(
|
||||
genderId == null
|
||||
||
|
||||
x.GenderId == genderId
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountIsAdminFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountIsAdminFilter(bool? query) : base(x =>
|
||||
(
|
||||
query == null
|
||||
||
|
||||
x.IsAdmin == query
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountJoinDateFromFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountJoinDateFromFilter(DateOnly? query) : base(x =>
|
||||
(
|
||||
query == null
|
||||
||
|
||||
x.JoinDate.UtcDateTime.CompareTo(query.Value) >= 0
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountJoinDateToFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountJoinDateToFilter(DateOnly? query) : base(x =>
|
||||
(
|
||||
query == null
|
||||
||
|
||||
x.JoinDate.UtcDateTime.CompareTo(query.Value) <= 0
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using WatchIt.DTO.Query;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.Account.Filters;
|
||||
|
||||
public record AccountUsernameFilter : Filter<Database.Model.Accounts.Account>
|
||||
{
|
||||
public AccountUsernameFilter(string? usernameRegex) : base(x =>
|
||||
(
|
||||
string.IsNullOrWhiteSpace(usernameRegex)
|
||||
||
|
||||
(
|
||||
!string.IsNullOrWhiteSpace(x.Username)
|
||||
&&
|
||||
Regex.IsMatch(x.Username, usernameRegex, RegexOptions.IgnoreCase)
|
||||
)
|
||||
)) { }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture;
|
||||
|
||||
public class AccountBackgroundPictureRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public Guid Id { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
using WatchIt.Database;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture;
|
||||
|
||||
public class AccountBackgroundPictureRequestValidator : AbstractValidator<AccountBackgroundPictureRequest>
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public AccountBackgroundPictureRequestValidator(DatabaseContext database)
|
||||
{
|
||||
RuleFor(x => x.Id).MustBeIn(database.PhotoBackgrounds, x => x.Id).WithMessage("Background does not exists");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountEmail;
|
||||
|
||||
public class AccountEmailRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string Email { get; set; } = null!;
|
||||
public string Password { get; set; } = null!;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using FluentValidation;
|
||||
using WatchIt.Database;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountEmail;
|
||||
|
||||
public class AccountEmailRequestValidator : AbstractValidator<AccountEmailRequest>
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public AccountEmailRequestValidator(DatabaseContext database)
|
||||
{
|
||||
RuleFor(x => x.Email).EmailAddress()
|
||||
.CannotBeIn(database.Accounts, x => x.Email).WithMessage("Email is already used");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountLogout;
|
||||
|
||||
public class AccountLogoutRequest
|
||||
{
|
||||
public string? RefreshToken { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountPassword;
|
||||
|
||||
public class AccountPasswordRequest : IPasswordEditRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string OldPassword { get; set; } = null!;
|
||||
public string Password { get; set; } = null!;
|
||||
public string PasswordConfirmation { get; set; } = null!;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountPassword;
|
||||
|
||||
public class AccountPasswordRequestValidator : AbstractValidator<AccountPasswordRequest>
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public AccountPasswordRequestValidator()
|
||||
{
|
||||
Include(new PasswordEditRequestValidator());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo;
|
||||
|
||||
public class AccountProfileInfoRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string? Description { get; set; }
|
||||
public short? GenderId { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using FluentValidation;
|
||||
using WatchIt.Database;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo;
|
||||
|
||||
public class AccountProfileInfoRequestValidator : AbstractValidator<AccountProfileInfoRequest>
|
||||
{
|
||||
public AccountProfileInfoRequestValidator(DatabaseContext database)
|
||||
{
|
||||
RuleFor(x => x.Description).MaximumLength(1000);
|
||||
When(x => x.GenderId.HasValue, () =>
|
||||
{
|
||||
RuleFor(x => x.GenderId!.Value).MustBeIn(database.Genders.Select(x => x.Id));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountUsername;
|
||||
|
||||
public class AccountUsernameRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public string Username { get; set; } = null!;
|
||||
public string Password { get; set; } = null!;
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using FluentValidation;
|
||||
using WatchIt.Database;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts.AccountUsername;
|
||||
|
||||
public class AccountUsernameRequestValidator : AbstractValidator<AccountUsernameRequest>
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public AccountUsernameRequestValidator(DatabaseContext database)
|
||||
{
|
||||
RuleFor(x => x.Username).MinimumLength(5)
|
||||
.MaximumLength(50)
|
||||
.CannotBeIn(database.Accounts, x => x.Username).WithMessage("Username is already used");
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
163
WatchIt.DTO/Models/Controllers/Accounts/AccountsMappers.cs
Normal file
163
WatchIt.DTO/Models/Controllers/Accounts/AccountsMappers.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using WatchIt.Database.Model.Accounts;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.Account;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.AccountBackgroundPicture;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.AccountEmail;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.AccountPassword;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.AccountProfileInfo;
|
||||
using WatchIt.DTO.Models.Controllers.Accounts.AccountUsername;
|
||||
using WatchIt.DTO.Models.Controllers.Genders;
|
||||
using WatchIt.DTO.Models.Generics.Image;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts;
|
||||
|
||||
public static class AccountsMappers
|
||||
{
|
||||
#region PUBLIC METHODS
|
||||
|
||||
#region Account
|
||||
|
||||
public static Database.Model.Accounts.Account ToEntity(this AccountRequest request, Func<string, PasswordData> passwordGenFunc)
|
||||
{
|
||||
PasswordData generatedPassword = passwordGenFunc(request.Password);
|
||||
return new Database.Model.Accounts.Account
|
||||
{
|
||||
Username = request.Username,
|
||||
Email = request.Email,
|
||||
Password = generatedPassword.PasswordHash,
|
||||
LeftSalt = generatedPassword.LeftSalt,
|
||||
RightSalt = generatedPassword.RightSalt,
|
||||
};
|
||||
}
|
||||
|
||||
public static AccountResponse ToResponse(this Database.Model.Accounts.Account account) => new AccountResponse
|
||||
{
|
||||
Id = account.Id,
|
||||
Username = account.Username,
|
||||
Email = account.Email,
|
||||
IsAdmin = account.IsAdmin,
|
||||
JoinDate = account.JoinDate,
|
||||
ActiveDate = account.ActiveDate,
|
||||
Description = account.Description,
|
||||
Gender = account.Gender?.ToResponse(),
|
||||
ProfilePicture = account.ProfilePicture?.ToResponse(),
|
||||
};
|
||||
|
||||
public static void UpdateActiveDate(this Database.Model.Accounts.Account account)
|
||||
{
|
||||
account.ActiveDate = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountUsername
|
||||
|
||||
public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountUsernameRequest request)
|
||||
{
|
||||
account.Username = request.Username;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountEmail
|
||||
|
||||
public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountEmailRequest request)
|
||||
{
|
||||
account.Email = request.Email;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountPassword
|
||||
|
||||
public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountPasswordRequest request, Func<string, PasswordData> passwordGenFunc)
|
||||
{
|
||||
PasswordData generatedPassword = passwordGenFunc(request.Password);
|
||||
account.Password = generatedPassword.PasswordHash;
|
||||
account.LeftSalt = generatedPassword.LeftSalt;
|
||||
account.RightSalt = generatedPassword.RightSalt;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountProfileInfo
|
||||
|
||||
public static void UpdateWithRequest(this Database.Model.Accounts.Account account, AccountProfileInfoRequest request)
|
||||
{
|
||||
account.Description = request.Description;
|
||||
account.GenderId = request.GenderId;
|
||||
}
|
||||
|
||||
public static AccountProfileInfoRequest ToProfileInfoRequest(this AccountResponse response) => new AccountProfileInfoRequest
|
||||
{
|
||||
Description = response.Description,
|
||||
GenderId = response.Gender?.Id
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountProfilePicture
|
||||
|
||||
public static AccountProfilePicture ToEntity(this ImageRequest request, long accountId) => new AccountProfilePicture
|
||||
{
|
||||
AccountId = accountId,
|
||||
Image = request.Image,
|
||||
MimeType = request.MimeType,
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountBackgroundPicture
|
||||
|
||||
public static Database.Model.Accounts.AccountBackgroundPicture ToEntity(this AccountBackgroundPictureRequest request, long accountId) => new Database.Model.Accounts.AccountBackgroundPicture
|
||||
{
|
||||
AccountId = accountId,
|
||||
BackgroundId = request.Id,
|
||||
};
|
||||
|
||||
public static void UpdateWithRequest(this Database.Model.Accounts.AccountBackgroundPicture entity, AccountBackgroundPictureRequest request)
|
||||
{
|
||||
entity.BackgroundId = request.Id;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountRefreshToken
|
||||
|
||||
public static AccountRefreshToken CreateAccountRefreshTokenEntity(Guid token, long accountId, DateTimeOffset expirationDate, bool isExtendable) => new AccountRefreshToken
|
||||
{
|
||||
Token = token,
|
||||
AccountId = accountId,
|
||||
ExpirationDate = expirationDate,
|
||||
IsExtendable = isExtendable,
|
||||
};
|
||||
|
||||
public static void UpdateExpirationDate(this AccountRefreshToken entity, DateTimeOffset expirationDate)
|
||||
{
|
||||
entity.ExpirationDate = expirationDate;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AccountFollow
|
||||
|
||||
public static AccountFollow CreateAccountFollowEntity(long accountFollowerId, long accountFollowedId) => new AccountFollow
|
||||
{
|
||||
FollowerId = accountFollowerId,
|
||||
FollowedId = accountFollowedId,
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region PasswordData
|
||||
|
||||
public static PasswordData GetPasswordData(this Database.Model.Accounts.Account account) => new PasswordData
|
||||
{
|
||||
PasswordHash = account.Password,
|
||||
LeftSalt = account.LeftSalt,
|
||||
RightSalt = account.RightSalt,
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts;
|
||||
|
||||
public interface IPasswordEditRequest
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
string Password { get; set; }
|
||||
string PasswordConfirmation { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
12
WatchIt.DTO/Models/Controllers/Accounts/PasswordData.cs
Normal file
12
WatchIt.DTO/Models/Controllers/Accounts/PasswordData.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts;
|
||||
|
||||
public struct PasswordData
|
||||
{
|
||||
#region PROPERTIES
|
||||
|
||||
public required byte[] PasswordHash { get; set; }
|
||||
public required string LeftSalt { get; set; }
|
||||
public required string RightSalt { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using FluentValidation;
|
||||
|
||||
namespace WatchIt.DTO.Models.Controllers.Accounts;
|
||||
|
||||
public class PasswordEditRequestValidator : AbstractValidator<IPasswordEditRequest>
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
public PasswordEditRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Password).NotNull()
|
||||
.NotEmpty();
|
||||
When(x => x.Password is not null, () =>
|
||||
{
|
||||
RuleFor(x => x.Password).MinimumLength(8)
|
||||
.Must(x => x.Any(char.IsUpper)).WithMessage("Password must contain at least one uppercase letter.")
|
||||
.Must(x => x.Any(char.IsLower)).WithMessage("Password must contain at least one lowercase letter.")
|
||||
.Must(x => x.Any(char.IsDigit)).WithMessage("Password must contain at least one digit.");
|
||||
});
|
||||
RuleFor(x => x.PasswordConfirmation).Equal(x => x.Password);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user