From dc07b4607a0c7d4c28f1190795d70602628fd232 Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Mon, 31 Jul 2023 11:19:01 +0100 Subject: [PATCH] fix: filter out urls and spam words from token names, closes #4017 --- src/app/common/utils/spam-filter.spec.ts | 26 +++++++++++++++++++ src/app/common/utils/spam-filter.ts | 24 +++++++++++++++++ .../crypto-currency-asset-item.tsx | 3 ++- .../transactions/token-transfer.hooks.ts | 1 - 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/app/common/utils/spam-filter.spec.ts create mode 100644 src/app/common/utils/spam-filter.ts diff --git a/src/app/common/utils/spam-filter.spec.ts b/src/app/common/utils/spam-filter.spec.ts new file mode 100644 index 00000000..ed6e3f4a --- /dev/null +++ b/src/app/common/utils/spam-filter.spec.ts @@ -0,0 +1,26 @@ +import { spamFilter, spamReplacement } from '@app/common/utils/spam-filter'; + +describe('Spam filter', () => { + it('should allow valid tokens', () => { + expect(spamFilter('This token name is OK')).not.toEqual(spamReplacement); + }); + it('should detect spam urls in strings and replace content', () => { + expect(spamFilter('www.fake')).toEqual(spamReplacement); + expect(spamFilter('https://www.fake.com')).toEqual(spamReplacement); + expect(spamFilter('fake.com')).toEqual(spamReplacement); + expect(spamFilter('https://www.fake')).toEqual(spamReplacement); + expect(spamFilter('http://www.fake')).toEqual(spamReplacement); + expect(spamFilter('ftp://fake.com')).toEqual(spamReplacement); + expect(spamFilter('https://fake.com')).toEqual(spamReplacement); + expect(spamFilter('http://fake.com')).toEqual(spamReplacement); + expect(spamFilter('https://fake')).toEqual(spamReplacement); + expect(spamFilter('http://fake')).toEqual(spamReplacement); + }); + it('should detect spam words in strings and replace content', () => { + expect(spamFilter('You won some stx')).toEqual(spamReplacement); + expect(spamFilter('You Win some stx')).toEqual(spamReplacement); + expect(spamFilter('You Won some stx')).toEqual(spamReplacement); + expect(spamFilter('click here for some stx')).toEqual(spamReplacement); + expect(spamFilter('Click here for some stx')).toEqual(spamReplacement); + }); +}); diff --git a/src/app/common/utils/spam-filter.ts b/src/app/common/utils/spam-filter.ts new file mode 100644 index 00000000..0e741726 --- /dev/null +++ b/src/app/common/utils/spam-filter.ts @@ -0,0 +1,24 @@ +const urlRegex = + /(http|https|ftp)|(((http|ftp|https):\/\/)?(((http|ftp|https):\/\/)?(([\w.-]*)\.([\w]*))))/g; +const spamWords = ['won', 'win', 'click']; +export const spamReplacement = 'Unknown token'; + +function spamUrlFilter(input: string) { + return input.match(urlRegex); +} + +function spamWordFilter(input: string): boolean { + const containsSpam = (element: string) => input.toLowerCase().includes(element); + return spamWords.some(containsSpam); +} + +export function spamFilter(input: string): string { + const urlFound = spamUrlFilter(input); + const spamWordsFound = spamWordFilter(input); + + if (urlFound || spamWordsFound) { + return spamReplacement; + } + + return input; +} diff --git a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx index 0640c13b..426739a2 100644 --- a/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx +++ b/src/app/components/crypto-assets/crypto-currency-asset/crypto-currency-asset-item.tsx @@ -7,6 +7,7 @@ import { forwardRefWithAs } from '@stacks/ui-core'; import type { AllCryptoCurrencyAssetBalances } from '@shared/models/crypto-asset-balance.model'; import { useAnalytics } from '@app/common/hooks/analytics/use-analytics'; +import { spamFilter } from '@app/common/utils/spam-filter'; import { AssetItemCopyIcon } from './asset-copy-icon'; import { CryptoCurrencyAssetItemLayout } from './crypto-currency-asset-item.layout'; @@ -70,7 +71,7 @@ export const CryptoCurrencyAssetItem = forwardRefWithAs( copyIcon={canCopy ? : undefined} isPressable={isPressable} ref={ref} - title={asset.name} + title={spamFilter(asset.name)} isHovered={isHovered} address={address} usdBalance={usdBalance} diff --git a/src/app/store/transactions/token-transfer.hooks.ts b/src/app/store/transactions/token-transfer.hooks.ts index 354e7991..792518f2 100644 --- a/src/app/store/transactions/token-transfer.hooks.ts +++ b/src/app/store/transactions/token-transfer.hooks.ts @@ -111,7 +111,6 @@ export function useGenerateFtTokenTransferUnsignedTx( return useCallback( async (values?: StacksSendFormValues | StacksTransactionFormValues) => { if (!assetTransferState || !account) return; - const { assetBalance, network,