1 import { c } from 'ttag';
3 import { Button } from '@proton/atoms';
4 import useModalState from '@proton/components/components/modalTwo/useModalState';
5 import Toggle from '@proton/components/components/toggle/Toggle';
6 import useApi from '@proton/components/hooks/useApi';
7 import useEventManager from '@proton/components/hooks/useEventManager';
8 import useNotifications from '@proton/components/hooks/useNotifications';
9 import useLoading from '@proton/hooks/useLoading';
10 import metrics, { observeApiError } from '@proton/metrics';
11 import { updateSessionAccountRecovery } from '@proton/shared/lib/api/sessionRecovery';
14 useAvailableRecoveryMethods,
15 useIsSessionRecoveryEnabled,
16 useIsSessionRecoveryInitiationAvailable,
17 } from '../../hooks/useSessionRecovery';
18 import ChangePasswordModal, { MODES } from '../account/ChangePasswordModal';
19 import ReauthUsingRecoveryModal from '../account/ReauthUsingRecoveryModal';
20 import SettingsLayout from '../account/SettingsLayout';
21 import SettingsLayoutLeft from '../account/SettingsLayoutLeft';
22 import SettingsLayoutRight from '../account/SettingsLayoutRight';
23 import SettingsParagraph from '../account/SettingsParagraph';
24 import SettingsSection from '../account/SettingsSection';
25 import InitiateSessionRecoveryModal from '../account/sessionRecovery/InitiateSessionRecoveryModal';
26 import ConfirmDisableSessionRecoveryModal from './ConfirmDisableSessionRecoveryModal';
28 export const SessionRecoverySection = () => {
30 const { call } = useEventManager();
32 const [loadingSessionRecovery, withLoadingSessionRecovery] = useLoading();
34 const [sessionRecoveryModal, setSessionRecoveryModalOpen, renderSessionRecoveryModal] = useModalState();
35 const [recoveryModal, setRecoveryModalOpen, renderRecoveryModal] = useModalState();
36 const [changePasswordModal, setChangePasswordModalOpen, renderChangePasswordModal] = useModalState();
38 confirmDisableSessionRecoveryModal,
39 setConfirmDisableSessionRecoveryModalOpen,
40 renderConfirmDisableSessionRecoveryModal,
43 const [availableRecoveryMethods, loadingUseHasRecoveryMethod] = useAvailableRecoveryMethods();
44 const hasRecoveryMethod = availableRecoveryMethods.length > 0;
45 const isSessionRecoveryEnabled = useIsSessionRecoveryEnabled();
46 const isSessionRecoveryInitiationAvailable = useIsSessionRecoveryInitiationAvailable();
48 const { createNotification } = useNotifications();
50 const handleEnableSessionRecoveryToggle = async () => {
52 await api(updateSessionAccountRecovery({ SessionAccountRecovery: 1 }));
54 metrics.core_session_recovery_settings_update_total.increment({
58 observeApiError(error, (status) =>
59 metrics.core_session_recovery_settings_update_total.increment({
68 {renderSessionRecoveryModal && (
69 <InitiateSessionRecoveryModal
70 onUseRecoveryMethodClick={() => {
71 sessionRecoveryModal.onClose();
72 setRecoveryModalOpen(true);
75 {...sessionRecoveryModal}
78 {renderRecoveryModal && (
79 <ReauthUsingRecoveryModal
80 availableRecoveryMethods={availableRecoveryMethods}
82 recoveryModal.onClose();
83 setSessionRecoveryModalOpen(true);
85 onInitiateSessionRecoveryClick={() => {
86 recoveryModal.onClose();
87 setSessionRecoveryModalOpen(true);
89 onSuccess={() => setChangePasswordModalOpen(true)}
93 {renderChangePasswordModal && (
95 mode={MODES.CHANGE_ONE_PASSWORD_MODE}
97 {...changePasswordModal}
100 {renderConfirmDisableSessionRecoveryModal && (
101 <ConfirmDisableSessionRecoveryModal {...confirmDisableSessionRecoveryModal} />
105 {c('session_recovery:settings:info')
106 .t`To enhance the security of your account and protect your data, you can request a password reset from your account settings in the web application.`}
111 <label className="pt-0 mb-2 md:mb-0 text-semibold" htmlFor="signedInReset">
112 <span className="mr-2">
113 {c('session_recovery:settings:action').t`Allow password reset from settings`}
116 </SettingsLayoutLeft>
117 <SettingsLayoutRight isToggleContainer>
118 <div className="flex items-center">
120 loading={loadingSessionRecovery}
121 checked={isSessionRecoveryEnabled}
122 disabled={loadingUseHasRecoveryMethod}
124 onChange={({ target: { checked } }) => {
125 if (!hasRecoveryMethod && !checked) {
127 text: c('session_recovery:settings:info')
128 .t`To disallow password reset, you must have a recovery method set up.`,
134 setConfirmDisableSessionRecoveryModalOpen(true);
138 void withLoadingSessionRecovery(handleEnableSessionRecoveryToggle());
143 {isSessionRecoveryInitiationAvailable && (
144 <Button className="mt-4" color="norm" onClick={() => setSessionRecoveryModalOpen(true)}>
145 {c('session_recovery:settings:action').t`Request password reset`}
148 </SettingsLayoutRight>