Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit b8edebe

Browse files
authored
Add PassphraseConfirmField component for registration and password recovery screens (#7044)
1 parent 5226edb commit b8edebe

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
Copyright 2021 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { PureComponent, RefCallback, RefObject } from "react";
18+
import { replaceableComponent } from "../../../utils/replaceableComponent";
19+
import Field, { IInputProps } from "../elements/Field";
20+
import withValidation, { IFieldState, IValidationResult } from "../elements/Validation";
21+
import { _t, _td } from "../../../languageHandler";
22+
23+
interface IProps extends Omit<IInputProps, "onValidate"> {
24+
id?: string;
25+
fieldRef?: RefCallback<Field> | RefObject<Field>;
26+
autoComplete?: string;
27+
value: string;
28+
password: string; // The password we're confirming
29+
30+
labelRequired?: string;
31+
labelInvalid?: string;
32+
33+
onChange(ev: React.FormEvent<HTMLElement>);
34+
onValidate?(result: IValidationResult);
35+
}
36+
37+
@replaceableComponent("views.auth.EmailField")
38+
class PassphraseConfirmField extends PureComponent<IProps> {
39+
static defaultProps = {
40+
label: _td("Confirm password"),
41+
labelRequired: _td("Confirm password"),
42+
labelInvalid: _td("Passwords don't match"),
43+
};
44+
45+
private validate = withValidation({
46+
rules: [
47+
{
48+
key: "required",
49+
test: ({ value, allowEmpty }) => allowEmpty || !!value,
50+
invalid: () => _t(this.props.labelRequired),
51+
},
52+
{
53+
key: "match",
54+
test: ({ value }) => !value || value === this.props.password,
55+
invalid: () => _t(this.props.labelInvalid),
56+
},
57+
],
58+
});
59+
60+
private onValidate = async (fieldState: IFieldState) => {
61+
const result = await this.validate(fieldState);
62+
if (this.props.onValidate) {
63+
this.props.onValidate(result);
64+
}
65+
66+
return result;
67+
};
68+
69+
render() {
70+
return <Field
71+
id={this.props.id}
72+
ref={this.props.fieldRef}
73+
type="password"
74+
label={_t(this.props.label)}
75+
autoComplete={this.props.autoComplete}
76+
value={this.props.value}
77+
onChange={this.props.onChange}
78+
onValidate={this.onValidate}
79+
/>;
80+
}
81+
}
82+
83+
export default PassphraseConfirmField;

src/components/views/auth/RegistrationForm.tsx

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
3535
import CountryDropdown from "./CountryDropdown";
3636

3737
import { logger } from "matrix-js-sdk/src/logger";
38+
import PassphraseConfirmField from "./PassphraseConfirmField";
3839

3940
enum RegistrationField {
4041
Email = "field_email",
@@ -295,29 +296,10 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
295296
});
296297
};
297298

298-
private onPasswordConfirmValidate = async fieldState => {
299-
const result = await this.validatePasswordConfirmRules(fieldState);
299+
private onPasswordConfirmValidate = (result: IValidationResult) => {
300300
this.markFieldValid(RegistrationField.PasswordConfirm, result.valid);
301-
return result;
302301
};
303302

304-
private validatePasswordConfirmRules = withValidation({
305-
rules: [
306-
{
307-
key: "required",
308-
test: ({ value, allowEmpty }) => allowEmpty || !!value,
309-
invalid: () => _t("Confirm password"),
310-
},
311-
{
312-
key: "match",
313-
test(this: RegistrationForm, { value }) {
314-
return !value || value === this.state.password;
315-
},
316-
invalid: () => _t("Passwords don't match"),
317-
},
318-
],
319-
});
320-
321303
private onPhoneCountryChange = newVal => {
322304
this.setState({
323305
phoneCountry: newVal.iso2,
@@ -477,13 +459,12 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
477459
}
478460

479461
renderPasswordConfirm() {
480-
return <Field
462+
return <PassphraseConfirmField
481463
id="mx_RegistrationForm_passwordConfirm"
482-
ref={field => this[RegistrationField.PasswordConfirm] = field}
483-
type="password"
464+
fieldRef={field => this[RegistrationField.PasswordConfirm] = field}
484465
autoComplete="new-password"
485-
label={_t("Confirm password")}
486466
value={this.state.passwordConfirm}
467+
password={this.state.password}
487468
onChange={this.onPasswordConfirmChange}
488469
onValidate={this.onPasswordConfirmValidate}
489470
onFocus={() => CountlyAnalytics.instance.track("onboarding_registration_passwordConfirm_focus")}

0 commit comments

Comments
 (0)