diff --git a/CHANGELOG.md b/CHANGELOG.md index a1bb8704f5..7234cb30b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ - fix update unread badge on when muting / unmuting a chat #4020 - fix update unread badge on receiving device messages #4020 - fix target chat was not opened on notification click #3983 +- fix "Password and Account" dialog not indicating invalid credentials, making it seem that you can change password like this #4032 +- fix "Password and Account" not restoring original credentials on "Cancel" sometimes #4033 diff --git a/src/renderer/components/LoginForm.tsx b/src/renderer/components/LoginForm.tsx index 8b86faed49..5827abc8ca 100644 --- a/src/renderer/components/LoginForm.tsx +++ b/src/renderer/components/LoginForm.tsx @@ -368,7 +368,7 @@ interface ConfigureProgressDialogProps { credentials?: Partial onSuccess?: () => void onUserCancellation?: () => void - onFail?: (error: string) => void + onFail: (error: string) => void } export function ConfigureProgressDialog({ @@ -403,10 +403,7 @@ export function ConfigureProgressDialog({ await BackendRemote.rpc.stopOngoingProcess(window.__selectedAccountId) } catch (error: any) { log.error('failed to stopOngoingProcess', error) - onFail && - onFail( - 'failed to stopOngoingProcess' + error.message || error.toString() - ) + onFail('failed to stopOngoingProcess' + error.message || error.toString()) // If it fails to cancel but is still successful, it should behave like normal. wasCanceled.current = false } @@ -446,7 +443,7 @@ export function ConfigureProgressDialog({ } catch (err: any) { log.error('configure error', err) onClose() - onFail && onFail(err.message || err.toString()) + onFail(err.message || err.toString()) } })() }, diff --git a/src/renderer/components/dialogs/EditAccountAndPasswordDialog.tsx b/src/renderer/components/dialogs/EditAccountAndPasswordDialog.tsx index a9807e39df..74be83601f 100644 --- a/src/renderer/components/dialogs/EditAccountAndPasswordDialog.tsx +++ b/src/renderer/components/dialogs/EditAccountAndPasswordDialog.tsx @@ -17,6 +17,7 @@ import useDialog from '../../hooks/dialog/useDialog' import useConfirmationDialog from '../../hooks/dialog/useConfirmationDialog' import type { DialogProps } from '../../contexts/DialogContext' +import AlertDialog from './AlertDialog' export default function EditAccountAndPasswordDialog({ onClose }: DialogProps) { const tx = useTranslationFunction() @@ -36,14 +37,20 @@ function EditAccountInner(onClose: DialogProps['onClose']) { const [accountSettings, _setAccountSettings] = useState(defaultCredentials()) - const [disableUpdate, setDisableUpdate] = useState(true) + const [userNeverChangedAccountSettings, setUserNeverChangedAccountSettings] = + useState(true) + const [ + userNeverAppliedNewAccountSettings, + setUserNeverAppliedNewAccountSettings, + ] = useState(true) const { openDialog } = useDialog() const openConfirmationDialog = useConfirmationDialog() const tx = useTranslationFunction() const setAccountSettings = (value: Credentials) => { - disableUpdate === true && setDisableUpdate(false) + userNeverChangedAccountSettings === true && + setUserNeverChangedAccountSettings(false) _setAccountSettings(value) } @@ -85,13 +92,17 @@ function EditAccountInner(onClose: DialogProps['onClose']) { }, []) const onUpdate = useCallback(async () => { - if (disableUpdate) return true + if (userNeverChangedAccountSettings) return true const onSuccess = () => onClose() const update = () => { + setUserNeverAppliedNewAccountSettings(false) openDialog(ConfigureProgressDialog, { credentials: accountSettings, onSuccess, + onFail: error => { + openDialog(AlertDialog, { message: error }) + }, }) } @@ -113,7 +124,7 @@ function EditAccountInner(onClose: DialogProps['onClose']) { } }, [ accountSettings, - disableUpdate, + userNeverChangedAccountSettings, initial_settings.addr, onClose, openConfirmationDialog, @@ -126,6 +137,44 @@ function EditAccountInner(onClose: DialogProps['onClose']) { if (update) onClose() }, [onClose, onUpdate]) + const onCacnel = () => { + if (userNeverAppliedNewAccountSettings) { + onClose() + return + } + // This for the case when the user edited credentials, pressed "OK", + // and then we failed to confugure account (see `ConfigureProgressDialog`), + // (which would result in `EditAccountAndPasswordDialog` + // not getting closed). + // In this case, "cancel" should revert back to the credentials that were + // set when the dialog was first opened. + // + // Yes, simply doing + // `await BackendRemote.rpc.batchSetConfig(accountId, initial_settings)` + // is also an option, but let's show the user that the original + // credentials are also not good, if that is the case. + // + // And yes, simply closing Delta Chat without pressing "Cancel", + // or the user closing the dialog wiht "Esc" + // would result this code not gettings invoked, and therefore + // original credentials not getting restored... + openDialog(ConfigureProgressDialog, { + credentials: initial_settings, // Yes, `initial_settings`. + onSuccess: () => {}, + onFail: error => { + // This shouldn't happen often, because + // we simply returned to original settings. + // But it could, if, for example, the credentials + // were changed on the server, + // and the user never entered the correct credentials. + openDialog(AlertDialog, { message: error }) + }, + }) + // Close the dialog immediately, no matter the result of the + // `ConfigureProgressDialog`. + onClose() + } + if (accountSettings === null) return null return ( <> @@ -139,7 +188,7 @@ function EditAccountInner(onClose: DialogProps['onClose']) { )} - onClose()} onOk={onOk} /> + ) } diff --git a/src/renderer/hooks/useInstantOnboarding.ts b/src/renderer/hooks/useInstantOnboarding.ts index fda3074143..d24140271a 100644 --- a/src/renderer/hooks/useInstantOnboarding.ts +++ b/src/renderer/hooks/useInstantOnboarding.ts @@ -15,6 +15,7 @@ import type { VerifyContactQr, VerifyGroupQr, } from '../backend/qr' +import AlertDialog from '../components/dialogs/AlertDialog' type InstantOnboarding = { createInstantAccount: (accountId: number) => Promise @@ -135,6 +136,9 @@ export default function useInstantOnboarding(): InstantOnboarding { reject(error) } }, + onFail: error => { + openDialog(AlertDialog, { message: error }) + }, }) }) },