public async Task SendPasswordRecoveryEmailAsync(string url, 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"); } 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.ResetPassword }); } string callbackUrl = url + actionToken; try { bool wasSent = _emailProvider.SendForgotPasswordMail(email, user.UserInfo.LastName + ' ' + user.UserInfo.FirstName, callbackUrl); if (!wasSent) { throw new SendMailException("The mail was not sent"); } } catch (Exception ex) { throw new SendMailException(ex.Message, ex); } }