Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amina/email and password #17960

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ReactElement } from 'react';
import { Localize, useTranslations, localize } from '@deriv-com/translations';
import { Div100vhContainer, Icon, MobileDialog, Modal, SendEmailTemplate, Text, Popover } from '@deriv/components';
import { getPlatformSettings, CFD_PLATFORMS } from '@deriv/shared';
import { getPlatformSettings, CFD_PLATFORMS, routes } from '@deriv/shared';
import { useDevice } from '@deriv-com/ui';
import { Chat } from '@deriv/utils';

Expand Down Expand Up @@ -151,29 +151,37 @@ const SentEmailModal = ({
);
}

const should_show_close_icon =
identifier_title !== 'Change_Email' ||
(window.location.pathname === routes.passwords && identifier_title === 'Change_Email');
identifier_title !== 'Change_Email';

return (
<Modal
className={'sent-email__modal'}
is_open={is_open}
has_close_icon
has_close_icon={should_show_close_icon}
should_header_stick_body
title=''
toggleModal={onClose}
width='440px'
should_close_on_click_outside={should_show_close_icon}
>
<Div100vhContainer
className='account__scrollbars_container-wrapper'
is_disabled={isDesktop}
height_offset='80px'
>
<Modal.Body>
<div
onClick={onClose}
className='send-email-template__close'
data-testid='dt_send_email_template_close'
>
<Icon icon='IcCross' />
</div>
{should_show_close_icon && (
<div
onClick={onClose}
className='send-email-template__close'
data-testid='dt_send_email_template_close'
>
<Icon icon='IcCross' />
</div>
)}
{sent_email_template}
</Modal.Body>
</Div100vhContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,4 @@ describe('<Passwords />', () => {
expect(screen.getByText('Email address')).toBeInTheDocument();
expect(screen.getByText('BrandDerivLogoCoralIcon')).toBeInTheDocument();
});

it('should render MT5 platform section', async () => {
const store_config = mockStore({
client: { is_dxtrade_password_not_set: true },
});
renderComponent({ store_config });

const ele_mt5 = await screen.findAllByText('Deriv MT5 password');
expect(ele_mt5).toHaveLength(2);
});

it('should render DerivX platform section', async () => {
const store_config = mockStore({
client: { is_mt5_password_not_set: true },
});
renderComponent({ store_config });

const ele_derivx = await screen.findAllByText('Deriv X password');
expect(ele_derivx).toHaveLength(2);
});
});
19 changes: 2 additions & 17 deletions packages/account/src/Sections/Security/Passwords/passwords.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,17 @@ import { Loading } from '@deriv/components';
import { observer, useStore } from '@deriv/stores';
import DerivPassword from './deriv-password';
import DerivEmail from './deriv-email';
import DerivMt5Password from './deriv-mt5-password';
import DerivXPassword from './deriv-x-password';

