Skip to content

Commit 32540d5

Browse files
committed
Fix resend email confirmation
Update src/Identity/UI/src/Areas/Identity/Pages/V3/Account/ResendEmailConfirmation.cshtml Co-Authored-By: campersau <[email protected]> Resend not reset Update ref Add new email confirmation link to templates test Fix test Revert website change
1 parent 7401e0b commit 32540d5

File tree

16 files changed

+376
-32
lines changed

16 files changed

+376
-32
lines changed

src/Identity/UI/ref/Microsoft.AspNetCore.Identity.UI.netcoreapp.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,22 @@ public InputModel() { }
208208
}
209209
}
210210
[Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute]
211+
public abstract partial class ResendEmailConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
212+
{
213+
protected ResendEmailConfirmationModel() { }
214+
[Microsoft.AspNetCore.Mvc.BindPropertyAttribute]
215+
public Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal.ResendEmailConfirmationModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
216+
public virtual void OnGet() { }
217+
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostAsync() { throw null; }
218+
public partial class InputModel
219+
{
220+
public InputModel() { }
221+
[System.ComponentModel.DataAnnotations.EmailAddressAttribute]
222+
[System.ComponentModel.DataAnnotations.RequiredAttribute]
223+
public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
224+
}
225+
}
226+
[Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute]
211227
public partial class ResetPasswordConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
212228
{
213229
public ResetPasswordConfirmationModel() { }
@@ -658,6 +674,22 @@ public InputModel() { }
658674
}
659675
}
660676
[Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute]
677+
public abstract partial class ResendEmailConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
678+
{
679+
protected ResendEmailConfirmationModel() { }
680+
[Microsoft.AspNetCore.Mvc.BindPropertyAttribute]
681+
public Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.ResendEmailConfirmationModel.InputModel Input { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
682+
public virtual void OnGet() { }
683+
public virtual System.Threading.Tasks.Task<Microsoft.AspNetCore.Mvc.IActionResult> OnPostAsync() { throw null; }
684+
public partial class InputModel
685+
{
686+
public InputModel() { }
687+
[System.ComponentModel.DataAnnotations.EmailAddressAttribute]
688+
[System.ComponentModel.DataAnnotations.RequiredAttribute]
689+
public string Email { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
690+
}
691+
}
692+
[Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute]
661693
public partial class ResetPasswordConfirmationModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
662694
{
663695
public ResetPasswordConfirmationModel() { }

src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
4343
</p>
4444
<p>
45-
<button id="resend-confirmation" type="submit" asp-page-handler="SendVerificationEmail" class="btn-link" style="padding:0px;margin:0px;border:0px">Resend email confirmation</button>
45+
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">Resend email confirmation</a>
4646
</p>
4747
</div>
4848
</form>

src/Identity/UI/src/Areas/Identity/Pages/V3/Account/Login.cshtml.cs

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -169,34 +169,5 @@ public override async Task<IActionResult> OnPostAsync(string returnUrl = null)
169169
// If we got this far, something failed, redisplay form
170170
return Page();
171171
}
172-
173-
public override async Task<IActionResult> OnPostSendVerificationEmailAsync()
174-
{
175-
if (!ModelState.IsValid)
176-
{
177-
return Page();
178-
}
179-
180-
var user = await _userManager.FindByEmailAsync(Input.Email);
181-
if (user == null)
182-
{
183-
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
184-
}
185-
186-
var userId = await _userManager.GetUserIdAsync(user);
187-
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
188-
var callbackUrl = Url.Page(
189-
"/Account/ConfirmEmail",
190-
pageHandler: null,
191-
values: new { userId = userId, code = code },
192-
protocol: Request.Scheme);
193-
await _emailSender.SendEmailAsync(
194-
Input.Email,
195-
"Confirm your email",
196-
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
197-
198-
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
199-
return Page();
200-
}
201172
}
202173
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@page
2+
@model ResendEmailConfirmationModel
3+
@{
4+
ViewData["Title"] = "Resend email confirmation";
5+
}
6+
7+
<h2>@ViewData["Title"]</h2>
8+
<h4>Enter your email.</h4>
9+
<hr />
10+
<div class="row">
11+
<div class="col-md-4">
12+
<form method="post">
13+
<div asp-validation-summary="All" class="text-danger"></div>
14+
<div class="form-group">
15+
<label asp-for="Input.Email"></label>
16+
<input asp-for="Input.Email" class="form-control" />
17+
<span asp-validation-for="Input.Email" class="text-danger"></span>
18+
</div>
19+
<button type="submit" class="btn btn-default">Resend</button>
20+
</form>
21+
</div>
22+
</div>
23+
24+
@section Scripts {
25+
<partial name="_ValidationScriptsPartial" />
26+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.ComponentModel.DataAnnotations;
6+
using System.Text.Encodings.Web;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Authorization;
9+
using Microsoft.AspNetCore.Identity.UI.Services;
10+
using Microsoft.AspNetCore.Mvc;
11+
using Microsoft.AspNetCore.Mvc.RazorPages;
12+
13+
namespace Microsoft.AspNetCore.Identity.UI.V3.Pages.Account.Internal
14+
{
15+
/// <summary>
16+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
17+
/// directly from your code. This API may change or be removed in future releases.
18+
/// </summary>
19+
[AllowAnonymous]
20+
[IdentityDefaultUI(typeof(ResendEmailConfirmationModel<>))]
21+
public abstract class ResendEmailConfirmationModel : PageModel
22+
{
23+
/// <summary>
24+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
25+
/// directly from your code. This API may change or be removed in future releases.
26+
/// </summary>
27+
[BindProperty]
28+
public InputModel Input { get; set; }
29+
30+
/// <summary>
31+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
32+
/// directly from your code. This API may change or be removed in future releases.
33+
/// </summary>
34+
public class InputModel
35+
{
36+
/// <summary>
37+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
38+
/// directly from your code. This API may change or be removed in future releases.
39+
/// </summary>
40+
[Required]
41+
[EmailAddress]
42+
public string Email { get; set; }
43+
}
44+
45+
/// <summary>
46+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
47+
/// directly from your code. This API may change or be removed in future releases.
48+
/// </summary>
49+
public virtual void OnGet() => throw new NotImplementedException();
50+
51+
/// <summary>
52+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
53+
/// directly from your code. This API may change or be removed in future releases.
54+
/// </summary>
55+
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
56+
}
57+
58+
internal class ResendEmailConfirmationModel<TUser> : ResendEmailConfirmationModel where TUser : class
59+
{
60+
private readonly UserManager<TUser> _userManager;
61+
private readonly IEmailSender _emailSender;
62+
63+
public ResendEmailConfirmationModel(UserManager<TUser> userManager, IEmailSender emailSender)
64+
{
65+
_userManager = userManager;
66+
_emailSender = emailSender;
67+
}
68+
69+
public override void OnGet()
70+
{
71+
}
72+
73+
public override async Task<IActionResult> OnPostAsync()
74+
{
75+
if (!ModelState.IsValid)
76+
{
77+
return Page();
78+
}
79+
80+
var user = await _userManager.FindByEmailAsync(Input.Email);
81+
if (user == null)
82+
{
83+
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
84+
return Page();
85+
}
86+
87+
var userId = await _userManager.GetUserIdAsync(user);
88+
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
89+
var callbackUrl = Url.Page(
90+
"/Account/ConfirmEmail",
91+
pageHandler: null,
92+
values: new { userId = userId, code = code },
93+
protocol: Request.Scheme);
94+
await _emailSender.SendEmailAsync(
95+
Input.Email,
96+
"Confirm your email",
97+
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
98+
99+
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
100+
return Page();
101+
}
102+
}
103+
}

src/Identity/UI/src/Areas/Identity/Pages/V4/Account/Login.cshtml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
<p>
4242
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
4343
</p>
44+
<p>
45+
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">Resend email confirmation</a>
46+
</p>
4447
</div>
4548
</form>
4649
</section>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@page
2+
@model ResendEmailConfirmationModel
3+
@{
4+
ViewData["Title"] = "Resend email confirmation";
5+
}
6+
7+
<h1>@ViewData["Title"]</h1>
8+
<h4>Enter your email.</h4>
9+
<hr />
10+
<div class="row">
11+
<div class="col-md-4">
12+
<form method="post">
13+
<div asp-validation-summary="All" class="text-danger"></div>
14+
<div class="form-group">
15+
<label asp-for="Input.Email"></label>
16+
<input asp-for="Input.Email" class="form-control" />
17+
<span asp-validation-for="Input.Email" class="text-danger"></span>
18+
</div>
19+
<button type="submit" class="btn btn-primary">Resend</button>
20+
</form>
21+
</div>
22+
</div>
23+
24+
@section Scripts {
25+
<partial name="_ValidationScriptsPartial" />
26+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.ComponentModel.DataAnnotations;
6+
using System.Text.Encodings.Web;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNetCore.Authorization;
9+
using Microsoft.AspNetCore.Identity.UI.Services;
10+
using Microsoft.AspNetCore.Mvc;
11+
using Microsoft.AspNetCore.Mvc.RazorPages;
12+
13+
namespace Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal
14+
{
15+
/// <summary>
16+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
17+
/// directly from your code. This API may change or be removed in future releases.
18+
/// </summary>
19+
[AllowAnonymous]
20+
[IdentityDefaultUI(typeof(ResendEmailConfirmationModel<>))]
21+
public abstract class ResendEmailConfirmationModel : PageModel
22+
{
23+
/// <summary>
24+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
25+
/// directly from your code. This API may change or be removed in future releases.
26+
/// </summary>
27+
[BindProperty]
28+
public InputModel Input { get; set; }
29+
30+
/// <summary>
31+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
32+
/// directly from your code. This API may change or be removed in future releases.
33+
/// </summary>
34+
public class InputModel
35+
{
36+
/// <summary>
37+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
38+
/// directly from your code. This API may change or be removed in future releases.
39+
/// </summary>
40+
[Required]
41+
[EmailAddress]
42+
public string Email { get; set; }
43+
}
44+
45+
/// <summary>
46+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
47+
/// directly from your code. This API may change or be removed in future releases.
48+
/// </summary>
49+
public virtual void OnGet() => throw new NotImplementedException();
50+
51+
/// <summary>
52+
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
53+
/// directly from your code. This API may change or be removed in future releases.
54+
/// </summary>
55+
public virtual Task<IActionResult> OnPostAsync() => throw new NotImplementedException();
56+
}
57+
58+
internal class ResendEmailConfirmationModel<TUser> : ResendEmailConfirmationModel where TUser : class
59+
{
60+
private readonly UserManager<TUser> _userManager;
61+
private readonly IEmailSender _emailSender;
62+
63+
public ResendEmailConfirmationModel(UserManager<TUser> userManager, IEmailSender emailSender)
64+
{
65+
_userManager = userManager;
66+
_emailSender = emailSender;
67+
}
68+
69+
public override void OnGet()
70+
{
71+
}
72+
73+
public override async Task<IActionResult> OnPostAsync()
74+
{
75+
if (!ModelState.IsValid)
76+
{
77+
return Page();
78+
}
79+
80+
var user = await _userManager.FindByEmailAsync(Input.Email);
81+
if (user == null)
82+
{
83+
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
84+
return Page();
85+
}
86+
87+
var userId = await _userManager.GetUserIdAsync(user);
88+
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
89+
var callbackUrl = Url.Page(
90+
"/Account/ConfirmEmail",
91+
pageHandler: null,
92+
values: new { userId = userId, code = code },
93+
protocol: Request.Scheme);
94+
await _emailSender.SendEmailAsync(
95+
Input.Email,
96+
"Confirm your email",
97+
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
98+
99+
ModelState.AddModelError(string.Empty, "Verification email sent. Please check your email.");
100+
return Page();
101+
}
102+
}
103+
}

src/Identity/samples/IdentitySample.DefaultUI/web.config

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
<configuration>
33
<system.webServer>
44
<handlers>
5-
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
5+
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
66
</handlers>
7-
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
7+
<aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false">
8+
<environmentVariables>
9+
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
10+
</environmentVariables>
11+
</aspNetCore>
812
</system.webServer>
913
</configuration>

0 commit comments

Comments
 (0)