Skip to content

Commit

Permalink
feat: update user registration process
Browse files Browse the repository at this point in the history
  • Loading branch information
Harish-osmosys committed Mar 22, 2024
1 parent cc977ad commit 7b1f65a
Show file tree
Hide file tree
Showing 15 changed files with 295 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,42 @@ public async Task<ActionResult<BaseResponse<int>>> ForgotPasswordAsync(string em
return StatusCode(StatusCodes.Status500InternalServerError, response);
}
}

/// <summary>
/// Confirm user email using token.
/// </summary>
/// <param name="request">Confirm email request</param>
[HttpPut("confirmemail")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<BaseResponse<int>>> ConfirmEmailAsync(ConfirmEmailRequest request)
{
BaseResponse<int> response = new(ResponseStatus.Fail);
try
{
await _authenticationService.ConfirmEmailAsync(request).ConfigureAwait(false);
response.Status = ResponseStatus.Success;

return Ok(response);
}
catch (NotFoundException ex)
{
response.Message = ex.Message;
response.Status = ResponseStatus.Error;
return BadRequest(response);
}
catch (InvalidTokenException ex)
{
response.Message = ex.Message;
response.Status = ResponseStatus.Error;
return BadRequest(response);
}
catch (Exception ex)
{
response.Message = ex.Message;
response.Status = ResponseStatus.Error;
return StatusCode(StatusCodes.Status500InternalServerError, response);
}
}
}
8 changes: 8 additions & 0 deletions DotnetFoundation/DotnetFoundation.Api/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@
"PasswordChange": {
"Path": "../DotnetFoundation.Api/wwwroot/Templates/Emails/PasswordChangeTemplate.html",
"Subject": "Password Update Confirmation"
},
"ConfirmEmail": {
"Path": "../DotnetFoundation.Api/wwwroot/Templates/Emails/ConfirmEmailTemplate.html",
"Subject": "Email Confirmation"
},
"CompleteRegistration": {
"Path": "../DotnetFoundation.Api/wwwroot/Templates/Emails/CompleteRegistrationTemplate.html",
"Subject": "Welcome to FoundationX"
}
},
"AllowedHosts": "*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ <h2>FoundationX</h2>
voluptas recusandae quaerat placeat eveniet soluta! Impedit quasi
iste rem quisquam natus illum?
</p>
<br />
<p>Thank you,<br />FoundationX Team</p>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Complete Registration</title>
<style>
table {
width: 100%;
max-width: 600px;
margin: 20px auto;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #e5ebe1;
font-family: "Arial", sans-serif;
}

th {
text-align: center;
padding: 20px;
}

.logo {
max-width: 90px;
border-radius: 8px;
}

h2 {
color: #40b01b;
margin-top: 0px;
}

td {
padding: 20px;
}

