Remove client-side isLoggedIn value
[ProtonMail-WebClient.git] / packages / pass / components / Export / ExportForm.tsx
blob25e7974b1126688863ed274c34894e049ba2d198
1 import { type FC, useMemo } from 'react';
2 import { useSelector } from 'react-redux';
4 import { Field, Form, type FormikContextType, FormikProvider } from 'formik';
5 import { c } from 'ttag';
7 import { Button } from '@proton/atoms';
8 import { Icon } from '@proton/components';
9 import { RadioGroupField } from '@proton/pass/components/Form/Field/RadioGroupField';
10 import { PasswordField } from '@proton/pass/components/Form/legacy/PasswordField';
11 import { Card } from '@proton/pass/components/Layout/Card/Card';
12 import { useOrganization } from '@proton/pass/components/Organization/OrganizationProvider';
13 import { type ExportFormValues, ExportFormat } from '@proton/pass/lib/export/types';
14 import { selectNonOwnedVaults } from '@proton/pass/store/selectors';
15 import { BitField } from '@proton/pass/types';
16 import { truthy } from '@proton/pass/utils/fp/predicates';
18 type ExporterProps = { form: FormikContextType<ExportFormValues>; loading: boolean };
20 export const ExportForm: FC<ExporterProps> = ({ form, loading = false }) => {
21     const hasNonOwnedVaults = useSelector(selectNonOwnedVaults).length > 0;
22     const org = useOrganization({ sync: true });
23     const orgExportDisabled = !org?.b2bAdmin && org?.settings.ExportMode === BitField.ACTIVE;
25     const warnings = useMemo(
26         () =>
27             [
28                 /* Safari ZIP warning */
29                 BUILD_TARGET === 'safari' &&
30                     form.values.format === ExportFormat.ZIP &&
31                     c('Info')
32                         .t`Before exporting your data with this format, please open Safari settings -> "General" tab -> disable the option "Open safe files after downloading". This will prevent Safari from incorrectly extracting the exported file.`,
34                 /* Safari PGP warning */
35                 BUILD_TARGET === 'safari' &&
36                     form.values.format === ExportFormat.PGP &&
37                     c('Info')
38                         .t`Due to a limitation of Safari browser extensions, after exporting the data the file extension will be missing ".pgp". Please rename the file to include the .pgp extension (e.g file.pgp) after exporting.`,
40                 /* CSV warning */
41                 form.values.format === ExportFormat.CSV &&
42                     c('Info')
43                         .t`CSV offers a convenient format to view your data. However due to its simplicity, some data will not be included (custom fields, passkeys...). For a complete export, we recommend using a different format.`,
45                 /* non-encrypted warning */
46                 form.values.format !== ExportFormat.PGP &&
47                     c('Info')
48                         .t`This export will be unencrypted and anyone with access to your exported file will be able to see your passwords. For security, please delete it after you are done using it.`,
50                 /* Owned vault warning */
51                 hasNonOwnedVaults && c('Info').t`The export will only contain vaults that you own.`,
52             ].filter(truthy),
53         [form.values.format, hasNonOwnedVaults]
54     );
56     return (
57         <FormikProvider value={form}>
58             <Form className="modal-two-dialog-container">
59                 <div className="flex align-center items-center gap-4 mb-4">
60                     <Field
61                         name="format"
62                         className="flex flex-nowrap ml-2 mt-2 mb-2"
63                         component={RadioGroupField}
64                         options={[
65                             {
66                                 value: ExportFormat.PGP,
67                                 label: c('Label').t`PGP-encrypted JSON (recommended)`,
68                             },
69                             {
70                                 value: ExportFormat.ZIP,
71                                 label: c('Label').t`JSON`,
72                             },
73                             {
74                                 value: ExportFormat.CSV,
75                                 label: 'CSV',
76                             },
77                         ]}
78                         checked={form.values.format}
79                         label={c('Label').t`File format`}
80                         disabled={orgExportDisabled}
81                     />
82                 </div>
84                 {warnings.length > 0 && (
85                     <Card className="mb-4 p-1 flex flex-column flex-nowrap gap-2 text-sm" type="primary">
86                         {warnings.map((text, idx) => (
87                             <div key={`warning-${idx}`} className={'flex items-start flex-nowrap w-full gap-2'}>
88                                 <Icon name="info-circle-filled" size={3} className="shrink-0 mt-0.5" />
89                                 <span>{text}</span>
90                             </div>
91                         ))}
92                     </Card>
93                 )}
95                 {form.values.format === ExportFormat.PGP && (
96                     <>
97                         <hr className="mt-2 mb-4 border-weak shrink-0" />
99                         <Field
100                             name="passphrase"
101                             label={
102                                 <div>
103                                     {c('Label').t`Passphrase`}{' '}
104                                     <em className="block text-normal text-sm color-weak my-1">
105                                         {c('Info')
106                                             .t`The exported file will be encrypted using PGP and requires a strong passphrase.`}
107                                     </em>
108                                 </div>
109                             }
110                             component={PasswordField}
111                             autoComplete="new-password"
112                         />
113                     </>
114                 )}
116                 {orgExportDisabled && (
117                     <Card className="mb-4 p-1 text-sm" type="primary">
118                         <div>{c('Info').t`This setting is disabled on the organization level`}</div>
119                     </Card>
120                 )}
122                 <Button
123                     type="submit"
124                     color="norm"
125                     loading={loading}
126                     disabled={!form.isValid || loading || orgExportDisabled}
127                     className="mt-5 w-full"
128                 >
129                     {c('Action').t`Export`}
130                 </Button>
131             </Form>
132         </FormikProvider>
133     );