Telegram bug #654272: opening the connection app link (immediate-open / connect button)
showed a full-page net::ERR_UNKNOWN_URL_SCHEME on Android and silently failed on iOS, while
working on desktop.
Cause: a programmatic top-level navigation to a custom scheme (happ://, v2rayng://, …) via
window.location.href is rendered as a full-page error inside in-app WebViews (Telegram/Yandex)
on Android and does nothing on iOS — also wiping the fallback UI.
Add openAppScheme(): http(s) navigate normally; custom schemes launch via a hidden, contained
iframe so a failed launch never replaces the page — the app opens if installed, otherwise the
manual 'Open app' link stays usable (a user tap is the reliable trigger). Applied in
DeepLinkRedirect.tsx, Connection.tsx and the static public/miniapp/redirect.html (which now
also surfaces the manual button immediately instead of after 2s).
public/miniapp/redirect.html read the `url` query param and assigned it to both
the manual <a href> and window.location.href with no validation. Served on the
cabinet's own origin, this was an open redirect (phishing) and — in Telegram /
WebView contexts that execute javascript: URIs in top-level navigation — a
DOM-XSS able to exfiltrate the refresh_token from localStorage (account takeover).
Add isSafeAppLink(): only a custom app deep link passes (scheme://, excluding
http/https/file/blob/about/intent/content and the javascript/data/vbscript
script schemes); anything else renders the no-URL state instead of navigating or
setting href. Mirrors the validation already in src/pages/DeepLinkRedirect.tsx.
Windows ships no glyphs for regional-indicator flag emoji, so flags fell back to country letters everywhere react-twemoji wasn't manually wrapped. Bundle the Twemoji country-flags woff2 locally (no runtime CDN — matters for our audience) and add it as an @font-face scoped with unicode-range to flag codepoints only, then put it first in every Tailwind font stack (sans/display/mono). The browser now uses it solely for flag characters, so every flag renders correctly app-wide with zero markup changes and no effect on any other text.