2 factor authentication and user account lockout completed
This commit is contained in:
		| @ -7,10 +7,6 @@ | ||||
| @inject IStringLocalizer<Index> Localizer | ||||
| @inject IStringLocalizer<SharedResources> SharedLocalizer | ||||
|  | ||||
| @if (_message != string.Empty) | ||||
| { | ||||
|     <ModuleMessage Message="@_message" Type="@_type" /> | ||||
| } | ||||
| <AuthorizeView Roles="@RoleNames.Registered"> | ||||
|     <Authorizing> | ||||
|         <text>...</text> | ||||
| @ -19,179 +15,208 @@ | ||||
| 		<div>@Localizer["Info.SignedIn"]</div> | ||||
|     </Authorized> | ||||
|     <NotAuthorized> | ||||
|         <form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate> | ||||
|             <div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))"> | ||||
|                 <div class="form-group"> | ||||
|                     <label for="Username" class="control-label">@SharedLocalizer["Username"] </label> | ||||
|                     <input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" required /> | ||||
|                 </div> | ||||
|                 <div class="form-group"> | ||||
|                     <label for="Password" class="control-label">@SharedLocalizer["Password"] </label> | ||||
|                     <input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" required /> | ||||
|                 </div> | ||||
|                 <div class="form-group"> | ||||
|                     <div class="form-check form-check-inline"> | ||||
|                         <label class="form-check-label" for="Remember">@Localizer["RememberMe"]</label>  | ||||
|                         <input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" /> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</button> | ||||
|                 <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button> | ||||
|                 <br /><br /> | ||||
|                 <button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button> | ||||
|             </div> | ||||
|         </form> | ||||
|     </NotAuthorized> | ||||
| 		@if (!twofactor) | ||||
| 		{ | ||||
| 			<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate> | ||||
| 				<div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))"> | ||||
| 					<div class="form-group"> | ||||
| 						<Label Class="control-label" For="username" HelpText="Please enter your Username" ResourceKey="Username">Username:</Label> | ||||
| 						<input id="username" type="text" @ref="username" class="form-control input" placeholder="@Localizer["Username.Placeholder"]" @bind="@_username" required /> | ||||
| 					</div> | ||||
| 					<div class="form-group mt-1"> | ||||
| 						<Label Class="control-label" For="password" HelpText="Please enter your Password" ResourceKey="Password">Password:</Label> | ||||
| 						<input id="password" type="password" name="Password" class="form-control input" placeholder="@Localizer["Password.Placeholder"]" @bind="@_password" required /> | ||||
| 					</div> | ||||
| 					<div class="form-group mt-1"> | ||||
| 						<div class="form-check"> | ||||
| 							<input id="remember" type="checkbox" class="form-check-input" @bind="@_remember" /> | ||||
| 							<Label Class="control-label" For="remember" HelpText="Specify if you would like to be signed back in automatically the next time you visit this site" ResourceKey="Remember">Remember Me?</Label> | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</button> | ||||
| 					<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button> | ||||
| 					<br /><br /> | ||||
| 					<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button> | ||||
| 				</div> | ||||
| 			</form> | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate> | ||||
| 				<div class="container Oqtane-Modules-Admin-Login"> | ||||
| 					<div class="form-group"> | ||||
| 						<Label Class="control-label" For="code" HelpText="Please enter the secure verification code which was sent to you by email" ResourceKey="Code">Verification Code:</Label> | ||||
| 						<input id="code" class="form-control input" @bind="@_code" placeholder="@Localizer["Code.Placeholder"]" maxlength="6" required /> | ||||
| 					</div> | ||||
| 					<br /> | ||||
| 					<button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</button> | ||||
| 					<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Cancel"]</button> | ||||
| 				</div> | ||||
| 			</form> | ||||
| 		} | ||||
| 	</NotAuthorized> | ||||
| </AuthorizeView> | ||||
|  | ||||
| @code { | ||||
|     private string _returnUrl = string.Empty; | ||||
|     private string _message = string.Empty; | ||||
|     private MessageType _type = MessageType.Info; | ||||
|     private string _username = string.Empty; | ||||
|     private string _password = string.Empty; | ||||
|     private bool _remember = false; | ||||
|     private bool validated = false; | ||||
| 	private ElementReference login; | ||||
| 	private bool validated = false; | ||||
| 	private bool twofactor = false; | ||||
| 	private string _username = string.Empty; | ||||
| 	private ElementReference username; | ||||
| 	private string _password = string.Empty; | ||||
| 	private bool _remember = false; | ||||
| 	private string _code = string.Empty; | ||||
|  | ||||
|     private ElementReference login; | ||||
|     private ElementReference username; | ||||
| 	private string _returnUrl = string.Empty; | ||||
|  | ||||
|     public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; | ||||
| 	public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; | ||||
|  | ||||
|     public override List<Resource> Resources => new List<Resource>() | ||||
| 	public override List<Resource> Resources => new List<Resource>() | ||||
|     { | ||||
|         new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" } | ||||
|     }; | ||||
|  | ||||
|     protected override async Task OnInitializedAsync() | ||||
|     { | ||||
|         if (PageState.QueryString.ContainsKey("returnurl")) | ||||
|         { | ||||
|             _returnUrl = PageState.QueryString["returnurl"]; | ||||
|         } | ||||
| 	protected override async Task OnInitializedAsync() | ||||
| 	{ | ||||
| 		if (PageState.QueryString.ContainsKey("returnurl")) | ||||
| 		{ | ||||
| 			_returnUrl = PageState.QueryString["returnurl"]; | ||||
| 		} | ||||
|  | ||||
|         if (PageState.QueryString.ContainsKey("name")) | ||||
|         { | ||||
|             _username = PageState.QueryString["name"]; | ||||
|         } | ||||
| 		if (PageState.QueryString.ContainsKey("name")) | ||||
| 		{ | ||||
| 			_username = PageState.QueryString["name"]; | ||||
| 		} | ||||
|  | ||||
|         if (PageState.QueryString.ContainsKey("token")) | ||||
|         { | ||||
|             var user = new User(); | ||||
|             user.SiteId = PageState.Site.SiteId; | ||||
|             user.Username = _username; | ||||
|             user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]); | ||||
| 		if (PageState.QueryString.ContainsKey("token")) | ||||
| 		{ | ||||
| 			var user = new User(); | ||||
| 			user.SiteId = PageState.Site.SiteId; | ||||
| 			user.Username = _username; | ||||
| 			user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]); | ||||
|  | ||||
|             if (user != null) | ||||
|             { | ||||
|                 await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username); | ||||
|                 _message = Localizer["Success.Account.Verified"]; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username); | ||||
|                 _message = Localizer["Message.Account.NotVerfied"]; | ||||
|                 _type = MessageType.Warning; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 			if (user != null) | ||||
| 			{ | ||||
| 				await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username); | ||||
| 				AddModuleMessage(Localizer["Success.Account.Verified"], MessageType.Info);						 | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username); | ||||
| 				AddModuleMessage(Localizer["Message.Account.NotVerfied"], MessageType.Warning);						 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|     protected override async Task OnAfterRenderAsync(bool firstRender) | ||||
|     { | ||||
|         if (firstRender) | ||||
|         { | ||||
|             if(PageState.User == null) | ||||
|             { | ||||
|                 await username.FocusAsync(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 	protected override async Task OnAfterRenderAsync(bool firstRender) | ||||
| 	{ | ||||
| 		if (firstRender && PageState.User == null) | ||||
| 		{ | ||||
| 			await username.FocusAsync(); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|     private async Task Login() | ||||
|     { | ||||
|         validated = true; | ||||
|         var interop = new Interop(JSRuntime); | ||||
|         if (await interop.FormValid(login)) | ||||
|         { | ||||
|             if (PageState.Runtime == Oqtane.Shared.Runtime.Server) | ||||
|             { | ||||
|                 var user = new User(); | ||||
|                 user.SiteId = PageState.Site.SiteId; | ||||
|                 user.Username = _username; | ||||
|                 user.Password = _password; | ||||
|                 user = await UserService.LoginUserAsync(user, false, false); | ||||
| 	private async Task Login() | ||||
| 	{ | ||||
| 		validated = true; | ||||
| 		var interop = new Interop(JSRuntime); | ||||
| 		if (await interop.FormValid(login)) | ||||
| 		{ | ||||
| 			var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password}; | ||||
|  | ||||
|                 if (user.IsAuthenticated) | ||||
|                 { | ||||
|                     await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username); | ||||
|                     // server-side Blazor needs to post to the Login page so that the cookies are set correctly | ||||
|                     var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl }; | ||||
|                     string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/"); | ||||
|                     await interop.SubmitForm(url, fields); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username); | ||||
|                     AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error); | ||||
|                 } | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // client-side Blazor | ||||
|                 var user = new User(); | ||||
|                 user.SiteId = PageState.Site.SiteId; | ||||
|                 user.Username = _username; | ||||
|                 user.Password = _password; | ||||
|                 user = await UserService.LoginUserAsync(user, true, _remember); | ||||
|                 if (user.IsAuthenticated) | ||||
|                 { | ||||
|                     await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username); | ||||
|                     var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); | ||||
|                     authstateprovider.NotifyAuthenticationChanged(); | ||||
|                     NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true)); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username); | ||||
|                     AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning); | ||||
|         } | ||||
|     } | ||||
| 			if (!twofactor) | ||||
| 			{ | ||||
| 				user = await UserService.LoginUserAsync(user, false, false); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				user = await UserService.VerifyTwoFactorAsync(user, _code); | ||||
| 			} | ||||
|  | ||||
|     private void Cancel() | ||||
|     { | ||||
|         NavigationManager.NavigateTo(_returnUrl); | ||||
|     } | ||||
| 			if (user.IsAuthenticated) | ||||
| 			{ | ||||
| 				await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username); | ||||
|  | ||||
|     private async Task Forgot() | ||||
|     { | ||||
|         if (_username != string.Empty) | ||||
|         { | ||||
|             var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId); | ||||
|             if (user != null) | ||||
|             { | ||||
|                 await UserService.ForgotPasswordAsync(user); | ||||
|                 await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username); | ||||
|                 _message = Localizer["Message.ForgotUser"]; | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 _message = Localizer["Message.UserDoesNotExist"]; | ||||
|                 _type = MessageType.Warning; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             _message = Localizer["Message.ForgotPassword"]; | ||||
|         } | ||||
| 				if (PageState.Runtime == Oqtane.Shared.Runtime.Server) | ||||
| 				{ | ||||
| 					// server-side Blazor needs to post to the Login page so that the cookies are set correctly | ||||
| 					var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl }; | ||||
| 					string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/"); | ||||
| 					await interop.SubmitForm(url, fields); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); | ||||
| 					authstateprovider.NotifyAuthenticationChanged(); | ||||
| 					NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true)); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (user.TwoFactorRequired) | ||||
| 				{ | ||||
| 					twofactor = true; | ||||
| 					validated = false; | ||||
| 					AddModuleMessage(Localizer["Message.TwoFactor"], MessageType.Info); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					if (!twofactor) | ||||
| 					{ | ||||
| 						await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username); | ||||
| 						AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);						 | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						await logger.LogInformation(LogFunction.Security, "Two Factor Verification Failed For Username {Username}", _username); | ||||
| 						AddModuleMessage(Localizer["Error.TwoFactor.Fail"], MessageType.Error);						 | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|         StateHasChanged(); | ||||
|     } | ||||
| 	private void Cancel() | ||||
| 	{ | ||||
| 		NavigationManager.NavigateTo(_returnUrl); | ||||
| 	} | ||||
|  | ||||
| 	private async Task Forgot() | ||||
| 	{ | ||||
| 		if (_username != string.Empty) | ||||
| 		{ | ||||
| 			var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId); | ||||
| 			if (user != null) | ||||
| 			{ | ||||
| 				await UserService.ForgotPasswordAsync(user); | ||||
| 				await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username); | ||||
| 				AddModuleMessage(Localizer["Message.ForgotUser"], MessageType.Info); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				AddModuleMessage(Localizer["Message.UserDoesNotExist"], MessageType.Warning); | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			AddModuleMessage(Localizer["Message.ForgotPassword"], MessageType.Info); | ||||
| 		} | ||||
|  | ||||
| 		StateHasChanged(); | ||||
| 	} | ||||
|  | ||||
| 	private void Reset() | ||||
| 	{ | ||||
| 		twofactor = false; | ||||
| 		_username = ""; | ||||
| 		_password = ""; | ||||
| 		ClearModuleMessage(); | ||||
| 		StateHasChanged(); | ||||
| 	} | ||||
|  | ||||
|     private async Task KeyPressed(KeyboardEventArgs e) | ||||
|     { | ||||
|  | ||||
| @ -41,6 +41,15 @@ else | ||||
|                         <input id="confirm" type="password" class="form-control" @bind="@confirm" autocomplete="new-password" /> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="row mb-1 align-items-center"> | ||||
|                     <Label Class="col-sm-3" For="twofactor" HelpText="Indicates if you are using two factor authentication" ResourceKey="TwoFactor"></Label> | ||||
|                     <div class="col-sm-9"> | ||||
| 						<select id="twofactor" class="form-select" @bind="@twofactor" required> | ||||
| 							<option value="True">@SharedLocalizer["Yes"]</option> | ||||
| 							<option value="False">@SharedLocalizer["No"]</option> | ||||
| 						</select> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="row mb-1 align-items-center"> | ||||
|                     <Label Class="col-sm-3" For="email" HelpText="Your email address where you wish to receive notifications" ResourceKey="Email"></Label> | ||||
|                     <div class="col-sm-9"> | ||||
| @ -201,104 +210,119 @@ else | ||||
|         } | ||||
|     </TabPanel> | ||||
| </TabStrip> | ||||
| <br /><br /> | ||||
|  | ||||
| @code { | ||||
|     private string username = string.Empty; | ||||
|     private string password = string.Empty; | ||||
|     private string confirm = string.Empty; | ||||
|     private string email = string.Empty; | ||||
|     private string displayname = string.Empty; | ||||
|     private FileManager filemanager; | ||||
|     private int folderid = -1; | ||||
|     private int photofileid = -1; | ||||
|     private File photo = null; | ||||
|     private List<Profile> profiles; | ||||
|     private Dictionary<string, string> settings; | ||||
|     private string category = string.Empty; | ||||
|     private string filter = "to"; | ||||
|     private List<Notification> notifications; | ||||
| 	private string username = string.Empty; | ||||
| 	private string password = string.Empty; | ||||
| 	private string confirm = string.Empty; | ||||
| 	private string twofactor = "False"; | ||||
| 	private string email = string.Empty; | ||||
| 	private string displayname = string.Empty; | ||||
| 	private FileManager filemanager; | ||||
| 	private int folderid = -1; | ||||
| 	private int photofileid = -1; | ||||
| 	private File photo = null; | ||||
| 	private List<Profile> profiles; | ||||
| 	private Dictionary<string, string> settings; | ||||
| 	private string category = string.Empty; | ||||
| 	private string filter = "to"; | ||||
| 	private List<Notification> notifications; | ||||
|  | ||||
|     public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; | ||||
| 	public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; | ||||
|  | ||||
|     protected override async Task OnParametersSetAsync() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (PageState.User != null) | ||||
|             { | ||||
|                 username = PageState.User.Username; | ||||
|                 email = PageState.User.Email; | ||||
|                 displayname = PageState.User.DisplayName; | ||||
| 	protected override async Task OnParametersSetAsync() | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			if (PageState.User != null) | ||||
| 			{ | ||||
| 				username = PageState.User.Username; | ||||
| 				twofactor = PageState.User.TwoFactorRequired.ToString(); | ||||
| 				email = PageState.User.Email; | ||||
| 				displayname = PageState.User.DisplayName; | ||||
|  | ||||
|                 // get user folder | ||||
|                 var folder = await FolderService.GetFolderAsync(ModuleState.SiteId, PageState.User.FolderPath); | ||||
|                 if (folder != null) | ||||
|                 { | ||||
|                     folderid = folder.FolderId; | ||||
|                 } | ||||
| 				// get user folder | ||||
| 				var folder = await FolderService.GetFolderAsync(ModuleState.SiteId, PageState.User.FolderPath); | ||||
| 				if (folder != null) | ||||
| 				{ | ||||
| 					folderid = folder.FolderId; | ||||
| 				} | ||||
|  | ||||
|                 if (PageState.User.PhotoFileId != null) | ||||
|                 { | ||||
|                     photofileid = PageState.User.PhotoFileId.Value; | ||||
|                     photo = await FileService.GetFileAsync(photofileid); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     photofileid = -1; | ||||
|                     photo = null; | ||||
|                 } | ||||
| 				if (PageState.User.PhotoFileId != null) | ||||
| 				{ | ||||
| 					photofileid = PageState.User.PhotoFileId.Value; | ||||
| 					photo = await FileService.GetFileAsync(photofileid); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					photofileid = -1; | ||||
| 					photo = null; | ||||
| 				} | ||||
|  | ||||
|                 profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId); | ||||
|                 settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); | ||||
| 				profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId); | ||||
| 				settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); | ||||
|  | ||||
|                 await LoadNotificationsAsync(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
|             await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); | ||||
|             AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error); | ||||
|         } | ||||
|     } | ||||
| 				await LoadNotificationsAsync(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning); | ||||
| 			} | ||||
| 		} | ||||
| 		catch (Exception ex) | ||||
| 		{ | ||||
| 			await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); | ||||
| 			AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|     private async Task LoadNotificationsAsync() | ||||
|     { | ||||
|         notifications = await NotificationService.GetNotificationsAsync(PageState.Site.SiteId, filter, PageState.User.UserId); | ||||
|         notifications = notifications.Where(item => item.DeletedBy != PageState.User.Username).ToList(); | ||||
|     } | ||||
| 	private async Task LoadNotificationsAsync() | ||||
| 	{ | ||||
| 		notifications = await NotificationService.GetNotificationsAsync(PageState.Site.SiteId, filter, PageState.User.UserId); | ||||
| 		notifications = notifications.Where(item => item.DeletedBy != PageState.User.Username).ToList(); | ||||
| 	} | ||||
|  | ||||
|     private string GetProfileValue(string SettingName, string DefaultValue) | ||||
|         => SettingService.GetSetting(settings, SettingName, DefaultValue); | ||||
| 	private string GetProfileValue(string SettingName, string DefaultValue) | ||||
| 		=> SettingService.GetSetting(settings, SettingName, DefaultValue); | ||||
|  | ||||
|     private async Task Save() | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (username != string.Empty && email != string.Empty && ValidateProfiles()) | ||||
|             { | ||||
|                 if (password == confirm) | ||||
|                 { | ||||
|                     var user = PageState.User; | ||||
|                     user.Username = username; | ||||
|                     user.Password = password; | ||||
|                     user.Email = email; | ||||
|                     user.DisplayName = (displayname == string.Empty ? username : displayname); | ||||
|                     user.PhotoFileId = filemanager.GetFileId(); | ||||
|                     if (user.PhotoFileId == -1) | ||||
|                     { | ||||
|                         user.PhotoFileId = null; | ||||
|                     } | ||||
| 	private async Task Save() | ||||
| 	{ | ||||
| 		try | ||||
| 		{ | ||||
| 			if (username != string.Empty && email != string.Empty && ValidateProfiles()) | ||||
| 			{ | ||||
| 				if (password == confirm) | ||||
| 				{ | ||||
| 					var user = PageState.User; | ||||
| 					user.Username = username; | ||||
| 					user.Password = password; | ||||
| 					user.TwoFactorRequired = bool.Parse(twofactor); | ||||
| 					user.Email = email; | ||||
| 					user.DisplayName = (displayname == string.Empty ? username : displayname); | ||||
| 					user.PhotoFileId = filemanager.GetFileId(); | ||||
| 					if (user.PhotoFileId == -1) | ||||
| 					{ | ||||
| 						user.PhotoFileId = null; | ||||
| 					} | ||||
| 					if (user.PhotoFileId != null) | ||||
| 					{ | ||||
| 						photofileid = user.PhotoFileId.Value; | ||||
| 						photo = await FileService.GetFileAsync(photofileid); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						photofileid = -1; | ||||
| 						photo = null; | ||||
| 					} | ||||
|  | ||||
|                     await UserService.UpdateUserAsync(user); | ||||
|                     await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); | ||||
|                     await logger.LogInformation("User Profile Saved"); | ||||
| 					await UserService.UpdateUserAsync(user); | ||||
| 					await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); | ||||
| 					await logger.LogInformation("User Profile Saved"); | ||||
|  | ||||
|                     NavigationManager.NavigateTo(NavigateUrl()); | ||||
|                 } | ||||
| 					AddModuleMessage(Localizer["Success.Profile.Update"], MessageType.Success); | ||||
| 					StateHasChanged(); | ||||
| 				} | ||||
|                 else | ||||
|                 { | ||||
|                     AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker