fix for owpg
This commit is contained in:
parent
d5c51f620c
commit
ddd26e51b5
2 changed files with 55 additions and 21 deletions
|
|
@ -157,6 +157,14 @@ func newHandler(cfg Config, logger *zap.Logger) (http.Handler, error) {
|
|||
if logger == nil {
|
||||
logger = zap.NewNop()
|
||||
}
|
||||
// links.ValidateBaseURL above guarantees cfg.PublicBaseURL parses with a
|
||||
// non-empty host; publicHost is the bare "host[:port]" used to build
|
||||
// owpg://<host>/<path> deep links (the client reinterprets those as
|
||||
// https://<host>/<path>, see LaunchActivity's "owpg" scheme case).
|
||||
publicHost := cfg.PublicBaseURL
|
||||
if u, err := url.Parse(cfg.PublicBaseURL); err == nil {
|
||||
publicHost = u.Host
|
||||
}
|
||||
h := &handler{
|
||||
stickerSets: cfg.StickerSets,
|
||||
users: cfg.Users,
|
||||
|
|
@ -166,6 +174,7 @@ func newHandler(cfg Config, logger *zap.Logger) (http.Handler, error) {
|
|||
uniqueGifts: cfg.UniqueGifts,
|
||||
giftWithdrawals: cfg.GiftWithdrawals,
|
||||
publicBaseURL: cfg.PublicBaseURL,
|
||||
publicHost: publicHost,
|
||||
appScheme: cfg.AppScheme,
|
||||
webBaseURL: cfg.WebBaseURL,
|
||||
appName: cfg.AppName,
|
||||
|
|
@ -199,6 +208,7 @@ type handler struct {
|
|||
uniqueGifts UniqueStarGiftResolver
|
||||
giftWithdrawals StarGiftWithdrawalResolver
|
||||
publicBaseURL string
|
||||
publicHost string
|
||||
appScheme string
|
||||
webBaseURL string
|
||||
appName string
|
||||
|
|
@ -284,7 +294,7 @@ func (h *handler) addList(w http.ResponseWriter, r *http.Request) {
|
|||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
app := h.appURL("addlist", "slug", slug)
|
||||
app := h.appURL("addlist", slug)
|
||||
data := pageData{
|
||||
AppName: h.appName,
|
||||
Title: "Shared Folder",
|
||||
|
|
@ -340,7 +350,7 @@ func (h *handler) uniqueGift(w http.ResponseWriter, r *http.Request) {
|
|||
if unique.AvailabilityIssued > 0 && unique.AvailabilityTotal >= unique.AvailabilityIssued {
|
||||
subtitle += fmt.Sprintf(" · %s/%s issued", groupedDecimal(unique.AvailabilityIssued), groupedDecimal(unique.AvailabilityTotal))
|
||||
}
|
||||
app := h.appURL("nft", "slug", canonicalSlug)
|
||||
app := h.appURL("nft", canonicalSlug)
|
||||
data := pageData{
|
||||
AppName: h.appName,
|
||||
Title: title,
|
||||
|
|
@ -385,8 +395,10 @@ func (h *handler) usernameLink(w http.ResponseWriter, r *http.Request) {
|
|||
h.serveUsernameNotFound(w, username)
|
||||
return
|
||||
}
|
||||
// owpg://<host>/<username> — built from params BEFORE "domain" is added
|
||||
// below, since owpg encodes the username in the path, not as a query key.
|
||||
app := h.appUsernameURL(peer.username, params)
|
||||
params.Set("domain", peer.username)
|
||||
app := schemeURLValues(h.appScheme, "resolve", params)
|
||||
description := peer.about
|
||||
if description == "" {
|
||||
description = peer.fallbackDescription(h.appName)
|
||||
|
|
@ -455,7 +467,7 @@ func (h *handler) inviteLink(w http.ResponseWriter, r *http.Request, hash string
|
|||
if title == "" {
|
||||
title = strings.TrimSpace(invite.Title)
|
||||
}
|
||||
app := h.appURL("join", "invite", hash)
|
||||
app := h.appInviteURL(hash)
|
||||
description := peer.about
|
||||
if description == "" {
|
||||
description = peer.fallbackDescription(h.appName)
|
||||
|
|
@ -618,7 +630,7 @@ func (h *handler) serveSet(w http.ResponseWriter, r *http.Request, pathKind stri
|
|||
if count == 0 {
|
||||
count = len(docs)
|
||||
}
|
||||
app := h.appURL(canonicalKind, "set", set.ShortName)
|
||||
app := h.appURL(canonicalKind, set.ShortName)
|
||||
data := pageData{
|
||||
AppName: h.appName,
|
||||
Title: fallbackTitle(set),
|
||||
|
|
@ -1169,10 +1181,32 @@ func itemNoun(set domain.StickerSet, count int) string {
|
|||
return "stickers"
|
||||
}
|
||||
|
||||
func (h *handler) appURL(kind, key, value string) string {
|
||||
return schemeURL(h.appScheme, kind, key, value)
|
||||
// appURL/appInviteURL/appUsernameURL build owpg://<host>/<path> deep links —
|
||||
// mirrors publicURL/publicInviteURL/publicUsernameURL (https://<host>/<path>)
|
||||
// but with the app scheme instead. The client's "owpg" URI handler reinterprets
|
||||
// owpg://<host>/<path>?<query> as https://<host>/<path>?<query> and falls
|
||||
// through to the normal t.me-style path router (LaunchActivity.java), which
|
||||
// expects a path, not a tg://-style "resolve?domain=" query. Do NOT use
|
||||
// schemeURL here — that format is only valid for the real tg:// scheme.
|
||||
func (h *handler) appURL(kind, value string) string {
|
||||
return h.appScheme + "://" + h.publicHost + "/" + kind + "/" + url.PathEscape(value)
|
||||
}
|
||||
|
||||
func (h *handler) appInviteURL(hash string) string {
|
||||
return h.appScheme + "://" + h.publicHost + "/+" + url.PathEscape(hash)
|
||||
}
|
||||
|
||||
func (h *handler) appUsernameURL(username string, extraQuery url.Values) string {
|
||||
u := h.appScheme + "://" + h.publicHost + "/" + url.PathEscape(username)
|
||||
if len(extraQuery) > 0 {
|
||||
u += "?" + extraQuery.Encode()
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// schemeURL/schemeURLValues build the real tg:// deep-link format
|
||||
// (tg://resolve?domain=X) — used only for the legacy-client fallback link
|
||||
// (LegacyTgURL), never for the app's own owpg:// scheme.
|
||||
func schemeURL(scheme, kind, key, value string) string {
|
||||
return scheme + "://" + kind + "?" + key + "=" + url.QueryEscape(value)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ func TestHandlerServesUniqueGiftLandingPage(t *testing.T) {
|
|||
for _, want := range []string{
|
||||
"Official Gift", "Collectible #7", "7/1 000 issued",
|
||||
"http://127.0.0.1:2401/nft/" + slug,
|
||||
"telesrv://nft?slug=" + slug,
|
||||
"telesrv://127.0.0.1:2401/nft/" + slug,
|
||||
"tg://nft?slug=" + slug,
|
||||
"Open it in the app to view its current details.",
|
||||
} {
|
||||
|
|
@ -219,7 +219,7 @@ func TestHandlerServesStickerSetLandingPage(t *testing.T) {
|
|||
for _, want := range []string{
|
||||
"Fresh Pack",
|
||||
"https://telesrv.net/addstickers/fresh_pack",
|
||||
"telesrv://addstickers?set=fresh_pack",
|
||||
"telesrv://telesrv.net/addstickers/fresh_pack",
|
||||
"Files are still fetched by the app through MTProto.",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
|
|
@ -257,7 +257,7 @@ func TestHandlerServesEmojiLandingPage(t *testing.T) {
|
|||
for _, want := range []string{
|
||||
"custom emoji set",
|
||||
"https://example.test/base/addemoji/emoji_pack",
|
||||
"telesrv://addemoji?set=emoji_pack",
|
||||
"telesrv://example.test/addemoji/emoji_pack",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("body missing %q:\n%s", want, body)
|
||||
|
|
@ -278,7 +278,7 @@ func TestHandlerServesChatlistLandingPage(t *testing.T) {
|
|||
for _, want := range []string{
|
||||
"Shared Folder",
|
||||
"http://127.0.0.1:2401/addlist/zNhytIbwRwjaC2GH",
|
||||
"telesrv://addlist?slug=zNhytIbwRwjaC2GH",
|
||||
"telesrv://127.0.0.1:2401/addlist/zNhytIbwRwjaC2GH",
|
||||
"preview and add this shared folder",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
|
|
@ -313,11 +313,11 @@ func TestHandlerServesBotUsernameLandingPage(t *testing.T) {
|
|||
"bot",
|
||||
"@TetrisBot",
|
||||
"http://127.0.0.1:2401/TetrisBot",
|
||||
"telesrv://resolve?domain=TetrisBot",
|
||||
"telesrv://127.0.0.1:2401/TetrisBot",
|
||||
"Start Bot",
|
||||
"Open telesrv to start a chat with this bot.",
|
||||
`property="og:title" content="Tetris Bot"`,
|
||||
`property="al:android:url" content="telesrv://resolve?domain=TetrisBot"`,
|
||||
`property="al:android:url" content="telesrv://127.0.0.1:2401/TetrisBot"`,
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("body missing %q:\n%s", want, body)
|
||||
|
|
@ -353,7 +353,7 @@ func TestHandlerUsesConfiguredClientLinksAndBrand(t *testing.T) {
|
|||
}
|
||||
body := rr.Body.String()
|
||||
for _, want := range []string{
|
||||
"example-chat://resolve?domain=Alice&start=hello",
|
||||
"example-chat://links.example.test/Alice?start=hello",
|
||||
"https://web.example.test/client/#?tgaddr=",
|
||||
"Example Chat",
|
||||
"Open Example Chat to send a message to @Alice.",
|
||||
|
|
@ -369,10 +369,10 @@ func TestHandlerUsesConfiguredClientLinksAndBrand(t *testing.T) {
|
|||
path string
|
||||
want string
|
||||
}{
|
||||
{path: "/addstickers/stickers_pack", want: "example-chat://addstickers?set=stickers_pack"},
|
||||
{path: "/addemoji/emoji_pack", want: "example-chat://addemoji?set=emoji_pack"},
|
||||
{path: "/addlist/shared-folder", want: "example-chat://addlist?slug=shared-folder"},
|
||||
{path: "/nft/gift-1", want: "example-chat://nft?slug=gift-1"},
|
||||
{path: "/addstickers/stickers_pack", want: "example-chat://links.example.test/addstickers/stickers_pack"},
|
||||
{path: "/addemoji/emoji_pack", want: "example-chat://links.example.test/addemoji/emoji_pack"},
|
||||
{path: "/addlist/shared-folder", want: "example-chat://links.example.test/addlist/shared-folder"},
|
||||
{path: "/nft/gift-1", want: "example-chat://links.example.test/nft/gift-1"},
|
||||
} {
|
||||
rr := httptest.NewRecorder()
|
||||
h.ServeHTTP(rr, httptest.NewRequest(http.MethodGet, tc.path, nil))
|
||||
|
|
@ -447,14 +447,14 @@ func TestHandlerServesUserChannelAndSupergroupLandingPages(t *testing.T) {
|
|||
path: "/aLiCe/",
|
||||
wants: []string{
|
||||
"Alice Example", "Public bio", "@Alice", "Send Message", "Verified",
|
||||
"https://telesrv.net/Alice", "telesrv://resolve?domain=Alice",
|
||||
"https://telesrv.net/Alice", "telesrv://telesrv.net/Alice",
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/NewsRoom",
|
||||
wants: []string{
|
||||
"News Room", "Public channel description", "12 001 subscribers", "View Channel",
|
||||
"https://telesrv.net/NewsRoom", "telesrv://resolve?domain=NewsRoom",
|
||||
"https://telesrv.net/NewsRoom", "telesrv://telesrv.net/NewsRoom",
|
||||
"/_public/avatar/NewsRoom/301",
|
||||
},
|
||||
},
|
||||
|
|
@ -497,7 +497,7 @@ func TestHandlerPreservesBoundedResolveQueryAndOverridesDomain(t *testing.T) {
|
|||
}
|
||||
body := rr.Body.String()
|
||||
for _, want := range []string{
|
||||
"telesrv://resolve?domain=TetrisBot&ref=campaign&start=hello",
|
||||
"telesrv://telesrv.net/TetrisBot?ref=campaign&start=hello",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Fatalf("body missing sanitized query %q:\n%s", want, body)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue