Migrate email on registration to new validation

This commit is contained in:
J. Ryan Stinnett 2019-04-18 22:53:46 +01:00
parent 1cbb4be6f7
commit 9064875312
4 changed files with 65 additions and 54 deletions

View file

@ -332,15 +332,9 @@ module.exports = React.createClass({
case "RegistrationForm.ERR_PASSWORD_LENGTH": case "RegistrationForm.ERR_PASSWORD_LENGTH":
errMsg = _t('Password too short (min %(MIN_PASSWORD_LENGTH)s).', {MIN_PASSWORD_LENGTH}); errMsg = _t('Password too short (min %(MIN_PASSWORD_LENGTH)s).', {MIN_PASSWORD_LENGTH});
break; break;
case "RegistrationForm.ERR_EMAIL_INVALID":
errMsg = _t('This doesn\'t look like a valid email address.');
break;
case "RegistrationForm.ERR_PHONE_NUMBER_INVALID": case "RegistrationForm.ERR_PHONE_NUMBER_INVALID":
errMsg = _t('This doesn\'t look like a valid phone number.'); errMsg = _t('This doesn\'t look like a valid phone number.');
break; break;
case "RegistrationForm.ERR_MISSING_EMAIL":
errMsg = _t('An email address is required to register on this homeserver.');
break;
case "RegistrationForm.ERR_MISSING_PHONE_NUMBER": case "RegistrationForm.ERR_MISSING_PHONE_NUMBER":
errMsg = _t('A phone number is required to register on this homeserver.'); errMsg = _t('A phone number is required to register on this homeserver.');
break; break;

View file

@ -91,7 +91,6 @@ module.exports = React.createClass({
// onValidationChange once for each invalid field. // onValidationChange once for each invalid field.
// TODO: Remove these calls once converted to new-style validation. // TODO: Remove these calls once converted to new-style validation.
this.validateField(FIELD_PHONE_NUMBER, ev.type); this.validateField(FIELD_PHONE_NUMBER, ev.type);
this.validateField(FIELD_EMAIL, ev.type);
this.validateField(FIELD_PASSWORD_CONFIRM, ev.type); this.validateField(FIELD_PASSWORD_CONFIRM, ev.type);
this.validateField(FIELD_PASSWORD, ev.type); this.validateField(FIELD_PASSWORD, ev.type);
@ -213,14 +212,6 @@ module.exports = React.createClass({
// TODO: Remove rules here as they are converted to new-style validation // TODO: Remove rules here as they are converted to new-style validation
switch (fieldID) { switch (fieldID) {
case FIELD_EMAIL: {
const email = this.state.email;
const emailValid = email === '' || Email.looksValid(email);
if (this._authStepIsRequired('m.login.email.identity') && (!emailValid || email === '')) {
this.markFieldError(fieldID, false, "RegistrationForm.ERR_MISSING_EMAIL");
} else this.markFieldError(fieldID, emailValid, "RegistrationForm.ERR_EMAIL_INVALID");
break;
}
case FIELD_PHONE_NUMBER: { case FIELD_PHONE_NUMBER: {
const phoneNumber = this.state.phoneNumber; const phoneNumber = this.state.phoneNumber;
const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber); const phoneNumberValid = phoneNumber === '' || phoneNumberLooksValid(phoneNumber);
@ -295,16 +286,36 @@ module.exports = React.createClass({
return cls; return cls;
}, },
onEmailBlur(ev) {
this.validateField(FIELD_EMAIL, ev.type);
},
onEmailChange(ev) { onEmailChange(ev) {
this.setState({ this.setState({
email: ev.target.value, email: ev.target.value,
}); });
}, },
onEmailValidate(fieldState) {
const result = this.validateEmailRules(fieldState);
this.markFieldValid(FIELD_EMAIL, result.valid);
return result;
},
validateEmailRules: withValidation({
description: () => _t("Use an email address to recover your account"),
rules: [
{
key: "required",
test: function({ value, allowEmpty }) {
return allowEmpty || !this._authStepIsRequired('m.login.email.identity') || !!value;
},
invalid: () => _t("Enter email address (required on this homeserver)"),
},
{
key: "email",
test: ({ value }) => !value || Email.looksValid(value),
invalid: () => _t("Doesn't look like a valid email address"),
},
],
}),
onPasswordBlur(ev) { onPasswordBlur(ev) {
this.validateField(FIELD_PASSWORD, ev.type); this.validateField(FIELD_PASSWORD, ev.type);
}, },
@ -394,6 +405,26 @@ module.exports = React.createClass({
}); });
}, },
renderEmail() {
if (!this._authStepIsUsed('m.login.email.identity')) {
return null;
}
const Field = sdk.getComponent('elements.Field');
const emailPlaceholder = this._authStepIsRequired('m.login.email.identity') ?
_t("Email") :
_t("Email (optional)");
return <Field
id="mx_RegistrationForm_email"
ref={field => this[FIELD_EMAIL] = field}
type="text"
label={emailPlaceholder}
defaultValue={this.props.defaultEmail}
value={this.state.email}
onChange={this.onEmailChange}
onValidate={this.onEmailValidate}
/>;
},
renderUsername() { renderUsername() {
const Field = sdk.getComponent('elements.Field'); const Field = sdk.getComponent('elements.Field');
return <Field return <Field
@ -437,26 +468,6 @@ module.exports = React.createClass({
</a>; </a>;
} }
let emailSection;
if (this._authStepIsUsed('m.login.email.identity')) {
const emailPlaceholder = this._authStepIsRequired('m.login.email.identity') ?
_t("Email") :
_t("Email (optional)");
emailSection = (
<Field
className={this._classForField(FIELD_EMAIL)}
id="mx_RegistrationForm_email"
type="text"
label={emailPlaceholder}
defaultValue={this.props.defaultEmail}
value={this.state.email}
onBlur={this.onEmailBlur}
onChange={this.onEmailChange}
/>
);
}
const threePidLogin = !SdkConfig.get().disable_3pid_login; const threePidLogin = !SdkConfig.get().disable_3pid_login;
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown'); const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
let phoneSection; let phoneSection;
@ -521,13 +532,11 @@ module.exports = React.createClass({
/> />
</div> </div>
<div className="mx_AuthBody_fieldRow"> <div className="mx_AuthBody_fieldRow">
{ emailSection } {this.renderEmail()}
{ phoneSection } { phoneSection }
</div> </div>
{_t( {_t("Use an email address to recover your account.") + " "}
"Use an email address to recover your account. Other users " + {_t("Other users can invite you to rooms using your contact details.")}
"can invite you to rooms using your contact details.",
)}
{ registerButton } { registerButton }
</form> </form>
</div> </div>

View file

@ -50,7 +50,10 @@ export default function withValidation({ description, rules }) {
if (!rule.key || !rule.test) { if (!rule.key || !rule.test) {
continue; continue;
} }
const ruleValid = rule.test({ value, allowEmpty }); // We're setting `this` to whichever component hold the validation
// function. That allows rules to access the state of the component.
// eslint-disable-next-line babel/no-invalid-this
const ruleValid = rule.test.call(this, { value, allowEmpty });
valid = valid && ruleValid; valid = valid && ruleValid;
if (ruleValid && rule.valid) { if (ruleValid && rule.valid) {
// If the rule's result is valid and has text to show for // If the rule's result is valid and has text to show for
@ -101,10 +104,13 @@ export default function withValidation({ description, rules }) {
summary = <div className="mx_Validation_description">{description()}</div>; summary = <div className="mx_Validation_description">{description()}</div>;
} }
const feedback = <div className="mx_Validation"> let feedback;
if (summary || details) {
feedback = <div className="mx_Validation">
{summary} {summary}
{details} {details}
</div>; </div>;
}
return { return {
valid, valid,

View file

@ -1322,15 +1322,19 @@
"Change": "Change", "Change": "Change",
"Sign in with": "Sign in with", "Sign in with": "Sign in with",
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?", "If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
"Use an email address to recover your account": "Use an email address to recover your account",
"Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)",
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
"Use letters, numbers, dashes and underscores only": "Use letters, numbers, dashes and underscores only", "Use letters, numbers, dashes and underscores only": "Use letters, numbers, dashes and underscores only",
"Some characters not allowed": "Some characters not allowed",
"Enter username": "Enter username", "Enter username": "Enter username",
"Some characters not allowed": "Some characters not allowed",
"Email (optional)": "Email (optional)",
"Create your Matrix account": "Create your Matrix account", "Create your Matrix account": "Create your Matrix account",
"Create your Matrix account on %(serverName)s": "Create your Matrix account on %(serverName)s", "Create your Matrix account on %(serverName)s": "Create your Matrix account on %(serverName)s",
"Email (optional)": "Email (optional)",
"Phone (optional)": "Phone (optional)", "Phone (optional)": "Phone (optional)",
"Confirm": "Confirm", "Confirm": "Confirm",
"Use an email address to recover your account. Other users can invite you to rooms using your contact details.": "Use an email address to recover your account. Other users can invite you to rooms using your contact details.", "Use an email address to recover your account.": "Use an email address to recover your account.",
"Other users can invite you to rooms using your contact details.": "Other users can invite you to rooms using your contact details.",
"Other servers": "Other servers", "Other servers": "Other servers",
"Enter custom server URLs <a>What does this mean?</a>": "Enter custom server URLs <a>What does this mean?</a>", "Enter custom server URLs <a>What does this mean?</a>": "Enter custom server URLs <a>What does this mean?</a>",
"Homeserver URL": "Homeserver URL", "Homeserver URL": "Homeserver URL",
@ -1521,9 +1525,7 @@
"Missing password.": "Missing password.", "Missing password.": "Missing password.",
"Passwords don't match.": "Passwords don't match.", "Passwords don't match.": "Passwords don't match.",
"Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Password too short (min %(MIN_PASSWORD_LENGTH)s).", "Password too short (min %(MIN_PASSWORD_LENGTH)s).": "Password too short (min %(MIN_PASSWORD_LENGTH)s).",
"This doesn't look like a valid email address.": "This doesn't look like a valid email address.",
"This doesn't look like a valid phone number.": "This doesn't look like a valid phone number.", "This doesn't look like a valid phone number.": "This doesn't look like a valid phone number.",
"An email address is required to register on this homeserver.": "An email address is required to register on this homeserver.",
"A phone number is required to register on this homeserver.": "A phone number is required to register on this homeserver.", "A phone number is required to register on this homeserver.": "A phone number is required to register on this homeserver.",
"An unknown error occurred.": "An unknown error occurred.", "An unknown error occurred.": "An unknown error occurred.",
"Create your account": "Create your account", "Create your account": "Create your account",