Ejemplo n.º 1
0
        public async Task <ActionResult <IActionResult> > ForgotPassword(string email)
        {
            if (String.IsNullOrWhiteSpace(email))
            {
                return(BadRequest());
            }

            if (_context.Users.Any(e => e.Email == email))
            {
                ResetTokenModel model = new ResetTokenModel
                {
                    Email       = email,
                    Expires     = DateTime.UtcNow.AddHours(24),
                    IsTokenUsed = false
                };

                // Generate reset token
                byte[] resetTokenBytes;
                new RNGCryptoServiceProvider().GetBytes(resetTokenBytes = new byte[16]);
                model.Token = Convert.ToBase64String(resetTokenBytes);

                //TODO: send reset email or whatever
                string message =
                    "Hi! To reset your password you need to open the following link within 24h: \n\n https://wanderer.app/passwordReset?token=" +
                    model.Token;


                _context.ResetTokens.Add(model.HashToken());
                await _context.SaveChangesAsync();

                return(Ok());
            }

            return(NotFound());
        }
Ejemplo n.º 2
0
        public async Task <ActionResult <UserModel> > ResetPassword(int id, string resetToken,
                                                                    string newPassword)
        {
            if (!_context.ResetTokens.Any(e => e.Id == id))
            {
                return(NotFound());
            }

            ResetTokenModel tokenModel = _context.ResetTokens.First(e => e.Id == id);

            if (DateTime.Now - tokenModel.Expires > TimeSpan.Zero || tokenModel.IsTokenUsed)
            {
                throw new UnauthorizedAccessException();
            }


            byte[] hashBytes = Convert.FromBase64String(tokenModel.Token);
            /* Get the salt */
            byte[] salt = new byte[16];
            Array.Copy(hashBytes, 0, salt, 0, 16);
            /* Compute the hash on the password the user entered */
            var pbkdf2 = new Rfc2898DeriveBytes(resetToken, salt, 10000);

            byte[] hash = pbkdf2.GetBytes(100);
            /* Compare the results */
            for (int i = 0; i < 20; i++)
            {
                if (hashBytes[i + 16] != hash[i])
                {
                    throw new UnauthorizedAccessException();
                }
            }


            // So the token exists, is not expired or used, and matches. Time to change the password.
            if (String.IsNullOrWhiteSpace(newPassword))
            {
                return(BadRequest());
            }

            UserModel user = _context.Users.First(it => it.Email == tokenModel.Email);

            user.Password = newPassword;
            user.HashPassword();
            _context.Users.Update(user);

            tokenModel.IsTokenUsed = true;
            _context.ResetTokens.Update(tokenModel);

            await _context.SaveChangesAsync();

            return(user.WithoutPassword());
        }
Ejemplo n.º 3
0
        public static ResetTokenModel HashToken(this ResetTokenModel resetToken)
        {
            byte[] salt;
            new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]);

            var pbkdf2 = new Rfc2898DeriveBytes(resetToken.Token, salt, 10000);

            byte[] hash = pbkdf2.GetBytes(20);

            byte[] hashBytes = new byte[36];
            Array.Copy(salt, 0, hashBytes, 0, 16);
            Array.Copy(hash, 0, hashBytes, 16, 20);

            resetToken.Token = Convert.ToBase64String(hashBytes);

            return(resetToken);
        }