Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update network punycode warning, isValidASCIIURL, and toPunycodeURL logic #29490

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,10 @@ function getValues(pendingApproval, t, actions, history, data) {
[t('blockExplorerUrl')]: t('blockExplorerUrlDefinition'),
},
warnings: {
[t('networkURL')]: isValidASCIIURL(customRpcUrl)
? undefined
: t('networkUrlErrorWarning', [toPunycodeURL(customRpcUrl)]),
[t('networkURL')]:
!customRpcUrl || isValidASCIIURL(customRpcUrl)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: isValidASCIIURL takes care of scenario when customRpcUrl is not defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't want to show the error if there is no URL passed so we need to check !customRpcUrl here

? undefined
: t('networkUrlErrorWarning', [toPunycodeURL(customRpcUrl)]),
[t('currencySymbol')]: data.currencySymbolWarning,
},
dictionary: {
Expand Down
26 changes: 24 additions & 2 deletions ui/pages/confirmations/utils/confirm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,34 @@ describe('confirm util', () => {
});

describe('isValidASCIIURL', () => {
it('returns true for URL containing only ASCII characters', () => {
it('returns true for URL containing only ASCII characters in its hostname', () => {
expect(isValidASCIIURL('https://www.google.com')).toEqual(true);
});

it('returns false for URL containing special character', () => {
it('returns true for URL with both its hostname and path containing ASCII characters', () => {
expect(
isValidASCIIURL('https://infura.io/gnosis?x=xn--ifura-dig.io'),
).toStrictEqual(true);
});

it('returns true for URL with its hostname containing ASCII characters and its path containing non-ASCII characters', () => {
expect(
isValidASCIIURL('https://infura.io/gnosis?x=iոfura.io'),
).toStrictEqual(true);
expect(
isValidASCIIURL('infura.io:7777/gnosis?x=iոfura.io'),
).toStrictEqual(true);
});

it('returns false for URL with its hostname containing non-ASCII characters', () => {
expect(isValidASCIIURL('https://iոfura.io/gnosis')).toStrictEqual(false);
expect(isValidASCIIURL('iոfura.io:7777/gnosis?x=test')).toStrictEqual(
false,
);
});

it('returns false for empty string', () => {
expect(isValidASCIIURL('')).toStrictEqual(false);
});
});

Expand Down
30 changes: 22 additions & 8 deletions ui/pages/confirmations/utils/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,37 @@ export const isPermitSignatureRequest = (request?: Confirmation) => {
return PRIMARY_TYPES_PERMIT.includes(primaryType);
};

export const isValidASCIIURL = (urlString?: string) => {
/**
* @param urlString - The URL to check
* @returns True if the URL hostname contains only ASCII characters, false otherwise. The URL is still valid if the path contains non-ASCII characters.
*/
export const isValidASCIIURL = (urlString?: string): boolean => {
try {
return urlString?.includes(new URL(urlString).host);
if (!urlString || urlString.length === 0) {
return false;
}

return urlString.includes(new URL(urlString).host);
} catch (exp: unknown) {
console.error(exp);
console.error(
`Failed to detect if URL hostname contains non-ASCII characters: ${urlString}. Error: ${exp}`,
);
return false;
}
};

export const toPunycodeURL = (urlString: string) => {
/**
* Converts the URL to Punycode
*
* @param urlString - The URL to convert
* @returns The Punycode URL
*/
export const toPunycodeURL = (urlString: string): string | undefined => {
try {
const url = new URL(urlString);
const { protocol, hostname, port, search, hash } = url;
const pathname =
url.pathname === '/' && !urlString.endsWith('/') ? '' : url.pathname;
const isWithoutEndSlash = url.pathname === '/' && !urlString.endsWith('/');

return `${protocol}//${hostname}${port}${pathname}${search}${hash}`;
return isWithoutEndSlash ? url.href.slice(0, -1) : url.href;
} catch (err: unknown) {
console.error(`Failed to convert URL to Punycode: ${err}`);
return undefined;
Expand Down
Loading