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

fix: allow external link with url: /pathname #2299

Merged
merged 7 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/components/Header/web3/WalletModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
useWalletModalToggle,
} from 'state/application/hooks'
import { useIsConnectingWallet } from 'state/authen/hooks'
import { ExternalLink } from 'theme'
import { isEVMWallet, isOverriddenWallet, isSolanaWallet } from 'utils'

import Option from './Option'
Expand Down Expand Up @@ -316,13 +317,13 @@ export default function WalletModal() {
<Text color={theme.subText}>
<Trans>
By connecting a wallet, you accept{' '}
<a href={TERM_FILES_PATH.KYBERSWAP_TERMS} onClick={e => e.stopPropagation()}>
<ExternalLink href={TERM_FILES_PATH.KYBERSWAP_TERMS} onClick={e => e.stopPropagation()}>
KyberSwap&lsquo;s Terms of Use
</a>{' '}
</ExternalLink>{' '}
and consent to its{' '}
<a href={TERM_FILES_PATH.PRIVACY_POLICY} onClick={e => e.stopPropagation()}>
<ExternalLink href={TERM_FILES_PATH.PRIVACY_POLICY} onClick={e => e.stopPropagation()}>
Privacy Policy
</a>
</ExternalLink>
. Last updated: {dayjs(TERM_FILES_PATH.VERSION).format('DD MMM YYYY')}
</Trans>
</Text>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ export default function Menu() {
)}

