Implement erasure option upon deactivation

This commit is contained in:
Luke Barnard 2018-05-23 16:33:32 +01:00
parent ba3dd0c87a
commit b124989968
2 changed files with 101 additions and 11 deletions

View file

@ -33,10 +33,21 @@ export default class DeactivateAccountDialog extends React.Component {
this._onOk = this._onOk.bind(this);
this._onCancel = this._onCancel.bind(this);
this._onPasswordFieldChange = this._onPasswordFieldChange.bind(this);
this._onEraseFieldChange = this._onEraseFieldChange.bind(this);
const deactivationPreferences =
MatrixClientPeg.get().getAccountData('im.riot.account_deactivation_preferences');
const shouldErase = (
deactivationPreferences &&
deactivationPreferences.getContent() &&
deactivationPreferences.getContent().shouldErase
) || false;
this.state = {
confirmButtonEnabled: false,
busy: false,
shouldErase,
errStr: null,
};
}
@ -47,16 +58,54 @@ export default class DeactivateAccountDialog extends React.Component {
});
}
_onEraseFieldChange(ev) {
this.setState({
shouldErase: ev.target.checked,
});
}
async _onOk() {
// This assumes that the HS requires password UI auth
// for this endpoint. In reality it could be any UI auth.
this.setState({busy: true});
// Before we deactivate the account insert an event into
// the user's account data indicating that they wish to be
// erased from the homeserver.
//
// We do this because the API for erasing after deactivation
// might not be supported by the connected homeserver. Leaving
// an indication in account data is only best-effort, and
// in the worse case, the HS maintainer would have to run a
// script to erase deactivated accounts that have shouldErase
// set to true in im.riot.account_deactivation_preferences.
//
// Note: The preferences are scoped to Riot, hence the
// "im.riot..." event type.
//
// Note: This may have already been set on previous attempts
// where, for example, the user entered the wrong password.
// This is fine because the UI always indicates the preference
// prior to us calling `deactivateAccount`.
try {
await MatrixClientPeg.get().deactivateAccount({
await MatrixClientPeg.get().setAccountData('im.riot.account_deactivation_preferences', {
shouldErase: this.state.shouldErase,
});
} catch (err) {
this.setState({
busy: false,
errStr: _t('Failed to indicate account erasure'),
});
return;
}
try {
// This assumes that the HS requires password UI auth
// for this endpoint. In reality it could be any UI auth.
const auth = {
type: 'm.login.password',
user: MatrixClientPeg.get().credentials.userId,
password: this._passwordField.value,
});
};
await MatrixClientPeg.get().deactivateAccount(auth, this.state.shouldErase);
} catch (err) {
let errStr = _t('Unknown error');
// https://matrix.org/jira/browse/SYN-744
@ -70,6 +119,7 @@ export default class DeactivateAccountDialog extends React.Component {
});
return;
}
Analytics.trackEvent('Account', 'Deactivate Account');
Lifecycle.onLoggedOut();
this.props.onFinished(false);
@ -107,21 +157,56 @@ export default class DeactivateAccountDialog extends React.Component {
onFinished={this.props.onFinished}
onEnterPressed={this.onOk}
titleClass="danger"
title={_t("Deactivate Account")}>
title={_t("Deactivate Account")}
>
<div className="mx_Dialog_content">
<p>{ _t("This will make your account permanently unusable. You will not be able to re-register the same user ID.") }</p>
<p>{ _t(
"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. " +
"<b>This action is irreversible.</b>",
{},
{ b: (sub) => <b> { sub } </b> },
) }</p>
<p>{ _t("This action is irreversible.") }</p>
<p>{ _t(
"Deactivating your account <b>does not by default erase messages you have sent.</b> " +
"If you would like to erase your messages, please tick the box below.",
{},
{ b: (sub) => <b> { sub } </b> },
) }</p>
<p>{ _t("To continue, please enter your password.") }</p>
<p>{ _t(
"Message visibility in Matrix is similar to email. " +
"Erasing your messages means that messages have you sent will not be shared with " +
"any new or unregistered users, but registered users who already had access to " +
"these messages will still have access to their copy.",
) }</p>
<p>{ _t("Password") }:</p>
<p>{ _t("To continue, please enter your password:") }</p>
<input
type="password"
placeholder={_t("password")}
onChange={this._onPasswordFieldChange}
ref={(e) => {this._passwordField = e;}}
className={passwordBoxClass}
/>
<p>
<label for="mx_DeactivateAccountDialog_erase_account_input">{ _t(
"Please erase all messages I have sent when my account is deactivated. " +
"(Warning: this will cause future users to see an incomplete view of conversations, " +
"which is a bad experience).",
) }
<input
id="mx_DeactivateAccountDialog_erase_account_input"
type="checkbox"
checked={this.state.shouldErase}
onChange={this._onEraseFieldChange}
/>
</label>
</p>
{ error }
</div>
<div className="mx_Dialog_buttons">