@namespace Oqtane.Modules.Admin.Users @using System.Text.RegularExpressions; @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @inject IProfileService ProfileService @inject ISettingService SettingService @inject IFileService FileService @inject ITimeZoneService TimeZoneService @inject IServiceProvider ServiceProvider @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer @if (_initialized) {
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) {
}


@if (_allowpasskeys) {
@if (_passkeys != null && _passkeys.Count > 0) {
  @Localizer["Passkey"]
@context.Name
} else {
@Localizer["Message.Passkeys.None"]
}

} @if (_allowexternallogin) {
@if (_logins != null && _logins.Count > 0) {
  @Localizer["Login"]
@context.Name
} else {
@Localizer["Message.Logins.None"]
}

}
@foreach (Profile profile in _profiles) { var p = profile; if (p.Category != _category) {
@p.Category
_category = p.Category; }
@if (!string.IsNullOrEmpty(p.Options)) { } else { @if (p.Rows == 1) { } else { } }
}

@SharedLocalizer["Cancel"] @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin) && PageState.Runtime != Shared.Runtime.Hybrid && !_ishost && _isdeleted != "True") { } @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host) && _isdeleted == "True") { }

} @code { private bool _initialized = false; private bool _allowpasskeys = false; private bool _allowexternallogin = false; private int _userid; private string _username = string.Empty; private string _email = string.Empty; private string _confirmed = string.Empty; private string _displayname = string.Empty; private List _timezones; private string _timezoneid = string.Empty; private string _isdeleted; private string _lastlogin; private string _lastipaddress; private bool _ishost = false; private string _passwordrequirements; private string _password = string.Empty; private string _passwordtype = "password"; private string _togglepassword = string.Empty; private string _confirm = string.Empty; private List _passkeys; private List _logins; private List _profiles; private Dictionary _settings; private string _category = string.Empty; private string _createdby; private DateTime _createdon; private string _modifiedby; private DateTime _modifiedon; private string _deletedby; private DateTime? _deletedon; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; protected override async Task OnInitializedAsync() { try { _allowpasskeys = (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:Passkeys", "false") == "true"); _allowexternallogin = (SettingService.GetSetting(PageState.Site.Settings, "ExternalLogin:ProviderType", "") != "") ? true : false; if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int UserId)) { _userid = UserId; var user = await UserService.GetUserAsync(_userid, PageState.Site.SiteId); if (user != null) { _username = user.Username; _email = user.Email; _confirmed = user.EmailConfirmed.ToString(); _displayname = user.DisplayName; _timezones = TimeZoneService.GetTimeZones(); _timezoneid = PageState.User.TimeZoneId; _isdeleted = user.IsDeleted.ToString(); _lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", UtcToLocal(user.LastLoginOn)); _lastipaddress = user.LastIPAddress; _ishost = UserSecurity.ContainsRole(user.Roles, RoleNames.Host); _passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId); _togglepassword = SharedLocalizer["ShowPassword"]; await GetPasskeys(); await GetLogins(); _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); foreach (var profile in _profiles) { if (profile.Options.ToLower().StartsWith("entityname:")) { var options = await SettingService.GetSettingsAsync(profile.Options.Substring(11), -1); options.Add("", $"<{SharedLocalizer["Not Specified"]}>"); profile.Options = string.Join(",", options.OrderBy(item => item.Value).Select(kvp => $"{kvp.Key}:{kvp.Value}")); } } _settings = user.Settings; _createdby = user.CreatedBy; _createdon = user.CreatedOn; _modifiedby = user.ModifiedBy; _modifiedon = user.ModifiedOn; _deletedby = user.DeletedBy; _deletedon = user.DeletedOn; } } _initialized = true; } catch (Exception ex) { await logger.LogError(ex, "Error Loading User {UserId} {Error}", _userid, ex.Message); AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); } } private string GetProfileValue(string SettingName, string DefaultValue) { string value = SettingService.GetSetting(_settings, SettingName, DefaultValue); if (value.Contains("]")) { value = value.Substring(value.IndexOf("]") + 1); } return value; } private async Task SaveUser() { try { if (_username != string.Empty && _email != string.Empty) { if (_password == _confirm) { if (ValidateProfiles()) { var user = await UserService.GetUserAsync(_userid, PageState.Site.SiteId); user.SiteId = PageState.Site.SiteId; user.Username = _username; user.Password = _password; user.Email = _email; user.EmailConfirmed = bool.Parse(_confirmed); user.DisplayName = string.IsNullOrWhiteSpace(_displayname) ? _username : _displayname; user.TimeZoneId = _timezoneid; if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) { user.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); } user = await UserService.UpdateUserAsync(user); if (user != null) { await SettingService.UpdateUserSettingsAsync(_settings, user.UserId); await logger.LogInformation("User Saved {User}", user); NavigationManager.NavigateTo(NavigateUrl()); } else { AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error); } } } else { AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning); } } else { AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Saving User {Username} {Email} {Error}", _username, _email, ex.Message); AddModuleMessage(Localizer["Error.User.Save"], MessageType.Error); } } private async Task ImpersonateUser() { try { await logger.LogInformation(LogFunction.Security, "User {Username} Impersonated By Administrator {Administrator}", _username, PageState.User.Username); // post back to the server so that the cookies are set correctly var interop = new Interop(JSRuntime); var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, returnurl = PageState.Alias.Path }; string url = Utilities.TenantUrl(PageState.Alias, "/pages/impersonate/"); await interop.SubmitForm(url, fields); } catch (Exception ex) { await logger.LogError(ex, "Error Impersonating User {Username} {Error}", _username, ex.Message); AddModuleMessage(Localizer["Error.User.Impersonate"], MessageType.Error); } } private async Task DeleteUser() { try { if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host) && _userid != PageState.User.UserId) { var user = await UserService.GetUserAsync(_userid, PageState.Site.SiteId); await UserService.DeleteUserAsync(user.UserId, PageState.Site.SiteId); await logger.LogInformation("User Permanently Deleted {User}", user); NavigationManager.NavigateTo(NavigateUrl()); } } catch (Exception ex) { await logger.LogError(ex, "Error Permanently Deleting User {UserId} {Error}", _userid, ex.Message); AddModuleMessage(Localizer["Error.DeleteUser"], MessageType.Error); } } private async Task GetPasskeys() { if (_allowpasskeys) { _passkeys = await UserService.GetPasskeysAsync(_userid); } } private async Task DeletePasskey(UserPasskey passkey) { await UserService.DeletePasskeyAsync(_userid, passkey.CredentialId); await GetPasskeys(); StateHasChanged(); } private async Task GetLogins() { if (_allowexternallogin) { _logins = await UserService.GetLoginsAsync(_userid); } } private async Task DeleteLogin(UserLogin login) { await UserService.DeleteLoginAsync(_userid, login.Provider, login.Key); await GetLogins(); StateHasChanged(); } private bool ValidateProfiles() { foreach (Profile profile in _profiles) { var value = GetProfileValue(profile.Name, string.Empty); if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue)) { _settings = SettingService.SetSetting(_settings, profile.Name, profile.DefaultValue); } if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) { if (profile.IsRequired && string.IsNullOrEmpty(value)) { AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning); return false; } if (!string.IsNullOrEmpty(profile.Validation)) { Regex regex = new Regex(profile.Validation); bool valid = regex.Match(value).Success; if (!valid) { AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning); return false; } } } } return true; } private void ProfileChanged(ChangeEventArgs e, string SettingName) { var value = (string)e.Value; _settings = SettingService.SetSetting(_settings, SettingName, value); } private void TogglePassword() { if (_passwordtype == "password") { _passwordtype = "text"; _togglepassword = SharedLocalizer["HidePassword"]; } else { _passwordtype = "password"; _togglepassword = SharedLocalizer["ShowPassword"]; } } }