diff --git a/ts/components/ProfileEditor.tsx b/ts/components/ProfileEditor.tsx index a903247cc975..28b4b6c34ea2 100644 --- a/ts/components/ProfileEditor.tsx +++ b/ts/components/ProfileEditor.tsx @@ -36,6 +36,7 @@ import { } from './conversation/conversation-details/ConversationDetailsIcon'; import { Spinner } from './Spinner'; import { UsernameSaveState } from '../state/ducks/conversationsEnums'; +import { MAX_USERNAME, MIN_USERNAME } from '../types/Username'; export enum EditState { None = 'None', @@ -124,26 +125,24 @@ function getUsernameInvalidKey( return undefined; } - const min = 3; - if (username.length < min) { + if (username.length < MIN_USERNAME) { return { key: 'ProfileEditor--username--check-character-min', - replacements: { min }, + replacements: { min: MIN_USERNAME }, }; } if (!/^[0-9a-z_]+$/.test(username)) { return { key: 'ProfileEditor--username--check-characters' }; } - if (/^[0-9]/.test(username)) { + if (!/^[a-z_]/.test(username)) { return { key: 'ProfileEditor--username--check-starting-character' }; } - const max = 25; - if (username.length > max) { + if (username.length > MAX_USERNAME) { return { key: 'ProfileEditor--username--check-character-max', - replacements: { max }, + replacements: { max: MAX_USERNAME }, }; } diff --git a/ts/test-node/types/Username_test.ts b/ts/test-node/types/Username_test.ts index c097f0911e30..016161b93b9c 100644 --- a/ts/test-node/types/Username_test.ts +++ b/ts/test-node/types/Username_test.ts @@ -12,20 +12,20 @@ describe('Username', () => { it('matches invalid username searches', () => { assert.strictEqual(getUsernameFromSearch('username!'), 'username!'); assert.strictEqual(getUsernameFromSearch('1username'), '1username'); - assert.strictEqual(getUsernameFromSearch('us'), 'us'); + assert.strictEqual(getUsernameFromSearch('use'), 'use'); assert.strictEqual( - getUsernameFromSearch('username901234567890123456'), - 'username901234567890123456' + getUsernameFromSearch('username9012345678901234567'), + 'username9012345678901234567' ); }); it('matches valid username searches', () => { assert.strictEqual(getUsernameFromSearch('username_34'), 'username_34'); assert.strictEqual(getUsernameFromSearch('u5ername'), 'u5ername'); - assert.strictEqual(getUsernameFromSearch('use'), 'use'); + assert.strictEqual(getUsernameFromSearch('user'), 'user'); assert.strictEqual( - getUsernameFromSearch('username90123456789012345'), - 'username90123456789012345' + getUsernameFromSearch('username901234567890123456'), + 'username901234567890123456' ); }); @@ -57,15 +57,16 @@ describe('Username', () => { it('does not match invalid username searches', () => { assert.isFalse(isValidUsername('username!')); assert.isFalse(isValidUsername('1username')); - assert.isFalse(isValidUsername('us')); - assert.isFalse(isValidUsername('username901234567890123456')); + assert.isFalse(isValidUsername('use')); + assert.isFalse(isValidUsername('username9012345678901234567')); }); it('matches valid usernames', () => { assert.isTrue(isValidUsername('username_34')); assert.isTrue(isValidUsername('u5ername')); - assert.isTrue(isValidUsername('use')); - assert.isTrue(isValidUsername('username90123456789012345')); + assert.isTrue(isValidUsername('_username')); + assert.isTrue(isValidUsername('user')); + assert.isTrue(isValidUsername('username901234567890123456')); }); it('does not match valid and invalid usernames with @ prefix or suffix', () => { diff --git a/ts/types/Username.ts b/ts/types/Username.ts index a65696580b45..d4699fe5d748 100644 --- a/ts/types/Username.ts +++ b/ts/types/Username.ts @@ -1,8 +1,11 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only +export const MAX_USERNAME = 26; +export const MIN_USERNAME = 4; + export function isValidUsername(searchTerm: string): boolean { - return /^[a-z][0-9a-z_]{2,24}$/.test(searchTerm); + return /^[a-z_][0-9a-z_]{3,25}$/.test(searchTerm); } export function getUsernameFromSearch(searchTerm: string): string | undefined {