Skip to content

Commit 491033c

Browse files
nicodhr404r
authored andcommitted
feat: add option to force encryption (deltachat#6410)
* fix: only save e2ee setting after successful login
1 parent 89c888d commit 491033c

6 files changed

Lines changed: 111 additions & 22 deletions

File tree

_locales/_untranslated_en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"prevent_dialog_spam_checkbox": {
5454
"message": "Don't allow the app to open this dialog again"
5555
},
56-
"react_more_emojis" : {
56+
"react_more_emojis": {
5757
"message": "More emojis..."
5858
},
5959
"channel_name_changed": {

packages/frontend/scss/login/_login.scss

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,23 @@ div.delta-form-group {
152152
}
153153
}
154154

155+
&.delta-switch {
156+
> label {
157+
display: flex;
158+
flex-direction: row;
159+
align-items: center;
160+
justify-content: space-between;
161+
width: 100%;
162+
height: auto;
163+
font-size: 15px;
164+
line-height: normal;
165+
cursor: pointer;
166+
color: var(--deltaChatPrimaryFgLight);
167+
padding-inline-end: 5px;
168+
padding-block-end: 4px;
169+
}
170+
}
171+
155172
&.delta-input {
156173
input {
157174
appearance: none;

packages/frontend/src/components/LoginForm.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { I18nContext } from '../contexts/I18nContext'
1212
const log = getLogger('renderer/loginForm')
1313

1414
import type { Credentials } from './Settings/DefaultCredentials'
15+
import { useSettingsStore } from '../stores/settings'
16+
import Switch from './Switch'
1517

1618
const Socket = {
1719
automatic: 'automatic',
@@ -29,19 +31,26 @@ const CertificateChecks = {
2931
type LoginProps = React.PropsWithChildren<{
3032
credentials: Credentials
3133
setCredentials: (credentials: Credentials) => void
34+
forceEncryption?: boolean
35+
setForceEncryption?: (forceEncryption: boolean) => void
3236
/** whether editing existing account */
3337
isEdit?: true
3438
}>
3539

3640
export default function LoginForm({
3741
credentials,
3842
setCredentials,
43+
forceEncryption: forceEncryptionProp,
44+
setForceEncryption,
3945
isEdit,
4046
}: LoginProps) {
4147
const [uiShowAdvanced, setUiShowAdvanced] = useState<boolean>(false)
4248
const [providerInfo, setProviderInfo] = useState<
4349
Type.ProviderInfo | undefined
4450
>()
51+
const settingsStore = useSettingsStore()[0]
52+
const forceEncryption =
53+
forceEncryptionProp ?? settingsStore?.settings['force_encryption'] === '1'
4554

4655
const handleCredentialsChange = (
4756
event: React.ChangeEvent<HTMLInputElement>
@@ -260,7 +269,6 @@ export default function LoginForm({
260269
<option value={Socket.starttls}>STARTTLS</option>
261270
<option value={Socket.plain}>{tx('off')}</option>
262271
</DeltaSelect>
263-
264272
<DeltaSelect
265273
id='certificateChecks'
266274
label={tx('login_certificate_checks')}
@@ -275,6 +283,22 @@ export default function LoginForm({
275283
{tx('accept_invalid_certificates')}
276284
</option>
277285
</DeltaSelect>
286+
<div className='delta-form-group delta-switch'>
287+
<label>
288+
<span>{tx('enforce_e2ee')}</span>
289+
{/** be aware that this setting applies to all relays! */}
290+
<Switch
291+
checked={forceEncryption}
292+
disabled={settingsStore == null}
293+
onChange={() => {
294+
if (setForceEncryption) {
295+
setForceEncryption(!forceEncryption)
296+
return
297+
}
298+
}}
299+
/>
300+
</label>
301+
</div>
278302
</Collapse>
279303
<br />
280304
</div>

packages/frontend/src/components/dialogs/EditAccountAndPasswordDialog.tsx

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import useDialog from '../../hooks/dialog/useDialog'
1616
import type { DialogProps } from '../../contexts/DialogContext'
1717
import AlertDialog from './AlertDialog'
1818
import { T } from '@deltachat/jsonrpc-client'
19-
import { useSettingsStore } from '../../stores/settings'
19+
import SettingsStoreInstance, { useSettingsStore } from '../../stores/settings'
2020
import { getLogger } from '@deltachat-desktop/shared/logger'
2121

2222
type AccountAndPasswordDialogProps = DialogProps & {
@@ -57,11 +57,15 @@ function EditAccountInner({
5757
onClose: DialogProps['onClose']
5858
addr?: string
5959
}) {
60+
const settingsStore = useSettingsStore()[0]
6061
const [initialSettings, setInitialAccountSettings] =
6162
useState<Credentials>(defaultCredentials())
6263

6364
const [accountSettings, setAccountSettings] =
6465
useState<Credentials>(defaultCredentials())
66+
const [forceEncryption, setForceEncryption] = useState<boolean>(
67+
settingsStore?.settings['force_encryption'] === '1'
68+
)
6569

6670
const { openDialog } = useDialog()
6771
const tx = useTranslationFunction()
@@ -105,7 +109,18 @@ function EditAccountInner({
105109
}, [addr])
106110

107111
const onUpdate = useCallback(async () => {
108-
const onSuccess = () => onClose()
112+
const onSuccess = async () => {
113+
const forceEncryptionValue = forceEncryption ? '1' : '0'
114+
if (
115+
settingsStore?.settings['force_encryption'] !== forceEncryptionValue
116+
) {
117+
await SettingsStoreInstance.effect.setCoreSetting(
118+
'force_encryption',
119+
forceEncryptionValue
120+
)
121+
}
122+
onClose()
123+
}
109124

110125
const update = () => {
111126
openDialog(ConfigureProgressDialog, {
@@ -121,8 +136,16 @@ function EditAccountInner({
121136
log.error('changing email addres of transport is not allowed')
122137
return
123138
}
139+
124140
update()
125-
}, [accountSettings, initialSettings, onClose, openDialog])
141+
}, [
142+
accountSettings,
143+
forceEncryption,
144+
initialSettings,
145+
onClose,
146+
openDialog,
147+
settingsStore,
148+
])
126149

127150
const onOk = useCallback(async () => {
128151
await onUpdate()
@@ -137,6 +160,8 @@ function EditAccountInner({
137160
<LoginForm
138161
credentials={accountSettings}
139162
setCredentials={setAccountSettings}
163+
forceEncryption={forceEncryption}
164+
setForceEncryption={setForceEncryption}
140165
isEdit
141166
/>
142167
)}

packages/frontend/src/components/screens/AccountSetupScreen.tsx

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import useTranslationFunction from '../../hooks/useTranslationFunction'
1616
import useDialog from '../../hooks/dialog/useDialog'
1717
import { DialogId } from '../../contexts/DialogContext'
1818
import AlertDialog from '../dialogs/AlertDialog'
19+
import SettingsStoreInstance, { useSettingsStore } from '../../stores/settings'
1920

2021
import type ScreenController from '../../ScreenController'
2122

@@ -32,25 +33,43 @@ export default function AccountSetupScreen({
3233

3334
const [credentials, setCredentials] =
3435
useState<Credentials>(defaultCredentials())
35-
36-
const onClickLogin = useCallback(
37-
() =>
38-
openDialog(ConfigureProgressDialog, {
39-
credentials,
40-
onSuccess: () => {
41-
selectAccount(accountId)
42-
},
43-
onFail: (error: string) =>
44-
setPromptDialogId(
45-
openDialog(AlertDialog, {
46-
message: error,
47-
cb: () => setPromptDialogId(null),
48-
})
49-
),
50-
}),
51-
[accountId, openDialog, selectAccount, credentials]
36+
const settingsStore = useSettingsStore()[0]
37+
const [forceEncryption, setForceEncryption] = useState<boolean>(
38+
settingsStore?.settings['force_encryption'] === '1'
5239
)
5340

41+
const onClickLogin = useCallback(() => {
42+
openDialog(ConfigureProgressDialog, {
43+
credentials,
44+
onSuccess: async () => {
45+
const forceEncryptionValue = forceEncryption ? '1' : '0'
46+
if (
47+
settingsStore?.settings['force_encryption'] !== forceEncryptionValue
48+
) {
49+
await SettingsStoreInstance.effect.setCoreSetting(
50+
'force_encryption',
51+
forceEncryptionValue
52+
)
53+
}
54+
selectAccount(accountId)
55+
},
56+
onFail: (error: string) =>
57+
setPromptDialogId(
58+
openDialog(AlertDialog, {
59+
message: error,
60+
cb: () => setPromptDialogId(null),
61+
})
62+
),
63+
})
64+
}, [
65+
accountId,
66+
credentials,
67+
forceEncryption,
68+
openDialog,
69+
selectAccount,
70+
settingsStore,
71+
])
72+
5473
// TODO(maxph): we're now using <dialog> and can submit result via input
5574
// and not an explicit keyboard handling
5675
const onKeyDown = useCallback(
@@ -88,6 +107,8 @@ export default function AccountSetupScreen({
88107
<LoginForm
89108
credentials={credentials}
90109
setCredentials={setCredentials}
110+
forceEncryption={forceEncryption}
111+
setForceEncryption={setForceEncryption}
91112
/>
92113
</DialogContent>
93114
</DialogBody>

packages/frontend/src/stores/settings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface SettingsStoreState {
1818
bcc_self: string
1919
delete_device_after: string
2020
download_limit: string
21+
force_encryption: '0' | '1'
2122
media_quality: string
2223
is_chatmail: '0' | '1'
2324
who_can_call_me: WhoCanCallMe
@@ -36,6 +37,7 @@ const settingsKeys = [
3637
'bcc_self',
3738
'delete_device_after',
3839
'download_limit',
40+
'force_encryption',
3941
'media_quality',
4042
'is_chatmail',
4143
'who_can_call_me',

0 commit comments

Comments
 (0)