Sprinkle forms and new-password designators to make autofill and password completion less wild

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2020-01-29 13:38:50 +00:00
parent cb0392b78d
commit fe71fe6033
5 changed files with 43 additions and 49 deletions

View file

@ -192,12 +192,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
}); });
} }
_onPassPhraseNextClick = () => { _onPassPhraseNextClick = async () => {
this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
}
_onPassPhraseKeyPress = async (e) => {
if (e.key === 'Enter') {
// If we're waiting for the timeout before updating the result at this point, // 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 // skip ahead and do it now, otherwise we'll deny the attempt to proceed
// even if the user entered a valid passphrase // even if the user entered a valid passphrase
@ -211,12 +206,13 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
}); });
} }
if (this._passPhraseIsValid()) { if (this._passPhraseIsValid()) {
this._onPassPhraseNextClick(); this.setState({phase: PHASE_PASSPHRASE_CONFIRM});
}
}
} }
};
_onPassPhraseConfirmNextClick = async () => { _onPassPhraseConfirmNextClick = async () => {
if (this.state.passPhrase !== this.state.passPhraseConfirm) return;
this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase); this._keyBackupInfo = await MatrixClientPeg.get().prepareKeyBackupVersion(this.state.passPhrase);
this.setState({ this.setState({
setPassPhrase: true, setPassPhrase: true,
@ -224,13 +220,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
downloaded: false, downloaded: false,
phase: PHASE_SHOWKEY, phase: PHASE_SHOWKEY,
}); });
} };
_onPassPhraseConfirmKeyPress = (e) => {
if (e.key === 'Enter' && this.state.passPhrase === this.state.passPhraseConfirm) {
this._onPassPhraseConfirmNextClick();
}
}
_onSetAgainClick = () => { _onSetAgainClick = () => {
this.setState({ this.setState({
@ -301,7 +291,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
</div>; </div>;
} }
return <div> return <form>
<p>{_t( <p>{_t(
"<b>Warning</b>: You should only set up key backup from a trusted computer.", {}, "<b>Warning</b>: You should only set up key backup from a trusted computer.", {},
{ b: sub => <b>{sub}</b> }, { b: sub => <b>{sub}</b> },
@ -316,7 +306,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
<div className="mx_CreateKeyBackupDialog_passPhraseContainer"> <div className="mx_CreateKeyBackupDialog_passPhraseContainer">
<input type="password" <input type="password"
onChange={this._onPassPhraseChange} onChange={this._onPassPhraseChange}
onKeyPress={this._onPassPhraseKeyPress}
value={this.state.passPhrase} value={this.state.passPhrase}
className="mx_CreateKeyBackupDialog_passPhraseInput" className="mx_CreateKeyBackupDialog_passPhraseInput"
placeholder={_t("Enter a passphrase...")} placeholder={_t("Enter a passphrase...")}
@ -329,9 +318,11 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
</div> </div>
</div> </div>
<DialogButtons primaryButton={_t('Next')} <DialogButtons
primaryButton={_t('Next')}
onPrimaryButtonClick={this._onPassPhraseNextClick} onPrimaryButtonClick={this._onPassPhraseNextClick}
hasCancel={false} hasCancel={false}
primaryIsSubmit={true}
disabled={!this._passPhraseIsValid()} disabled={!this._passPhraseIsValid()}
/> />
@ -341,7 +332,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
{_t("Set up with a Recovery Key")} {_t("Set up with a Recovery Key")}
</button></p> </button></p>
</details> </details>
</div>; </form>;
} }
_renderPhasePassPhraseConfirm() { _renderPhasePassPhraseConfirm() {
@ -373,7 +364,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
</div>; </div>;
} }
const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return <div> return <form>
<p>{_t( <p>{_t(
"Please enter your passphrase a second time to confirm.", "Please enter your passphrase a second time to confirm.",
)}</p> )}</p>
@ -382,7 +373,6 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
<div> <div>
<input type="password" <input type="password"
onChange={this._onPassPhraseConfirmChange} onChange={this._onPassPhraseConfirmChange}
onKeyPress={this._onPassPhraseConfirmKeyPress}
value={this.state.passPhraseConfirm} value={this.state.passPhraseConfirm}
className="mx_CreateKeyBackupDialog_passPhraseInput" className="mx_CreateKeyBackupDialog_passPhraseInput"
placeholder={_t("Repeat your passphrase...")} placeholder={_t("Repeat your passphrase...")}
@ -392,12 +382,14 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
{passPhraseMatch} {passPhraseMatch}
</div> </div>
</div> </div>
<DialogButtons primaryButton={_t('Next')} <DialogButtons
primaryButton={_t('Next')}
onPrimaryButtonClick={this._onPassPhraseConfirmNextClick} onPrimaryButtonClick={this._onPassPhraseConfirmNextClick}
hasCancel={false} hasCancel={false}
primaryIsSubmit={true}
disabled={this.state.passPhrase !== this.state.passPhraseConfirm} disabled={this.state.passPhrase !== this.state.passPhraseConfirm}
/> />
</div>; </form>;
} }
_renderPhaseShowKey() { _renderPhaseShowKey() {

View file

@ -486,6 +486,7 @@ export default createReactClass({
id="mx_RegistrationForm_password" id="mx_RegistrationForm_password"
ref={field => this[FIELD_PASSWORD] = field} ref={field => this[FIELD_PASSWORD] = field}
type="password" type="password"
autoComplete="new-password"
label={_t("Password")} label={_t("Password")}
value={this.state.password} value={this.state.password}
onChange={this.onPasswordChange} onChange={this.onPasswordChange}
@ -499,6 +500,7 @@ export default createReactClass({
id="mx_RegistrationForm_passwordConfirm" id="mx_RegistrationForm_passwordConfirm"
ref={field => this[FIELD_PASSWORD_CONFIRM] = field} ref={field => this[FIELD_PASSWORD_CONFIRM] = field}
type="password" type="password"
autoComplete="new-password"
label={_t("Confirm")} label={_t("Confirm")}
value={this.state.passwordConfirm} value={this.state.passwordConfirm}
onChange={this.onPasswordConfirmChange} onChange={this.onPasswordConfirmChange}

View file

@ -118,6 +118,7 @@ export default class DeactivateAccountDialog extends React.Component {
const Field = sdk.getComponent('elements.Field'); const Field = sdk.getComponent('elements.Field');
// this is on purpose not a <form /> to prevent Enter triggering submission, to further prevent accidents
return ( return (
<BaseDialog className="mx_DeactivateAccountDialog" <BaseDialog className="mx_DeactivateAccountDialog"
onFinished={this.props.onFinished} onFinished={this.props.onFinished}

View file

@ -157,12 +157,6 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
}); });
} }
_onPassPhraseKeyPress = (e) => {
if (e.key === Key.ENTER) {
this._onPassPhraseNext();
}
}
_onRecoveryKeyKeyPress = (e) => { _onRecoveryKeyKeyPress = (e) => {
if (e.key === Key.ENTER && this.state.recoveryKeyValid) { if (e.key === Key.ENTER && this.state.recoveryKeyValid) {
this._onRecoveryKeyNext(); this._onRecoveryKeyNext();
@ -305,21 +299,22 @@ export default class RestoreKeyBackupDialog extends React.PureComponent {
"messaging by entering your recovery passphrase.", "messaging by entering your recovery passphrase.",
)}</p> )}</p>
<div className="mx_RestoreKeyBackupDialog_primaryContainer"> <form className="mx_RestoreKeyBackupDialog_primaryContainer">
<input type="password" <input type="password"
className="mx_RestoreKeyBackupDialog_passPhraseInput" className="mx_RestoreKeyBackupDialog_passPhraseInput"
onChange={this._onPassPhraseChange} onChange={this._onPassPhraseChange}
onKeyPress={this._onPassPhraseKeyPress}
value={this.state.passPhrase} value={this.state.passPhrase}
autoFocus={true} autoFocus={true}
/> />
<DialogButtons primaryButton={_t('Next')} <DialogButtons
primaryButton={_t('Next')}
onPrimaryButtonClick={this._onPassPhraseNext} onPrimaryButtonClick={this._onPassPhraseNext}
primaryIsSubmit={true}
hasCancel={true} hasCancel={true}
onCancel={this._onCancel} onCancel={this._onCancel}
focus={false} focus={false}
/> />
</div> </form>
{_t( {_t(
"If you've forgotten your recovery passphrase you can "+ "If you've forgotten your recovery passphrase you can "+
"<button1>use your recovery key</button1> or " + "<button1>use your recovery key</button1> or " +

View file

@ -253,20 +253,24 @@ export default createReactClass({
<form className={this.props.className} onSubmit={this.onClickChange}> <form className={this.props.className} onSubmit={this.onClickChange}>
{ currentPassword } { currentPassword }
<div className={rowClassName}> <div className={rowClassName}>
<Field id="mx_ChangePassword_newPassword" <Field
id="mx_ChangePassword_newPassword"
type="password" type="password"
label={passwordLabel} label={passwordLabel}
value={this.state.newPassword} value={this.state.newPassword}
autoFocus={this.props.autoFocusNewPasswordInput} autoFocus={this.props.autoFocusNewPasswordInput}
onChange={this.onChangeNewPassword} onChange={this.onChangeNewPassword}
autoComplete="new-password"
/> />
</div> </div>
<div className={rowClassName}> <div className={rowClassName}>
<Field id="mx_ChangePassword_newPasswordConfirm" <Field
id="mx_ChangePassword_newPasswordConfirm"
type="password" type="password"
label={_t("Confirm password")} label={_t("Confirm password")}
value={this.state.newPasswordConfirm} value={this.state.newPasswordConfirm}
onChange={this.onChangeNewPasswordConfirm} onChange={this.onChangeNewPasswordConfirm}
autoComplete="new-password"
/> />
</div> </div>
<AccessibleButton className={buttonClassName} kind={this.props.buttonKind} onClick={this.onClickChange}> <AccessibleButton className={buttonClassName} kind={this.props.buttonKind} onClick={this.onClickChange}>