import React, { useLayoutEffect } from "react"; import { AppState } from "@appsmith/reducers"; import { Link, withRouter, RouteComponentProps } from "react-router-dom"; import { connect } from "react-redux"; import { InjectedFormProps, reduxForm, Field } from "redux-form"; import { RESET_PASSWORD_FORM_NAME } from "@appsmith/constants/forms"; import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants"; import { getIsTokenValid, getIsValidatingToken } from "selectors/authSelectors"; import { Icon } from "@blueprintjs/core"; import FormTextField from "components/utils/ReduxFormTextField"; import { Button, FormGroup, FormMessage, FormMessageProps, MessageAction, Size, } from "design-system"; import Spinner from "components/editorComponents/Spinner"; import StyledForm from "components/editorComponents/Form"; import { isEmptyString, isStrongPassword } from "utils/formhelpers"; import { ResetPasswordFormValues, resetPasswordSubmitHandler } from "./helpers"; import { BlackAuthCardNavLink, FormActions } from "./StyledComponents"; import { AUTH_LOGIN_URL, FORGOT_PASSWORD_URL } from "constants/routes"; import { withTheme } from "styled-components"; import { Theme } from "constants/DefaultTheme"; import { RESET_PASSWORD_PAGE_PASSWORD_INPUT_LABEL, RESET_PASSWORD_PAGE_PASSWORD_INPUT_PLACEHOLDER, RESET_PASSWORD_LOGIN_LINK_TEXT, RESET_PASSWORD_SUBMIT_BUTTON_TEXT, RESET_PASSWORD_PAGE_TITLE, FORM_VALIDATION_INVALID_PASSWORD, FORM_VALIDATION_EMPTY_PASSWORD, RESET_PASSWORD_EXPIRED_TOKEN, RESET_PASSWORD_FORGOT_PASSWORD_LINK, RESET_PASSWORD_INVALID_TOKEN, RESET_PASSWORD_RESET_SUCCESS, RESET_PASSWORD_RESET_SUCCESS_LOGIN_LINK, createMessage, } from "@appsmith/constants/messages"; import Container from "./Container"; const validate = (values: ResetPasswordFormValues) => { const errors: ResetPasswordFormValues = {}; if (!values.password || isEmptyString(values.password)) { errors.password = createMessage(FORM_VALIDATION_EMPTY_PASSWORD); } else if (!isStrongPassword(values.password)) { errors.password = createMessage(FORM_VALIDATION_INVALID_PASSWORD); } return errors; }; type ResetPasswordProps = InjectedFormProps< ResetPasswordFormValues, { verifyToken: (token: string) => void; isTokenValid: boolean; validatingToken: boolean; } > & { verifyToken: (token: string) => void; isTokenValid: boolean; validatingToken: boolean; theme: Theme; } & RouteComponentProps<{ email: string; token: string }>; export function ResetPassword(props: ResetPasswordProps) { const { error, handleSubmit, initialValues, isTokenValid, pristine, submitFailed, submitSucceeded, submitting, validatingToken, verifyToken, } = props; useLayoutEffect(() => { if (initialValues.token) verifyToken(initialValues.token); }, [initialValues.token, verifyToken]); const showInvalidMessage = !initialValues.token; const showExpiredMessage = !isTokenValid && !validatingToken; const showSuccessMessage = submitSucceeded && !pristine; const showFailureMessage = submitFailed && !!error; let message = ""; let messageActions: MessageAction[] | undefined = undefined; if (showExpiredMessage || showInvalidMessage) { const messageActionText = createMessage( RESET_PASSWORD_FORGOT_PASSWORD_LINK, ); messageActions = [ { linkElement: {messageActionText}, text: messageActionText, intent: "primary", }, ]; } if (showExpiredMessage) { message = createMessage(RESET_PASSWORD_EXPIRED_TOKEN); } if (showInvalidMessage) { message = createMessage(RESET_PASSWORD_INVALID_TOKEN); } if (showSuccessMessage) { const messageActionText = createMessage( RESET_PASSWORD_RESET_SUCCESS_LOGIN_LINK, ); message = createMessage(RESET_PASSWORD_RESET_SUCCESS); messageActions = [ { linkElement: {messageActionText}, text: messageActionText, intent: "success", }, ]; } if (showFailureMessage) { message = error; if ( message .toLowerCase() .includes( createMessage(RESET_PASSWORD_FORGOT_PASSWORD_LINK).toLowerCase(), ) ) { const messageActionText = createMessage( RESET_PASSWORD_FORGOT_PASSWORD_LINK, ); messageActions = [ { linkElement: ( {messageActionText} ), text: messageActionText, intent: "primary", }, ]; } } const messageTagProps: FormMessageProps = { intent: showInvalidMessage || showExpiredMessage || showFailureMessage ? "danger" : "lightSuccess", message, actions: messageActions, }; if (showInvalidMessage || showExpiredMessage) { return ; } if (!isTokenValid && validatingToken) { return ; } return ( {createMessage(RESET_PASSWORD_LOGIN_LINK_TEXT)} } title={createMessage(RESET_PASSWORD_PAGE_TITLE)} > {(showSuccessMessage || showFailureMessage) && ( )}