Fixes 1731, compare URLs case-insensitive (#1980)
parent
ec819f06ce
commit
edf3114e47
|
@ -1,3 +1,5 @@
|
|||
import {it, describe, expect} from '@jest/globals'
|
||||
|
||||
import {
|
||||
linkRequiresWarning,
|
||||
isPossiblyAUrl,
|
||||
|
@ -6,6 +8,7 @@ import {
|
|||
|
||||
describe('linkRequiresWarning', () => {
|
||||
type Case = [string, string, boolean]
|
||||
|
||||
const cases: Case[] = [
|
||||
['http://example.com', 'http://example.com', false],
|
||||
['http://example.com', 'example.com', false],
|
||||
|
@ -64,6 +67,10 @@ describe('linkRequiresWarning', () => {
|
|||
['http://bsky.app/', 'https://google.com', true],
|
||||
['https://bsky.app/', 'https://google.com', true],
|
||||
|
||||
// case insensitive
|
||||
['https://Example.com', 'example.com', false],
|
||||
['https://example.com', 'Example.com', false],
|
||||
|
||||
// bad uri inputs, default to true
|
||||
['', '', true],
|
||||
['example.com', 'example.com', true],
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
import {configure} from '@testing-library/react-native'
|
||||
import 'react-native-gesture-handler/jestSetup'
|
||||
|
||||
// IMPORTANT: this is what's used in the native runtime
|
||||
import 'react-native-url-polyfill/auto'
|
||||
|
||||
configure({asyncUtilTimeout: 20000})
|
||||
|
||||
jest.mock('@react-native-async-storage/async-storage', () =>
|
||||
|
|
|
@ -168,8 +168,15 @@ export function getYoutubeVideoId(link: string): string | undefined {
|
|||
return videoId
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the label in the post text matches the host of the link facet.
|
||||
*
|
||||
* Hosts are case-insensitive, so should be lowercase for comparison.
|
||||
* @see https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2
|
||||
*/
|
||||
export function linkRequiresWarning(uri: string, label: string) {
|
||||
const labelDomain = labelToDomain(label)
|
||||
|
||||
let urip
|
||||
try {
|
||||
urip = new URL(uri)
|
||||
|
@ -177,7 +184,9 @@ export function linkRequiresWarning(uri: string, label: string) {
|
|||
return true
|
||||
}
|
||||
|
||||
if (urip.hostname === 'bsky.app') {
|
||||
const host = urip.hostname.toLowerCase()
|
||||
|
||||
if (host === 'bsky.app') {
|
||||
// if this is a link to internal content,
|
||||
// warn if it represents itself as a URL to another app
|
||||
if (
|
||||
|
@ -194,20 +203,26 @@ export function linkRequiresWarning(uri: string, label: string) {
|
|||
if (!labelDomain) {
|
||||
return true
|
||||
}
|
||||
return labelDomain !== urip.hostname
|
||||
return labelDomain !== host
|
||||
}
|
||||
}
|
||||
|
||||
function labelToDomain(label: string): string | undefined {
|
||||
/**
|
||||
* Returns a lowercase domain hostname if the label is a valid URL.
|
||||
*
|
||||
* Hosts are case-insensitive, so should be lowercase for comparison.
|
||||
* @see https://www.rfc-editor.org/rfc/rfc3986#section-3.2.2
|
||||
*/
|
||||
export function labelToDomain(label: string): string | undefined {
|
||||
// any spaces just immediately consider the label a non-url
|
||||
if (/\s/.test(label)) {
|
||||
return undefined
|
||||
}
|
||||
try {
|
||||
return new URL(label).hostname
|
||||
return new URL(label).hostname.toLowerCase()
|
||||
} catch {}
|
||||
try {
|
||||
return new URL('https://' + label).hostname
|
||||
return new URL('https://' + label).hostname.toLowerCase()
|
||||
} catch {}
|
||||
return undefined
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue