diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index bb284a008bb..73c277168f6 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -111,9 +111,6 @@ window.SignalContext = { platform: '', release: '', }, - usernames: { - hash: input => Buffer.from(input), - } as any, config: {} as any, getHourCyclePreference: () => HourCyclePreference.UnknownPreference, diff --git a/test/setup-test-node.js b/test/setup-test-node.js index 412b91cad2d..a65b9db8e8f 100644 --- a/test/setup-test-node.js +++ b/test/setup-test-node.js @@ -5,7 +5,6 @@ const chai = require('chai'); const chaiAsPromised = require('chai-as-promised'); -const { usernames } = require('@signalapp/libsignal-client'); const { Crypto } = require('../ts/context/Crypto'); const { setEnvironment, Environment } = require('../ts/environment'); @@ -23,7 +22,6 @@ global.window = { performance, SignalContext: { crypto: new Crypto(), - usernames, log: { info: (...args) => console.log(...args), warn: (...args) => console.warn(...args), diff --git a/ts/components/LeftPane.stories.tsx b/ts/components/LeftPane.stories.tsx index c29b7bf5179..4099a9baa92 100644 --- a/ts/components/LeftPane.stories.tsx +++ b/ts/components/LeftPane.stories.tsx @@ -660,6 +660,7 @@ export function ComposeNoResults(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: '', + username: undefined, }, })} /> @@ -677,6 +678,7 @@ export function ComposeSomeContactsNoSearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: '', + username: undefined, }, })} /> @@ -694,6 +696,7 @@ export function ComposeSomeContactsWithASearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: 'ar', + username: undefined, }, })} /> @@ -711,6 +714,7 @@ export function ComposeSomeGroupsNoSearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: '', + username: undefined, }, })} /> @@ -728,6 +732,7 @@ export function ComposeSomeGroupsWithSearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: 'ar', + username: undefined, }, })} /> @@ -745,6 +750,7 @@ export function ComposeSearchIsValidUsername(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: 'someone', + username: 'someone', }, })} /> @@ -764,6 +770,7 @@ export function ComposeSearchIsValidUsernameFetchingUsername(): JSX.Element { }, regionCode: 'US', searchTerm: 'someone', + username: 'someone', }, })} /> @@ -781,6 +788,7 @@ export function ComposeSearchIsValidPhoneNumber(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: '2125555454', + username: undefined, }, })} /> @@ -800,6 +808,7 @@ export function ComposeSearchIsValidPhoneNumberFetchingPhoneNumber(): JSX.Elemen }, regionCode: 'US', searchTerm: '(212)5555454', + username: undefined, }, })} /> @@ -817,6 +826,7 @@ export function ComposeAllKindsOfResultsNoSearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: '', + username: undefined, }, })} /> @@ -834,6 +844,7 @@ export function ComposeAllKindsOfResultsWithASearchTerm(): JSX.Element { uuidFetchState: {}, regionCode: 'US', searchTerm: 'someone', + username: 'someone', }, })} /> @@ -912,6 +923,7 @@ export function ChooseGroupMembersPartialPhoneNumber(): JSX.Element { ourE164: undefined, ourUsername: undefined, searchTerm: '+1(212) 555', + username: undefined, regionCode: 'US', selectedContacts: [], }, @@ -937,6 +949,7 @@ export function ChooseGroupMembersValidPhoneNumber(): JSX.Element { searchTerm: '+1(212) 555 5454', regionCode: 'US', selectedContacts: [], + username: undefined, }, })} /> @@ -957,9 +970,10 @@ export function ChooseGroupMembersUsername(): JSX.Element { isShowingMaximumGroupSizeModal: false, ourE164: undefined, ourUsername: undefined, - searchTerm: '@signal', + searchTerm: 'signal.01', regionCode: 'US', selectedContacts: [], + username: 'signal.01', }, })} /> diff --git a/ts/components/conversation/conversation-details/AddGroupMembersModal.stories.tsx b/ts/components/conversation/conversation-details/AddGroupMembersModal.stories.tsx index 08a0b9a0cf6..a84bdf16d03 100644 --- a/ts/components/conversation/conversation-details/AddGroupMembersModal.stories.tsx +++ b/ts/components/conversation/conversation-details/AddGroupMembersModal.stories.tsx @@ -70,6 +70,7 @@ const createProps = ( i18n={i18n} lookupConversationWithoutServiceId={lookupConversationWithoutServiceId} showUserNotFoundModal={action('showUserNotFoundModal')} + username={undefined} /> ); }, diff --git a/ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx b/ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx index 88c01f3c449..e4224d1ca67 100644 --- a/ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx +++ b/ts/components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal.tsx @@ -12,7 +12,6 @@ import { omit } from 'lodash'; import type { ListRowProps } from 'react-virtualized'; import type { LocalizerType, ThemeType } from '../../../../types/Util'; -import { getUsernameFromSearch } from '../../../../types/Username'; import { strictAssert, assertDev } from '../../../../util/assert'; import { refMerger } from '../../../../util/refMerger'; import { useRestoreFocus } from '../../../../hooks/useRestoreFocus'; @@ -59,6 +58,7 @@ export type StatePropsType = { ourUsername: string | undefined; searchTerm: string; selectedContacts: ReadonlyArray; + username: string | undefined; confirmAdds: () => void; onClose: () => void; @@ -96,11 +96,10 @@ export function ChooseGroupMembersModal({ toggleSelectedContact, lookupConversationWithoutServiceId, showUserNotFoundModal, + username, }: PropsType): JSX.Element { const [focusRef] = useRestoreFocus(); - const username = getUsernameFromSearch(searchTerm); - const isUsernameChecked = selectedContacts.some( contact => contact.username === username ); diff --git a/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx b/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx index d09caaa40a3..fc87d26ea5e 100644 --- a/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx +++ b/ts/components/conversation/conversation-details/ConversationDetails.stories.tsx @@ -126,6 +126,7 @@ const createProps = ( ourE164={undefined} ourUsername={undefined} showUserNotFoundModal={action('showUserNotFoundModal')} + username={undefined} /> ); }, diff --git a/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx b/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx index c121766ff13..5bedc05670c 100644 --- a/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx +++ b/ts/components/leftPane/LeftPaneChooseGroupMembersHelper.tsx @@ -18,7 +18,6 @@ import { } from '../AddGroupMemberErrorDialog'; import { Button } from '../Button'; import type { LocalizerType } from '../../types/Util'; -import { getUsernameFromSearch } from '../../types/Username'; import type { ParsedE164Type } from '../../util/libphonenumberInstance'; import { parseAndFormatPhoneNumber } from '../../util/libphonenumberInstance'; import type { UUIDFetchStateType } from '../../util/uuidFetchState'; @@ -38,6 +37,7 @@ export type LeftPaneChooseGroupMembersPropsType = { ourUsername: string | undefined; searchTerm: string; regionCode: string | undefined; + username: string | undefined; selectedContacts: Array; }; @@ -80,6 +80,7 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper) { super(); @@ -93,7 +94,6 @@ export class LeftPaneChooseGroupMembersHelper extends LeftPaneHelper) { super(); @@ -65,8 +66,6 @@ export class LeftPaneComposeHelper extends LeftPaneHelper) { super(); this.searchTerm = searchTerm; this.uuidFetchState = uuidFetchState; - this.username = getUsernameFromSearch(this.searchTerm); + this.username = username; } override getHeaderContents({ diff --git a/ts/state/smart/ChooseGroupMembersModal.tsx b/ts/state/smart/ChooseGroupMembersModal.tsx index 997fa519f78..29dd768a312 100644 --- a/ts/state/smart/ChooseGroupMembersModal.tsx +++ b/ts/state/smart/ChooseGroupMembersModal.tsx @@ -7,6 +7,7 @@ import type { StateType } from '../reducer'; import { mapDispatchToProps } from '../actions'; import { strictAssert } from '../../util/assert'; import { lookupConversationWithoutServiceId } from '../../util/lookupConversationWithoutServiceId'; +import { getUsernameFromSearch } from '../../util/Username'; import type { StatePropsType } from '../../components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal'; import { ChooseGroupMembersModal } from '../../components/conversation/conversation-details/AddGroupMembersModal/ChooseGroupMembersModal'; @@ -47,6 +48,8 @@ const mapStateToProps = ( return convo; }); + const { searchTerm } = props; + return { ...props, regionCode: getRegionCode(state), @@ -58,6 +61,7 @@ const mapStateToProps = ( ourUsername: getMe(state).username, selectedContacts, lookupConversationWithoutServiceId, + username: getUsernameFromSearch(searchTerm), }; }; diff --git a/ts/state/smart/LeftPane.tsx b/ts/state/smart/LeftPane.tsx index 6ddafe89721..6977cd8cc9a 100644 --- a/ts/state/smart/LeftPane.tsx +++ b/ts/state/smart/LeftPane.tsx @@ -14,6 +14,7 @@ import { missingCaseError } from '../../util/missingCaseError'; import { lookupConversationWithoutServiceId } from '../../util/lookupConversationWithoutServiceId'; import { isDone as isRegistrationDone } from '../../util/registration'; import { getCountryDataForLocale } from '../../util/getCountryData'; +import { getUsernameFromSearch } from '../../util/Username'; import { LeftPaneMode } from '../../types/leftPane'; import { ComposerStep, OneTimeModalState } from '../ducks/conversationsEnums'; @@ -182,12 +183,18 @@ const getModeSpecificProps = ( regionCode: getRegionCode(state), searchTerm: getComposerConversationSearchTerm(state), uuidFetchState: getComposerUUIDFetchState(state), + username: getUsernameFromSearch( + getComposerConversationSearchTerm(state) + ), }; case ComposerStep.FindByUsername: return { mode: LeftPaneMode.FindByUsername, searchTerm: getComposerConversationSearchTerm(state), uuidFetchState: getComposerUUIDFetchState(state), + username: getUsernameFromSearch( + getComposerConversationSearchTerm(state) + ), }; case ComposerStep.FindByPhoneNumber: return { @@ -215,6 +222,9 @@ const getModeSpecificProps = ( searchTerm: getComposerConversationSearchTerm(state), selectedContacts: getComposeSelectedContacts(state), uuidFetchState: getComposerUUIDFetchState(state), + username: getUsernameFromSearch( + getComposerConversationSearchTerm(state) + ), }; case ComposerStep.SetGroupMetadata: return { diff --git a/ts/test-node/types/Username_test.ts b/ts/test-electron/util/Username_test.ts similarity index 69% rename from ts/test-node/types/Username_test.ts rename to ts/test-electron/util/Username_test.ts index 6436caf0aab..43bc9f5fb79 100644 --- a/ts/test-node/types/Username_test.ts +++ b/ts/test-electron/util/Username_test.ts @@ -3,15 +3,20 @@ import { assert } from 'chai'; -import * as Username from '../../types/Username'; +import * as Username from '../../util/Username'; describe('Username', () => { describe('getUsernameFromSearch', () => { const { getUsernameFromSearch } = Username; it('matches invalid username searches', () => { - assert.isUndefined(getUsernameFromSearch('use')); - assert.isUndefined(getUsernameFromSearch('username9012345678901234567')); + assert.isUndefined(getUsernameFromSearch('us')); + assert.isUndefined(getUsernameFromSearch('123')); + }); + + it('matches partial username searches without discriminator', () => { + assert.strictEqual(getUsernameFromSearch('use'), 'use'); + assert.strictEqual(getUsernameFromSearch('use.'), 'use.'); }); it('matches valid username searches', () => { diff --git a/ts/test-node/components/leftPane/LeftPaneChooseGroupMembersHelper_test.ts b/ts/test-node/components/leftPane/LeftPaneChooseGroupMembersHelper_test.ts index c15c24aa6ee..4b0ac0c44ea 100644 --- a/ts/test-node/components/leftPane/LeftPaneChooseGroupMembersHelper_test.ts +++ b/ts/test-node/components/leftPane/LeftPaneChooseGroupMembersHelper_test.ts @@ -21,6 +21,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { groupSizeRecommendedLimit: 22, groupSizeHardLimit: 33, searchTerm: '', + username: undefined, regionCode: 'US', selectedContacts: [], }; @@ -44,6 +45,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: '', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRowCount(), 0 @@ -53,6 +55,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: 'foo bar', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRowCount(), 0 @@ -68,6 +71,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { getDefaultConversation(), ], searchTerm: '', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRowCount(), 4 @@ -82,6 +86,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: '', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRow(0) ); @@ -90,6 +95,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: '', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRow(99) ); @@ -98,6 +104,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: 'foo bar', + username: undefined, selectedContacts: [getDefaultConversation()], }).getRow(0) ); @@ -112,6 +119,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts, searchTerm: 'foo bar', + username: undefined, selectedContacts: [candidateContacts[1]], }); @@ -137,6 +145,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts, searchTerm: 'foo bar', + username: undefined, selectedContacts: candidateContacts.slice(1, 33), }); @@ -159,6 +168,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: '212 555', + username: undefined, selectedContacts: [], }); @@ -184,6 +194,7 @@ describe('LeftPaneChooseGroupMembersHelper', () => { ...defaults, candidateContacts: [], searchTerm: 'signal.01', + username: 'signal.01', selectedContacts: [], }); diff --git a/ts/test-node/components/leftPane/LeftPaneComposeHelper_test.ts b/ts/test-node/components/leftPane/LeftPaneComposeHelper_test.ts index ee7b3c5b69b..687e6db1a24 100644 --- a/ts/test-node/components/leftPane/LeftPaneComposeHelper_test.ts +++ b/ts/test-node/components/leftPane/LeftPaneComposeHelper_test.ts @@ -32,6 +32,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }); assert.strictEqual(helper.getBackAction({ showInbox }), showInbox); @@ -46,6 +47,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '', + username: undefined, uuidFetchState: {}, }).getRowCount(), 3 @@ -60,6 +62,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }).getRowCount(), 6 ); @@ -73,6 +76,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }).getRowCount(), 9 ); @@ -86,6 +90,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'someone.01', uuidFetchState: {}, + username: 'someone.01', }).getRowCount(), 8 ); @@ -99,6 +104,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'foobar.01', uuidFetchState: {}, + username: 'foobar.01', }).getRowCount(), 2 ); @@ -109,6 +115,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'foobar.01', uuidFetchState: {}, + username: 'foobar.01', }).getRowCount(), 5 ); @@ -119,6 +126,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'foobar.01', uuidFetchState: {}, + username: 'foobar.01', }).getRowCount(), 7 ); @@ -132,6 +140,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '+16505551234', uuidFetchState: {}, + username: undefined, }).getRowCount(), 2 ); @@ -145,6 +154,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'someone.02', uuidFetchState: {}, + username: 'someone.02', }).getRowCount(), 2 ); @@ -158,6 +168,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '+16505551234', uuidFetchState: {}, + username: undefined, }).getRowCount(), 5 ); @@ -172,6 +183,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }); assert.deepEqual(helper.getRow(0), { @@ -197,6 +209,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }); assert.deepEqual(helper.getRow(0), { @@ -236,6 +249,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '', uuidFetchState: {}, + username: undefined, }); assert.deepEqual(helper.getRow(0), { @@ -280,6 +294,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: 'foo bar', uuidFetchState: {}, + username: undefined, }); assert.deepEqual(helper.getRow(1), { @@ -301,6 +316,7 @@ describe('LeftPaneComposeHelper', () => { regionCode: 'US', searchTerm: '+1(650) 555 12 34', uuidFetchState: {}, + username: undefined, }); assert.deepEqual( @@ -327,6 +343,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: username, + username, uuidFetchState: { [`username:${username}`]: true, }, @@ -354,6 +371,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '+1(650) 555 12 34', + username: undefined, uuidFetchState: {}, }); @@ -391,6 +409,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -405,6 +424,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -425,6 +445,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -434,6 +455,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'different search', + username: undefined, uuidFetchState: {}, }) ); @@ -443,6 +465,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'last search', + username: undefined, uuidFetchState: {}, }) ); @@ -454,6 +477,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '', + username: undefined, uuidFetchState: {}, }); @@ -463,6 +487,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '', + username: undefined, uuidFetchState: {}, }) ); @@ -474,6 +499,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -483,6 +509,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '', + username: undefined, uuidFetchState: {}, }) ); @@ -492,6 +519,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '+16505551234', + username: undefined, uuidFetchState: {}, }) ); @@ -503,6 +531,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: '', + username: undefined, uuidFetchState: {}, }); @@ -512,6 +541,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }) ); @@ -523,6 +553,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -532,6 +563,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [getDefaultGroupListItem(), getDefaultGroupListItem()], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }) ); @@ -541,6 +573,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [getDefaultGroupListItem(), getDefaultGroupListItem()], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }); @@ -550,6 +583,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [], regionCode: 'US', searchTerm: 'foo bar', + username: undefined, uuidFetchState: {}, }) ); @@ -561,6 +595,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [getDefaultGroupListItem()], regionCode: 'US', searchTerm: 'soup', + username: 'soup', uuidFetchState: {}, }); @@ -570,6 +605,7 @@ describe('LeftPaneComposeHelper', () => { composeGroups: [getDefaultGroupListItem(), getDefaultGroupListItem()], regionCode: 'US', searchTerm: 'soup', + username: 'soup', uuidFetchState: {}, }) ); diff --git a/ts/types/Username.ts b/ts/types/Username.ts index 0e482e46840..adcd25c58a7 100644 --- a/ts/types/Username.ts +++ b/ts/types/Username.ts @@ -27,15 +27,6 @@ export enum ConfirmUsernameResult { ConflictOrGone = 'ConflictOrGone', } -export function getUsernameFromSearch(searchTerm: string): string | undefined { - try { - window.SignalContext.usernames.hash(searchTerm); - return searchTerm; - } catch { - return undefined; - } -} - export function getNickname(username: string): string | undefined { const match = username.match(/^(.*?)(?:\.|$)/); if (!match) { diff --git a/ts/util/Username.ts b/ts/util/Username.ts index 477447ca0f6..f6d19c5d04e 100644 --- a/ts/util/Username.ts +++ b/ts/util/Username.ts @@ -1,7 +1,10 @@ // Copyright 2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only +import { usernames } from '@signalapp/libsignal-client'; + import * as RemoteConfig from '../RemoteConfig'; +import { getNickname } from '../types/Username'; import { parseIntWithFallback } from './parseIntWithFallback'; export function getMaxNickname(): number { @@ -13,3 +16,26 @@ export function getMaxNickname(): number { export function getMinNickname(): number { return parseIntWithFallback(RemoteConfig.getValue('global.nicknames.min'), 3); } + +export function getUsernameFromSearch(searchTerm: string): string | undefined { + const nickname = getNickname(searchTerm); + if (nickname == null || nickname.length < getMinNickname()) { + return undefined; + } + + let modifiedTerm = searchTerm; + if (searchTerm.endsWith('.')) { + // Allow nicknames without full discriminator + modifiedTerm = `${searchTerm}01`; + } else if (!/\.\d*$/.test(searchTerm)) { + // Allow nicknames without discriminator + modifiedTerm = `${searchTerm}.01`; + } + + try { + usernames.hash(modifiedTerm); + return searchTerm; + } catch { + return undefined; + } +} diff --git a/ts/windows/context.ts b/ts/windows/context.ts index ab36db3a069..5eb4b1f7598 100644 --- a/ts/windows/context.ts +++ b/ts/windows/context.ts @@ -3,7 +3,6 @@ import { ipcRenderer } from 'electron'; import type { MenuItemConstructorOptions } from 'electron'; -import { usernames } from '@signalapp/libsignal-client'; import type { MenuOptionsType } from '../types/menu'; import type { IPCEventsValuesType } from '../util/createIPCEvents'; @@ -71,7 +70,6 @@ export type MinimalSignalContextType = { export type SignalContextType = { bytes: Bytes; crypto: Crypto; - usernames: typeof usernames; i18n: LocalizerType; log: LoggerType; renderWindow?: () => void; @@ -83,7 +81,6 @@ export const SignalContext: SignalContextType = { ...MinimalSignalContext, bytes: new Bytes(), crypto: new Crypto(), - usernames, i18n, log: window.SignalContext.log, setIsCallActive(isCallActive: boolean): void {