From 07a9f84c49fd7fabd45da525f35eb95aca1b71f5 Mon Sep 17 00:00:00 2001 From: konstantin krivlenia Date: Fri, 22 May 2020 00:11:58 +0300 Subject: [PATCH] allow non latin letter for user name --- frontend/.size-limit.js | 2 +- .../auth__anonymous-login-form.tsx | 9 ++++----- .../__email-login-form/auth__email-login-form.tsx | 5 +++-- .../app/components/auth/validateUserName.test.ts | 13 +++++++++++++ frontend/app/components/auth/validateUserName.ts | 4 ++++ frontend/app/locales/en.json | 2 +- 6 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 frontend/app/components/auth/validateUserName.test.ts create mode 100644 frontend/app/components/auth/validateUserName.ts diff --git a/frontend/.size-limit.js b/frontend/.size-limit.js index d9cf4dc0..1379630b 100644 --- a/frontend/.size-limit.js +++ b/frontend/.size-limit.js @@ -4,7 +4,7 @@ module.exports = [ limit: '2.55 KB', }, { - limit: '83 KB', + limit: '86 KB', path: 'public/remark.js', }, { diff --git a/frontend/app/components/auth/__anonymous-login-form/auth__anonymous-login-form.tsx b/frontend/app/components/auth/__anonymous-login-form/auth__anonymous-login-form.tsx index 51ec00b6..77ab38ba 100644 --- a/frontend/app/components/auth/__anonymous-login-form/auth__anonymous-login-form.tsx +++ b/frontend/app/components/auth/__anonymous-login-form/auth__anonymous-login-form.tsx @@ -7,6 +7,8 @@ import { Theme } from '@app/common/types'; import { Input } from '@app/components/input'; import { Button } from '@app/components/button'; +import { validateUserName } from '../validateUserName'; + interface Props { onSubmit(username: string): Promise; theme: Theme; @@ -26,7 +28,7 @@ export const messages = defineMessages({ }, symbolLimit: { id: 'anonymousLoginForm.symbol-limit', - defaultMessage: 'Username must start with a letter and contain only latin letters, numbers, underscores, or spaces', + defaultMessage: 'Username must contain only letters, numbers, underscores or spaces', }, userName: { id: 'anonymousLoginForm.user-name', @@ -35,13 +37,10 @@ export const messages = defineMessages({ }); export class AnonymousLoginForm extends Component { - static usernameRegex = /^[a-zA-Z][\w ]+$/; - inputRef = createRef(); constructor(props: Props) { super(props); - this.state = { inputValue: '', honeyPotValue: false, @@ -70,7 +69,7 @@ export class AnonymousLoginForm extends Component { const value = this.state.inputValue; const intl = this.props.intl; if (value.length < 3) return intl.formatMessage(messages.lengthLimit); - if (!AnonymousLoginForm.usernameRegex.test(value)) return intl.formatMessage(messages.symbolLimit); + if (!validateUserName(value)) return intl.formatMessage(messages.symbolLimit); return null; } diff --git a/frontend/app/components/auth/__email-login-form/auth__email-login-form.tsx b/frontend/app/components/auth/__email-login-form/auth__email-login-form.tsx index a5c7da76..c6b544af 100644 --- a/frontend/app/components/auth/__email-login-form/auth__email-login-form.tsx +++ b/frontend/app/components/auth/__email-login-form/auth__email-login-form.tsx @@ -13,6 +13,8 @@ import { Button } from '@app/components/button'; import { isJwtExpired } from '@app/utils/jwt'; import { defineMessages, IntlShape, useIntl, FormattedMessage } from 'react-intl'; +import { validateUserName } from '../validateUserName'; + import { messages as loginForm } from '../__anonymous-login-form/auth__anonymous-login-form'; interface OwnProps { @@ -65,7 +67,6 @@ const messages = defineMessages({ }); export class EmailLoginForm extends Component { - static usernameRegex = /^[a-zA-Z][\w ]+$/; static emailRegex = /[^@]+@[^.]+\..+/; usernameInputRef = createRef(); @@ -179,7 +180,7 @@ export class EmailLoginForm extends Component { if (this.state.loading) return intl.formatMessage(messages.loading); const username = this.state.usernameValue; if (username.length < 3) return intl.formatMessage(loginForm.lengthLimit); - if (!EmailLoginForm.usernameRegex.test(username)) return intl.formatMessage(loginForm.symbolLimit); + if (!validateUserName(username)) return intl.formatMessage(loginForm.symbolLimit); if (!EmailLoginForm.emailRegex.test(this.state.addressValue)) return intl.formatMessage(messages.invalidEmail); return null; } diff --git a/frontend/app/components/auth/validateUserName.test.ts b/frontend/app/components/auth/validateUserName.test.ts new file mode 100644 index 00000000..80b5994d --- /dev/null +++ b/frontend/app/components/auth/validateUserName.test.ts @@ -0,0 +1,13 @@ +import { validateUserName } from './validateUserName'; + +describe('validate user name', () => { + it('should allow good name', () => { + expect(validateUserName('Раз_Два Три_34567')).toEqual(true); + }); + it('should not allow bad name', () => { + expect(validateUserName('**blah123')).toEqual(false); + }); + it('should not allow only spaces', () => { + expect(validateUserName(' ')).toEqual(false); + }); +}); diff --git a/frontend/app/components/auth/validateUserName.ts b/frontend/app/components/auth/validateUserName.ts new file mode 100644 index 00000000..988a4785 --- /dev/null +++ b/frontend/app/components/auth/validateUserName.ts @@ -0,0 +1,4 @@ +const userNameRegex = /^[\p{L}\d_ ]+$/u; +export function validateUserName(userName: string) { + return userNameRegex.test(userName.trim()); +} diff --git a/frontend/app/locales/en.json b/frontend/app/locales/en.json index d6bb133f..040dec92 100644 --- a/frontend/app/locales/en.json +++ b/frontend/app/locales/en.json @@ -1,7 +1,7 @@ { "anonymousLoginForm.length-limit": "Username must be at least 3 characters long", "anonymousLoginForm.log-in": "Log in", - "anonymousLoginForm.symbol-limit": "Username must start with a letter and contain only latin letters, numbers, underscores, or spaces", + "anonymousLoginForm.symbol-limit": "Username must contain only letters, numbers, underscores or spaces", "anonymousLoginForm.user-name": "Username", "authPanel.anonymous-provider": "Anonymous", "authPanel.disable-comments": "Disable comments",