From b8fcb855104ead9b4fb56e01a5d8004bc24bbb78 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 26 Oct 2021 15:35:47 +0100 Subject: [PATCH 1/5] Create PassphraseConfirmField Signed-off-by: Paulo Pinto --- .../views/auth/PassphraseConfirmField.tsx | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/components/views/auth/PassphraseConfirmField.tsx diff --git a/src/components/views/auth/PassphraseConfirmField.tsx b/src/components/views/auth/PassphraseConfirmField.tsx new file mode 100644 index 00000000000..dedda889ea2 --- /dev/null +++ b/src/components/views/auth/PassphraseConfirmField.tsx @@ -0,0 +1,29 @@ +/* +Copyright 2021 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. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { PureComponent } from "react"; +import { replaceableComponent } from "../../../utils/replaceableComponent"; +import { IInputProps } from "../elements/Field"; + +interface IProps extends Omit { +} + +@replaceableComponent("views.auth.EmailField") +class PassphraseConfirmField extends PureComponent { + +} + +export default PassphraseConfirmField; From bdcb0230e3be263d1a5e50f1002cbb673aabd41c Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 26 Oct 2021 15:43:01 +0100 Subject: [PATCH 2/5] Implement PassphraseConfirmField Signed-off-by: Paulo Pinto --- .../views/auth/PassphraseConfirmField.tsx | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/components/views/auth/PassphraseConfirmField.tsx b/src/components/views/auth/PassphraseConfirmField.tsx index dedda889ea2..1ddeb0cd92f 100644 --- a/src/components/views/auth/PassphraseConfirmField.tsx +++ b/src/components/views/auth/PassphraseConfirmField.tsx @@ -14,16 +14,38 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { PureComponent } from "react"; +import React, { PureComponent, RefCallback, RefObject } from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; -import { IInputProps } from "../elements/Field"; +import Field, { IInputProps } from "../elements/Field"; +import { _t, _td } from "../../../languageHandler"; interface IProps extends Omit { + id?: string; + fieldRef?: RefCallback | RefObject; + autoComplete?: string; + value: string; + password: string; // The password we're confirming + + onChange(ev: React.FormEvent); } @replaceableComponent("views.auth.EmailField") class PassphraseConfirmField extends PureComponent { - + static defaultProps = { + label: _td("Confirm password"), + }; + + render() { + return ; + } } export default PassphraseConfirmField; From e1cd462027c4cbd5ae5ecf29b204f793c5c95336 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 26 Oct 2021 16:12:45 +0100 Subject: [PATCH 3/5] Validate PassphraseConfirmField Signed-off-by: Paulo Pinto --- .../views/auth/PassphraseConfirmField.tsx | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/components/views/auth/PassphraseConfirmField.tsx b/src/components/views/auth/PassphraseConfirmField.tsx index 1ddeb0cd92f..b1a65a2cb14 100644 --- a/src/components/views/auth/PassphraseConfirmField.tsx +++ b/src/components/views/auth/PassphraseConfirmField.tsx @@ -17,6 +17,7 @@ limitations under the License. import React, { PureComponent, RefCallback, RefObject } from "react"; import { replaceableComponent } from "../../../utils/replaceableComponent"; import Field, { IInputProps } from "../elements/Field"; +import withValidation, { IFieldState, IValidationResult } from "../elements/Validation"; import { _t, _td } from "../../../languageHandler"; interface IProps extends Omit { @@ -26,13 +27,43 @@ interface IProps extends Omit { value: string; password: string; // The password we're confirming + labelRequired?: string; + labelInvalid?: string; + onChange(ev: React.FormEvent); + onValidate?(result: IValidationResult); } @replaceableComponent("views.auth.EmailField") class PassphraseConfirmField extends PureComponent { static defaultProps = { label: _td("Confirm password"), + labelRequired: _td("Confirm password"), + labelInvalid: _td("Passwords don't match"), + }; + + private validate = withValidation({ + rules: [ + { + key: "required", + test: ({ value, allowEmpty }) => allowEmpty || !!value, + invalid: () => _t(this.props.labelRequired), + }, + { + key: "match", + test: ({ value }) => !value || value === this.props.password, + invalid: () => _t(this.props.labelInvalid), + }, + ], + }); + + onValidate = async (fieldState: IFieldState) => { + const result = await this.validate(fieldState); + if (this.props.onValidate) { + this.props.onValidate(result); + } + + return result; }; render() { @@ -44,6 +75,7 @@ class PassphraseConfirmField extends PureComponent { autoComplete={this.props.autoComplete} value={this.props.value} onChange={this.props.onChange} + onValidate={this.onValidate} />; } } From ed693d320151573abc24d687cff40469c63bf727 Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Tue, 26 Oct 2021 16:14:04 +0100 Subject: [PATCH 4/5] Use PassphraseConfirmField in RegistrationForm Signed-off-by: Paulo Pinto --- .../views/auth/RegistrationForm.tsx | 29 ++++--------------- 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.tsx b/src/components/views/auth/RegistrationForm.tsx index 24e73f29926..11b55a9d11a 100644 --- a/src/components/views/auth/RegistrationForm.tsx +++ b/src/components/views/auth/RegistrationForm.tsx @@ -34,6 +34,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent"; import CountryDropdown from "./CountryDropdown"; import { logger } from "matrix-js-sdk/src/logger"; +import PassphraseConfirmField from "./PassphraseConfirmField"; enum RegistrationField { Email = "field_email", @@ -293,29 +294,10 @@ export default class RegistrationForm extends React.PureComponent { - const result = await this.validatePasswordConfirmRules(fieldState); + private onPasswordConfirmValidate = (result: IValidationResult) => { this.markFieldValid(RegistrationField.PasswordConfirm, result.valid); - return result; }; - private validatePasswordConfirmRules = withValidation({ - rules: [ - { - key: "required", - test: ({ value, allowEmpty }) => allowEmpty || !!value, - invalid: () => _t("Confirm password"), - }, - { - key: "match", - test(this: RegistrationForm, { value }) { - return !value || value === this.state.password; - }, - invalid: () => _t("Passwords don't match"), - }, - ], - }); - private onPhoneCountryChange = newVal => { this.setState({ phoneCountry: newVal.iso2, @@ -454,13 +436,12 @@ export default class RegistrationForm extends React.PureComponent this[RegistrationField.PasswordConfirm] = field} - type="password" + fieldRef={field => this[RegistrationField.PasswordConfirm] = field} autoComplete="new-password" - label={_t("Confirm password")} value={this.state.passwordConfirm} + password={this.state.password} onChange={this.onPasswordConfirmChange} onValidate={this.onPasswordConfirmValidate} onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_passwordConfirm_focus")} From d118b41d5510e7bdfdb8e54c8bb4c8fb76959e2e Mon Sep 17 00:00:00 2001 From: Paulo Pinto Date: Wed, 10 Nov 2021 17:30:13 +0000 Subject: [PATCH 5/5] Make handler private Signed-off-by: Paulo Pinto --- src/components/views/auth/PassphraseConfirmField.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/auth/PassphraseConfirmField.tsx b/src/components/views/auth/PassphraseConfirmField.tsx index b1a65a2cb14..74ce711470c 100644 --- a/src/components/views/auth/PassphraseConfirmField.tsx +++ b/src/components/views/auth/PassphraseConfirmField.tsx @@ -57,7 +57,7 @@ class PassphraseConfirmField extends PureComponent { ], }); - onValidate = async (fieldState: IFieldState) => { + private onValidate = async (fieldState: IFieldState) => { const result = await this.validate(fieldState); if (this.props.onValidate) { this.props.onValidate(result);