about summary refs log tree commit diff
path: root/src/lib/strings/url-helpers.ts
diff options
context:
space:
mode:
authorPaul Frazee <pfrazee@gmail.com>2023-10-02 14:47:39 -0700
committerGitHub <noreply@github.com>2023-10-02 14:47:39 -0700
commitfd5bbb27699942f7d741d074eafdf16bfc9ecdd6 (patch)
treea7e7e6f1e7b07fc45a4988504e2509db97689079 /src/lib/strings/url-helpers.ts
parent2f157c152a59dc8bda3d4409204d850c2ac256a1 (diff)
downloadvoidsky-fd5bbb27699942f7d741d074eafdf16bfc9ecdd6.tar.zst
Warn the user on links that dont match their text (#1573)
* Add link warning modal when URLs do not match their text

* Simplify the misleading link case for clarity

* Fix typecheck

* fix dark mode

* Give a stronger visual indication of the root domain in the link warning

* More rigorous URL mismatch logic

* Remove debug

---------

Co-authored-by: Ansh Nanda <anshnanda10@gmail.com>
Diffstat (limited to 'src/lib/strings/url-helpers.ts')
-rw-r--r--src/lib/strings/url-helpers.ts51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/lib/strings/url-helpers.ts b/src/lib/strings/url-helpers.ts
index 671dc9781..3c27d8639 100644
--- a/src/lib/strings/url-helpers.ts
+++ b/src/lib/strings/url-helpers.ts
@@ -1,6 +1,7 @@
 import {AtUri} from '@atproto/api'
 import {PROD_SERVICE} from 'state/index'
 import TLDs from 'tlds'
+import psl from 'psl'
 
 export function isValidDomain(str: string): boolean {
   return !!TLDs.find(tld => {
@@ -166,3 +167,53 @@ export function getYoutubeVideoId(link: string): string | undefined {
   }
   return videoId
 }
+
+export function linkRequiresWarning(uri: string, label: string) {
+  const labelDomain = labelToDomain(label)
+  if (!labelDomain) {
+    return true
+  }
+  try {
+    const urip = new URL(uri)
+    return labelDomain !== urip.hostname
+  } catch {
+    return true
+  }
+}
+
+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
+  } catch {}
+  try {
+    return new URL('https://' + label).hostname
+  } catch {}
+  return undefined
+}
+
+export function isPossiblyAUrl(str: string): boolean {
+  str = str.trim()
+  if (str.startsWith('http://')) {
+    return true
+  }
+  if (str.startsWith('https://')) {
+    return true
+  }
+  const [firstWord] = str.split(/[\s\/]/)
+  return isValidDomain(firstWord)
+}
+
+export function splitApexDomain(hostname: string): [string, string] {
+  const hostnamep = psl.parse(hostname)
+  if (hostnamep.error || !hostnamep.listed || !hostnamep.domain) {
+    return ['', hostname]
+  }
+  return [
+    hostnamep.subdomain ? `${hostnamep.subdomain}.` : '',
+    hostnamep.domain,
+  ]
+}