Skip to content

Commit 2725842

Browse files
committed
quote posts etc with our domain
1 parent 5cadbe4 commit 2725842

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

src/config/eurosky.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,17 @@ export const EUROSKY = {
1919
/** Display name used in page/tab titles and in-app brand text. */
2020
name: 'Eurosky',
2121
},
22+
web: {
23+
/**
24+
* Web hostnames this app serves its own UI on. A link pasted to one of
25+
* these hosts (in the composer or a DM) is detected as a first-party
26+
* record - quote post, feed, list, or starter pack - and rendered as a
27+
* rich embed, exactly like a bsky.app link, instead of a plain link card.
28+
*
29+
* Bare hostnames only: no scheme, no trailing slash, no subdomain wildcard
30+
* (matching is exact). bsky.app is always treated as first-party in
31+
* addition to these.
32+
*/
33+
hosts: ['mu.social'],
34+
},
2235
} as const

src/lib/strings/url-helpers.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,27 @@ import {BSKY_SERVICE} from '#/lib/constants'
66
import {isInvalidHandle} from '#/lib/strings/handles'
77
import {startUriToStarterPackUri} from '#/lib/strings/starter-pack'
88
import {logger} from '#/logger'
9+
import {EUROSKY} from '#/config/eurosky'
910

1011
export 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+
1122
const 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

123137
export 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

127148
export function isRelativeUrl(url: string): boolean {
128149
return /^\/[^/]/.test(url)
129150
}
130151

131152
export function isBskyRSSUrl(url: string): boolean {
132-
return (
133-
(url.startsWith('https://bsky.app/') || isRelativeUrl(url)) &&
134-
/\/rss\/?$/.test(url)
135-
)
153+
return (isBskyAppUrl(url) || isRelativeUrl(url)) && /\/rss\/?$/.test(url)
136154
}
137155

138156
export function isExternalUrl(url: string): boolean {

0 commit comments

Comments
 (0)