Support accounts with cross signing but no SSSS

At least at the login stage.

Fixes https://github.com/vector-im/riot-web/issues/13894
This commit is contained in:
David Baker 2020-06-05 16:40:20 +01:00
parent b82a893a79
commit 68e555a0c6
4 changed files with 29 additions and 14 deletions

View file

@ -1900,10 +1900,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
return setLoggedInPromise; return setLoggedInPromise;
} }
// Test for the master cross-signing key in SSSS as a quick proxy for // wait for the client to finish downloading cross-signing keys for us so we
// whether cross-signing has been set up on the account. // know whether or not we have keys set up on this account
const masterKeyInStorage = !!cli.getAccountData("m.cross_signing.master"); await cli.downloadKeys([cli.getUserId()]);
if (masterKeyInStorage) {
const crossSigningIsSetUp = cli.getStoredCrossSigningForUser(cli.getUserId());
if (crossSigningIsSetUp) {
this.setStateForNewView({ view: Views.COMPLETE_SECURITY }); this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
} else if (await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) { } else if (await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) {
this.setStateForNewView({ view: Views.E2E_SETUP }); this.setStateForNewView({ view: Views.E2E_SETUP });

View file

@ -16,7 +16,7 @@ limitations under the License.
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { _t } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { MatrixClientPeg } from '../../../MatrixClientPeg';
import * as sdk from '../../../index'; import * as sdk from '../../../index';
import withValidation from '../../views/elements/Validation'; import withValidation from '../../views/elements/Validation';
@ -196,11 +196,27 @@ export default class SetupEncryptionBody extends React.Component {
} else if (phase === PHASE_INTRO) { } else if (phase === PHASE_INTRO) {
const store = SetupEncryptionStore.sharedInstance(); const store = SetupEncryptionStore.sharedInstance();
let recoveryKeyPrompt; let recoveryKeyPrompt;
if (keyHasPassphrase(store.keyInfo)) { if (store.keyInfo && keyHasPassphrase(store.keyInfo)) {
recoveryKeyPrompt = _t("Use Recovery Key or Passphrase"); recoveryKeyPrompt = _t("Use Recovery Key or Passphrase");
} else { } else if (store.keyInfo) {
recoveryKeyPrompt = _t("Use Recovery Key"); recoveryKeyPrompt = _t("Use Recovery Key");
} }
let useRecoveryKeyButton;
let resetKeysCaption;
if (recoveryKeyPrompt) {
useRecoveryKeyButton = <AccessibleButton kind="link" onClick={this._onUseRecoveryKeyClick}>
{recoveryKeyPrompt}
</AccessibleButton>;
resetKeysCaption = _td(
"If you've forgotten your recovery key you can <button>set up new recovery options</button>",
);
} else {
resetKeysCaption = _td(
"If you have no other devices you can <button>set up new recovery options</button>",
);
}
return ( return (
<div> <div>
<p>{_t( <p>{_t(
@ -224,16 +240,12 @@ export default class SetupEncryptionBody extends React.Component {
</div> </div>
<div className="mx_CompleteSecurity_actionRow"> <div className="mx_CompleteSecurity_actionRow">
<AccessibleButton kind="link" onClick={this._onUseRecoveryKeyClick}> {useRecoveryKeyButton}
{recoveryKeyPrompt}
</AccessibleButton>
<AccessibleButton kind="danger" onClick={this.onSkipClick}> <AccessibleButton kind="danger" onClick={this.onSkipClick}>
{_t("Skip")} {_t("Skip")}
</AccessibleButton> </AccessibleButton>
</div> </div>
<div className="mx_CompleteSecurity_resetText">{_t( <div className="mx_CompleteSecurity_resetText">{_t(resetKeysCaption, {}, {
"If you've forgotten your recovery key you can " +
"<button>set up new recovery options</button>", {}, {
button: sub => <AccessibleButton button: sub => <AccessibleButton
element="span" className="mx_linkButton" onClick={this._onResetClick} element="span" className="mx_linkButton" onClick={this._onResetClick}
> >

View file

@ -2101,6 +2101,7 @@
"Looks good!": "Looks good!", "Looks good!": "Looks good!",
"Use Recovery Key or Passphrase": "Use Recovery Key or Passphrase", "Use Recovery Key or Passphrase": "Use Recovery Key or Passphrase",
"Use Recovery Key": "Use Recovery Key", "Use Recovery Key": "Use Recovery Key",
"If you have no other devices you can <button>set up new recovery options</button>": "If you have no other devices you can <button>set up new recovery options</button>",
"Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.", "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.",
"This requires the latest Riot on your other devices:": "This requires the latest Riot on your other devices:", "This requires the latest Riot on your other devices:": "This requires the latest Riot on your other devices:",
"or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client", "or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client",

View file

@ -68,7 +68,7 @@ export class SetupEncryptionStore extends EventEmitter {
async fetchKeyInfo() { async fetchKeyInfo() {
const keys = await MatrixClientPeg.get().isSecretStored('m.cross_signing.master', false); const keys = await MatrixClientPeg.get().isSecretStored('m.cross_signing.master', false);
if (Object.keys(keys).length === 0) { if (!keys || Object.keys(keys).length === 0) {
this.keyId = null; this.keyId = null;
this.keyInfo = null; this.keyInfo = null;
} else { } else {