From c0632d01956bfc39fa2aac3b7618550b47272ccb Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 17:17:17 -0600 Subject: [PATCH 1/3] Acquire a new session before enacting deactivation Fixes https://github.com/vector-im/riot-web/issues/13645 Every time the checkbox value changes we acquire a new session now. This avoids us asking the server to change its direction partway through the request. This causes a bit of UI jerk as the dialog goes from auth -> loading -> auth, however it's better than the alternative of reworking the entire UIA structure to support the `authData` dict changing. Originally this commit consisted of a `disabled` flag on the `InteractiveAuth` component which carried through to the stage's component, however it turns out that stack doesn't respect changes to the `authData` prop, which means the session ID we eventually send down is wrong (`erase: false` instead of the one with `erase: true`). Therefore, we do some logic to ensure we remount `InteractiveAuth` completely. Further work in this area is described in https://github.com/vector-im/riot-web/issues/13646 --- .../views/dialogs/DeactivateAccountDialog.js | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index b269ec2fdb..d84042011d 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -34,6 +34,7 @@ export default class DeactivateAccountDialog extends React.Component { shouldErase: false, errStr: null, authData: null, // for UIA + authEnabled: true, // see usages for information // A few strings that are passed to InteractiveAuth for design or are displayed // next to the InteractiveAuth component. @@ -42,21 +43,7 @@ export default class DeactivateAccountDialog extends React.Component { continueKind: null, }; - MatrixClientPeg.get().deactivateAccount(null, false).then(r => { - // If we got here, oops. The server didn't require any auth. - // Our application lifecycle will catch the error and do the logout bits. - // We'll try to log something in an vain attempt to record what happened (storage - // is also obliterated on logout). - console.warn("User's account got deactivated without confirmation: Server had no auth"); - this.setState({errStr: _t("Server did not require any authentication")}); - }).catch(e => { - if (e && e.httpStatus === 401 && e.data) { - // Valid UIA response - this.setState({authData: e.data}); - } else { - this.setState({errStr: _t("Server did not return valid authentication information.")}); - } - }); + this._initAuth(/* shouldErase= */false); } _onStagePhaseChange = (stage, phase) => { @@ -124,13 +111,40 @@ export default class DeactivateAccountDialog extends React.Component { _onEraseFieldChange = (ev) => { this.setState({ shouldErase: ev.target.checked, + + // Disable the auth form because we're going to have to reinitialize the auth + // information. We do this because we can't modify the parameters in the UIA + // session, and the user will have selected something which changes the request. + // Therefore, we throw away the last auth session and try a new one. + authEnabled: false, }); + + // As mentioned above, set up for auth again to get updated UIA session info + this._initAuth(/* shouldErase= */ev.target.checked); }; _onCancel() { this.props.onFinished(false); } + _initAuth(shouldErase) { + MatrixClientPeg.get().deactivateAccount(null, shouldErase).then(r => { + // If we got here, oops. The server didn't require any auth. + // Our application lifecycle will catch the error and do the logout bits. + // We'll try to log something in an vain attempt to record what happened (storage + // is also obliterated on logout). + console.warn("User's account got deactivated without confirmation: Server had no auth"); + this.setState({errStr: _t("Server did not require any authentication")}); + }).catch(e => { + if (e && e.httpStatus === 401 && e.data) { + // Valid UIA response + this.setState({authData: e.data, authEnabled: true}); + } else { + this.setState({errStr: _t("Server did not return valid authentication information.")}); + } + }); + }; + render() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); @@ -142,7 +156,7 @@ export default class DeactivateAccountDialog extends React.Component { } let auth =
{_t("Loading...")}
; - if (this.state.authData) { + if (this.state.authData && this.state.authEnabled) { auth = (
{this.state.bodyText} From 5e86dc2d60cf0a3b9bbfef6baabc23aafb2cccb6 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 17:20:11 -0600 Subject: [PATCH 2/3] Update i18n strings --- src/i18n/strings/en_EN.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b2fe409aa5..30e033bb43 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1589,13 +1589,13 @@ "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ": "You've previously used a newer version of Riot on %(host)s. To use this version again with end to end encryption, you will need to sign out and back in again. ", "Incompatible Database": "Incompatible Database", "Continue With Encryption Disabled": "Continue With Encryption Disabled", - "Server did not require any authentication": "Server did not require any authentication", - "Server did not return valid authentication information.": "Server did not return valid authentication information.", "Confirm your account deactivation by using Single Sign On to prove your identity.": "Confirm your account deactivation by using Single Sign On to prove your identity.", "Are you sure you want to deactivate your account? This is irreversible.": "Are you sure you want to deactivate your account? This is irreversible.", "Confirm account deactivation": "Confirm account deactivation", "To continue, please enter your password:": "To continue, please enter your password:", "There was a problem communicating with the server. Please try again.": "There was a problem communicating with the server. Please try again.", + "Server did not require any authentication": "Server did not require any authentication", + "Server did not return valid authentication information.": "Server did not return valid authentication information.", "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.", "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.", "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.", From 6d90a9d1a31170e497609eee9519ffd12ceff0af Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 12 May 2020 17:20:26 -0600 Subject: [PATCH 3/3] Appease the linter --- src/components/views/dialogs/DeactivateAccountDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/DeactivateAccountDialog.js b/src/components/views/dialogs/DeactivateAccountDialog.js index d84042011d..ffef2a30c7 100644 --- a/src/components/views/dialogs/DeactivateAccountDialog.js +++ b/src/components/views/dialogs/DeactivateAccountDialog.js @@ -143,7 +143,7 @@ export default class DeactivateAccountDialog extends React.Component { this.setState({errStr: _t("Server did not return valid authentication information.")}); } }); - }; + } render() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');