/**
* Displays the Email, Password, section under Account settings.
* @name Passwords
* @returns {ReactNode}
*/
const Passwords = observer(() => {
const { client, common } = useStore();
const {
is_populating_mt5_account_list,
is_populating_dxtrade_account_list,
is_social_signup,
mt5_login_list,
is_mt5_password_not_set,
dxtrade_accounts_list,
is_dxtrade_password_not_set,
} = client;
const { is_from_derivgo } = common;
const { client } = useStore();
const { is_populating_mt5_account_list, is_populating_dxtrade_account_list, is_social_signup } = client;

const [is_loading, setIsLoading] = useState(true);
const has_mt5_accounts = mt5_login_list?.length > 0 || !is_mt5_password_not_set;
const has_dxtrade_accounts = dxtrade_accounts_list?.length > 0 || !is_dxtrade_password_not_set;

useEffect(() => {
if (
Expand All @@ -46,8 +33,6 @@ const Passwords = observer(() => {
<div className='account__passwords'>
<DerivEmail />
<DerivPassword />
{!is_from_derivgo && has_mt5_accounts && <DerivMt5Password />}
{!is_from_derivgo && has_dxtrade_accounts && <DerivXPassword />}
</div>
);
});
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/App/Constants/routes-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { localize } from '@deriv/translations';
import Redirect from 'App/Containers/Redirect';
import RootComponent from 'App/Containers/RootComponent';
import Endpoint from 'Modules/Endpoint';
import RedirectionPage from 'Modules/redirection-page';

import OSRedirect from '../Containers/OSRedirect';
import CallbackPage from '../../Modules/Callback/CallbackPage.tsx';
Expand Down Expand Up @@ -383,6 +384,7 @@ const initRoutesConfig = () => [
{ path: routes.index, component: RouterRedirect, getTitle: () => '', to: routes.traders_hub },
{ path: routes.endpoint, component: Endpoint, getTitle: () => 'Endpoint' }, // doesn't need localization as it's for internal use
{ path: routes.os_redirect, component: OSRedirect, getTitle: () => localize('Redirect') },
{ path: routes.redirect_page, component: RedirectionPage, getTitle: () => '' },
{ path: routes.redirect, component: Redirect, getTitle: () => localize('Redirect') },
{ path: routes.callback_page, component: CallbackPage, getTitle: () => 'Callback' },
{
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/App/Containers/Layout/app-contents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ const AppContents = observer(({ children }) => {
'app-contents--is-route-modal': is_route_modal_on,
'app-contents--is-scrollable': is_cfd_page || is_cashier_visible,
'app-contents--is-hidden': platforms[platform] && !(is_from_tradershub_os && isMobile),
'app-contents--is-onboarding': window.location.pathname === routes.onboarding,
'app-contents--is-onboarding':
window.location.pathname === routes.onboarding || window.location.pathname === routes.redirect_page,
'app-contents--is-dtrader-v2': dtrader_v2_enabled_mobile || dtrader_v2_enabled_desktop,
})}
ref={scroll_ref}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/App/Containers/Layout/footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Footer = () => {
const is_dtrader_route = pathname === routes.trade;
const show_in_tablet_routes = [routes.contract];

if (pathname === routes.onboarding) {
if (pathname === routes.onboarding || pathname === routes.redirect_page) {
return null;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/App/Containers/Layout/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const Header = observer(() => {
let result;
switch (true) {
case pathname === routes.onboarding:
case pathname === routes.redirect_page:
result = null;
break;
case traders_hub_routes:
Expand All @@ -93,7 +94,7 @@ const Header = observer(() => {
break;
}
return result;
} else if (pathname === routes.onboarding) {
} else if (pathname === routes.onboarding || pathname === routes.redirect_page) {
return null;
}
return has_wallet ? <DefaultHeaderWallets /> : <DefaultHeader />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('LinkExpiredModal', () => {
expect(screen.queryByText('Link expired')).not.toBeInTheDocument();
});

it('should not render the component close and resend email buttons', () => {
it('should render the component resend email buttons', () => {
// @ts-expect-error ignore this until find a way to make arguments as partial
mockUseRequest.mockReturnValue({ isLoading: false });
const mock = mockStore({ ui: { is_link_expired_modal_visible: true } });
Expand All @@ -53,7 +53,7 @@ describe('LinkExpiredModal', () => {
</APIProvider>
),
});
expect(screen.getByRole('button', { name: /Close/ })).toBeInTheDocument();

expect(screen.getByRole('button', { name: /Resend email/ })).toBeInTheDocument();
});

Expand All @@ -76,24 +76,7 @@ describe('LinkExpiredModal', () => {
expect(resend_button).toBeEnabled();
});

it('should close the modal on clicking close button', async () => {
// @ts-expect-error ignore this until find a way to make arguments as partial
mockUseRequest.mockReturnValue({ isLoading: false });
const mock = mockStore({ ui: { is_link_expired_modal_visible: true } });
render(<LinkExpiredModal />, {
wrapper: ({ children }) => (
<APIProvider>
<StoreProvider store={mock}>{children}</StoreProvider>
</APIProvider>
),
});
const close_button = screen.getByRole('button', { name: /Close/ });
userEvent.click(close_button);
expect(mock.ui.toggleLinkExpiredModal).toBeCalledTimes(1);
expect(mock.ui.toggleLinkExpiredModal).toHaveBeenCalledWith(false);
});

it('should call the verify email websocket API on clicking resend mail button', () => {
it('should call the verify email websocket API on clicking resend mail button', async () => {
// @ts-expect-error ignore this until find a way to make arguments as partial
mockUseRequest.mockReturnValue({ isLoading: false });
const mock = mockStore({ ui: { is_link_expired_modal_visible: true } });
Expand All @@ -108,7 +91,7 @@ describe('LinkExpiredModal', () => {
fireEvent.change(screen.getByRole('textbox', { name: /Email address/i }), {
target: { value: '[email protected]' },
});
userEvent.click(resend_button);
await userEvent.click(resend_button);
expect(mockUseRequest).toBeCalledWith('verify_email');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const LinkExpiredModal = observer(() => {
disableApp={disableApp}
enableApp={enableApp}
title={is_email_sent ? '' : localize('Link expired')}
has_close_icon
onConfirm={() => toggleLinkExpiredModal(false)}
>
<div className='link-expired'>
Expand Down Expand Up @@ -92,9 +91,6 @@ const LinkExpiredModal = observer(() => {
/>
</fieldset>
<FormSubmitButton
has_cancel
cancel_label={localize('Close')}
onCancel={() => toggleLinkExpiredModal(false)}
is_disabled={!values.email || !!errors.email || isSubmitting}
is_loading={isSubmitting}
label={localize('Resend email')}
Expand Down
21 changes: 21 additions & 0 deletions packages/core/src/App/Containers/Redirect/redirect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ const Redirect = observer(() => {
break;
}
case 'reset_password': {
history.push({
pathname: routes.redirect_page,
search: url_query_string,
});
redirected_to_route = true;

toggleResetPasswordModal(true);
break;
}
Expand All @@ -104,6 +110,11 @@ const Redirect = observer(() => {
redirectToLogin(is_logged_in, getLanguage(), true);
redirected_to_route = true;
} else {
history.push({
pathname: routes.redirect_page,
search: url_query_string,
});
redirected_to_route = true;
if (!verification_code[action_param]) {
const request_email_code = sessionStorage.getItem('request_email_code');
setVerificationCode(request_email_code, action_param);
Expand All @@ -114,10 +125,20 @@ const Redirect = observer(() => {
break;
}
case 'social_email_change': {
history.push({
pathname: routes.redirect_page,
search: url_query_string,
});
redirected_to_route = true;
toggleResetPasswordModal(true);
break;
}
case 'system_email_change': {
history.push({
pathname: routes.redirect_page,
search: url_query_string,
});
redirected_to_route = true;
toggleUpdateEmailModal(true);
break;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import classNames from 'classnames';
import { Formik, Form, FormikErrors } from 'formik';
import { useHistory } from 'react-router-dom';
import { Button, Dialog, Text, Input } from '@deriv/components';
import { validEmail, getErrorMessages } from '@deriv/shared';
import { Localize, localize } from '@deriv/translations';
import { validEmail, getErrorMessages, loginUrl, routes } from '@deriv/shared';
import { Localize, localize, getLanguage } from '@deriv/translations';
import { ConfirmEmailModal } from '../ConfirmEmailModal/confirm-email-modal';
import { observer, useStore } from '@deriv/stores';

Expand All @@ -13,8 +14,9 @@ type TResetEmailInitValues = {

const ResetEmailModal = observer(() => {
const { ui, client } = useStore();
const history = useHistory();
const { disableApp, enableApp, is_loading, is_reset_email_modal_visible: is_visible, toggleResetEmailModal } = ui;
const { email } = client;
const { email, is_logged_in } = client;
const [is_confirm_email_modal_open, setIsConfirmResetEmailModal] = React.useState(false);
const [email_error_msg, setEmailErrorMsg] = React.useState('');
const [email_value, setEmailValue] = React.useState('');
Expand Down Expand Up @@ -50,7 +52,14 @@ const ResetEmailModal = observer(() => {
/>
);
}

const onCancel = () => {
toggleResetEmailModal(false);
if (is_logged_in) {
history.push(routes.passwords);
} else {
window.location.href = loginUrl({ language: getLanguage() });
}
};
return (
<Formik
initialValues={reset_initial_values}
Expand All @@ -67,6 +76,8 @@ const ResetEmailModal = observer(() => {
dismissable={status.error_msg || email_error_msg}
onConfirm={() => toggleResetEmailModal(false)}
is_closed_on_cancel={false}
has_close_icon={!!errors.email || !!email_error_msg}
onClose={onCancel}
>
<div className='reset-email'>
<Form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import classNames from 'classnames';
import { Formik, Form, FormikHelpers, FormikErrors } from 'formik';
import { Button, Dialog, PasswordInput, PasswordMeter, Text } from '@deriv/components';
import { redirectToLogin, validPassword, validLength, getErrorMessages, WS, removeActionParam } from '@deriv/shared';
import { validPassword, validLength, getErrorMessages, WS, removeActionParam, loginUrl } from '@deriv/shared';
import { getLanguage, localize, Localize } from '@deriv/translations';
import { observer, useStore } from '@deriv/stores';
import { TSocketError, TSocketRequest, TSocketResponse } from '@deriv/api/types';
Expand Down Expand Up @@ -49,7 +49,9 @@ const ResetPasswordModal = observer(() => {

actions.setStatus({ reset_complete: true });
logoutClient().then(() => {
redirectToLogin(false, getLanguage(), false);
sessionStorage.removeItem('redirect_url');
removeActionParam('reset_password');
window.location.href = loginUrl({ language: getLanguage() });
});
};

Expand Down Expand Up @@ -114,7 +116,6 @@ const ResetPasswordModal = observer(() => {
dismissable={status.error_msg}
onConfirm={closeResetPasswordModal}
title={localize('Reset your password')}
has_close_icon
is_closed_on_cancel={false}
>
<div className='reset-password'>
Expand Down
Loading
Loading