Skip to content

Commit

Permalink
feat: login page register and pwd links
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions committed May 28, 2022
1 parent 407acbe commit 2914654
Show file tree
Hide file tree
Showing 14 changed files with 406 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,4 @@ override.tf.json
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
# example: *tfplan*
/sample/Aguacongas.TheIdServer.MtlsSample/client.pks
/sample/Aguacongas.TheIdServer.MtlsSample/.dccache
24 changes: 24 additions & 0 deletions src/Aguacongas.TheIdServer.Duende/Localization-fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -2042,5 +2042,29 @@
{
"key": "allowed identity token signing algorithms",
"value": "algorithmes de signature de jeton d'identité autorisés"
},
{
"key": "Reset password",
"value": "Réinitialiser le mot de passe"
},
{
"key": "Reset your password.",
"value": "Réinitialisez votre mot de passe."
},
{
"key": "Reset",
"value": "Réinitialiser"
},
{
"key": "Reset password confirmation",
"value": "Confirmation de la réinitialisation du mot de passe"
},
{
"key": "Your password has been reset.",
"value": "Votre mot de passe a été réinitialisé."
},
{
"key": "Please click here to log in",
"value": "Veuillez cliquer ici pour vous connecter"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ public IActionResult AccessDenied()
private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)
{
var context = await _interaction.GetAuthorizationContextAsync(returnUrl).ConfigureAwait(false);

if (context?.IdP != null && await _schemeProvider.GetSchemeAsync(context.IdP).ConfigureAwait(false) != null)
{
var local = context.IdP == IdentityServerConstants.LocalIdentityProvider;
Expand Down Expand Up @@ -304,7 +305,10 @@ private async Task<LoginViewModel> BuildLoginViewModelAsync(string returnUrl)
EnableLocalLogin = allowLocal && settings.AllowLocalLogin,
ReturnUrl = returnUrl,
Username = context?.LoginHint,
ExternalProviders = providers.ToArray()
ExternalProviders = providers.ToArray(),
ShowForgotPassworLink = settings.ShowForgotPassworLink,
ShowRegisterLink = settings.ShowRegisterLink,
ShowResendEmailConfirmationLink = settings.ShowResendEmailConfirmationLink
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,12 @@ public class AccountOptions
public bool IncludeWindowsGroups { get; set; } = false;

public string InvalidCredentialsErrorMessage { get; set; } = "Invalid username or password";

public bool ShowForgotPassworLink { get; set; } = true;

public bool ShowRegisterLink { get; set; } = true;

public bool ShowResendEmailConfirmationLink { get; set; } = true;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@ public class LoginViewModel : LoginInputModel

public bool IsExternalLoginOnly => !EnableLocalLogin && ExternalProviders?.Count() == 1;
public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null;

public bool ShowForgotPassworLink { get; set; } = true;

public bool ShowRegisterLink { get; set; } = true;

public bool ShowResendEmailConfirmationLink { get; set; } = true;
}
}
24 changes: 22 additions & 2 deletions src/Aguacongas.TheIdServer.Shared/Views/Account/Login.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,36 @@
<button class="w-100 btn btn-lg btn-primary mb-2" name="button" value="login">
@Localizer["Login"]
</button>
<button class="w-100 btn btn-lg btn btn-secondary mb-2" name="button" value="cancel">@Localizer["Cancel"]</button>
<button class="w-100 btn btn-lg btn btn-secondary mb-3" name="button" value="cancel">@Localizer["Cancel"]</button>
@if (Model.AllowRememberLogin)
{
<div class="login-remember">
<div class="login-remember mb-3">
<label asp-for="RememberLogin">
<input asp-for="RememberLogin">
<strong>@Localizer["Remember My Login"]</strong>
</label>
</div>
}
<div>
@if (Model.ShowForgotPassworLink)
{
<p>
<a asp-area="Identity" asp-page="/Account/ForgotPassword" asp-route-returnUrl="@Model.ReturnUrl">Forgot your password?</a>
</p>
}
@if (Model.ShowRegisterLink)
{
<p>
<a asp-area="Identity" asp-page="/Account/Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
}
@if (Model.ShowResendEmailConfirmationLink)
{
<p>
<a asp-area="Identity" asp-page="/Account/ResendEmailConfirmation">Resend email confirmation</a>
</p>
}
</div>
</div>
</div>
</fieldset>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Copyright (c) 2022 @Olivier Lefebvre
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<input asp-for="Input.ReturnUrl" type="hidden" />
<div class="form-floating mb-2">
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" />
<label asp-for="Input.Email" class="form-label"></label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public class InputModel
[Required]
[EmailAddress]
public string Email { get; set; }
public string ReturnUrl { get; set; }
}

