Skip to content

Commit

Permalink
Update trusted hosts, allow #, and add more tests (#3232)
Browse files Browse the repository at this point in the history
* Update trusted hosts, allow `#`, and add more tests

* update comments
  • Loading branch information
haileyok authored Mar 19, 2024
1 parent 5b4b8e4 commit 5e0a6a1
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 12 deletions.
38 changes: 38 additions & 0 deletions __tests__/lib/strings/url-helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
linkRequiresWarning,
isPossiblyAUrl,
splitApexDomain,
isTrustedUrl,
} from '../../../src/lib/strings/url-helpers'

describe('linkRequiresWarning', () => {
Expand Down Expand Up @@ -74,6 +75,10 @@ describe('linkRequiresWarning', () => {
// bad uri inputs, default to true
['', '', true],
['example.com', 'example.com', true],
['/profile', 'Username', false],
['#', 'Show More', false],
['https://docs.bsky.app', 'https://docs.bsky.app', false],
['https://bsky.app/compose/intent?text=test', 'Compose a post', false],
]

it.each(cases)(
Expand Down Expand Up @@ -139,3 +144,36 @@ describe('splitApexDomain', () => {
},
)
})

describe('isTrustedUrl', () => {
const cases = [
['#', true],
['#profile', true],
['/', true],
['/profile', true],
['/profile/', true],
['/profile/bob.test', true],
['https://bsky.app', true],
['https://bsky.app/', true],
['https://bsky.app/profile/bob.test', true],
['https://www.bsky.app', true],
['https://www.bsky.app/', true],
['https://docs.bsky.app', true],
['https://bsky.social', true],
['https://bsky.social/blog', true],
['https://blueskyweb.xyz', true],
['https://blueskyweb.zendesk.com', true],
['http://bsky.app', true],
['http://bsky.social', true],
['http://blueskyweb.xyz', true],
['http://blueskyweb.zendesk.com', true],
['https://google.com', false],
['https://docs.google.com', false],
['https://google.com/#', false],
]

it.each(cases)('given input uri %p, returns %p', (str, expected) => {
const output = isTrustedUrl(str)
expect(output).toEqual(expected)
})
})
38 changes: 26 additions & 12 deletions src/lib/strings/url-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ import TLDs from 'tlds'
import psl from 'psl'

export const BSKY_APP_HOST = 'https://bsky.app'
const BSKY_TRUSTED_HOSTS = [
'bsky.app',
'bsky.social',
'blueskyweb.xyz',
'blueskyweb.zendesk.com',
...(__DEV__ ? ['localhost:19006', 'localhost:8100'] : []),
]

/*
* This will allow any BSKY_TRUSTED_HOSTS value by itself or with a subdomain.
* It will also allow relative paths like /profile as well as #.
*/
const TRUSTED_REGEX = new RegExp(
`^(http(s)?://(([\\w-]+\\.)?${BSKY_TRUSTED_HOSTS.join(
'|([\\w-]+\\.)?',
)})|/|#)`,
)

export function isValidDomain(str: string): boolean {
return !!TLDs.find(tld => {
Expand Down Expand Up @@ -86,6 +103,10 @@ export function isExternalUrl(url: string): boolean {
return external || rss
}

export function isTrustedUrl(url: string): boolean {
return TRUSTED_REGEX.test(url)
}

export function isBskyPostUrl(url: string): boolean {
if (isBskyAppUrl(url)) {
try {
Expand Down Expand Up @@ -163,8 +184,8 @@ export function feedUriToHref(url: string): string {
export function linkRequiresWarning(uri: string, label: string) {
const labelDomain = labelToDomain(label)

// If the uri started with a / we know it is internal.
if (isRelativeUrl(uri)) {
// We should trust any relative URL or a # since we know it links to internal content
if (isRelativeUrl(uri) || uri === '#') {
return false
}

Expand All @@ -176,18 +197,11 @@ export function linkRequiresWarning(uri: string, label: string) {
}

const host = urip.hostname.toLowerCase()
// Hosts that end with bsky.app or bsky.social should be trusted by default.
if (
host.endsWith('bsky.app') ||
host.endsWith('bsky.social') ||
host.endsWith('blueskyweb.xyz')
) {
// if this is a link to internal content,
// warn if it represents itself as a URL to another app
if (isTrustedUrl(uri)) {
// if this is a link to internal content, warn if it represents itself as a URL to another app
return !!labelDomain && labelDomain !== host && isPossiblyAUrl(labelDomain)
} else {
// if this is a link to external content,
// warn if the label doesnt match the target
// if this is a link to external content, warn if the label doesnt match the target
if (!labelDomain) {
return true
}
Expand Down

0 comments on commit 5e0a6a1

Please sign in to comment.