identity: add support for account email changing

This commit is contained in:
Abdullah Atta
2023-01-16 13:25:38 +05:00
parent 1b5678a26c
commit fc17e7a2fb
6 changed files with 191 additions and 354 deletions

View File

@@ -116,7 +116,7 @@ namespace Streetwriters.Identity.Controllers
}
[HttpPost("verify")]
public async Task<IActionResult> SendVerificationEmail()
public async Task<IActionResult> SendVerificationEmail([FromForm] string newEmail)
{
var client = Clients.FindClientById(User.FindFirstValue("client_id"));
if (client == null) return BadRequest("Invalid client_id.");
@@ -124,9 +124,17 @@ namespace Streetwriters.Identity.Controllers
var user = await UserManager.GetUserAsync(User);
if (!await IsUserValidAsync(user, client.Id)) return BadRequest($"Unable to find user with ID '{UserManager.GetUserId(User)}'.");
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CONFRIM_EMAIL, Request.Scheme);
await EmailSender.SendConfirmationEmailAsync(user.Email, callbackUrl, client);
if (string.IsNullOrEmpty(newEmail))
{
var code = await UserManager.GenerateEmailConfirmationTokenAsync(user);
var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CONFRIM_EMAIL, Request.Scheme);
await EmailSender.SendConfirmationEmailAsync(user.Email, callbackUrl, client);
}
else
{
var code = await UserManager.GenerateChangeEmailTokenAsync(user, newEmail);
await EmailSender.SendChangeEmailConfirmationAsync(newEmail, code, client);
}
return Ok();
}
@@ -145,6 +153,9 @@ namespace Streetwriters.Identity.Controllers
}
await UserManager.RemoveFromRoleAsync(user, client.Id);
IdentityUserClaim<string> statusClaim = user.Claims.FirstOrDefault((c) => c.ClaimType == $"{client.Id}:status");
await UserManager.RemoveClaimAsync(user, statusClaim.ToClaim());
return Ok();
}
@@ -256,11 +267,22 @@ namespace Streetwriters.Identity.Controllers
{
case "change_email":
{
var code = await UserManager.GenerateChangeEmailTokenAsync(user, form.NewEmail);
// var callbackUrl = Url.TokenLink(user.Id.ToString(), code, client.Id, TokenType.CHANGE_EMAIL, Request.Scheme);
await EmailSender.SendChangeEmailConfirmationAsync(user.Email, code, client);
await UserManager.AddClaimAsync(user, new Claim("new_email", form.NewEmail));
return Ok();
var result = await UserManager.ChangeEmailAsync(user, form.NewEmail, form.VerificationCode);
if (result.Succeeded)
{
result = await UserManager.RemovePasswordAsync(user);
if (result.Succeeded)
{
result = await UserManager.AddPasswordAsync(user, form.Password);
if (result.Succeeded)
{
await UserManager.SetUserNameAsync(user, form.NewEmail);
await SendEmailChangedMessageAsync(user.Id.ToString());
return Ok();
}
}
}
return BadRequest(result.Errors.ToErrors());
}
case "change_password":
{
@@ -327,6 +349,19 @@ namespace Streetwriters.Identity.Controllers
});
}
private async Task SendEmailChangedMessageAsync(string userId)
{
await WampServers.MessengerServer.PublishMessageAsync(WampServers.MessengerServer.Topics.SendSSETopic, new SendSSEMessage
{
UserId = userId,
OriginTokenId = User.FindFirstValue("jti"),
Message = new Message
{
Type = "userEmailChanged"
}
});
}
public async Task<bool> IsUserValidAsync(User user, string clientId)
{
return user != null && await UserManager.IsInRoleAsync(user, clientId);

View File

@@ -44,10 +44,24 @@ namespace Streetwriters.Identity.Models
get; set;
}
[BindProperty(Name = "password")]
public string Password
{
get; set;
}
[BindProperty(Name = "new_email")]
public string NewEmail
{
get; set;
}
[BindProperty(Name = "verification_code")]
public string VerificationCode
{
get; set;
}
}
}

