diff --git a/Oqtane.Client/Resources/SharedResources.resx b/Oqtane.Client/Resources/SharedResources.resx index 888afd89..c547480a 100644 --- a/Oqtane.Client/Resources/SharedResources.resx +++ b/Oqtane.Client/Resources/SharedResources.resx @@ -411,4 +411,19 @@ To + + At Least One Digit + + + At Least One Lowercase Letter + + + At Least One Punctuation Mark + + + At Least One Uppercase Letter + + + Passwords Must Have A Minimum Length Of {0} Characters, Including At Least {1} Unique Character(s), {2}{3}{4}{5} To Satisfy Password Compexity Requirements For This Site. + \ No newline at end of file diff --git a/Oqtane.Client/Services/Interfaces/IUserService.cs b/Oqtane.Client/Services/Interfaces/IUserService.cs index 01dfa022..f2a7a83b 100644 --- a/Oqtane.Client/Services/Interfaces/IUserService.cs +++ b/Oqtane.Client/Services/Interfaces/IUserService.cs @@ -1,4 +1,5 @@ using Oqtane.Models; +using System.Collections.Generic; using System.Threading.Tasks; namespace Oqtane.Services diff --git a/Oqtane.Client/Services/UserService.cs b/Oqtane.Client/Services/UserService.cs index 8e0e9f94..033b585d 100644 --- a/Oqtane.Client/Services/UserService.cs +++ b/Oqtane.Client/Services/UserService.cs @@ -4,14 +4,20 @@ using System.Net.Http; using System.Threading.Tasks; using Oqtane.Documentation; using System.Net; -using System.ComponentModel.DataAnnotations; +using System.Collections.Generic; +using Microsoft.Extensions.Localization; namespace Oqtane.Services { [PrivateApi("Don't show in the documentation, as everything should use the Interface")] public class UserService : ServiceBase, IUserService { - public UserService(HttpClient http, SiteState siteState) : base(http, siteState) { } + private readonly IStringLocalizer _localizer; + + public UserService(IStringLocalizer localizer, HttpClient http, SiteState siteState) : base(http, siteState) + { + _localizer = localizer; + } private string Apiurl => CreateApiUrl("User"); @@ -98,7 +104,24 @@ namespace Oqtane.Services public async Task GetPasswordRequirementsAsync(int siteId) { - return await GetStringAsync($"{Apiurl}/passwordrequirements/{siteId}"); + var requirements = await GetJsonAsync>($"{Apiurl}/passwordrequirements/{siteId}"); + + var minimumlength = (requirements.ContainsKey("IdentityOptions:Password:RequiredLength")) ? requirements["IdentityOptions:Password:RequiredLength"] : "6"; + var uniquecharacters = (requirements.ContainsKey("IdentityOptions:Password:RequiredUniqueChars")) ? requirements["IdentityOptions:Password:RequiredUniqueChars"] : "1"; + var requiredigit = bool.Parse((requirements.ContainsKey("IdentityOptions:Password:RequireDigit")) ? requirements["IdentityOptions:Password:RequireDigit"] : "true"); + var requireupper = bool.Parse((requirements.ContainsKey("IdentityOptions:Password:RequireUppercase")) ? requirements["IdentityOptions:Password:RequireUppercase"] : "true"); + var requirelower = bool.Parse((requirements.ContainsKey("IdentityOptions:Password:RequireLowercase")) ? requirements["IdentityOptions:Password:RequireLowercase"] : "true"); + var requirepunctuation = bool.Parse((requirements.ContainsKey("IdentityOptions:Password:RequireNonAlphanumeric")) ? requirements["IdentityOptions:Password:RequireNonAlphanumeric"] : "true"); + + // replace the placeholders with the setting values + string digitRequirement = requiredigit ? _localizer["Password.DigitRequirement"] + ", " : ""; + string uppercaseRequirement = requireupper ? _localizer["Password.UppercaseRequirement"] + ", " : ""; + string lowercaseRequirement = requirelower ? _localizer["Password.LowercaseRequirement"] + ", " : ""; + string punctuationRequirement = requirepunctuation ? _localizer["Password.PunctuationRequirement"] + ", " : ""; + string passwordValidationCriteriaTemplate = _localizer["Password.ValidationCriteria"]; + + // format requirements + return string.Format(passwordValidationCriteriaTemplate, minimumlength, uniquecharacters, digitRequirement, uppercaseRequirement, lowercaseRequirement, punctuationRequirement); } } } diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 7e17e035..f26ece36 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -14,10 +14,7 @@ using Oqtane.Repository; using Oqtane.Security; using Oqtane.Extensions; using Oqtane.Managers; -using Oqtane.Services; -using static System.Runtime.InteropServices.JavaScript.JSType; -using Microsoft.Extensions.Localization; -using Oqtane.Modules.Admin.Roles; +using System.Collections.Generic; namespace Oqtane.Controllers { @@ -31,9 +28,8 @@ namespace Oqtane.Controllers private readonly IUserPermissions _userPermissions; private readonly IJwtManager _jwtManager; private readonly ILogManager _logger; - private readonly IStringLocalizer _localizer; - public UserController(IUserRepository users, ITenantManager tenantManager, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ILogManager logger, IStringLocalizer localizer) + public UserController(IUserRepository users, ITenantManager tenantManager, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ILogManager logger) { _users = users; _tenantManager = tenantManager; @@ -42,7 +38,6 @@ namespace Oqtane.Controllers _userPermissions = userPermissions; _jwtManager = jwtManager; _logger = logger; - _localizer = localizer; } // GET api//5?siteid=x @@ -345,31 +340,17 @@ namespace Oqtane.Controllers // GET api//passwordrequirements/5 [HttpGet("passwordrequirements/{siteid}")] - public string PasswordRequirements(int siteid) + public Dictionary PasswordRequirements(int siteid) { - var requirements = ""; + var requirements = new Dictionary(); var site = _sites.GetSite(siteid); if (site != null && (site.AllowRegistration || User.IsInRole(RoleNames.Registered))) { - // get settings + // get password settings var sitesettings = HttpContext.GetSiteSettings(); - var minimumlength = sitesettings.GetValue("IdentityOptions:Password:RequiredLength", "6"); - var uniquecharacters = sitesettings.GetValue("IdentityOptions:Password:RequiredUniqueChars", "1"); - var requiredigit = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireDigit", "true")); - var requireupper = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireUppercase", "true")); - var requirelower = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireLowercase", "true")); - var requirepunctuation = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireNonAlphanumeric", "true")); - - // replace the placeholders with the setting values - string digitRequirement = requiredigit ? _localizer["Password.DigitRequirement"] + ", " : ""; - string uppercaseRequirement = requireupper ? _localizer["Password.UppercaseRequirement"] + ", " : ""; - string lowercaseRequirement = requirelower ? _localizer["Password.LowercaseRequirement"] + ", " : ""; - string punctuationRequirement = requirepunctuation ? _localizer["Password.PunctuationRequirement"] + ", " : ""; - string passwordValidationCriteriaTemplate = _localizer["Password.ValidationCriteria"]; - - // format requirements - requirements = string.Format(passwordValidationCriteriaTemplate, minimumlength, uniquecharacters, digitRequirement, uppercaseRequirement, lowercaseRequirement, punctuationRequirement); + requirements = sitesettings.Where(item => item.Key.StartsWith("IdentityOptions:Password:")) + .ToDictionary(item => item.Key, item => item.Value); } return requirements; diff --git a/Oqtane.Server/Resources/Controllers/UserController.resx b/Oqtane.Server/Resources/Controllers/UserController.resx deleted file mode 100644 index 49c8338e..00000000 --- a/Oqtane.Server/Resources/Controllers/UserController.resx +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - At Least One Digit - - - At Least One Lowercase Letter - - - At Least One Punctuation Mark - - - At Least One Uppercase Letter - - - Passwords Must Have A Minimum Length Of {0} Characters, Including At Least {1} Unique Character(s), {2}{3}{4}{5} To Satisfy Password Compexity Requirements For This Site. - - \ No newline at end of file