1 import { c } from 'ttag';
3 import type { UserSettings } from '@proton/shared/lib/interfaces';
4 import isTruthy from '@proton/utils/isTruthy';
6 import type { RecoveryCardStatusProps } from './RecoveryCardStatus';
8 export type EmailSettings = Pick<UserSettings['Email'], 'Value' | 'Status' | 'Notify' | 'Reset'>;
9 export type PhoneSettings = Pick<UserSettings['Phone'], 'Value' | 'Status' | 'Notify' | 'Reset'>;
15 interface CallToAction {
19 export const populateCallToActions = (
20 type: 'phone number' | 'email address' | `recovery phrase`,
27 if (type === 'recovery phrase') {
29 text: c('Info').t`Set recovery phrase`,
30 path: `/recovery#${ids.data}`,
37 if (type === 'phone number') {
38 text = c('Info').t`Add a recovery phone number`;
39 } else if (type === 'email address') {
40 text = c('Info').t`Add a recovery email address`;
42 } else if (hasMnemonic && enabled) {
43 if (type === 'phone number') {
44 text = c('Info').t`Disable recovery by phone number`;
45 } else if (type === 'email address') {
46 text = c('Info').t`Disable recovery by email address`;
49 if (type === 'phone number') {
50 text = c('Info').t`Verify phone number`;
51 } else if (type === 'email address') {
52 text = c('Info').t`Verify email address`;
57 path: `/recovery#${ids.account}`,
61 const sortActionTypes = (a: CallToAction, b: CallToAction) => {
62 if (a.text.startsWith('Disable') && !b.text.startsWith('Disable')) {
64 } else if (!a.text.startsWith('Disable') && b.text.startsWith('Disable')) {
71 const getSentinelRecoveryProps = (
76 ): RecoveryCardStatusProps => {
77 const hasEmail = !!email.Value;
78 const hasEmailVerified = !!email.Status;
79 const hasEmailEnabled = !!email.Reset;
80 const hasPhone = !!phone.Value;
81 const hasPhoneVerified = !!phone.Status;
82 const hasPhoneEnabled = !!phone.Reset;
84 const hasVerifiedandDisabledEmail = hasEmail && hasEmailVerified && !hasEmailEnabled;
85 const hasVerifiedandDisabledPhone = hasPhone && hasPhoneVerified && !hasPhoneEnabled;
88 if (hasMnemonic && hasVerifiedandDisabledEmail && hasVerifiedandDisabledPhone) {
91 statusText: c('Info').t`Your account recovery method is set`,
96 const emailCTA = populateCallToActions(
104 const phoneCTA = populateCallToActions(
112 const recoveryCTA = populateCallToActions('recovery phrase', ids);
117 statusText: c('Info').t`To ensure highest possible security of your account`,
118 callToActions: [!hasVerifiedandDisabledEmail && emailCTA, !hasVerifiedandDisabledPhone && phoneCTA]
120 .sort(sortActionTypes),
124 if (!hasMnemonic && ((hasEmailVerified && hasEmailEnabled) || (hasPhoneVerified && hasPhoneEnabled))) {
127 statusText: c('Info').t`To ensure highest possible security of your account`,
128 callToActions: [recoveryCTA, !hasEmailVerified && emailCTA, !hasPhoneVerified && phoneCTA].filter(isTruthy),
134 ((hasEmail && hasEmailEnabled && !hasEmailVerified) || (hasPhone && hasPhoneEnabled && !hasPhoneVerified))
138 statusText: c('Info').t`To ensure continuous access to your account, set an account recovery method`,
141 !hasVerifiedandDisabledEmail && emailCTA,
142 !hasVerifiedandDisabledPhone && phoneCTA,
150 statusText: c('Info').t`No account recovery method set; you are at risk of losing access to your account`,
152 !hasMnemonic && recoveryCTA,
153 !hasVerifiedandDisabledEmail && emailCTA,
154 !hasVerifiedandDisabledPhone && phoneCTA,
159 export default getSentinelRecoveryProps;