View File

@@ -124,7 +124,7 @@ namespace Streetwriters.Identity.Services
await SendEmailAsync(email, template, client);
}
public async Task SendChangeEmailConfirmationAsync(string email, string callbackUrl, IClient client)
public async Task SendChangeEmailConfirmationAsync(string email, string code, IClient client)
{
var template = new EmailTemplate
{
@@ -134,7 +134,7 @@ namespace Streetwriters.Identity.Services
Data = new
{
app_name = client.Name,
confirm_link = callbackUrl
code = code
}
};
await SendEmailAsync(email, template, client);

View File

@@ -86,6 +86,8 @@ namespace Streetwriters.Identity
// User settings.
//options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._";
options.User.RequireUniqueEmail = true;
options.Tokens.ChangeEmailTokenProvider = TokenOptions.DefaultPhoneProvider;
}, (options) =>
{
options.RolesCollection = "roles";

View File

@@ -227,10 +227,7 @@
>
<tr>
<td role="module-content">
<p>
Confirm your new email to change it for
your {{app_name}} account.
</p>
<p></p>
</td>
</tr>
</table>
@@ -243,14 +240,14 @@
cellspacing="0"
width="100%"
style="table-layout: fixed"
data-muid="14957e19-e5cc-41de-b9a5-4ee51daed01f"
data-muid="ee9d04d5-2dd9-446e-8f33-04b3a587d059"
data-mc-module-version="2019-10-22"
>
<tbody>
<tr>
<td
style="
padding: 0px 0px 0px 0px;
padding: 18px 0px 18px 0px;
line-height: 40px;
text-align: inherit;
"
@@ -278,7 +275,7 @@
cellspacing="0"
width="100%"
style="table-layout: fixed"
data-muid="47ff054b-8636-4ba1-b9fc-a67b7bec8707"
data-muid="64d4899b-5911-439e-b9c8-734d70c579c7"
data-mc-module-version="2019-10-22"
>
<tbody>
@@ -301,26 +298,9 @@
text-align: inherit;
"
>
Hey there!
</div>
<div
style="
font-family: inherit;
text-align: inherit;
"
>
<br />
</div>
<div
style="
font-family: inherit;
text-align: inherit;
"
>
Please confirm your new email by
clicking
<a href="{{confirm_link}}">here</a>
or the button below.
Please use the following
verification code to change to your
account email:
</div>
<div></div>
</div>
@@ -329,71 +309,122 @@
</tbody>
</table>
<table
class="module"
role="module"
data-type="text"
border="0"
cellpadding="0"
cellspacing="0"
class="module"
data-role="module-button"
data-type="button"
role="module"
style="table-layout: fixed"
width="100%"
data-muid="be84daa7-3077-40d3-9592-f8de5d03c0cf"
style="table-layout: fixed"
data-muid="e7321d14-60a8-4113-a301-b95bc8fc3001"
data-mc-module-version="2019-10-22"
>
<tbody>
<tr>
<td
align="center"
style="
padding: 18px 0px 18px 0px;
line-height: 22px;
text-align: inherit;
"
height="100%"
valign="top"
bgcolor=""
class="outer-td"
style="padding: 5px 0px 5px 0px"
role="module-content"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
class="wrapper-mobile"
style="text-align: center"
>
<tbody>
<tr>
<td
align="center"
bgcolor="#000000"
class="inner-td"
style="
border-radius: 6px;
font-size: 16px;
text-align: center;
background-color: inherit;
"
>
<a
href="{{confirm_link}}"
style="
background-color: #000000;
border: 1px solid #333333;
border-color: #333333;
border-radius: 5px;
border-width: 1px;
color: #ffffff;
display: inline-block;
font-size: 14px;
font-weight: normal;
letter-spacing: 0px;
line-height: normal;
padding: 12px 18px 12px 18px;
text-align: center;
text-decoration: none;
border-style: solid;
"
target="_blank"
>Confirm Email</a
>
</td>
</tr>
</tbody>
</table>
<div>
<div
style="
font-family: inherit;
text-align: center;
"
>
<span
style="
font-size: 60px;
font-family: 'courier new',
courier, monospace;
"
>{{code}}</span
>
</div>
<div></div>
</div>
</td>
</tr>
</tbody>
</table>
<table
class="module"
role="module"
data-type="text"
border="0"
cellpadding="0"
cellspacing="0"
width="100%"
style="table-layout: fixed"
data-muid="eaa21ef5-8f16-4212-adf0-f095932f2559"
data-mc-module-version="2019-10-22"
>
<tbody>
<tr>
<td
style="
padding: 18px 0px 18px 0px;
line-height: 22px;
text-align: inherit;
"
height="100%"
valign="top"
bgcolor=""
role="module-content"
>
<div>
<div
style="
font-family: inherit;
text-align: inherit;
"
>
<span
style="
color: #000000;
font-family: arial, helvetica,
sans-serif;
font-size: 14px;
font-style: normal;
font-variant-ligatures: normal;
font-variant-caps: normal;
font-weight: 400;
letter-spacing: normal;
text-align: start;
text-indent: 0px;
text-transform: none;
white-space: pre-wrap;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
float: none;
display: inline;
"
><em
>If you did not request to a
verification code, please report
this to us at
support@streetwriters.co</em
></span
>
</div>
<div></div>
</div>
</td>
</tr>
</tbody>
@@ -407,7 +438,7 @@
cellspacing="0"
width="100%"
style="table-layout: fixed"
data-muid="aca25e2b-4cbf-43ae-b606-419fa0702f66"
data-muid="ca9de43c-4050-4410-8963-d49989152c4c"
>
<tbody>
<tr>
@@ -452,7 +483,7 @@
cellspacing="0"
width="100%"
style="table-layout: fixed"
data-muid="5e37834f-be09-4696-a807-ae46f2725837"
data-muid="3d5612f4-e335-4774-9238-fbe38b2d85ed"
data-mc-module-version="2019-10-22"
>
<tbody>
@@ -477,99 +508,26 @@
>
<span
style="
font-family: arial, helvetica,
sans-serif;
font-style: normal;
font-variant-ligatures: normal;
font-variant-caps: normal;
font-weight: 400;
letter-spacing: normal;
orphans: 2;
text-align: start;
text-indent: 0px;
text-transform: none;
white-space: pre-wrap;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
float: none;
display: inline;
color: #444444;
font-size: 11px;
color: #555555;
"
>This email has been sent to you
because you signed up on </span
><span
style="
font-family: arial, helvetica,
sans-serif;
font-style: normal;
font-variant-ligatures: normal;
font-variant-caps: normal;
font-weight: 400;
letter-spacing: normal;
orphans: 2;
text-align: start;
text-indent: 0px;
text-transform: none;
white-space: pre-wrap;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
float: none;
display: inline;
font-size: 11px;
color: #000000;
"
>{{app_name}}</span
><strong
>{{app_name}}</strong
></span
><span
style="
font-family: arial, helvetica,
sans-serif;
font-style: normal;
font-variant-ligatures: normal;
font-variant-caps: normal;
font-weight: 400;
letter-spacing: normal;
orphans: 2;
text-align: start;
text-indent: 0px;
text-transform: none;
white-space: pre-wrap;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
float: none;
display: inline;
color: #444444;
font-size: 11px;
color: #555555;
"
>
a service of Streetwriters
- a service by Streetwriters
(Private) Ltd.</span
>
</div>
@@ -581,61 +539,8 @@
>
<span
style="
box-sizing: border-box;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
font-style: inherit;
font-variant-ligatures: inherit;
font-variant-caps: inherit;
font-variant-numeric: inherit;
font-variant-east-asian: inherit;
font-weight: inherit;
font-stretch: inherit;
line-height: 20px;
font-family: inherit;
vertical-align: baseline;
border-top-width: 0px;
border-right-width: 0px;
border-bottom-width: 0px;
border-left-width: 0px;
border-top-style: initial;
border-right-style: initial;
border-bottom-style: initial;
border-left-style: initial;
border-top-color: initial;
border-right-color: initial;
border-bottom-color: initial;
border-left-color: initial;
border-image-source: initial;
border-image-slice: initial;
border-image-width: initial;
border-image-outset: initial;
border-image-repeat: initial;
color: #444444;
letter-spacing: normal;
orphans: 2;
text-align: center;
text-indent: 0px;
text-transform: none;
white-space: normal;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
font-size: 11px;
color: #555555;
"
>1st Floor, Valley Plaza, Mardowal
Chowk, Naushera</span
@@ -649,132 +554,11 @@
>
<span
style="
box-sizing: border-box;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
font-style: inherit;
font-variant-ligatures: inherit;
font-variant-caps: inherit;
font-variant-numeric: inherit;
font-variant-east-asian: inherit;
font-weight: inherit;
font-stretch: inherit;
line-height: 20px;
font-family: inherit;
vertical-align: baseline;
border-top-width: 0px;
border-right-width: 0px;
border-bottom-width: 0px;
border-left-width: 0px;
border-top-style: initial;
border-right-style: initial;
border-bottom-style: initial;
border-left-style: initial;
border-top-color: initial;
border-right-color: initial;
border-bottom-color: initial;
border-left-color: initial;
border-image-source: initial;
border-image-slice: initial;
border-image-width: initial;
border-image-outset: initial;
border-image-repeat: initial;
color: #444444;
letter-spacing: normal;
orphans: 2;
text-align: center;
text-indent: 0px;
text-transform: none;
white-space: normal;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
font-size: 11px;
color: #555555;
"
>Khushab,</span
><span style="font-size: 11px">
</span
><span
style="
box-sizing: border-box;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
font-style: inherit;
font-variant-ligatures: inherit;
font-variant-caps: inherit;
font-variant-numeric: inherit;
font-variant-east-asian: inherit;
font-weight: inherit;
font-stretch: inherit;
line-height: 20px;
font-family: inherit;
vertical-align: baseline;
border-top-width: 0px;
border-right-width: 0px;
border-bottom-width: 0px;
border-left-width: 0px;
border-top-style: initial;
border-right-style: initial;
border-bottom-style: initial;
border-left-style: initial;
border-top-color: initial;
border-right-color: initial;
border-bottom-color: initial;
border-left-color: initial;
border-image-source: initial;
border-image-slice: initial;
border-image-width: initial;
border-image-outset: initial;
border-image-repeat: initial;
color: #444444;
letter-spacing: normal;
orphans: 2;
text-align: center;
text-indent: 0px;
text-transform: none;
white-space: normal;
widows: 2;
word-spacing: 0px;
-webkit-text-stroke-width: 0px;
background-color: rgb(
255,
255,
255
);
text-decoration-thickness: initial;
text-decoration-style: initial;
text-decoration-color: initial;
font-size: 11px;
"
>Punjab</span
><span style="font-size: 11px">
</span
><span
style="
color: #444444;
font-size: 11px;
"
>41100 Pakistan</span
>Khushab, Punjab 41100
Pakistan</span
>
</div>
<div></div>

View File

@@ -4,9 +4,11 @@ Confirm your new email to change it for your {{app_name}} account.
{{app_name}}
************
Hey there!
Please use the following verification code to change to your account email:
Please confirm your new email by going to this link: {{confirm_link}}
{{code}}
If you did not request a verification code, please report this to us at support@streetwriters.co
------------