public void OnGet(string returnUrl = null)
{
Input = new InputModel
{
ReturnUrl = returnUrl
};
}

public async Task<IActionResult> OnPostAsync()
Expand All @@ -59,7 +68,7 @@ public async Task<IActionResult> OnPostAsync()
var callbackUrl = Url.Page(
"/Account/ResetPassword",
pageHandler: null,
values: new { area = "Identity", code },
values: new { area = "Identity", code, returnUrl = Input.ReturnUrl },
protocol: Request.Scheme);

await _emailSender.SendEmailAsync(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@page
@model ResendEmailConfirmationModel
@{
ViewData["Title"] = "Resend email confirmation";
}

<h1>@ViewData["Title"]</h1>
<h2>Enter your email.</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-floating mb-2">
<input asp-for="Input.Email" class="form-control" aria-required="true" />
<label asp-for="Input.Email" class="form-label"></label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary">Resend</button>
</form>
</div>
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#nullable disable

using Aguacongas.TheIdServer.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Localization;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

namespace Aguacongas.TheIdServer.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ResendEmailConfirmationModel : PageModel
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IEmailSender _emailSender;
private readonly IStringLocalizer _localizer;

public ResendEmailConfirmationModel(UserManager<ApplicationUser> userManager, IEmailSender emailSender, IStringLocalizer<ResendEmailConfirmationModel> localizer)
{
_userManager = userManager;
_emailSender = emailSender;
_localizer = localizer;
}

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[BindProperty]
public InputModel Input { get; set; }

/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
public class InputModel
{
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Required]
[EmailAddress]
public string Email { get; set; }
}

public void OnGet()
{
}

public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}

var user = await _userManager.FindByEmailAsync(Input.Email);
if (user == null)
{
ModelState.AddModelError(string.Empty, _localizer["Verification email sent. Please check your email."]);
return Page();
}

var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(
Input.Email,
_localizer["Confirm your email"],
_localizer[$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."]);

ModelState.AddModelError(string.Empty, _localizer["Verification email sent. Please check your email."]);
return Page();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
@*
Project: Aguafrommars/TheIdServer
Copyright (c) 2022 @Olivier Lefebvre
*@
@page
@inject IViewLocalizer Localizer

@model ResetPasswordModel
@{
ViewData["Title"] = Localizer["Reset password"];
}

<h1>@ViewData["Title"]</h1>
<h2>@Localizer["Reset your password."]</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="Input.Code" type="hidden" />
<input asp-for="Input.ReturnUrl" type="hidden" />
<div class="form-floating mb-2">
<input asp-for="Input.Email" class="form-control" autocomplete="username" aria-required="true" />
<label asp-for="Input.Email" class="form-label"></label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-floating mb-2">
<input asp-for="Input.Password" class="form-control" autocomplete="new-password" aria-required="true" />
<label asp-for="Input.Password" class="form-label"></label>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-floating mb-2">
<input asp-for="Input.ConfirmPassword" class="form-control" autocomplete="new-password" aria-required="true" />
<label asp-for="Input.ConfirmPassword" class="form-label"></label>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="w-100 btn btn-lg btn-primary">@Localizer["Reset"]</button>
</form>
</div>
</div>

@section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Loading

0 comments on commit 2914654

Please sign in to comment.