refactor: add functionality to require confirmed Email and PhoneNumber to te able to authenticate
This commit is contained in:
parent
8b9c9ae324
commit
ea0681f78a
@ -23,7 +23,7 @@ public class AuthenticationController : ControllerBase
|
||||
}
|
||||
|
||||
[HttpPost("register")]
|
||||
public async Task<IActionResult> RegisterAsync([FromBody] RegistrationRequest request)
|
||||
public async Task<IActionResult> Register([FromBody] RegistrationRequest request)
|
||||
{
|
||||
var result = await _authService.Register(request);
|
||||
|
||||
@ -34,6 +34,19 @@ public class AuthenticationController : ControllerBase
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("sendEmailConfirmationCode")]
|
||||
public async Task<IActionResult> SendEmailConfirmationCode([FromBody] SendConfirmationRegistrationEmailRequest request)
|
||||
{
|
||||
var result = await _authService.SendEmailConfirmationCode(request);
|
||||
|
||||
if (!result.succeeded)
|
||||
{
|
||||
return result.actionResult;
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("confirmEmail")]
|
||||
public async Task<IActionResult> ConfirmEmail([FromBody] ConfirmRegistrationEmailRequest request)
|
||||
@ -48,6 +61,19 @@ public class AuthenticationController : ControllerBase
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("sendPhoneNumberConfirmationCode")]
|
||||
public async Task<IActionResult> SendPhoneNumberConfirmationCode([FromBody] SendConfirmationRegistrationPhoneNumberRequest request)
|
||||
{
|
||||
var result = await _authService.SendPhoneNumberConfirmationCode(request);
|
||||
|
||||
if (!result.succeeded)
|
||||
{
|
||||
return result.actionResult;
|
||||
}
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpPost("confirmPhoneNumber")]
|
||||
public async Task<IActionResult> ConfirmPhoneNumber([FromBody] ConfirmRegistrationPhoneNumberRequest request)
|
||||
{
|
||||
@ -65,7 +91,7 @@ public class AuthenticationController : ControllerBase
|
||||
public async Task<IActionResult> Authenticate(AuthenticationRequest authRequest)
|
||||
{
|
||||
var (succeeded, authResponse, refreshToken) =
|
||||
await _authService.AuthenticateAsync(authRequest);
|
||||
await _authService.Authenticate(authRequest);
|
||||
|
||||
if (!succeeded)
|
||||
{
|
||||
@ -81,7 +107,7 @@ public class AuthenticationController : ControllerBase
|
||||
public async Task<IActionResult> AuthenticateWithGoogle(GoogleAuthenticationRequest authRequest)
|
||||
{
|
||||
var (succeeded, authResponse, refreshToken) =
|
||||
await _authService.AuthenticateWithGoogleAsync(authRequest);
|
||||
await _authService.AuthenticateWithGoogle(authRequest);
|
||||
|
||||
if (!succeeded)
|
||||
{
|
||||
@ -99,7 +125,7 @@ public class AuthenticationController : ControllerBase
|
||||
var refreshToken = Request.Cookies["refreshToken"];
|
||||
|
||||
var (succeeded, authResponse, newRefreshToken) =
|
||||
await _authService.RenewRefreshTokenAsync(refreshToken);
|
||||
await _authService.RenewRefreshToken(refreshToken);
|
||||
|
||||
if (!succeeded)
|
||||
{
|
||||
|
@ -70,16 +70,30 @@ public class AuthenticationService : IAuthenticationService
|
||||
|
||||
await _userManager.AddToRoleAsync(user, Identity.DefaultRole.ToString());
|
||||
|
||||
var emailConfirmationToken = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||
var confirmationMessage =
|
||||
var emailMessage =
|
||||
"Someone registered an account on our service with your email.\n" +
|
||||
$"Here is your confirmation code: {emailConfirmationToken}\n\n" +
|
||||
"If this was not you, please ignore this message.";
|
||||
|
||||
try { await _emailSender.SendMail(user.Email, "Email confirmation", confirmationMessage); }
|
||||
try { await _emailSender.SendMail(user.Email, "Account Registration", emailMessage); }
|
||||
catch (Exception e) { /* ignored */ }
|
||||
|
||||
// TODO: Add phone number confirmation
|
||||
return (true, null!);
|
||||
}
|
||||
|
||||
public async Task<(bool succeeded, IActionResult actionResult)> SendEmailConfirmationCode(SendConfirmationRegistrationEmailRequest request)
|
||||
{
|
||||
var dbUser = await _userManager.FindByEmailAsync(request.Email);
|
||||
|
||||
if (dbUser == null)
|
||||
{
|
||||
return (false, new BadRequestObjectResult("Email not registered"));
|
||||
}
|
||||
|
||||
var emailConfirmationToken = await _userManager.GenerateEmailConfirmationTokenAsync(dbUser);
|
||||
var confirmationMessage = $"Confirmation code: {emailConfirmationToken}";
|
||||
|
||||
try { await _emailSender.SendMail(dbUser.Email, "Email Confirmation", confirmationMessage); }
|
||||
catch (Exception e) { /* ignored */ }
|
||||
|
||||
return (true, null!);
|
||||
}
|
||||
@ -97,17 +111,25 @@ public class AuthenticationService : IAuthenticationService
|
||||
return (true, null!);
|
||||
}
|
||||
|
||||
public Task<(bool succeeded, IActionResult actionResult)> SendPhoneNumberConfirmationCode(SendConfirmationRegistrationPhoneNumberRequest request)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<(bool succeeded, IActionResult actionResult)> ConfirmRegistrationPhoneNumber(ConfirmRegistrationPhoneNumberRequest numberRequest)
|
||||
{
|
||||
var dbUser = await _userManager.Users.FirstAsync(u => u.PhoneNumber == numberRequest.PhoneNumber);
|
||||
|
||||
// TODO: Add phone number confirmation token validation
|
||||
|
||||
dbUser.PhoneNumberConfirmed = true;
|
||||
await _userManager.UpdateAsync(dbUser);
|
||||
|
||||
return (true, null!);
|
||||
}
|
||||
|
||||
public async Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
AuthenticateAsync(AuthenticationRequest request)
|
||||
Authenticate(AuthenticationRequest request)
|
||||
{
|
||||
var authResponse = new AuthenticationResponse();
|
||||
|
||||
@ -118,10 +140,22 @@ public class AuthenticationService : IAuthenticationService
|
||||
authResponse.Message = $"No accounts registered with {request.Email}.";
|
||||
return (false, authResponse, null);
|
||||
}
|
||||
|
||||
if (!user.EmailConfirmed)
|
||||
{
|
||||
authResponse.Message = "You must confirm your email before logging in";
|
||||
return (false, authResponse, null);
|
||||
}
|
||||
|
||||
if (!user.PhoneNumberConfirmed)
|
||||
{
|
||||
authResponse.Message = "You must confirm your phone number before logging in";
|
||||
return (false, authResponse, null);
|
||||
}
|
||||
|
||||
if (!await _userManager.CheckPasswordAsync(user, request.Password))
|
||||
{
|
||||
authResponse.Message = $"Incorrect email or password.";
|
||||
authResponse.Message = "Incorrect email or password.";
|
||||
return (false, authResponse, null);
|
||||
}
|
||||
|
||||
@ -150,7 +184,7 @@ public class AuthenticationService : IAuthenticationService
|
||||
}
|
||||
|
||||
public async Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
AuthenticateWithGoogleAsync(GoogleAuthenticationRequest request)
|
||||
AuthenticateWithGoogle(GoogleAuthenticationRequest request)
|
||||
{
|
||||
GoogleJsonWebSignature.ValidationSettings settings = new GoogleJsonWebSignature.ValidationSettings();
|
||||
|
||||
@ -200,7 +234,7 @@ public class AuthenticationService : IAuthenticationService
|
||||
}
|
||||
|
||||
public async Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
RenewRefreshTokenAsync(string? token)
|
||||
RenewRefreshToken(string? token)
|
||||
{
|
||||
var authResponse = new AuthenticationResponse();
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SharedModels.Requests;
|
||||
using SharedModels.Requests.Authentication;
|
||||
using SharedModels.Responses;
|
||||
|
||||
@ -9,18 +8,22 @@ public interface IAuthenticationService
|
||||
{
|
||||
Task<(bool succeeded, IActionResult actionResult)> Register(RegistrationRequest request);
|
||||
|
||||
Task<(bool succeeded, IActionResult actionResult)> SendEmailConfirmationCode(SendConfirmationRegistrationEmailRequest request);
|
||||
|
||||
Task<(bool succeeded, IActionResult actionResult)> ConfirmRegistrationEmail(ConfirmRegistrationEmailRequest request);
|
||||
|
||||
Task<(bool succeeded, IActionResult actionResult)> SendPhoneNumberConfirmationCode(SendConfirmationRegistrationPhoneNumberRequest request);
|
||||
|
||||
Task<(bool succeeded, IActionResult actionResult)> ConfirmRegistrationPhoneNumber(ConfirmRegistrationPhoneNumberRequest numberRequest);
|
||||
|
||||
Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
AuthenticateAsync(AuthenticationRequest request);
|
||||
Authenticate(AuthenticationRequest request);
|
||||
|
||||
Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
AuthenticateWithGoogleAsync(GoogleAuthenticationRequest request);
|
||||
AuthenticateWithGoogle(GoogleAuthenticationRequest request);
|
||||
|
||||
Task<(bool succeeded, AuthenticationResponse authResponse, string? refreshToken)>
|
||||
RenewRefreshTokenAsync(string? token);
|
||||
RenewRefreshToken(string? token);
|
||||
|
||||
Task<bool> RevokeRefreshToken(string? token);
|
||||
}
|
||||
|
@ -2,12 +2,8 @@ using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SharedModels.Requests.Authentication;
|
||||
|
||||
public class ConfirmRegistrationEmailRequest
|
||||
public class ConfirmRegistrationEmailRequest : SendConfirmationRegistrationEmailRequest
|
||||
{
|
||||
[Required]
|
||||
[DataType(DataType.EmailAddress)]
|
||||
public string Email { get; set; } = null!;
|
||||
|
||||
[Required]
|
||||
public string Token { get; set; } = null!;
|
||||
}
|
@ -2,12 +2,8 @@ using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SharedModels.Requests.Authentication;
|
||||
|
||||
public class ConfirmRegistrationPhoneNumberRequest
|
||||
public class ConfirmRegistrationPhoneNumberRequest : SendConfirmationRegistrationPhoneNumberRequest
|
||||
{
|
||||
[Required]
|
||||
[DataType(DataType.PhoneNumber)]
|
||||
public string PhoneNumber { get; set; } = null!;
|
||||
|
||||
[Required]
|
||||
public string Token { get; set; } = null!;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SharedModels.Requests.Authentication;
|
||||
|
||||
public class SendConfirmationRegistrationEmailRequest
|
||||
{
|
||||
[Required]
|
||||
[DataType(DataType.EmailAddress)]
|
||||
public string Email { get; set; } = null!;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SharedModels.Requests.Authentication;
|
||||
|
||||
public class SendConfirmationRegistrationPhoneNumberRequest
|
||||
{
|
||||
[Required]
|
||||
[DataType(DataType.PhoneNumber)]
|
||||
public string PhoneNumber { get; set; } = null!;
|
||||
}
|
Loading…
Reference in New Issue
Block a user