Hi, I'm new to this, so I'm not so good, your help is my pleasure, thank you.
I am having a problem with login, the API emailConfirmed still works when I give it token and userId. As far as I know, the EmailConfirmed doesn't confirm itself. I think I missed an URL in the verification mail, but I don't know how to get a URL for that. If you know any solution or documents, etc.? Please let me know, I would very much appreciate it, please.
using SendGrid.Helpers.Mail;
using System.Net.Mail;
using System.Threading.Tasks;
namespace ChatApp_BE.Helpers
{
public class IEmailSenders
{
private readonly IConfiguration _configuration;
public IEmailSenders(IConfiguration configuration)
{
_configuration = configuration;
}
public async Task SendEmailAsync(string subject, string toEmail, string message)
{
var apiKey = _configuration["SendGrid:ApiSenderKey"];
var client = new SendGridClient(apiKey);
var from = new EmailAddress("minhnhut.services.test@gmail.com", "ChapApp");
var to = new EmailAddress(toEmail);
//var plainTextContent = message;
//var htmlContent = message;
var templateId = _configuration["SendGrid:TemplateId"];
var templateData = new Dictionary<string, object>
{
{"confirm_link", "confirm_link" },
};
var msg = MailHelper.CreateSingleTemplateEmail(from, to, templateId, templateData);
var response = await client.SendEmailAsync(msg);
}
}
}
[HttpPost("register")]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (user != null && await _userManager.IsEmailConfirmedAsync(user))
{
return BadRequest("Email was already used.");
}
user = new ApplicationUser
{
UserName = model.Email,
Email = model.Email,
FullName = model.FullName,
};
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
user.EmailConfirmationToken = token;
await _userManager.UpdateAsync(user);
user.EmailConfirmed = true;
var confirmationLink = Url.Action(
nameof(ConfirmEmail),
"ApplicationUser",
new { userId = user.Id, token },
Request.Scheme
);
await _emailSender.SendEmailAsync("Confirm your email",
model.Email,
$"Please confirm your email by clicking <a href=\"{confirmationLink}\">here</a>.");
return Ok(new { Message = "Registration successful! Please check your email to confirm your account." });
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return BadRequest(ModelState);
}
[AllowAnonymous]
[HttpGet("confirmemail")]
public async Task<IActionResult> ConfirmEmail(string userId, string token)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null || token == null)
{
return BadRequest("Invalid email confirmation request.");
}
if (user.EmailConfirmationToken != token)
{
return BadRequest("Invalid email confirmation token.");
}
var result = await _userManager.ConfirmEmailAsync(user, token);
//if (user.EmailConfirmationToken == token)
//{
// user.EmailConfirmed = true;
//}
if (result.Succeeded)
{
user.EmailConfirmationToken = null;
await _userManager.UpdateAsync(user);
return Ok("Email confirmed successfully!");
}
return BadRequest("Email confirmation failed.");
}
[HttpPost("login")]
public async Task<IActionResult> Login(LoginViewModel model)
{
try
{
if (ModelState.IsValid)
{
var user = await _userManager.FindByEmailAsync(model.Email);
if (!user.EmailConfirmed)
{
return BadRequest("Email is not confirmed.");
}
if (user == null || !await _userManager.CheckPasswordAsync(user, model.Password))
{
return Unauthorized("Invalid login attempt.");
}
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_config.GetSection("Jwt:SecretKey").Value!);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
var tokenString = tokenHandler.WriteToken(token);
return Ok(new { Token = tokenString });
}
return BadRequest(ModelState);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}