From 7ec90d55e972ff967826580ba70bbcaeaf0fa1ce Mon Sep 17 00:00:00 2001 From: Warrick Corfe-Tan Date: Mon, 3 May 2021 22:23:53 +1000 Subject: [PATCH] Password confirmation field appearing and preventing submission of mismatching passwords. --- .../session/SessionPasswordModal.tsx | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx index 64c4872eb..fc50b860e 100644 --- a/ts/components/session/SessionPasswordModal.tsx +++ b/ts/components/session/SessionPasswordModal.tsx @@ -24,6 +24,7 @@ interface State { error: string | null; currentPasswordEntered: string | null; currentPasswordConfirmEntered: string | null; + currentPasswordRetypeEntered: string | null; } class SessionPasswordModalInner extends React.Component { @@ -36,6 +37,7 @@ class SessionPasswordModalInner extends React.Component { error: null, currentPasswordEntered: null, currentPasswordConfirmEntered: null, + currentPasswordRetypeEntered: null }; this.showError = this.showError.bind(this); @@ -45,6 +47,7 @@ class SessionPasswordModalInner extends React.Component { this.onPasswordInput = this.onPasswordInput.bind(this); this.onPasswordConfirmInput = this.onPasswordConfirmInput.bind(this); + this.onPasswordRetypeInput = this.onPasswordRetypeInput.bind(this); } public componentDidMount() { @@ -58,7 +61,7 @@ class SessionPasswordModalInner extends React.Component { const { action, onOk } = this.props; const placeholders = action === PasswordAction.Change - ? [window.i18n('typeInOldPassword'), window.i18n('enterPassword')] + ? [window.i18n('typeInOldPassword'), window.i18n('enterPassword'), window.i18n('confirmPassword')] : [window.i18n('enterPassword'), window.i18n('confirmPassword')]; const confirmButtonColor = @@ -92,6 +95,14 @@ class SessionPasswordModalInner extends React.Component { onKeyUp={this.onPasswordConfirmInput} /> )} + {action === PasswordAction.Change && ( + + )}
@@ -185,12 +196,21 @@ class SessionPasswordModalInner extends React.Component { this.closeDialog(); } - private async handleActionChange(oldPassword: string, newPassword: string) { + private async handleActionChange(oldPassword: string, newPassword: string, newConfirmedPassword: string) { // We don't validate oldPassword on change: this is validate on the validatePasswordHash below // we only validate the newPassword here if (!this.validatePassword(newPassword)) { return; } + + // Check the retyped password matches the new password + if (newPassword !== newConfirmedPassword) { + this.setState({ + error: window.i18n('passwordsDoNotMatch') + }) + return + } + const isValidWithStoredInDB = Boolean( await this.validatePasswordHash(oldPassword) ); @@ -242,12 +262,14 @@ class SessionPasswordModalInner extends React.Component { const { currentPasswordEntered, currentPasswordConfirmEntered, + currentPasswordRetypeEntered } = this.state; const { Set, Remove, Change } = PasswordAction; // Trim leading / trailing whitespace for UX const firstPasswordEntered = (currentPasswordEntered || '').trim(); const secondPasswordEntered = (currentPasswordConfirmEntered || '').trim(); + const thirdPasswordEntered = (currentPasswordRetypeEntered || '').trim(); switch (action) { case Set: { @@ -257,7 +279,8 @@ class SessionPasswordModalInner extends React.Component { case Change: { await this.handleActionChange( firstPasswordEntered, - secondPasswordEntered + secondPasswordEntered, + thirdPasswordEntered ); return; } @@ -293,6 +316,15 @@ class SessionPasswordModalInner extends React.Component { this.setState({ currentPasswordConfirmEntered }); } + + private async onPasswordRetypeInput(event: any) { + if (event.key === 'Enter') { + return this.setPassword(); + } + const currentPasswordRetypeEntered = event.target.value; + + this.setState({ currentPasswordRetypeEntered }); + } } export const SessionPasswordModal = withTheme(SessionPasswordModalInner);