Files
Aaru.Server/Aaru.Server.New/Components/Account/Pages/Manage/ExternalLogins.razor

141 lines
5.1 KiB
Plaintext

@page "/Account/Manage/ExternalLogins"
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity
@inject UserManager<IdentityUser> UserManager
@inject SignInManager<IdentityUser> SignInManager
@inject IdentityUserAccessor UserAccessor
@inject IUserStore<IdentityUser> UserStore
@inject IdentityRedirectManager RedirectManager
<PageTitle>Manage your external logins</PageTitle>
<StatusMessage/>
@if(currentLogins?.Count > 0)
{
<h3>Registered Logins</h3>
<table class="table">
<tbody>
@foreach(UserLoginInfo login in currentLogins)
{
<tr>
<td>@login.ProviderDisplayName</td>
<td>
@if(showRemoveButton)
{
<form @formname="@($"remove-login-{login.LoginProvider}")" method="post" @onsubmit="OnSubmitAsync">
<AntiforgeryToken/>
<div>
<input name="@nameof(LoginProvider)" type="hidden" value="@login.LoginProvider"/>
<input name="@nameof(ProviderKey)" type="hidden" value="@login.ProviderKey"/>
<button class="btn btn-primary" title="Remove this @login.ProviderDisplayName login from your account" type="submit">Remove</button>
</div>
</form>
}
else
{
@: &nbsp;
}
</td>
</tr>
}
</tbody>
</table>
}
@if(otherLogins?.Count > 0)
{
<h4>Add another service to log in.</h4>
<hr/>
<form action="Account/Manage/LinkExternalLogin" class="form-horizontal" method="post">
<AntiforgeryToken/>
<div>
<p>
@foreach(AuthenticationScheme provider in otherLogins)
{
<button class="btn btn-primary" name="Provider" title="Log in using your @provider.DisplayName account" type="submit" value="@provider.Name">
@provider.DisplayName
</button>
}
</p>
</div>
</form>
}
@code {
public const string LinkLoginCallbackAction = "LinkLoginCallback";
private IdentityUser user = default!;
private IList<UserLoginInfo>? currentLogins;
private IList<AuthenticationScheme>? otherLogins;
private bool showRemoveButton;
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
[SupplyParameterFromForm]
private string? LoginProvider { get; set; }
[SupplyParameterFromForm]
private string? ProviderKey { get; set; }
[SupplyParameterFromQuery]
private string? Action { get; set; }
protected override async Task OnInitializedAsync()
{
user = await UserAccessor.GetRequiredUserAsync(HttpContext);
currentLogins = await UserManager.GetLoginsAsync(user);
otherLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Where(auth => currentLogins.All(ul => auth.Name != ul.LoginProvider)).ToList();
string? passwordHash = null;
if(UserStore is IUserPasswordStore<IdentityUser> userPasswordStore)
{
passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
}
showRemoveButton = passwordHash is not null || currentLogins.Count > 1;
if(HttpMethods.IsGet(HttpContext.Request.Method) && Action == LinkLoginCallbackAction)
{
await OnGetLinkLoginCallbackAsync();
}
}
private async Task OnSubmitAsync()
{
IdentityResult result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!);
if(!result.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", HttpContext);
}
await SignInManager.RefreshSignInAsync(user);
RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", HttpContext);
}
private async Task OnGetLinkLoginCallbackAsync()
{
string userId = await UserManager.GetUserIdAsync(user);
ExternalLoginInfo? info = await SignInManager.GetExternalLoginInfoAsync(userId);
if(info is null)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext);
}
IdentityResult result = await UserManager.AddLoginAsync(user, info);
if(!result.Succeeded)
{
RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", HttpContext);
}
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", HttpContext);
}
}