From 8592e76e124c28d69903865e43180c7153bbaee0 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 13 Dec 2018 16:05:34 -0700 Subject: [PATCH 1/2] Standardize errors about localpart structure Fixes https://github.com/vector-im/riot-web/issues/5833 This also includes changing some Jira references that aren't searchable anymore, and a thing to replace the spinner on the SetMxidDialog as per https://github.com/vector-im/riot-web/issues/5833#issuecomment-445323177 --- src/Registration.js | 4 ++++ src/components/structures/login/Registration.js | 2 +- src/components/views/dialogs/SetMxIdDialog.js | 15 ++++++--------- src/components/views/login/RegistrationForm.js | 7 +++---- .../views/room_settings/AliasSettings.js | 2 +- src/i18n/strings/en_EN.json | 3 ++- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/Registration.js b/src/Registration.js index f86c9cc618..8364fc7cdb 100644 --- a/src/Registration.js +++ b/src/Registration.js @@ -26,6 +26,10 @@ import MatrixClientPeg from './MatrixClientPeg'; import Modal from './Modal'; import { _t } from './languageHandler'; +// Regex for what a "safe" or "Matrix-looking" localpart would be. +// TODO: Update as needed for https://github.com/matrix-org/matrix-doc/issues/1514 +export const SAFE_LOCALPART_REGEX = /^[a-z0-9=_\-./]+$/g; + /** * Starts either the ILAG or full registration flow, depending * on what the HS supports diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js index 98fd61370d..ad3ea5f19c 100644 --- a/src/components/structures/login/Registration.js +++ b/src/components/structures/login/Registration.js @@ -342,7 +342,7 @@ module.exports = React.createClass({ errMsg = _t('A phone number is required to register on this homeserver.'); break; case "RegistrationForm.ERR_USERNAME_INVALID": - errMsg = _t('User names may only contain letters, numbers, dots, hyphens and underscores.'); + errMsg = _t("Only use lower case letters, numbers and '=_-./'"); break; case "RegistrationForm.ERR_USERNAME_BLANK": errMsg = _t('You need to enter a user name.'); diff --git a/src/components/views/dialogs/SetMxIdDialog.js b/src/components/views/dialogs/SetMxIdDialog.js index fb892c4a0a..222a2c35fe 100644 --- a/src/components/views/dialogs/SetMxIdDialog.js +++ b/src/components/views/dialogs/SetMxIdDialog.js @@ -23,6 +23,7 @@ import MatrixClientPeg from '../../../MatrixClientPeg'; import classnames from 'classnames'; import { KeyCode } from '../../../Keyboard'; import { _t } from '../../../languageHandler'; +import { SAFE_LOCALPART_REGEX } from '../../../Registration'; // The amount of time to wait for further changes to the input username before // sending a request to the server @@ -110,12 +111,11 @@ export default React.createClass({ }, _doUsernameCheck: function() { - // XXX: SPEC-1 - // Check if username is valid - // Naive impl copied from https://github.com/matrix-org/matrix-react-sdk/blob/66c3a6d9ca695780eb6b662e242e88323053ff33/src/components/views/login/RegistrationForm.js#L190 - if (encodeURIComponent(this.state.username) !== this.state.username) { + // We do a quick check ahead of the username availability API to ensure the + // user ID roughly looks okay from a Matrix perspective. + if (!SAFE_LOCALPART_REGEX.test(this.state.username)) { this.setState({ - usernameError: _t('User names may only contain letters, numbers, dots, hyphens and underscores.'), + usernameError: _t("Only use lower case letters, numbers and '=_-./'"), }); return Promise.reject(); } @@ -210,7 +210,6 @@ export default React.createClass({ render: function() { const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth'); - const Spinner = sdk.getComponent('elements.Spinner'); let auth; if (this.state.doingUIAuth) { @@ -230,9 +229,8 @@ export default React.createClass({ }); let usernameIndicator = null; - let usernameBusyIndicator = null; if (this.state.usernameBusy) { - usernameBusyIndicator = ; + usernameIndicator =
{_t("Checking...")}
; } else { const usernameAvailable = this.state.username && this.state.usernameCheckSupport && !this.state.usernameError; @@ -270,7 +268,6 @@ export default React.createClass({ size="30" className={inputClasses} /> - { usernameBusyIndicator } { usernameIndicator }

diff --git a/src/components/views/login/RegistrationForm.js b/src/components/views/login/RegistrationForm.js index fe977025ae..137aeada91 100644 --- a/src/components/views/login/RegistrationForm.js +++ b/src/components/views/login/RegistrationForm.js @@ -25,7 +25,7 @@ import { looksValid as phoneNumberLooksValid } from '../../../phonenumber'; import Modal from '../../../Modal'; import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; -import SettingsStore from "../../../settings/SettingsStore"; +import { SAFE_LOCALPART_REGEX } from '../../../Registration'; const FIELD_EMAIL = 'field_email'; const FIELD_PHONE_COUNTRY = 'field_phone_country'; @@ -194,9 +194,8 @@ module.exports = React.createClass({ } else this.markFieldValid(field_id, phoneNumberValid, "RegistrationForm.ERR_PHONE_NUMBER_INVALID"); break; case FIELD_USERNAME: - // XXX: SPEC-1 - var username = this.refs.username.value.trim(); - if (encodeURIComponent(username) != username) { + const username = this.refs.username.value.trim(); + if (!SAFE_LOCALPART_REGEX.test(username)) { this.markFieldValid( field_id, false, diff --git a/src/components/views/room_settings/AliasSettings.js b/src/components/views/room_settings/AliasSettings.js index de5d3db625..f68670b2f9 100644 --- a/src/components/views/room_settings/AliasSettings.js +++ b/src/components/views/room_settings/AliasSettings.js @@ -130,7 +130,7 @@ module.exports = React.createClass({ }, isAliasValid: function(alias) { - // XXX: FIXME SPEC-1 + // XXX: FIXME https://github.com/matrix-org/matrix-doc/issues/668 return (alias.match(/^#([^\/:,]+?):(.+)$/) && encodeURI(alias) === alias); }, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 92fb545b4e..c3282c8bf8 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -985,10 +985,11 @@ "Unable to verify email address.": "Unable to verify email address.", "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", "Skip": "Skip", - "User names may only contain letters, numbers, dots, hyphens and underscores.": "User names may only contain letters, numbers, dots, hyphens and underscores.", + "Only use lower case letters, numbers and '=_-./'": "Only use lower case letters, numbers and '=_-./'", "Username not available": "Username not available", "Username invalid: %(errMessage)s": "Username invalid: %(errMessage)s", "An error occurred: %(error_string)s": "An error occurred: %(error_string)s", + "Checking...": "Checking...", "Username available": "Username available", "To get started, please pick a username!": "To get started, please pick a username!", "This will be your account name on the homeserver, or you can pick a different server.": "This will be your account name on the homeserver, or you can pick a different server.", From 576bfedfb54e5625bcda2b976b1ca62aadfb0e11 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 13 Dec 2018 22:00:06 -0700 Subject: [PATCH 2/2] Remove global flag Regular expression objects are stateful, and the global flag interferes badly with the expression. A valid call can cause it to act like a flip flop instead of a stateless test. --- src/Registration.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Registration.js b/src/Registration.js index 8364fc7cdb..98aee3ac83 100644 --- a/src/Registration.js +++ b/src/Registration.js @@ -28,7 +28,7 @@ import { _t } from './languageHandler'; // Regex for what a "safe" or "Matrix-looking" localpart would be. // TODO: Update as needed for https://github.com/matrix-org/matrix-doc/issues/1514 -export const SAFE_LOCALPART_REGEX = /^[a-z0-9=_\-./]+$/g; +export const SAFE_LOCALPART_REGEX = /^[a-z0-9=_\-./]+$/; /** * Starts either the ILAG or full registration flow, depending