Skip to content
Snippets Groups Projects
Unverified Commit 3a0815a7 authored by Sloan Sparger's avatar Sloan Sparger Committed by GitHub
Browse files

Disable password reset button after click in admin (#38619)


* disables password reset button in admin after the user has clicked the button once

* add email throttle

* fix test

---------

Co-authored-by: default avatarJerry Huang <jhuang37050@gmail.com>
parent 3415469d
Branches
Tags
No related merge requests found
......@@ -17,16 +17,26 @@ import { clearTemporaryPassword } from "../people";
import { ButtonContainer } from "./UserPasswordResetModal.styled";
class UserPasswordResetModal extends Component {
state = {
resetButtonDisabled: false,
};
componentWillUnmount() {
this.props.clearTemporaryPassword(this.props.params.userId);
}
handleClose = () => {
this.setState({ resetButtonDisabled: false });
this.props.onClose();
};
render() {
const { user, emailConfigured, temporaryPassword, onClose } = this.props;
const { user, emailConfigured, temporaryPassword } = this.props;
return temporaryPassword ? (
<ModalContent
title={t`${user.common_name}'s password has been reset`}
footer={<Button primary onClick={onClose}>{t`Done`}</Button>}
onClose={onClose}
footer={<Button primary onClick={this.handleClose}>{t`Done`}</Button>}
onClose={this.handleClose}
>
<span className="pb3 block">{t`Here’s a temporary password they can use to log in and then change their password.`}</span>
......@@ -35,17 +45,19 @@ class UserPasswordResetModal extends Component {
) : (
<ModalContent
title={t`Reset ${user.common_name}'s password?`}
onClose={onClose}
onClose={this.handleClose}
>
<p>{t`Are you sure you want to do this?`}</p>
<ButtonContainer>
<Button
className="ml-auto"
disabled={this.state.resetButtonDisabled}
onClick={async () => {
this.setState({ resetButtonDisabled: true });
if (emailConfigured) {
await user.resetPasswordEmail();
onClose();
this.handleClose();
} else {
await user.resetPasswordManual();
}
......
......@@ -213,8 +213,8 @@
;; There's also no need to salt the token because it's already random <3
(def ^:private forgot-password-throttlers
{:email (throttle/make-throttler :email)
:ip-address (throttle/make-throttler :email, :attempts-threshold 50)})
{:email (throttle/make-throttler :email :attempts-threshold 3 :attempt-ttl-ms 1000)
:ip-address (throttle/make-throttler :email :attempts-threshold 50)})
(defn- forgot-password-impl
[email]
......
......@@ -269,12 +269,12 @@
(deftest forgot-password-throttling-test
(reset-throttlers!)
(testing "Test that email based throttling kicks in after the login failure threshold (10) has been reached"
(testing "Test that email based throttling kicks in after the login failure threshold (3) has been reached"
(letfn [(send-password-reset! [& [expected-status & _more]]
(mt/client :post (or expected-status 204) "session/forgot_password" {:email "not-found@metabase.com"}))]
(with-redefs [api.session/forgot-password-throttlers (cleaned-throttlers #'api.session/forgot-password-throttlers
[:email :ip-address])]
(dotimes [_ 10]
(dotimes [_ 3]
(send-password-reset!))
(let [error (fn []
(-> (send-password-reset! 400)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment