mirror of https://github.com/vector-im/riot-web
Merge pull request #3974 from matrix-org/t3chguy/password_completion
Use forms to wrap password fields so Chrome doesn't go wildpull/21833/head
commit
ffb40d90da
|
@ -85,3 +85,9 @@ limitations under the License.
|
|||
flex: 1;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.mx_CreateKeyBackupDialog {
|
||||
details .mx_AccessibleButton {
|
||||
margin: 1em 0; // emulate paragraph spacing because we can't put this button in a paragraph due to HTML rules
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { scorePassword } from '../../../../utils/PasswordScorer';
|
|||
import { _t } from '../../../../languageHandler';
|
||||
import { accessSecretStorage } from '../../../../CrossSigningManager';
|
||||
import SettingsStore from '../../../../settings/SettingsStore';
|
||||
import AccessibleButton from "../../../../components/views/elements/AccessibleButton";
|
||||
|
||||
const PHASE_PASSPHRASE = 0;
|
||||
const PHASE_PASSPHRASE_CONFIRM = 1;
|
||||
|
@ -191,44 +192,38 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseNextClick = () => {
|
||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||
}
|
||||
_onPassPhraseNextClick = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
_onPassPhraseKeyPress = async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
// If we're waiting for the timeout before updating the result at this point,
|
||||
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
||||
// even if the user entered a valid passphrase
|
||||
if (this._setZxcvbnResultTimeout !== null) {
|
||||
clearTimeout(this._setZxcvbnResultTimeout);
|
||||
this._setZxcvbnResultTimeout = null;
|
||||
await new Promise((resolve) => {
|
||||
this.setState({
|
||||
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||
}, resolve);
|
||||
});
|
||||
}
|
||||
if (this._passPhraseIsValid()) {
|
||||
this._onPassPhraseNextClick();
|
||||
}
|
||||
// If we're waiting for the timeout before updating the result at this point,
|
||||
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
||||
// even if the user entered a valid passphrase
|
||||
if (this._setZxcvbnResultTimeout !== null) {
|
||||
clearTimeout(this._setZxcvbnResultTimeout);
|
||||
this._setZxcvbnResultTimeout = null;
|
||||
await new Promise((resolve) => {
|
||||
this.setState({
|
||||
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||
}, resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this._passPhraseIsValid()) {
|
||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||
}
|
||||
};
|
||||
|
||||
_onPassPhraseConfirmNextClick = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.passPhrase !== this.state.passPhraseConfirm) return;
|
||||
|
||||
_onPassPhraseConfirmNextClick = async () => {
|
||||
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
|
||||
this.setState({
|
||||
copied: false,
|
||||
downloaded: false,
|
||||
phase: PHASE_SHOWKEY,
|
||||
});
|
||||
}
|
||||
|
||||
_onPassPhraseConfirmKeyPress = (e) => {
|
||||
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
|
||||
this._onPassPhraseConfirmNextClick();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_onSetAgainClick = () => {
|
||||
this.setState({
|
||||
|
@ -299,7 +294,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
</div>;
|
||||
}
|
||||
|
||||
return <div>
|
||||
return <form onSubmit={this._onPassPhraseNextClick}>
|
||||
<p>{_t(
|
||||
"<b>Warning</b>: You should only set up key backup from a trusted computer.", {},
|
||||
{ b: sub => <b>{sub}</b> },
|
||||
|
@ -314,7 +309,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
<div className="mx_CreateKeyBackupDialog_passPhraseContainer">
|
||||
<input type="password"
|
||||
onChange={this._onPassPhraseChange}
|
||||
onKeyPress={this._onPassPhraseKeyPress}
|
||||
value={this.state.passPhrase}
|
||||
className="mx_CreateKeyBackupDialog_passPhraseInput"
|
||||
placeholder={_t("Enter a passphrase...")}
|
||||
|
@ -327,7 +321,8 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onPassPhraseNextClick}
|
||||
hasCancel={false}
|
||||
disabled={!this._passPhraseIsValid()}
|
||||
|
@ -335,11 +330,11 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
|
||||
<details>
|
||||
<summary>{_t("Advanced")}</summary>
|
||||
<p><button onClick={this._onSkipPassPhraseClick} >
|
||||
<AccessibleButton kind='primary' onClick={this._onSkipPassPhraseClick} >
|
||||
{_t("Set up with a recovery key")}
|
||||
</button></p>
|
||||
</AccessibleButton>
|
||||
</details>
|
||||
</div>;
|
||||
</form>;
|
||||
}
|
||||
|
||||
_renderPhasePassPhraseConfirm() {
|
||||
|
@ -371,7 +366,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
</div>;
|
||||
}
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
return <div>
|
||||
return <form onSubmit={this._onPassPhraseConfirmNextClick}>
|
||||
<p>{_t(
|
||||
"Please enter your passphrase a second time to confirm.",
|
||||
)}</p>
|
||||
|
@ -380,7 +375,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
<div>
|
||||
<input type="password"
|
||||
onChange={this._onPassPhraseConfirmChange}
|
||||
onKeyPress={this._onPassPhraseConfirmKeyPress}
|
||||
value={this.state.passPhraseConfirm}
|
||||
className="mx_CreateKeyBackupDialog_passPhraseInput"
|
||||
placeholder={_t("Repeat your passphrase...")}
|
||||
|
@ -390,12 +384,13 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
|
|||
{passPhraseMatch}
|
||||
</div>
|
||||
</div>
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onPassPhraseConfirmNextClick}
|
||||
hasCancel={false}
|
||||
disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
|
||||
/>
|
||||
</div>;
|
||||
</form>;
|
||||
}
|
||||
|
||||
_renderPhaseShowKey() {
|
||||
|
|
|
@ -289,31 +289,31 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseNextClick = () => {
|
||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||
}
|
||||
_onPassPhraseNextClick = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
_onPassPhraseKeyPress = async (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
// If we're waiting for the timeout before updating the result at this point,
|
||||
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
||||
// even if the user entered a valid passphrase
|
||||
if (this._setZxcvbnResultTimeout !== null) {
|
||||
clearTimeout(this._setZxcvbnResultTimeout);
|
||||
this._setZxcvbnResultTimeout = null;
|
||||
await new Promise((resolve) => {
|
||||
this.setState({
|
||||
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||
}, resolve);
|
||||
});
|
||||
}
|
||||
if (this._passPhraseIsValid()) {
|
||||
this._onPassPhraseNextClick();
|
||||
}
|
||||
// If we're waiting for the timeout before updating the result at this point,
|
||||
// skip ahead and do it now, otherwise we'll deny the attempt to proceed
|
||||
// even if the user entered a valid passphrase
|
||||
if (this._setZxcvbnResultTimeout !== null) {
|
||||
clearTimeout(this._setZxcvbnResultTimeout);
|
||||
this._setZxcvbnResultTimeout = null;
|
||||
await new Promise((resolve) => {
|
||||
this.setState({
|
||||
zxcvbnResult: scorePassword(this.state.passPhrase),
|
||||
}, resolve);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this._passPhraseIsValid()) {
|
||||
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
|
||||
}
|
||||
};
|
||||
|
||||
_onPassPhraseConfirmNextClick = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.passPhrase !== this.state.passPhraseConfirm) return;
|
||||
|
||||
_onPassPhraseConfirmNextClick = async () => {
|
||||
const [keyInfo, encodedRecoveryKey] =
|
||||
await MatrixClientPeg.get().createRecoveryKeyFromPassphrase(this.state.passPhrase);
|
||||
this._keyInfo = keyInfo;
|
||||
|
@ -325,12 +325,6 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseConfirmKeyPress = (e) => {
|
||||
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
|
||||
this._onPassPhraseConfirmNextClick();
|
||||
}
|
||||
}
|
||||
|
||||
_onSetAgainClick = () => {
|
||||
this.setState({
|
||||
passPhrase: '',
|
||||
|
@ -400,7 +394,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
} else if (this.state.canUploadKeysWithPasswordOnly) {
|
||||
authPrompt = <div>
|
||||
<div>{_t("Enter your account password to confirm the upgrade:")}</div>
|
||||
<div><Field type="password"
|
||||
<div><Field
|
||||
type="password"
|
||||
id="mx_CreateSecretStorage_accountPassword"
|
||||
label={_t("Password")}
|
||||
value={this.state.accountPassword}
|
||||
|
@ -422,8 +417,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
"as trusted for other users.",
|
||||
)}</p>
|
||||
<div>{authPrompt}</div>
|
||||
<DialogButtons primaryButton={nextCaption}
|
||||
primaryIsSubmit={true}
|
||||
<DialogButtons
|
||||
primaryButton={nextCaption}
|
||||
hasCancel={false}
|
||||
primaryDisabled={this.state.canUploadKeysWithPasswordOnly && !this.state.accountPassword}
|
||||
>
|
||||
|
@ -467,7 +462,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>;
|
||||
}
|
||||
|
||||
return <div>
|
||||
return <form onSubmit={this._onPassPhraseNextClick}>
|
||||
<p>{_t(
|
||||
"Set up encryption on this session to allow it to verify other sessions, " +
|
||||
"granting them access to encrypted messages and marking them as trusted for other users.",
|
||||
|
@ -483,10 +478,10 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
id="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
className="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
onChange={this._onPassPhraseChange}
|
||||
onKeyPress={this._onPassPhraseKeyPress}
|
||||
value={this.state.passPhrase}
|
||||
label={_t("Enter a passphrase")}
|
||||
autoFocus={true}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
<div className="mx_CreateSecretStorageDialog_passPhraseHelp">
|
||||
{strengthMeter}
|
||||
|
@ -499,7 +494,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
onChange={this._onUseKeyBackupChange} value={this.state.useKeyBackup}
|
||||
/>
|
||||
|
||||
<DialogButtons primaryButton={_t('Continue')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Continue')}
|
||||
onPrimaryButtonClick={this._onPassPhraseNextClick}
|
||||
hasCancel={false}
|
||||
disabled={!this._passPhraseIsValid()}
|
||||
|
@ -516,7 +512,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
{_t("Set up with a recovery key")}
|
||||
</AccessibleButton>
|
||||
</details>
|
||||
</div>;
|
||||
</form>;
|
||||
}
|
||||
|
||||
_renderPhasePassPhraseConfirm() {
|
||||
|
@ -549,25 +545,27 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
</div>;
|
||||
}
|
||||
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
|
||||
return <div>
|
||||
return <form onSubmit={this._onPassPhraseConfirmNextClick}>
|
||||
<p>{_t(
|
||||
"Enter your passphrase a second time to confirm it.",
|
||||
)}</p>
|
||||
<div className="mx_CreateSecretStorageDialog_passPhraseContainer">
|
||||
<Field type="password"
|
||||
<Field
|
||||
type="password"
|
||||
id="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
onChange={this._onPassPhraseConfirmChange}
|
||||
onKeyPress={this._onPassPhraseConfirmKeyPress}
|
||||
value={this.state.passPhraseConfirm}
|
||||
className="mx_CreateSecretStorageDialog_passPhraseField"
|
||||
label={_t("Confirm your passphrase")}
|
||||
autoFocus={true}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
<div className="mx_CreateSecretStorageDialog_passPhraseMatch">
|
||||
{passPhraseMatch}
|
||||
</div>
|
||||
</div>
|
||||
<DialogButtons primaryButton={_t('Continue')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Continue')}
|
||||
onPrimaryButtonClick={this._onPassPhraseConfirmNextClick}
|
||||
hasCancel={false}
|
||||
disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
|
||||
|
@ -577,7 +575,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
|||
className="danger"
|
||||
>{_t("Skip")}</button>
|
||||
</DialogButtons>
|
||||
</div>;
|
||||
</form>;
|
||||
}
|
||||
|
||||
_renderPhaseShowKey() {
|
||||
|
|
|
@ -160,6 +160,7 @@ export default createReactClass({
|
|||
onKeyDown={ this._onKeyDown }
|
||||
onBlur={this._onBlur}
|
||||
placeholder={ placeholder }
|
||||
autoComplete="off"
|
||||
/>
|
||||
{ clearButton }
|
||||
</div>
|
||||
|
|
|
@ -486,6 +486,7 @@ export default createReactClass({
|
|||
id="mx_RegistrationForm_password"
|
||||
ref={field => this[FIELD_PASSWORD] = field}
|
||||
type="password"
|
||||
autoComplete="new-password"
|
||||
label={_t("Password")}
|
||||
value={this.state.password}
|
||||
onChange={this.onPasswordChange}
|
||||
|
@ -499,6 +500,7 @@ export default createReactClass({
|
|||
id="mx_RegistrationForm_passwordConfirm"
|
||||
ref={field => this[FIELD_PASSWORD_CONFIRM] = field}
|
||||
type="password"
|
||||
autoComplete="new-password"
|
||||
label={_t("Confirm")}
|
||||
value={this.state.passwordConfirm}
|
||||
onChange={this.onPasswordConfirmChange}
|
||||
|
|
|
@ -118,6 +118,7 @@ export default class DeactivateAccountDialog extends React.Component {
|
|||
|
||||
const Field = sdk.getComponent('elements.Field');
|
||||
|
||||
// this is on purpose not a <form /> to prevent Enter triggering submission, to further prevent accidents
|
||||
return (
|
||||
<BaseDialog className="mx_DeactivateAccountDialog"
|
||||
onFinished={this.props.onFinished}
|
||||
|
|
|
@ -22,7 +22,6 @@ import {MatrixClientPeg} from '../../../../MatrixClientPeg';
|
|||
import { MatrixClient } from 'matrix-js-sdk';
|
||||
import Modal from '../../../../Modal';
|
||||
import { _t } from '../../../../languageHandler';
|
||||
import {Key} from "../../../../Keyboard";
|
||||
import { accessSecretStorage } from '../../../../CrossSigningManager';
|
||||
|
||||
const RESTORE_TYPE_PASSPHRASE = 0;
|
||||
|
@ -125,6 +124,8 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
}
|
||||
|
||||
_onRecoveryKeyNext = async () => {
|
||||
if (!this.state.recoveryKeyValid) return;
|
||||
|
||||
this.setState({
|
||||
loading: true,
|
||||
restoreError: null,
|
||||
|
@ -157,18 +158,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseKeyPress = (e) => {
|
||||
if (e.key === Key.ENTER) {
|
||||
this._onPassPhraseNext();
|
||||
}
|
||||
}
|
||||
|
||||
_onRecoveryKeyKeyPress = (e) => {
|
||||
if (e.key === Key.ENTER && this.state.recoveryKeyValid) {
|
||||
this._onRecoveryKeyNext();
|
||||
}
|
||||
}
|
||||
|
||||
async _restoreWithSecretStorage() {
|
||||
this.setState({
|
||||
loading: true,
|
||||
|
@ -305,21 +294,22 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
"messaging by entering your recovery passphrase.",
|
||||
)}</p>
|
||||
|
||||
<div className="mx_RestoreKeyBackupDialog_primaryContainer">
|
||||
<form className="mx_RestoreKeyBackupDialog_primaryContainer">
|
||||
<input type="password"
|
||||
className="mx_RestoreKeyBackupDialog_passPhraseInput"
|
||||
onChange={this._onPassPhraseChange}
|
||||
onKeyPress={this._onPassPhraseKeyPress}
|
||||
value={this.state.passPhrase}
|
||||
autoFocus={true}
|
||||
/>
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onPassPhraseNext}
|
||||
primaryIsSubmit={true}
|
||||
hasCancel={true}
|
||||
onCancel={this._onCancel}
|
||||
focus={false}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{_t(
|
||||
"If you've forgotten your recovery passphrase you can "+
|
||||
"<button1>use your recovery key</button1> or " +
|
||||
|
@ -371,7 +361,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
|
|||
<div className="mx_RestoreKeyBackupDialog_primaryContainer">
|
||||
<input className="mx_RestoreKeyBackupDialog_recoveryKeyInput"
|
||||
onChange={this._onRecoveryKeyChange}
|
||||
onKeyPress={this._onRecoveryKeyKeyPress}
|
||||
value={this.state.recoveryKey}
|
||||
autoFocus={true}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -21,7 +21,6 @@ import * as sdk from '../../../../index';
|
|||
import {MatrixClientPeg} from '../../../../MatrixClientPeg';
|
||||
|
||||
import { _t } from '../../../../languageHandler';
|
||||
import { Key } from "../../../../Keyboard";
|
||||
|
||||
/*
|
||||
* Access Secure Secret Storage by requesting the user's passphrase.
|
||||
|
@ -68,7 +67,11 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseNext = async () => {
|
||||
_onPassPhraseNext = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (this.state.passPhrase.length <= 0) return;
|
||||
|
||||
this.setState({ keyMatches: null });
|
||||
const input = { passphrase: this.state.passPhrase };
|
||||
const keyMatches = await this.props.checkPrivateKey(input);
|
||||
|
@ -79,7 +82,11 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
_onRecoveryKeyNext = async () => {
|
||||
_onRecoveryKeyNext = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!this.state.recoveryKeyValid) return;
|
||||
|
||||
this.setState({ keyMatches: null });
|
||||
const input = { recoveryKey: this.state.recoveryKey };
|
||||
const keyMatches = await this.props.checkPrivateKey(input);
|
||||
|
@ -97,18 +104,6 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
});
|
||||
}
|
||||
|
||||
_onPassPhraseKeyPress = (e) => {
|
||||
if (e.key === Key.ENTER && this.state.passPhrase.length > 0) {
|
||||
this._onPassPhraseNext();
|
||||
}
|
||||
}
|
||||
|
||||
_onRecoveryKeyKeyPress = (e) => {
|
||||
if (e.key === Key.ENTER && this.state.recoveryKeyValid) {
|
||||
this._onRecoveryKeyNext();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
|
||||
|
||||
|
@ -135,7 +130,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
)}
|
||||
</div>;
|
||||
} else {
|
||||
keyStatus = <div className="mx_AccessSecretStorageDialog_keyStatus"></div>;
|
||||
keyStatus = <div className="mx_AccessSecretStorageDialog_keyStatus" />;
|
||||
}
|
||||
|
||||
content = <div>
|
||||
|
@ -149,23 +144,25 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
"identity for verifying other sessions by entering your passphrase.",
|
||||
)}</p>
|
||||
|
||||
<div className="mx_AccessSecretStorageDialog_primaryContainer">
|
||||
<input type="password"
|
||||
<form className="mx_AccessSecretStorageDialog_primaryContainer" onSubmit={this._onPassPhraseNext}>
|
||||
<input
|
||||
type="password"
|
||||
className="mx_AccessSecretStorageDialog_passPhraseInput"
|
||||
onChange={this._onPassPhraseChange}
|
||||
onKeyPress={this._onPassPhraseKeyPress}
|
||||
value={this.state.passPhrase}
|
||||
autoFocus={true}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
{keyStatus}
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onPassPhraseNext}
|
||||
hasCancel={true}
|
||||
onCancel={this._onCancel}
|
||||
focus={false}
|
||||
primaryDisabled={this.state.passPhrase.length === 0}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{_t(
|
||||
"If you've forgotten your passphrase you can "+
|
||||
"<button1>use your recovery key</button1> or " +
|
||||
|
@ -192,7 +189,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
|
||||
let keyStatus;
|
||||
if (this.state.recoveryKey.length === 0) {
|
||||
keyStatus = <div className="mx_AccessSecretStorageDialog_keyStatus"></div>;
|
||||
keyStatus = <div className="mx_AccessSecretStorageDialog_keyStatus" />;
|
||||
} else if (this.state.recoveryKeyValid) {
|
||||
keyStatus = <div className="mx_AccessSecretStorageDialog_keyStatus">
|
||||
{"\uD83D\uDC4D "}{_t("This looks like a valid recovery key!")}
|
||||
|
@ -221,22 +218,22 @@ export default class AccessSecretStorageDialog extends React.PureComponent {
|
|||
"identity for verifying other sessions by entering your recovery key.",
|
||||
)}</p>
|
||||
|
||||
<div className="mx_AccessSecretStorageDialog_primaryContainer">
|
||||
<form className="mx_AccessSecretStorageDialog_primaryContainer" onSubmit={this._onRecoveryKeyNext}>
|
||||
<input className="mx_AccessSecretStorageDialog_recoveryKeyInput"
|
||||
onChange={this._onRecoveryKeyChange}
|
||||
onKeyPress={this._onRecoveryKeyKeyPress}
|
||||
value={this.state.recoveryKey}
|
||||
autoFocus={true}
|
||||
/>
|
||||
{keyStatus}
|
||||
<DialogButtons primaryButton={_t('Next')}
|
||||
<DialogButtons
|
||||
primaryButton={_t('Next')}
|
||||
onPrimaryButtonClick={this._onRecoveryKeyNext}
|
||||
hasCancel={true}
|
||||
onCancel={this._onCancel}
|
||||
focus={false}
|
||||
primaryDisabled={!this.state.recoveryKeyValid}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
{_t(
|
||||
"If you've forgotten your recovery key you can "+
|
||||
"<button>set up new recovery options</button>."
|
||||
|
|
|
@ -253,20 +253,24 @@ export default createReactClass({
|
|||
<form className={this.props.className} onSubmit={this.onClickChange}>
|
||||
{ currentPassword }
|
||||
<div className={rowClassName}>
|
||||
<Field id="mx_ChangePassword_newPassword"
|
||||
<Field
|
||||
id="mx_ChangePassword_newPassword"
|
||||
type="password"
|
||||
label={passwordLabel}
|
||||
value={this.state.newPassword}
|
||||
autoFocus={this.props.autoFocusNewPasswordInput}
|
||||
onChange={this.onChangeNewPassword}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
<div className={rowClassName}>
|
||||
<Field id="mx_ChangePassword_newPasswordConfirm"
|
||||
<Field
|
||||
id="mx_ChangePassword_newPasswordConfirm"
|
||||
type="password"
|
||||
label={_t("Confirm password")}
|
||||
value={this.state.newPasswordConfirm}
|
||||
onChange={this.onChangeNewPasswordConfirm}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
<AccessibleButton className={buttonClassName} kind={this.props.buttonKind} onClick={this.onClickChange}>
|
||||
|
|
Loading…
Reference in New Issue