actual/packages/desktop-client/src/components/modals/CreateEncryptionKey.js
Tom French 9c0df36e16
Sort import in alphabetical order (#238)
* style: enforce sorting of imports

* style: alphabetize imports

* style: merge duplicated imports
2022-09-02 15:07:24 +01:00

170 lines
5.2 KiB
JavaScript

import React, { useState } from 'react';
import { css } from 'glamor';
import { send } from 'loot-core/src/platform/client/fetch';
import { getCreateKeyError } from 'loot-core/src/shared/errors';
import {
View,
Text,
Modal,
ButtonWithLoading,
ExternalLink,
P,
ModalButtons,
Input,
InitialFocus
} from 'loot-design/src/components/common';
import { colors } from 'loot-design/src/style';
export default function CreateEncryptionKey({
modalProps,
actions,
budgetId,
options = {}
}) {
let [enabling, setEnabling] = useState(false);
let [password, setPassword] = useState('');
let [loading, setLoading] = useState(false);
let [error, setError] = useState('');
let [showPassword, setShowPassword] = useState(false);
let isRecreating = options.recreate;
async function onCreateKey() {
if (password !== '' && !loading) {
setLoading(true);
setError(null);
let res = await send('key-make', { password });
if (res.error) {
setLoading(null);
setError(getCreateKeyError(res.error));
return;
}
actions.loadGlobalPrefs();
actions.loadAllFiles();
actions.sync();
setLoading(false);
actions.popModal();
}
}
return (
<Modal
{...modalProps}
style={{ width: 600 }}
title={isRecreating ? 'Generate new key' : 'Enable encryption'}
onClose={() => actions.popModal()}
>
{() => (
<>
{!isRecreating ? (
<>
<P style={{ marginTop: 5 }}>
To enable end-to-end encryption, you need to create a key. We
will generate a key based on a password and use it to encrypt
from now on. <strong>This requires a sync reset</strong> and all
other devices will have to revert to this version of your data.{' '}
<ExternalLink
asAnchor
href="https://actualbudget.com/encrypted-syncing"
>
Learn more
</ExternalLink>
</P>
<P>
<ul {...css({ marginTop: 0, '& li': { marginBottom: 8 } })}>
<li>
<strong>Important:</strong> if you forget this password{' '}
<em>and</em> you don't have any local copies of your data,
you will lose access to all your data. We cannot decrypt
your data.
</li>
<li>
This key only applies to this file. You will need to
generate a new key for each file you want to encrypt.
</li>
<li>
If you've already downloaded your data on other devices, you
will need to reset them. Actual will automatically take you
through this process.
</li>
</ul>
</P>
</>
) : (
<>
<P style={{ marginTop: 5 }}>
This will generate a new key for encrypting your data.{' '}
<strong>This requires a sync reset</strong> and all other
devices will have to revert to this version of your data. Actual
will take you through that process on those devices.{' '}
<ExternalLink
asAnchor
href="https://actualbudget.com/encrypted-syncing"
>
Learn more
</ExternalLink>
</P>
<P>
Key generation is randomized. The same password will create
different keys, so this will change your key regardless of the
password being different.
</P>
</>
)}
<form
onSubmit={e => {
e.preventDefault();
onCreateKey();
}}
>
<View style={{ alignItems: 'center' }}>
<Text style={{ fontWeight: 600, marginBottom: 3 }}>Password</Text>
{error && (
<View
style={{
color: colors.r4,
textAlign: 'center',
fontSize: 13,
marginBottom: 3
}}
>
{error}
</View>
)}
<InitialFocus>
<Input
type={showPassword ? 'text' : 'password'}
style={{ width: 300 }}
onChange={e => setPassword(e.target.value)}
/>
</InitialFocus>
<Text style={{ marginTop: 5 }}>
<label style={{ userSelect: 'none' }}>
<input
type="checkbox"
onClick={() => setShowPassword(!showPassword)}
/>{' '}
Show password
</label>
</Text>
</View>
<ModalButtons style={{ marginTop: 20 }}>
<ButtonWithLoading loading={loading} primary>
Enable
</ButtonWithLoading>
</ModalButtons>
</form>
</>
)}
</Modal>
);
}