Skip to content

Commit

Permalink
fix(settings): fixed two IPFS gateway issues
Browse files Browse the repository at this point in the history
- adds back in two bugfixes that were originally in #19283
  - fixes #16871
  - fixes #18140

- achieves 100% code coverage for /ui/pages/settings/security-tab
- removes the npm package `valid-url`, which has not been updated in 10 years
  • Loading branch information
HowardBraham committed Jul 31, 2023
1 parent 3b0d37c commit 3484147
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 126 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { ethErrors, errorCodes } from 'eth-rpc-errors';
import validUrl from 'valid-url';
import { omit } from 'lodash';
import { ApprovalType } from '@metamask/controller-utils';
import {
Expand All @@ -11,6 +10,7 @@ import {
isSafeChainId,
} from '../../../../../shared/modules/network.utils';
import { MetaMetricsNetworkEventSource } from '../../../../../shared/constants/metametrics';
import { isLocalhostOrHttps } from '../../util';

const addEthereumChain = {
methodNames: [MESSAGE_TYPE.ADD_ETHEREUM_CHAIN],
Expand Down Expand Up @@ -83,27 +83,14 @@ async function addEthereumChainHandler(
);
}

const isLocalhost = (strUrl) => {
try {
const url = new URL(strUrl);
return url.hostname === 'localhost' || url.hostname === '127.0.0.1';
} catch (error) {
return false;
}
};

const firstValidRPCUrl = Array.isArray(rpcUrls)
? rpcUrls.find(
(rpcUrl) => isLocalhost(rpcUrl) || validUrl.isHttpsUri(rpcUrl),
)
? rpcUrls.find((rpcUrl) => isLocalhostOrHttps(rpcUrl))
: null;

const firstValidBlockExplorerUrl =
blockExplorerUrls !== null && Array.isArray(blockExplorerUrls)
? blockExplorerUrls.find(
(blockExplorerUrl) =>
isLocalhost(blockExplorerUrl) ||
validUrl.isHttpsUri(blockExplorerUrl),
? blockExplorerUrls.find((blockExplorerUrl) =>
isLocalhostOrHttps(blockExplorerUrl),
)
: null;

Expand Down
76 changes: 59 additions & 17 deletions app/scripts/lib/util.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { AccessList } from '@ethereumjs/tx';
import BN from 'bn.js';
import { memoize } from 'lodash';
import { AccessList } from '@ethereumjs/tx';
import { CHAIN_IDS, TEST_CHAINS } from '../../../shared/constants/network';

import {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_BACKGROUND,
PLATFORM_FIREFOX,
PLATFORM_OPERA,
ENVIRONMENT_TYPE_FULLSCREEN,
ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP,
PLATFORM_BRAVE,
PLATFORM_CHROME,
PLATFORM_EDGE,
PLATFORM_BRAVE,
PLATFORM_FIREFOX,
PLATFORM_OPERA,
} from '../../../shared/constants/app';
import { stripHexPrefix } from '../../../shared/modules/hexstring-utils';
import { CHAIN_IDS, TEST_CHAINS } from '../../../shared/constants/network';
import {
TransactionEnvelopeType,
TransactionMeta,
} from '../../../shared/constants/transaction';
import { stripHexPrefix } from '../../../shared/modules/hexstring-utils';

/**
* @see {@link getEnvironmentType}
Expand Down Expand Up @@ -143,13 +142,13 @@ function checkAlarmExists(alarmList: { name: string }[], alarmName: string) {
}

export {
getPlatform,
getEnvironmentType,
hexToBn,
BnMultiplyByFraction,
addHexPrefix,
getChainType,
checkAlarmExists,
getChainType,
getEnvironmentType,
getPlatform,
hexToBn,
};

// Taken from https://stackoverflow.com/a/1349426/3696652
Expand Down Expand Up @@ -235,10 +234,53 @@ export function previousValueComparator<A>(
}

export function addUrlProtocolPrefix(urlString: string) {
if (!urlString.match(/(^http:\/\/)|(^https:\/\/)/u)) {
return `https://${urlString}`;
let trimmed = urlString.trim();

if (trimmed.length > 0 && !trimmed.match(/(^http:\/\/)|(^https:\/\/)/u)) {
trimmed = `https://${trimmed}`;
}

if (isValidUrl(trimmed)) {
return trimmed;
}

return null;
}

export function isLocalhostOrHttps(urlString: string) {
try {
const url = new URL(urlString);
return (
url.hostname === 'localhost' ||
url.hostname === '127.0.0.1' ||
url.protocol === 'https:'
);
} catch (error) {
return false;
}
}

export function isValidUrl(urlString: string): boolean {
try {
const url = new URL(urlString);

return url.hostname.length > 0 && url.pathname.length > 0;
} catch (error) {
return false;
}
}

export function isWebUrl(urlString: string): boolean {
try {
const url = new URL(urlString);
return (
url.hostname.length > 0 &&
(url.protocol === 'https:' || url.protocol === 'http:') &&
url.pathname.length > 0
);
} catch (error) {
return false;
}
return urlString;
}

interface FormattedTransactionMeta {
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,6 @@
"single-call-balance-checker-abi": "^1.0.0",
"unicode-confusables": "^0.1.1",
"uuid": "^8.3.2",
"valid-url": "^1.0.9",
"web3-stream-provider": "^4.0.0",
"zxcvbn": "^4.4.2"
},
Expand Down
2 changes: 1 addition & 1 deletion ui/pages/keychains/reveal-seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const RevealSeedPage = () => {

const renderPasswordPromptContent = () => {
return (
<form onSubmit={(event) => handleSubmit(event)}>
<form onSubmit={handleSubmit}>
<Label htmlFor="password-box">{t('enterPasswordContinue')}</Label>
<TextField
inputProps={{
Expand Down
93 changes: 40 additions & 53 deletions ui/pages/settings/networks-tab/networks-form/networks-form.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import classnames from 'classnames';
import { isEqual } from 'lodash';
import log from 'loglevel';
import PropTypes from 'prop-types';
import React, {
useCallback,
useContext,
Expand All @@ -6,12 +10,18 @@ import React, {
useState,
} from 'react';
import { useDispatch } from 'react-redux';
import PropTypes from 'prop-types';
import validUrl from 'valid-url';
import log from 'loglevel';
import classnames from 'classnames';
import { isEqual } from 'lodash';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import { isWebUrl } from '../../../../../app/scripts/lib/util';
import {
MetaMetricsEventCategory,
MetaMetricsEventName,
MetaMetricsNetworkEventSource,
} from '../../../../../shared/constants/metametrics';
import {
FEATURED_RPCS,
infuraProjectId,
} from '../../../../../shared/constants/network';
import fetchWithCache from '../../../../../shared/lib/fetch-with-cache';
import { decimalToHex } from '../../../../../shared/modules/conversion.utils';
import {
isPrefixedFormattedHexString,
isSafeChainId,
Expand All @@ -20,27 +30,17 @@ import { jsonRpcRequest } from '../../../../../shared/modules/rpc.utils';
import ActionableMessage from '../../../../components/ui/actionable-message';
import Button from '../../../../components/ui/button';
import FormField from '../../../../components/ui/form-field';
import { MetaMetricsContext } from '../../../../contexts/metametrics';
import { getNetworkLabelKey } from '../../../../helpers/utils/i18n-helper';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import { usePrevious } from '../../../../hooks/usePrevious';
import {
setSelectedNetworkConfigurationId,
upsertNetworkConfiguration,
editAndSetNetworkConfiguration,
showModal,
setNewNetworkAdded,
setSelectedNetworkConfigurationId,
showModal,
upsertNetworkConfiguration,
} from '../../../../store/actions';
import fetchWithCache from '../../../../../shared/lib/fetch-with-cache';
import { usePrevious } from '../../../../hooks/usePrevious';
import {
MetaMetricsEventCategory,
MetaMetricsEventName,
MetaMetricsNetworkEventSource,
} from '../../../../../shared/constants/metametrics';
import {
infuraProjectId,
FEATURED_RPCS,
} from '../../../../../shared/constants/network';
import { decimalToHex } from '../../../../../shared/modules/conversion.utils';
import { MetaMetricsContext } from '../../../../contexts/metametrics';
import { getNetworkLabelKey } from '../../../../helpers/utils/i18n-helper';

/**
* Attempts to convert the given chainId to a decimal string, for display
Expand Down Expand Up @@ -74,11 +74,6 @@ const prefixChainId = (chainId) => {
return prefixedChainId;
};

const isValidWhenAppended = (url) => {
const appendedRpc = `http://${url}`;
return validUrl.isWebUri(appendedRpc) && !url.match(/^https?:\/\/$/u);
};

const NetworksForm = ({
addNewNetwork,
restrictHeight,
Expand Down Expand Up @@ -208,23 +203,20 @@ const NetworksForm = ({

const validateBlockExplorerURL = useCallback(
(url) => {
if (!validUrl.isWebUri(url) && url !== '') {
let errorKey;
let errorMessage;

if (isValidWhenAppended(url)) {
errorKey = 'urlErrorMsg';
errorMessage = t('urlErrorMsg');
} else {
errorKey = 'invalidBlockExplorerURL';
errorMessage = t('invalidBlockExplorerURL');
if (url.length > 0 && !isWebUrl(url)) {
if (isWebUrl(`https://${url}`)) {
return {
key: 'urlErrorMsg',
msg: t('urlErrorMsg'),
};
}

return {
key: errorKey,
msg: errorMessage,
key: 'invalidBlockExplorerURL',
msg: t('invalidBlockExplorerURL'),
};
}

return null;
},
[t],
Expand Down Expand Up @@ -407,7 +399,6 @@ const NetworksForm = ({

const validateRPCUrl = useCallback(
(url) => {
const isValidUrl = validUrl.isWebUri(url);
const [
{
rpcUrl: matchingRPCUrl = null,
Expand All @@ -417,20 +408,16 @@ const NetworksForm = ({
] = networksToRender.filter((e) => e.rpcUrl === url);
const { rpcUrl: selectedNetworkRpcUrl } = selectedNetwork;

if (!isValidUrl && url !== '') {
let errorKey;
let errorMessage;
if (isValidWhenAppended(url)) {
errorKey = 'urlErrorMsg';
errorMessage = t('urlErrorMsg');
} else {
errorKey = 'invalidRPC';
errorMessage = t('invalidRPC');
if (url.length > 0 && !isWebUrl(url)) {
if (isWebUrl(`https://${url}`)) {
return {
key: 'urlErrorMsg',
msg: t('urlErrorMsg'),
};
}

return {
key: errorKey,
msg: errorMessage,
key: 'invalidRPC',
msg: t('invalidRPC'),
};
} else if (matchingRPCUrl && matchingRPCUrl !== selectedNetworkRpcUrl) {
return {
Expand Down
Loading

0 comments on commit 3484147

Please sign in to comment.