<MenuItem>
<a
<ExternalLink
href={TERM_FILES_PATH.KYBERSWAP_TERMS}
onClick={() => {
toggle()
Expand All @@ -482,10 +482,10 @@ export default function Menu() {
>
<FileText />
<Trans>Terms</Trans>
</a>
</ExternalLink>
</MenuItem>
<MenuItem>
<a
<ExternalLink
href={TERM_FILES_PATH.PRIVACY_POLICY}
onClick={() => {
toggle()
Expand All @@ -494,7 +494,7 @@ export default function Menu() {
>
<FileText />
<Trans>Privacy Policy</Trans>
</a>
</ExternalLink>
</MenuItem>
<MenuItem>
<ExternalLink
Expand Down
13 changes: 7 additions & 6 deletions src/pages/KyberDAO/KNCUtility/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ export default function KNCUtility() {
<Text fontSize={14} fontWeight={400} lineHeight="20px">
<Trans>
These Terms and Conditions should be read in conjunction with the KyberSwap{' '}
<a href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</a>, which lay out the terms and conditions
that apply to all KyberSwap activities.
<ExternalLink href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</ExternalLink>, which lay out
the terms and conditions that apply to all KyberSwap activities.
</Trans>
</Text>
</li>
Expand All @@ -290,7 +290,7 @@ export default function KNCUtility() {
<Trans>
By visiting KyberSwap and participating in the program, the User is deemed to have read,
understood, and agreed to these Terms and Conditions and the KyberSwap{' '}
<a href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</a>.
<ExternalLink href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</ExternalLink>.
</Trans>
</Text>
</li>
Expand All @@ -308,9 +308,10 @@ export default function KNCUtility() {
<Text fontSize={14} fontWeight={400} lineHeight="20px">
<Trans>
KyberSwap maintains the right, at its sole discretion, to take action or remove rewards against
the User who violates the KyberSwap <a href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</a>{' '}
and/or violates, cheats, or exploits the program, including but not limited to, any suspicious
activities, or any attempts to circumvent these Terms and Conditions.
the User who violates the KyberSwap{' '}
<ExternalLink href={TERM_FILES_PATH.KYBERSWAP_TERMS}>Terms of Use</ExternalLink> and/or violates,
cheats, or exploits the program, including but not limited to, any suspicious activities, or any
attempts to circumvent these Terms and Conditions.
</Trans>
</Text>
</li>
Expand Down
35 changes: 18 additions & 17 deletions src/pages/SwapV3/Tabs/LimitTab.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Trans } from '@lingui/macro'
import { rgba } from 'polished'
import { useLocation } from 'react-router-dom'
import { Text } from 'rebass'
import { useGetNumberOfInsufficientFundOrdersQuery } from 'services/limitOrder'
import styled from 'styled-components'

Expand Down Expand Up @@ -45,22 +44,24 @@ export default function LimitTab({ onClick }: Props) {
}

return (
<Tab id="limit-button" data-testid="limit-button" onClick={onClick} isActive={isLimitPage}>
<Text fontSize={20} fontWeight={500}>
<Trans>Limit</Trans>{' '}
{numberOfInsufficientFundOrders ? (
<MouseoverTooltip
placement="top"
text={
<Trans>
You have {numberOfInsufficientFundOrders} active orders that don&apos;t have sufficient funds
</Trans>
}
>
<WarningBadge>{numberOfInsufficientFundOrders}</WarningBadge>
</MouseoverTooltip>
) : null}
</Text>
<Tab
id="limit-button"
data-testid="limit-button"
onClick={onClick}
isActive={isLimitPage}
style={{ display: 'flex', gap: '4px', fontSize: '20px', fontWeight: '500' }}
>
<Trans>Limit</Trans>{' '}
{!!numberOfInsufficientFundOrders && (
<MouseoverTooltip
placement="top"
text={
<Trans>You have {numberOfInsufficientFundOrders} active orders that don&apos;t have sufficient funds</Trans>
}
>
<WarningBadge>{numberOfInsufficientFundOrders}</WarningBadge>
</MouseoverTooltip>
)}
</Tab>
)
}
20 changes: 16 additions & 4 deletions src/theme/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export function ExternalLink({
}: Omit<HTMLProps<HTMLAnchorElement>, 'as' | 'ref'> & { href: string }) {
const handleClick = useCallback(
(event: React.MouseEvent<HTMLAnchorElement>) => {
onClick && onClick(event)
onClick?.(event)
// don't prevent default, don't redirect if it's a new tab
if (target === '_blank' || event.ctrlKey || event.metaKey) {
} else {
Expand All @@ -203,7 +203,13 @@ export function ExternalLink({
[target, onClick],
)
return (
<StyledLink target={target} rel={rel} href={validateRedirectURL(href, false)} onClick={handleClick} {...rest} />
<StyledLink
target={target}
rel={rel}
href={validateRedirectURL(href, { _dangerousSkipCheckWhitelist: true, allowRelativePath: true })}
onClick={handleClick}
{...rest}
/>
)
}

Expand All @@ -221,13 +227,19 @@ export function ExternalLinkIcon({
console.debug('Fired outbound link event', href)
} else {
event.preventDefault()
navigateToUrl(href, false)
navigateToUrl(href, { _dangerousSkipCheckWhitelist: true, allowRelativePath: true })
}
},
[href, target],
)
return (
<LinkIconWrapper target={target} rel={rel} href={validateRedirectURL(href, false)} onClick={handleClick} {...rest}>
<LinkIconWrapper
target={target}
rel={rel}
href={validateRedirectURL(href, { _dangerousSkipCheckWhitelist: true, allowRelativePath: true })}
onClick={handleClick}
{...rest}
>
<LinkIcon color={color} />
</LinkIconWrapper>
)
Expand Down
20 changes: 12 additions & 8 deletions src/utils/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import { useActiveWeb3React } from 'hooks'
import { useChangeNetwork } from 'hooks/web3/useChangeNetwork'

const whiteListDomains = [/https:\/\/(.+?\.)?kyberswap\.com$/, /https:\/\/(.+)\.kyberengineering\.io$/]
export const validateRedirectURL = (url: string | undefined, whitelistKyberSwap = true) => {

type Options = { _dangerousSkipCheckWhitelist?: boolean; allowRelativePath?: boolean }
export const validateRedirectURL = (
url: string | undefined,
{ _dangerousSkipCheckWhitelist = false, allowRelativePath = false }: Options = {},
) => {
try {
if (!url) throw new Error()
const newUrl = new URL(url) // valid url
if (!url || url.endsWith('.js')) throw new Error()
const newUrl = allowRelativePath && url.startsWith('/') ? new URL(`${window.location.origin}${url}`) : new URL(url)
if (
url.endsWith('.js') ||
newUrl.pathname.endsWith('.js') ||
!['https:', 'http:'].includes(newUrl.protocol) ||
(whitelistKyberSwap && !whiteListDomains.some(regex => newUrl.origin.match(regex)))
(!_dangerousSkipCheckWhitelist && !whiteListDomains.some(regex => newUrl.origin.match(regex)))
) {
throw new Error()
}
Expand All @@ -24,8 +28,8 @@ export const validateRedirectURL = (url: string | undefined, whitelistKyberSwap
}
}

export const navigateToUrl = (url: string | undefined, whitelistKyberSwap = true) => {
const urlFormatted = validateRedirectURL(url, whitelistKyberSwap)
export const navigateToUrl = (url: string | undefined, options?: Options) => {
const urlFormatted = validateRedirectURL(url, options)
if (urlFormatted) window.location.href = urlFormatted
}

Expand All @@ -46,7 +50,7 @@ export const useNavigateToUrl = () => {
return
}
const { pathname, host, search } = new URL(actionURL)
if (!validateRedirectURL(actionURL, false)) return
if (!validateRedirectURL(actionURL, { _dangerousSkipCheckWhitelist: true })) return
if (window.location.host === host) {
navigate(`${pathname}${search}`)
} else {
Expand Down
Loading