@@ -6,13 +6,27 @@ import {BSKY_SERVICE} from '#/lib/constants'
66import { isInvalidHandle } from '#/lib/strings/handles'
77import { startUriToStarterPackUri } from '#/lib/strings/starter-pack'
88import { logger } from '#/logger'
9+ import { EUROSKY } from '#/config/eurosky'
910
1011export const BSKY_APP_HOST = 'https://bsky.app'
12+
13+ /**
14+ * Hostnames whose web URLs we treat as first-party app links. Pasting one of
15+ * these into the composer or a DM resolves it to an in-app record embed (quote
16+ * post, feed, list, starter pack) instead of a plain external link card.
17+ * Upstream only knows about bsky.app; the fork adds its own web host(s) via
18+ * EUROSKY.web.hosts. See isBskyAppUrl().
19+ */
20+ const APP_URL_HOSTS = [ 'bsky.app' , ...EUROSKY . web . hosts ]
21+
1122const BSKY_TRUSTED_HOSTS = [
1223 'bsky\\.app' ,
1324 'bsky\\.social' ,
1425 'blueskyweb\\.xyz' ,
1526 'blueskyweb\\.zendesk\\.com' ,
27+ // Fork web host(s) are first-party too, so links to them are not treated as
28+ // untrusted/external (e.g. no phishing warning interstitial).
29+ ...EUROSKY . web . hosts . map ( host => host . replace ( / \. / g, '\\.' ) ) ,
1630 ...( __DEV__ ? [ 'localhost:19006' , 'localhost:8100' ] : [ ] ) ,
1731]
1832
@@ -121,18 +135,22 @@ export function toBskyAppUrl(url: string): string {
121135}
122136
123137export function isBskyAppUrl ( url : string ) : boolean {
124- return url . startsWith ( 'https://bsky.app/' )
138+ // Match by parsed hostname rather than a string prefix so that fork hosts are
139+ // supported and look-alike hosts (e.g. https://bsky.app.evil.com/) are not.
140+ try {
141+ const urlp = new URL ( url )
142+ return urlp . protocol === 'https:' && APP_URL_HOSTS . includes ( urlp . hostname )
143+ } catch {
144+ return false
145+ }
125146}
126147
127148export function isRelativeUrl ( url : string ) : boolean {
128149 return / ^ \/ [ ^ / ] / . test ( url )
129150}
130151
131152export function isBskyRSSUrl ( url : string ) : boolean {
132- return (
133- ( url . startsWith ( 'https://bsky.app/' ) || isRelativeUrl ( url ) ) &&
134- / \/ r s s \/ ? $ / . test ( url )
135- )
153+ return ( isBskyAppUrl ( url ) || isRelativeUrl ( url ) ) && / \/ r s s \/ ? $ / . test ( url )
136154}
137155
138156export function isExternalUrl ( url : string ) : boolean {
0 commit comments