import { connect } from 'react-redux'; import ReCAPTCHA from 'react-google-recaptcha'; import withPageTitle from 'HOCs/withPageTitle'; import { Loader, Button, Link, Icon, Message } from 'UI'; import { requestResetPassword, resetPassword } from 'Duck/user'; import { login as loginRoute } from 'App/routes'; import { withRouter } from 'react-router-dom'; import { validateEmail } from 'App/validate'; import cn from 'classnames'; import stl from './forgotPassword.css'; const LOGIN = loginRoute(); const recaptchaRef = React.createRef(); const ERROR_DONT_MATCH = "Passwords don't match."; const MIN_LENGTH = 8; const PASSWORD_POLICY = `Password should contain at least ${ MIN_LENGTH } symbols.`; const checkDontMatch = (newPassword, newPasswordRepeat) => newPasswordRepeat.length > 0 && newPasswordRepeat !== newPassword; @connect( (state, props) => ({ errors: state.getIn([ 'user', 'requestResetPassowrd', 'errors' ]), resetErrors: state.getIn([ 'user', 'resetPassword', 'errors' ]), loading: state.getIn([ 'user', 'requestResetPassowrd', 'loading' ]) || state.getIn([ 'user', 'resetPassword', 'loading' ]), params: new URLSearchParams(props.location.search) }), { requestResetPassword, resetPassword }, ) @withPageTitle("Password Reset - OpenReplay") @withRouter export default class ForgotPassword extends React.PureComponent { state = { email: '', code: ' ', password: '', passwordRepeat: '', requested: false, updated: false, }; handleSubmit = (token) => { const { email, requested, code, password } = this.state; const { params } = this.props; const pass = params.get('pass') const invitation = params.get('invitation') const resetting = pass && invitation if (!resetting) { this.props.requestResetPassword({ email: email.trim(), 'g-recaptcha-response': token }).then(() => { const { errors } = this.props; if (!errors) this.setState({ requested: true }); }); } else { if (this.isSubmitDisabled()) return; this.props.resetPassword({ email: email.trim(), invitation, pass, password }).then(() => { const { resetErrors } = this.props; if (!resetErrors) this.setState({ updated: true }); }); } } isSubmitDisabled() { const { password, passwordRepeat } = this.state; if (password !== passwordRepeat || password.length < MIN_LENGTH) return true; return false; } write = ({ target: { value, name } }) => this.setState({ [ name ]: value }) shouldShouwPolicy() { const { password } = this.state; if (password.length > 7) return false; if (password === '') return false; return true; } onSubmit = e => { e.preventDefault(); if (window.ENV.CAPTCHA_ENABLED && recaptchaRef.current) { recaptchaRef.current.execute() } else if (!window.ENV.CAPTCHA_ENABLED) { this.handleSubmit(); } } render() { const { errors, loading, params } = this.props; const { requested, updated, password, passwordRepeat, email } = this.state; const dontMatch = checkDontMatch(password, passwordRepeat); const pass = params.get('pass') const invitation = params.get('invitation') const resetting = pass && invitation const validEmail = validateEmail(email) return (