From 40ac24014bede155ca355dedff9a954c8d1c6d97 Mon Sep 17 00:00:00 2001 From: Andrea Cecchi Date: Thu, 27 Oct 2022 09:47:00 +0200 Subject: [PATCH] fix: customize password reset routes until we use Volto 16 (volto #3448) (#602) --- src/config/italiaConfig.js | 6 + .../volto/components/theme/Login/Login.jsx | 326 ++++++++++++++++++ src/routes.js | 23 ++ 3 files changed, 355 insertions(+) create mode 100644 src/customizations/volto/components/theme/Login/Login.jsx diff --git a/src/config/italiaConfig.js b/src/config/italiaConfig.js index 82c8017e..bba342e8 100644 --- a/src/config/italiaConfig.js +++ b/src/config/italiaConfig.js @@ -244,6 +244,12 @@ export default function applyConfig(voltoConfig) { }, videoAllowExternalsDefault: false, showTrasparenzaFields: false, + // TO DO: DA RIMUOVERE QUANDO AGGIORNIAMO A VOLTO16 + nonContentRoutes: [ + ...config.settings.nonContentRoutes, + /\/passwordreset\/.*$/, + '/passwordreset', + ], }; /****************************************************************************** diff --git a/src/customizations/volto/components/theme/Login/Login.jsx b/src/customizations/volto/components/theme/Login/Login.jsx new file mode 100644 index 00000000..87270b79 --- /dev/null +++ b/src/customizations/volto/components/theme/Login/Login.jsx @@ -0,0 +1,326 @@ +/** + * Login container. + * @module components/theme/Login/Login + * TO DO: DA RIMUOVERE QUANDO AGGIORNIAMO A VOLTO16 + */ + +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { Helmet } from '@plone/volto/helpers'; +import { connect } from 'react-redux'; +import { compose } from 'redux'; +import { Link } from 'react-router-dom'; +import { + Container, + Button, + Form, + Input, + Segment, + Grid, +} from 'semantic-ui-react'; +import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; +import qs from 'query-string'; +import { withRouter } from 'react-router-dom'; + +import { Icon } from '@plone/volto/components'; +import { login } from '@plone/volto/actions'; +import { toast } from 'react-toastify'; +import { Toast } from '@plone/volto/components'; + +import aheadSVG from '@plone/volto/icons/ahead.svg'; +import clearSVG from '@plone/volto/icons/clear.svg'; + +import config from '@plone/volto/registry'; + +const messages = defineMessages({ + login: { + id: 'Log in', + defaultMessage: 'Log in', + }, + loginName: { + id: 'Login Name', + defaultMessage: 'Login Name', + }, + Login: { + id: 'Login', + defaultMessage: 'Login', + }, + password: { + id: 'Password', + defaultMessage: 'Password', + }, + cancel: { + id: 'Cancel', + defaultMessage: 'Cancel', + }, + error: { + id: 'Error', + defaultMessage: 'Error', + }, + loginFailed: { + id: 'Login Failed', + defaultMessage: 'Login Failed', + }, + loginFailedContent: { + id: + 'Both email address and password are case sensitive, check that caps lock is not enabled.', + defaultMessage: + 'Both email address and password are case sensitive, check that caps lock is not enabled.', + }, + register: { + id: 'Register', + defaultMessage: 'Register', + }, + forgotPassword: { + id: 'box_forgot_password_option', + defaultMessage: 'Forgot your password?', + }, +}); + +/** + * Login class. + * @class Login + * @extends Component + */ +class Login extends Component { + /** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ + static propTypes = { + login: PropTypes.func.isRequired, + error: PropTypes.shape({ + message: PropTypes.string, + }), + loading: PropTypes.bool, + token: PropTypes.string, // eslint-disable-line react/no-unused-prop-types + returnUrl: PropTypes.string, + }; + + /** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ + static defaultProps = { + error: null, + loading: null, + token: null, + returnUrl: null, + }; + + /** + * Constructor + * @method constructor + * @param {Object} props Component properties + * @constructs WysiwygEditor + */ + constructor(props) { + super(props); + this.onLogin = this.onLogin.bind(this); + } + + /** + * Component will receive props + * @method componentWillReceiveProps + * @param {Object} nextProps Next properties + * @returns {undefined} + */ + UNSAFE_componentWillReceiveProps(nextProps) { + if (nextProps.token) { + this.props.history.push(this.props.returnUrl || '/'); + if (toast.isActive('loginFailed')) { + toast.dismiss('loginFailed'); + } + } + if (nextProps.error) { + if (!toast.isActive('loginFailed')) { + toast.error( + , + { autoClose: false, toastId: 'loginFailed' }, + ); + } + } + } + + componentWillUnmount() { + if (toast.isActive('loginFailed')) { + toast.dismiss('loginFailed'); + } + } + + /** + * On login handler + * @method onLogin + * @param {Object} event Event object. + * @returns {undefined} + */ + onLogin(event) { + this.props.login( + document.getElementsByName('login')[0].value, + document.getElementsByName('password')[0].value, + ); + event.preventDefault(); + } + + /** + * Render method. + * @method render + * @returns {string} Markup for the component. + */ + render() { + return ( +
+ + +
+ + + + + + + + + + + + +
+ +
+
+ + {/* eslint-disable jsx-a11y/no-autofocus */} + + +
+
+
+ + + + +
+ +
+
+ + + +
+
+
+ + + + {config.settings.showSelfRegistration && ( + +

+ + {this.props.intl.formatMessage(messages.register)} + +

+
+ )} + +

+ + {this.props.intl.formatMessage( + messages.forgotPassword, + )} + +

+
+
+
+
+
+ + + + + +
+
+
+
+ ); + } +} + +export default compose( + withRouter, + injectIntl, + connect( + (state, props) => ({ + error: state.userSession.login.error, + loading: state.userSession.login.loading, + token: state.userSession.token, + returnUrl: + qs.parse(props.location.search).return_url || + props.location.pathname + .replace(/\/login$/, '') + .replace(/\/logout$/, '') || + '/', + }), + { login }, + ), +)(Login); diff --git a/src/routes.js b/src/routes.js index 65a8239d..41f3d0c9 100644 --- a/src/routes.js +++ b/src/routes.js @@ -5,6 +5,7 @@ import { App, Search, Contents } from '@plone/volto/components'; import { defaultRoutes, multilingualRoutes } from '@plone/volto/routes'; +import { PasswordReset, RequestPasswordReset } from '@plone/volto/components'; // TO DO: DA RIMUOVERE QUANDO AGGIORNIAMO A VOLTO16 import config from '@plone/volto/registry'; export const italiaRoutes = [ @@ -18,6 +19,28 @@ export const italiaRoutes = [ path: ['/contents', '/**/contents'], component: Contents, }, + { + path: `/(${config.settings?.supportedLanguages.join('|')})/passwordreset`, + component: RequestPasswordReset, + exact: true, + }, + { + path: `/(${config.settings?.supportedLanguages.join( + '|', + )})/passwordreset/:token`, + component: PasswordReset, + exact: true, + }, + { + path: '/passwordreset', + component: RequestPasswordReset, + exact: true, + }, + { + path: '/passwordreset/:token', + component: PasswordReset, + exact: true, + }, ]; /**