Compare commits
3 Commits
535bafa73a
...
592e8a1b42
Author | SHA1 | Date | |
---|---|---|---|
592e8a1b42 | |||
a27549092b | |||
f27d07fb5a |
@ -23,7 +23,6 @@ using System.IO;
|
||||
using System.Net.Mail;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mirea.Api.Endpoint.Controllers.Configuration;
|
||||
|
||||
@ -31,7 +30,7 @@ namespace Mirea.Api.Endpoint.Controllers.Configuration;
|
||||
[ApiController]
|
||||
[MaintenanceModeIgnore]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public partial class SetupController(
|
||||
public class SetupController(
|
||||
ISetupToken setupToken,
|
||||
IMaintenanceModeNotConfigureService notConfigureService,
|
||||
IMemoryCache cache,
|
||||
@ -212,7 +211,7 @@ public partial class SetupController(
|
||||
[BadRequestResponse]
|
||||
public ActionResult<string> CreateAdmin([FromBody] CreateUserRequest user)
|
||||
{
|
||||
if (user.Password.Length < 8 || !PasswordExistUpperLetter().IsMatch(user.Password) || !PasswordExistSpecialSymbol().IsMatch(user.Password))
|
||||
if (PasswordHashService.HasPasswordInPolicySecurity(user.Password))
|
||||
throw new ControllerArgumentException("The password must be at least 8 characters long and contain at least one uppercase letter and one special character.");
|
||||
|
||||
if (!MailAddress.TryCreate(user.Email, out _))
|
||||
|
@ -7,6 +7,7 @@ using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Dto.Requests;
|
||||
using Mirea.Api.Dto.Responses;
|
||||
using Mirea.Api.Endpoint.Common.Attributes;
|
||||
using Mirea.Api.Endpoint.Common.Exceptions;
|
||||
using Mirea.Api.Endpoint.Common.Services;
|
||||
using Mirea.Api.Endpoint.Common.Settings;
|
||||
using Mirea.Api.Security.Common.Dto.Requests;
|
||||
@ -165,4 +166,29 @@ public class AuthController(IOptionsSnapshot<Admin> user, AuthService auth, Pass
|
||||
[Authorize]
|
||||
[CacheMaxAge(0, 0, 1)]
|
||||
public ActionResult<AuthRoles> GetRole() => Ok(AuthRoles.Admin);
|
||||
|
||||
[HttpPost("RenewPassword")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[Localhost]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<string> RenewPassword([FromBody] string? password = null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(password))
|
||||
password = string.Empty;
|
||||
else if (!PasswordHashService.HasPasswordInPolicySecurity(password))
|
||||
throw new ControllerArgumentException("The password must be at least 8 characters long and contain at least one uppercase letter and one special character.");
|
||||
|
||||
while (!PasswordHashService.HasPasswordInPolicySecurity(password))
|
||||
password = GeneratorKey.GenerateAlphaNumeric(16, includes: "!@#%^");
|
||||
|
||||
var (salt, hash) = passwordService.HashPassword(password);
|
||||
|
||||
var admin = user.Value;
|
||||
|
||||
admin.Salt = salt;
|
||||
admin.PasswordHash = hash;
|
||||
admin.SaveSetting();
|
||||
|
||||
return Ok(password);
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,9 @@
|
||||
<ImplicitUsings>disable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Company>Winsomnia</Company>
|
||||
<Version>1.0.0-b0</Version>
|
||||
<AssemblyVersion>1.0.1.0</AssemblyVersion>
|
||||
<FileVersion>1.0.1.0</FileVersion>
|
||||
<Version>1.0.0-b3</Version>
|
||||
<AssemblyVersion>1.0.1.3</AssemblyVersion>
|
||||
<FileVersion>1.0.1.3</FileVersion>
|
||||
<AssemblyName>Mirea.Api.Endpoint</AssemblyName>
|
||||
<RootNamespace>$(AssemblyName)</RootNamespace>
|
||||
<OutputType>Exe</OutputType>
|
||||
@ -23,20 +23,21 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Cronos" Version="0.8.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.7">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.6.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="8.0.8" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.7.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.7.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Versioning" Version="2.0.0" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -1,10 +1,11 @@
|
||||
using Konscious.Security.Cryptography;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Mirea.Api.Security.Services;
|
||||
|
||||
public class PasswordHashService
|
||||
public partial class PasswordHashService
|
||||
{
|
||||
public int SaltSize { private get; init; }
|
||||
public int HashSize { private get; init; }
|
||||
@ -53,4 +54,15 @@ public class PasswordHashService
|
||||
|
||||
public bool VerifyPassword(string password, string saltBase64, string hashBase64) =>
|
||||
VerifyPassword(password, Convert.FromBase64String(saltBase64), Convert.FromBase64String(hashBase64));
|
||||
|
||||
public static bool HasPasswordInPolicySecurity(string password) =>
|
||||
password.Length >= 8 &&
|
||||
PasswordExistSpecialSymbol().IsMatch(password) &&
|
||||
PasswordExistUpperLetter().IsMatch(password);
|
||||
|
||||
[GeneratedRegex("[A-Z]+")]
|
||||
private static partial Regex PasswordExistUpperLetter();
|
||||
|
||||
[GeneratedRegex("[!@#$%^&*]+")]
|
||||
private static partial Regex PasswordExistSpecialSymbol();
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
<PackageReference Include="FluentValidation" Version="11.9.2" />
|
||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.9.2" />
|
||||
<PackageReference Include="MediatR" Version="12.4.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -13,8 +13,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.7" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user