.footer {
background-color: #b3c6a6;
text-align: center;
padding: 10px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th colspan="2">
<img
src="https://i.postimg.cc/3wC1mFSj/logo.png"
alt="Logo Image"
class="logo"
/>
<h2>FoundationX</h2>
</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" style="padding: 20px">
<p>Hello,</p>
<div>
<strong>Welcome to FoundationX!</strong>
<p>
Thank you for verifying your email and joining our community.
We're excited to have you on board!
</p>
</div>
<br />
<p>Thank you,<br />FoundationX Team</p>
</td>
</tr>
</tbody>
<tfoot>
<tr class="footer">
<td>Contact us at <strong>[email protected]</strong></td>
</tr>
</tfoot>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Confirm Email</title>
<style>
table {
width: 100%;
max-width: 600px;
margin: 20px auto;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: #e5ebe1;
font-family: "Arial", sans-serif;
}

th {
text-align: center;
padding: 20px;
}

.logo {
max-width: 90px;
border-radius: 8px;
}

h2 {
color: #40b01b;
margin-top: 0px;
}

td {
padding: 20px;
}

.footer {
background-color: #b3c6a6;
text-align: center;
padding: 10px;
}
</style>
</head>
<body>
<table>
<thead>
<tr>
<th colspan="2">
<img
src="https://i.postimg.cc/3wC1mFSj/logo.png"
alt="Logo Image"
class="logo"
/>
<h2>FoundationX</h2>
</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2" style="padding: 20px">
<p>Hello,</p>
<div>
<strong>Use this token to Confirm your email.</strong>
<p><strong>Token :</strong> {body}</p>
</div>
<br />
<p>Thank you,<br />FoundationX Team</p>
</td>
</tr>
</tbody>
<tfoot>
<tr class="footer">
<td>Contact us at <strong>[email protected]</strong></td>
</tr>
</tfoot>
</table>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ <h2>FoundationX</h2>
<strong>contact us immediately</strong>
to report any unauthorized access to your account.
</p>
<br />
<p>Thank you,<br />FoundationX Team</p>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ <h2>FoundationX</h2>
<strong>Use this token to reset your password.</strong>
<p><strong>Token :</strong> {body}</p>
</div>
<br />
<p>Thank you,<br />FoundationX Team</p>
</td>
</tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ public interface IEmailService
/// <returns>A task that represents the asynchronous send operation. The task result contains the send result.</returns>
public Task<string> SendForgetPasswordEmailAsync(string email, string body);
public Task<string> SendChangePasswordEmailAsync(string email);
public Task<string> SendConfirmationEmailAsync(string email, string body);
public Task<string> SendCompleteRegistrationEmailAsync(string email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public interface IUserRepository
public Task ResetPasswordAsync(string email, string token, string newPassword);
public Task<bool> AddUserRoleAsync(string email, Roles role);
public Task<int> UpdateUserAsync(User user);
public Task<string> GetConfirmationToken(string Id);
public Task ConfirmEmailAsync(string email, string token);
public Task<User> DeleteUserAsync(int userId);
public Task<List<string>> GetUserRoleAsync(string email);
public Task<bool> CheckEmailExist(string email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ public interface IAuthenticationService
public Task<AuthenticationResponse> LoginAsync(LoginRequest request);
public Task ForgotPasswordAsync(string email);
public Task ResetPasswordAsync(PasswordResetRequest request);
public Task ConfirmEmailAsync(ConfirmEmailRequest request);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;

namespace DotnetFoundation.Application.Models.DTOs.AuthenticationDTO;

public class ConfirmEmailRequest
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid email")]
public string Email { get; init; } = String.Empty;
[Required(ErrorMessage = "Token is required")]
public string Token { get; init; } = String.Empty;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi
});

// Configure indentity service
services.AddIdentity<IdentityApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<SqlDatabaseContext>()
.AddDefaultTokenProviders();
services.AddIdentity<IdentityApplicationUser, IdentityRole>(options =>
{
options.SignIn.RequireConfirmedEmail = true;
})
.AddEntityFrameworkStores<SqlDatabaseContext>()
.AddDefaultTokenProviders();

services.Configure<DataProtectionTokenProviderOptions>(options => options.TokenLifespan = TimeSpan.FromMinutes(Convert.ToDouble(configuration["Appsettings:IdentityTokenLifespanInMinutes"])));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public async Task<string> SendForgetPasswordEmailAsync(string email, string body

return await SendNotificationAsync(payload).ConfigureAwait(false);
}

public async Task<string> SendChangePasswordEmailAsync(string email)
{
string templatePath = _configuration["Emails:PasswordChange:Path"] ?? throw new Exception("PasswordChange template path Missing");
Expand All @@ -37,6 +38,25 @@ public async Task<string> SendChangePasswordEmailAsync(string email)

return await SendNotificationAsync(payload).ConfigureAwait(false);
}

public async Task<string> SendConfirmationEmailAsync(string email, string body)
{
string templatePath = _configuration["Emails:ConfirmEmail:Path"] ?? throw new Exception("ConfirmEmail template path Missing");
string subject = _configuration["Emails:ConfirmEmail:Subject"] ?? throw new Exception("ConfirmEmail subject Missing");

Notification payload = CreateNotificationPayload(email, subject, ReadHtmlTemplate(templatePath, body));
return await SendNotificationAsync(payload).ConfigureAwait(false);
}

public async Task<string> SendCompleteRegistrationEmailAsync(string email)
{
string templatePath = _configuration["Emails:CompleteRegistration:Path"] ?? throw new Exception("CompleteRegistration template path Missing");
string subject = _configuration["Emails:CompleteRegistration:Subject"] ?? throw new Exception("CompleteRegistration subject Missing");

Notification payload = CreateNotificationPayload(email, subject, ReadHtmlTemplate(templatePath, ""));

return await SendNotificationAsync(payload).ConfigureAwait(false);
}
private Notification CreateNotificationPayload(string to, string subject, string htmlBody)
{
return new Notification
Expand Down
Loading

0 comments on commit 7b1f65a

Please sign in to comment.