mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-21 09:38:01 +02:00
parent
5f7e130ff9
commit
8696052e27
@ -133,6 +133,7 @@ packages/app-desktop/gui/ClipperConfigScreen.js
|
|||||||
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
|
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
|
||||||
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
|
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
|
||||||
packages/app-desktop/gui/ConfigScreen/Sidebar.js
|
packages/app-desktop/gui/ConfigScreen/Sidebar.js
|
||||||
|
packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -119,6 +119,7 @@ packages/app-desktop/gui/ClipperConfigScreen.js
|
|||||||
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
|
packages/app-desktop/gui/ConfigScreen/ButtonBar.js
|
||||||
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
|
packages/app-desktop/gui/ConfigScreen/ConfigScreen.js
|
||||||
packages/app-desktop/gui/ConfigScreen/Sidebar.js
|
packages/app-desktop/gui/ConfigScreen/Sidebar.js
|
||||||
|
packages/app-desktop/gui/ConfigScreen/controls/ToggleAdvancedSettingsButton.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginBox.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/PluginsStates.js
|
||||||
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
packages/app-desktop/gui/ConfigScreen/controls/plugins/SearchPlugins.js
|
||||||
|
@ -19,6 +19,7 @@ import PluginService from '@joplin/lib/services/plugins/PluginService';
|
|||||||
import { getDefaultPluginsInstallState, updateDefaultPluginsInstallState } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
|
import { getDefaultPluginsInstallState, updateDefaultPluginsInstallState } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
|
||||||
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
|
import getDefaultPluginsInfo from '@joplin/lib/services/plugins/defaultPlugins/desktopDefaultPluginsInfo';
|
||||||
import JoplinCloudConfigScreen from '../JoplinCloudConfigScreen';
|
import JoplinCloudConfigScreen from '../JoplinCloudConfigScreen';
|
||||||
|
import ToggleAdvancedSettingsButton from './controls/ToggleAdvancedSettingsButton';
|
||||||
const { KeymapConfigScreen } = require('../KeymapConfig/KeymapConfigScreen');
|
const { KeymapConfigScreen } = require('../KeymapConfig/KeymapConfigScreen');
|
||||||
|
|
||||||
const settingKeyToControl: any = {
|
const settingKeyToControl: any = {
|
||||||
@ -208,17 +209,11 @@ class ConfigScreenComponent extends React.Component<any, any> {
|
|||||||
const advancedSettingsSectionStyle = { display: 'none' };
|
const advancedSettingsSectionStyle = { display: 'none' };
|
||||||
|
|
||||||
if (advancedSettingComps.length) {
|
if (advancedSettingComps.length) {
|
||||||
const iconName = this.state.showAdvancedSettings ? 'fa fa-angle-down' : 'fa fa-angle-right';
|
|
||||||
// const advancedSettingsButtonStyle = { ...theme.buttonStyle, marginBottom: 10 };
|
|
||||||
advancedSettingsButton = (
|
advancedSettingsButton = (
|
||||||
<div style={{ marginBottom: 10 }}>
|
<ToggleAdvancedSettingsButton
|
||||||
<Button
|
onClick={() => shared.advancedSettingsButton_click(this)}
|
||||||
level={ButtonLevel.Secondary}
|
advancedSettingsVisible={this.state.showAdvancedSettings}
|
||||||
onClick={() => shared.advancedSettingsButton_click(this)}
|
/>
|
||||||
iconName={iconName}
|
|
||||||
title={_('Show Advanced Settings')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
advancedSettingsSectionStyle.display = this.state.showAdvancedSettings ? 'block' : 'none';
|
advancedSettingsSectionStyle.display = this.state.showAdvancedSettings ? 'block' : 'none';
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import Button, { ButtonLevel } from '../../Button/Button';
|
||||||
|
import { _ } from '@joplin/lib/locale';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onClick: ()=> void;
|
||||||
|
advancedSettingsVisible: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ToggleAdvancedSettingsButton: React.FunctionComponent<Props> = props => {
|
||||||
|
const iconName = props.advancedSettingsVisible ? 'fa fa-angle-down' : 'fa fa-angle-right';
|
||||||
|
return (
|
||||||
|
<div style={{ marginBottom: 10 }}>
|
||||||
|
<Button
|
||||||
|
level={ButtonLevel.Secondary}
|
||||||
|
onClick={props.onClick}
|
||||||
|
iconName={iconName}
|
||||||
|
title={_('Show Advanced Settings')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default ToggleAdvancedSettingsButton;
|
@ -10,12 +10,13 @@ import { MasterKeyEntity } from '@joplin/lib/services/e2ee/types';
|
|||||||
import { getEncryptionEnabled, masterKeyEnabled, SyncInfo } from '@joplin/lib/services/synchronizer/syncInfoUtils';
|
import { getEncryptionEnabled, masterKeyEnabled, SyncInfo } from '@joplin/lib/services/synchronizer/syncInfoUtils';
|
||||||
import { getDefaultMasterKey, getMasterPasswordStatusMessage, masterPasswordIsValid, toggleAndSetupEncryption } from '@joplin/lib/services/e2ee/utils';
|
import { getDefaultMasterKey, getMasterPasswordStatusMessage, masterPasswordIsValid, toggleAndSetupEncryption } from '@joplin/lib/services/e2ee/utils';
|
||||||
import Button, { ButtonLevel } from '../Button/Button';
|
import Button, { ButtonLevel } from '../Button/Button';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import Setting from '@joplin/lib/models/Setting';
|
import Setting from '@joplin/lib/models/Setting';
|
||||||
import CommandService from '@joplin/lib/services/CommandService';
|
import CommandService from '@joplin/lib/services/CommandService';
|
||||||
import { PublicPrivateKeyPair } from '@joplin/lib/services/e2ee/ppk';
|
import { PublicPrivateKeyPair } from '@joplin/lib/services/e2ee/ppk';
|
||||||
|
import ToggleAdvancedSettingsButton from '../ConfigScreen/controls/ToggleAdvancedSettingsButton';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
themeId: any;
|
themeId: any;
|
||||||
@ -83,34 +84,6 @@ const EncryptionConfigScreen = (props: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderReencryptData = () => {
|
|
||||||
if (!shim.isElectron()) return null;
|
|
||||||
if (!props.shouldReencrypt) return null;
|
|
||||||
|
|
||||||
const theme = themeStyle(props.themeId);
|
|
||||||
const buttonLabel = _('Re-encrypt data');
|
|
||||||
|
|
||||||
const intro = props.shouldReencrypt ? _('The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.') : _('You may use the tool below to re-encrypt your data, for example if you know that some of your notes are encrypted with an obsolete encryption method.');
|
|
||||||
|
|
||||||
let t = `${intro}\n\n${_('In order to do so, your entire data set will have to be encrypted and synchronised, so it is best to run it overnight.\n\nTo start, please follow these instructions:\n\n1. Synchronise all your devices.\n2. Click "%s".\n3. Let it run to completion. While it runs, avoid changing any note on your other devices, to avoid conflicts.\n4. Once sync is done on this device, sync all your other devices and let it run to completion.\n\nImportant: you only need to run this ONCE on one device.', buttonLabel)}`;
|
|
||||||
|
|
||||||
t = t.replace(/\n\n/g, '</p><p>');
|
|
||||||
t = t.replace(/\n/g, '<br>');
|
|
||||||
t = `<p>${t}</p>`;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2>{_('Re-encryption')}</h2>
|
|
||||||
<p style={theme.textStyle} dangerouslySetInnerHTML={{ __html: t }}></p>
|
|
||||||
<span style={{ marginRight: 10 }}>
|
|
||||||
<button onClick={() => void reencryptData()} style={theme.buttonStyle}>{buttonLabel}</button>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{ !props.shouldReencrypt ? null : <button onClick={() => dontReencryptData()} style={theme.buttonStyle}>{_('Ignore')}</button> }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderMasterKey = (mk: MasterKeyEntity) => {
|
const renderMasterKey = (mk: MasterKeyEntity) => {
|
||||||
const theme = themeStyle(props.themeId);
|
const theme = themeStyle(props.themeId);
|
||||||
|
|
||||||
@ -239,7 +212,6 @@ const EncryptionConfigScreen = (props: Props) => {
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
const needUpgradeSection = renderNeedUpgradeSection();
|
const needUpgradeSection = renderNeedUpgradeSection();
|
||||||
const reencryptDataSection = renderReencryptData();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
@ -254,7 +226,6 @@ const EncryptionConfigScreen = (props: Props) => {
|
|||||||
{decryptedItemsInfo}
|
{decryptedItemsInfo}
|
||||||
{toggleButton}
|
{toggleButton}
|
||||||
{needUpgradeSection}
|
{needUpgradeSection}
|
||||||
{props.shouldReencrypt ? reencryptDataSection : null}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -338,6 +309,56 @@ const EncryptionConfigScreen = (props: Props) => {
|
|||||||
return nonExistingMasterKeySection;
|
return nonExistingMasterKeySection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderReencryptData = () => {
|
||||||
|
if (!shim.isElectron()) return null;
|
||||||
|
if (!props.encryptionEnabled) return null;
|
||||||
|
|
||||||
|
const theme = themeStyle(props.themeId);
|
||||||
|
const buttonLabel = _('Re-encrypt data');
|
||||||
|
|
||||||
|
const intro = props.shouldReencrypt ? _('The default encryption method has been changed to a more secure one and it is recommended that you apply it to your data.') : _('You may use the tool below to re-encrypt your data, for example if you know that some of your notes are encrypted with an obsolete encryption method.');
|
||||||
|
|
||||||
|
let t = `${intro}\n\n${_('In order to do so, your entire data set will have to be encrypted and synchronised, so it is best to run it overnight.\n\nTo start, please follow these instructions:\n\n1. Synchronise all your devices.\n2. Click "%s".\n3. Let it run to completion. While it runs, avoid changing any note on your other devices, to avoid conflicts.\n4. Once sync is done on this device, sync all your other devices and let it run to completion.\n\nImportant: you only need to run this ONCE on one device.', buttonLabel)}`;
|
||||||
|
|
||||||
|
t = t.replace(/\n\n/g, '</p><p>');
|
||||||
|
t = t.replace(/\n/g, '<br>');
|
||||||
|
t = `<p>${t}</p>`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>{_('Re-encryption')}</h2>
|
||||||
|
<p style={theme.textStyle} dangerouslySetInnerHTML={{ __html: t }}></p>
|
||||||
|
<span style={{ marginRight: 10 }}>
|
||||||
|
<button onClick={() => void reencryptData()} style={theme.buttonStyle}>{buttonLabel}</button>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{ !props.shouldReencrypt ? null : <button onClick={() => dontReencryptData()} style={theme.buttonStyle}>{_('Ignore')}</button> }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the user should re-encrypt, ensure that the section is visible initially.
|
||||||
|
const [showAdvanced, setShowAdvanced] = useState<boolean>(props.shouldReencrypt);
|
||||||
|
const toggleAdvanced = useCallback(() => {
|
||||||
|
setShowAdvanced(!showAdvanced);
|
||||||
|
}, [showAdvanced]);
|
||||||
|
|
||||||
|
const renderAdvancedSection = () => {
|
||||||
|
const reEncryptSection = renderReencryptData();
|
||||||
|
|
||||||
|
if (!reEncryptSection) return null;
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<ToggleAdvancedSettingsButton
|
||||||
|
onClick={toggleAdvanced}
|
||||||
|
advancedSettingsVisible={showAdvanced}/>
|
||||||
|
{ showAdvanced ? reEncryptSection : null }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="config-screen-content">
|
<div className="config-screen-content">
|
||||||
{renderDebugSection()}
|
{renderDebugSection()}
|
||||||
@ -346,6 +367,7 @@ const EncryptionConfigScreen = (props: Props) => {
|
|||||||
{renderMasterKeySection(props.masterKeys.filter(mk => masterKeyEnabled(mk)), true)}
|
{renderMasterKeySection(props.masterKeys.filter(mk => masterKeyEnabled(mk)), true)}
|
||||||
{renderMasterKeySection(props.masterKeys.filter(mk => !masterKeyEnabled(mk)), false)}
|
{renderMasterKeySection(props.masterKeys.filter(mk => !masterKeyEnabled(mk)), false)}
|
||||||
{renderNonExistingMasterKeysSection()}
|
{renderNonExistingMasterKeysSection()}
|
||||||
|
{renderAdvancedSection()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user