public async Task SendConfirmationEmailAsync(string domain, string email) { if (string.IsNullOrWhiteSpace(email)) { throw new InvalidModelException("Email is empty"); } var user = await _context.Set <Entities.User>() .Include(x => x.UserInfo) .FirstOrDefaultAsync(x => x.UserInfo.Email == email); if (user == null) { throw new NotFoundException($"User with email { email } not found"); } if (user.UserInfo.EmailConfirmed == true) { throw new CanceledException(System.Net.HttpStatusCode.Forbidden, "Email is already confirmed"); } var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.UTF8.GetBytes(_appSettings.Secret); var claimes = new List <Claim>(); Guid actionId = Guid.NewGuid(); claimes.Add(new Claim("uid", user.Id.ToString())); claimes.Add(new Claim("aid", actionId.ToString())); var actionTokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claimes), Expires = DateTime.UtcNow.AddMinutes(30), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature), Audience = _appSettings.Audience, Issuer = _appSettings.Issuer }; var acToken = tokenHandler.CreateToken(actionTokenDescriptor); var actionToken = tokenHandler.WriteToken(acToken); lock (syncTokenObj) { tokens.Add(new TokenInfo { actionId = actionId, userId = user.Id, expires = DateTime.UtcNow.AddMinutes(30), type = TokenType.MailConfirmation }); } string callbackUrl = $"{ domain }/{ actionToken }"; try { bool wasSent = _emailProvider.SendEmailConfirmationMail(user.UserInfo.Email, user.UserInfo.FirstName + ' ' + user.UserInfo.LastName, callbackUrl); if (!wasSent) { throw new SendMailException("The mail was not sent"); } } catch (Exception ex) { throw new SendMailException(ex.Message, ex); } }