diff --git a/.changelog/656.feature.md b/.changelog/656.feature.md new file mode 100644 index 000000000..c616d0d81 --- /dev/null +++ b/.changelog/656.feature.md @@ -0,0 +1 @@ +Add check against sending menmonics to search diff --git a/src/app/components/Search/index.tsx b/src/app/components/Search/index.tsx index 765b6de0f..67f3ab625 100644 --- a/src/app/components/Search/index.tsx +++ b/src/app/components/Search/index.tsx @@ -19,6 +19,7 @@ import { SearchScope } from '../../../types/searchScope' import { textSearchMininumLength } from './search-utils' import Typography from '@mui/material/Typography' import { isValidBlockHeight } from '../../utils/helpers' +import { isValidMnemonic } from '../../utils/helpers' export type SearchVariant = 'button' | 'icon' | 'expandable' @@ -105,14 +106,21 @@ const SearchCmp: FC = ({ scope, variant, disabled, onFocusChange: o const [isFocused, setIsFocused] = useState(false) const valueInSearchParams = useSearchParams()[0].get('q') ?? '' - const valueWithoutPrefix = value.trim() + const wordsOfPower = t('search.wordsOfPower') + const hasWordsOfPower = value.trim().toLowerCase().startsWith(wordsOfPower.toLowerCase()) + const valueWithoutPrefix = hasWordsOfPower + ? value.trim().substring(wordsOfPower.length).trim() + : value.trim() const isTooShort = !!value && valueWithoutPrefix.length < textSearchMininumLength && !isValidBlockHeight(valueWithoutPrefix) + const hasPrivacyProblem = !hasWordsOfPower && isValidMnemonic(valueWithoutPrefix) + useEffect(() => { - setValue(valueInSearchParams) - }, [valueInSearchParams]) + setValue(hasWordsOfPower ? `${wordsOfPower} ${valueInSearchParams}` : valueInSearchParams) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [valueInSearchParams]) // We only want to update the value from code when the URL changes const onChange = (newValue: string) => { setValue(newValue) @@ -146,7 +154,13 @@ const SearchCmp: FC = ({ scope, variant, disabled, onFocusChange: o const searchButtonContent = variant !== 'button' ? : t('search.searchBtnText') - const hasError = isTooShort + const errorMessage = isTooShort + ? t('search.error.tooShort') + : hasPrivacyProblem + ? t('search.error.privacy', { appName: t('pageTitle'), wordsOfPower }) + : undefined + + const hasError = !!errorMessage return ( = ({ scope, variant, disabled, onFocusChange: o value && value !== valueInSearchParams && (
- {isTooShort && ( + {hasError && ( <> = ({ scope, variant, disabled, onFocusChange: o >   - {t('search.error.tooShort')} + {errorMessage}
diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 4ce7a708d..a333afaf9 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -375,7 +375,8 @@ "search": { "placeholder": "Address, Block, Contract, Txn Hash, Transaction ID, Token name, etc", "error": { - "tooShort": "Please enter either at least 3 characters or a number in order to perform a search." + "tooShort": "Please enter either at least 3 characters or a number in order to perform a search.", + "privacy": "It seems like you might accidentally entered a keyphrase for a wallet. Please note that your mnemonic is a secret key that should never be shared, even not with our {{ pagetitle }}.\nExecuting this search is highly unlikely to return any results. If you want to proceed nonetheless, please add “{{ wordsOfPower }}” in front of your search query to perform the search at your own risk." }, "mobilePlaceholder": "Search Address, Block, Txn, Token, etc", "noResults": { @@ -412,6 +413,7 @@ }, "searchBtnText": "Search", "searchSuggestions": "Not sure what to look for? Try out a search: Block, Transaction, Address, Token ", - "sectionHeader": "Results on {{ scope }}" + "sectionHeader": "Results on {{ scope }}", + "wordsOfPower": "I COMMAND THEE TO SEARCH FOR" } }