-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#115 chore: added account page to change username/password
- Loading branch information
1 parent
f27c815
commit 866bea4
Showing
8 changed files
with
224 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
@page "/account" | ||
@using Linguard.Core.Utils | ||
@using Microsoft.AspNetCore.Components | ||
@using Microsoft.AspNetCore.Identity | ||
@using System.Security.Claims | ||
@using Linguard.Web.Services | ||
|
||
<PageTitle>@($"{AssemblyInfo.Product} | {Title}")</PageTitle> | ||
|
||
<RadzenHeading Text="@Title" class="mb-3"/> | ||
|
||
<RadzenCard class="mb-2"> | ||
<RadzenTemplateForm class="align-items-center" Data="@("")"> | ||
<RadzenTabs SelectedIndex="0" RenderMode="TabRenderMode.Server"> | ||
<Tabs> | ||
<RadzenTabsItem Text="Details"> | ||
<div class="row"> | ||
<div class="col-xxl"> | ||
<div class="row"> | ||
<div class=" mb-2"> | ||
<RadzenLabel Text="Username"/> | ||
</div> | ||
</div> | ||
<div class="row"> | ||
<div class="col-xxl-3"> | ||
<RadzenTextBox @bind-Value="_user.UserName" class="w-100"/> | ||
</div> | ||
</div> | ||
<div class="row mt-3"> | ||
<div class="col"> | ||
<RadzenButton ButtonType="ButtonType.Button" Icon="save" Text="Save" class="me-2" | ||
ButtonStyle="ButtonStyle.Primary" Click="Save"/> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</RadzenTabsItem> | ||
<RadzenTabsItem Text="Password"> | ||
<div class="row"> | ||
<div class="col-xxl"> | ||
<div class="row mb-2"> | ||
<div class="col"> | ||
<RadzenLabel Text="Current password"/> | ||
</div> | ||
</div> | ||
<div class="row"> | ||
<div class="col-xxl-3"> | ||
<RadzenPassword @ref="_currentPassword" class="w-100"/> | ||
</div> | ||
</div> | ||
<div class="row my-2"> | ||
<div class="col"> | ||
<RadzenLabel Text="New password"/> | ||
</div> | ||
</div> | ||
<div class="row"> | ||
<div class="col-xxl-3"> | ||
<RadzenPassword @ref="_newPassword" class="w-100"/> | ||
</div> | ||
</div> | ||
<div class="row my-2"> | ||
<div class="col"> | ||
<RadzenLabel Text="Confirm new password"/> | ||
</div> | ||
</div> | ||
<div class="row"> | ||
<div class="col-xxl-3"> | ||
<RadzenPassword @ref="_confirmNewPassword" class="w-100"/> | ||
</div> | ||
</div> | ||
<div class="row mt-3"> | ||
<div class="col"> | ||
<RadzenButton ButtonType="ButtonType.Button" Icon="save" Text="Save" class="me-2" | ||
ButtonStyle="ButtonStyle.Primary" Click="ChangePassword"/> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</RadzenTabsItem> | ||
</Tabs> | ||
</RadzenTabs> | ||
</RadzenTemplateForm> | ||
</RadzenCard> | ||
|
||
@inject NotificationService _notificationService | ||
@inject ILogger _logger | ||
@inject AuthenticationStateProvider _authenticationStateProvider | ||
@inject UserManager<IdentityUser> _userManager | ||
@inject IStateHasChangedNotifierService _notifier | ||
|
||
@code { | ||
private const string Title = "Account"; | ||
private IdentityUser _user; | ||
private RadzenPassword _currentPassword; | ||
private RadzenPassword _newPassword; | ||
private RadzenPassword _confirmNewPassword; | ||
|
||
|
||
protected override async Task OnInitializedAsync() { | ||
var authState = await _authenticationStateProvider.GetAuthenticationStateAsync(); | ||
var userId = authState.User.Claims.SingleOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)); | ||
_user = await _userManager.FindByIdAsync(userId?.Value); | ||
} | ||
|
||
private async Task Save() { | ||
try { | ||
await _userManager.UpdateAsync(_user); | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Success, | ||
Summary = "Account updated!" | ||
}); | ||
_notifier.Notify(); | ||
} | ||
catch (Exception e) { | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Error, | ||
Summary = "Failed to update account", | ||
Detail = e.Message | ||
}); | ||
} | ||
} | ||
|
||
private async Task ChangePassword() { | ||
var result = await IsPasswordValid(); | ||
if (!result) return; | ||
try { | ||
await _userManager.ChangePasswordAsync(_user, _currentPassword.Value, _newPassword.Value); | ||
// TODO not working | ||
// _currentPassword.Value = string.Empty; | ||
// _newPassword.Value = string.Empty; | ||
// _confirmNewPassword.Value = string.Empty; | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Success, | ||
Summary = "Password updated!" | ||
}); | ||
StateHasChanged(); | ||
} | ||
catch (Exception e) { | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Error, | ||
Summary = "Unable to update password!", | ||
Detail = e.Message | ||
}); | ||
} | ||
} | ||
|
||
private async Task<bool> IsPasswordValid() { | ||
var passwordOk = !string.IsNullOrEmpty(_currentPassword.Value) | ||
&& await _userManager.CheckPasswordAsync(_user, _currentPassword.Value); | ||
if (!passwordOk) { | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Error, | ||
Summary = "Unable to update password!", | ||
Detail = "Current password is not correct." | ||
}); | ||
return await Task.FromResult(false); | ||
} | ||
if (string.IsNullOrEmpty(_newPassword.Value) || string.IsNullOrEmpty(_confirmNewPassword.Value)) { | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Error, | ||
Summary = "Unable to update password!", | ||
Detail = "Password cannot be empty." | ||
}); | ||
return await Task.FromResult(false); | ||
} | ||
if (!_newPassword.Value.Equals(_confirmNewPassword.Value)) { | ||
_notificationService.Notify(new NotificationMessage { | ||
Severity = NotificationSeverity.Error, | ||
Summary = "Unable to update password!", | ||
Detail = "Passwords do not match." | ||
}); | ||
return await Task.FromResult(false); | ||
} | ||
return await Task.FromResult(true); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Linguard.Web.Services; | ||
|
||
public interface IStateHasChangedNotifierService { | ||
void Subscribe(EventHandler handler); | ||
void UnSubscribe(EventHandler handler); | ||
void Notify(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace Linguard.Web.Services; | ||
|
||
public class StateHasChangedNotifierService : IStateHasChangedNotifierService { | ||
private readonly ISet<EventHandler> _handlers = new HashSet<EventHandler>(); | ||
public void Subscribe(EventHandler handler) { | ||
_handlers.Add(handler); | ||
} | ||
|
||
public void UnSubscribe(EventHandler handler) { | ||
_handlers.Remove(handler); | ||
} | ||
|
||
public void Notify() { | ||
foreach (var handler in _handlers) { | ||
handler.Invoke(this, EventArgs.Empty); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,12 +27,14 @@ | |
@inject AuthenticationStateProvider _authenticationStateProvider | ||
@inject IJSRuntime _jsRuntime | ||
@inject IAuthenticationService _authenticationService | ||
@inject UserManager<IdentityUser> _userManager | ||
@inject IStateHasChangedNotifierService _notifier | ||
|
||
@code { | ||
|
||
string? _user; | ||
IdentityUser? _user; | ||
string? _email; | ||
string GreetingMessage => $"Hi, {_user}"; | ||
string GreetingMessage => $"Hi, {_user?.UserName}"; | ||
string GravatarEmail => _email ?? "[email protected]"; | ||
|
||
async Task OnStyleChanged(string value) { | ||
|
@@ -44,8 +46,12 @@ | |
|
||
protected override async Task OnInitializedAsync() { | ||
await base.OnInitializedAsync(); | ||
var state = await _authenticationStateProvider.GetAuthenticationStateAsync(); | ||
_user = state.User.Identity?.Name; | ||
var authState = await _authenticationStateProvider.GetAuthenticationStateAsync(); | ||
var userId = authState.User.Claims.SingleOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)); | ||
_user = await _userManager.FindByIdAsync(userId?.Value); | ||
_notifier.Subscribe((_, _) => { | ||
StateHasChanged(); | ||
}); | ||
} | ||
|
||
private void Logout() { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters