From 629253ab6192a799a25c0236c93fac83e2b155a8 Mon Sep 17 00:00:00 2001 From: Seongmin Lee Date: Fri, 16 Jan 2026 10:41:29 +0000 Subject: [PATCH] appview: strip scheme from `CoreConfig.AppviewHost` Signed-off-by: Seongmin Lee --- appview/config/config.go | 11 +++++++++++ appview/pages/pages.go | 1 + appview/repo/archive.go | 2 +- appview/repo/feed.go | 8 ++++---- appview/settings/settings.go | 15 +++++++-------- appview/state/profile.go | 8 ++++---- nix/modules/appview.nix | 4 ++-- appview/pages/markup/markdown.go | 7 ++++--- appview/pages/markup/markdown_test.go | 4 ++-- appview/pages/markup/reference_link.go | 11 ++++------- appview/pages/markup/reference_link_test.go | 2 +- appview/pages/markup/extension/tangledlink.go | 2 +- appview/pages/markup/extension/tangledlink_test.go | 2 +- 13 file(s) changed, 43 insertion(s)(+), 34 deletion(s)(-) diff --git a/appview/config/config.go b/appview/config/config.go --- a/appview/config/config.go +++ b/appview/config/config.go @@ -25,6 +25,17 @@ TmpAltAppPassword string `env:"ALT_APP_PASSWORD"` } +func (c *CoreConfig) UseTLS() bool { + return !c.Dev +} + +func (c *CoreConfig) BaseUrl() string { + if c.UseTLS() { + return "https://" + c.AppviewHost + } + return "http://" + c.AppviewHost +} + type OAuthConfig struct { ClientSecret string `env:"CLIENT_SECRET"` ClientKid string `env:"CLIENT_KID"` diff --git a/appview/pages/pages.go b/appview/pages/pages.go --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -55,6 +55,7 @@ // initialized with safe defaults, can be overriden per use rctx := &markup.RenderContext{ IsDev: config.Core.Dev, + Hostname: config.Core.AppviewHost, CamoUrl: config.Camo.Host, CamoSecret: config.Camo.SharedSecret, Sanitizer: markup.NewSanitizer(), diff --git a/appview/repo/archive.go b/appview/repo/archive.go --- a/appview/repo/archive.go +++ b/appview/repo/archive.go @@ -66,7 +66,7 @@ if link := resp.Header.Get("Link"); link != "" { if resolvedRef, err := extractImmutableLink(link); err == nil { newLink := fmt.Sprintf("<%s/%s/archive/%s.tar.gz>; rel=\"immutable\"", - rp.config.Core.AppviewHost, f.DidSlashRepo(), resolvedRef) + rp.config.Core.BaseUrl(), f.DidSlashRepo(), resolvedRef) w.Header().Set("Link", newLink) } } diff --git a/appview/repo/feed.go b/appview/repo/feed.go --- a/appview/repo/feed.go +++ b/appview/repo/feed.go @@ -37,7 +37,7 @@ feed := &feeds.Feed{ Title: fmt.Sprintf("activity feed for @%s", ownerSlashRepo), - Link: &feeds.Link{Href: fmt.Sprintf("%s/%s", rp.config.Core.AppviewHost, ownerSlashRepo), Type: "text/html", Rel: "alternate"}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/%s", rp.config.Core.BaseUrl(), ownerSlashRepo), Type: "text/html", Rel: "alternate"}, Items: make([]*feeds.Item, 0), Updated: time.UnixMilli(0), } @@ -86,7 +86,7 @@ mainItem := &feeds.Item{ Title: fmt.Sprintf("[PR #%d] %s", pull.PullId, pull.Title), Description: description, - Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d", rp.config.Core.AppviewHost, ownerSlashRepo, pull.PullId)}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d", rp.config.Core.BaseUrl(), ownerSlashRepo, pull.PullId)}, Created: pull.Created, Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)}, } @@ -100,7 +100,7 @@ roundItem := &feeds.Item{ Title: fmt.Sprintf("[PR #%d] %s (round #%d)", pull.PullId, pull.Title, round.RoundNumber), Description: fmt.Sprintf("@%s submitted changes (at round #%d) on PR #%d in @%s", owner.Handle, round.RoundNumber, pull.PullId, ownerSlashRepo), - Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d/round/%d/", rp.config.Core.AppviewHost, ownerSlashRepo, pull.PullId, round.RoundNumber)}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/pulls/%d/round/%d/", rp.config.Core.BaseUrl(), ownerSlashRepo, pull.PullId, round.RoundNumber)}, Created: round.Created, Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)}, } @@ -124,7 +124,7 @@ return &feeds.Item{ Title: fmt.Sprintf("[Issue #%d] %s", issue.IssueId, issue.Title), Description: fmt.Sprintf("@%s %s issue #%d in @%s", owner.Handle, state, issue.IssueId, ownerSlashRepo), - Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/issues/%d", rp.config.Core.AppviewHost, ownerSlashRepo, issue.IssueId)}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/%s/issues/%d", rp.config.Core.BaseUrl(), ownerSlashRepo, issue.IssueId)}, Created: issue.Created, Author: &feeds.Author{Name: fmt.Sprintf("@%s", owner.Handle)}, }, nil diff --git a/appview/settings/settings.go b/appview/settings/settings.go --- a/appview/settings/settings.go +++ b/appview/settings/settings.go @@ -277,14 +277,13 @@ } func (s *Settings) verifyUrl(did string, email string, code string) string { - var appUrl string - if s.Config.Core.Dev { - appUrl = "http://" + s.Config.Core.ListenAddr - } else { - appUrl = s.Config.Core.AppviewHost - } - - return fmt.Sprintf("%s/settings/emails/verify?did=%s&email=%s&code=%s", appUrl, url.QueryEscape(did), url.QueryEscape(email), url.QueryEscape(code)) + return fmt.Sprintf( + "%s/settings/emails/verify?did=%s&email=%s&code=%s", + s.Config.Core.BaseUrl(), + url.QueryEscape(did), + url.QueryEscape(email), + url.QueryEscape(code), + ) } func (s *Settings) emailsVerify(w http.ResponseWriter, r *http.Request) { diff --git a/appview/state/profile.go b/appview/state/profile.go --- a/appview/state/profile.go +++ b/appview/state/profile.go @@ -415,7 +415,7 @@ feed := feeds.Feed{ Title: fmt.Sprintf("%s's timeline", author.Name), - Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s", s.config.Core.AppviewHost, id.Handle), Type: "text/html", Rel: "alternate"}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s", s.config.Core.BaseUrl(), id.Handle), Type: "text/html", Rel: "alternate"}, Items: make([]*feeds.Item, 0), Updated: time.UnixMilli(0), Author: author, @@ -483,7 +483,7 @@ func (s *State) createPullRequestItem(pull *models.Pull, owner *identity.Identity, author *feeds.Author) *feeds.Item { return &feeds.Item{ Title: fmt.Sprintf("%s created pull request '%s' in @%s/%s", author.Name, pull.Title, owner.Handle, pull.Repo.Name), - Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s/pulls/%d", s.config.Core.AppviewHost, owner.Handle, pull.Repo.Name, pull.PullId), Type: "text/html", Rel: "alternate"}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s/pulls/%d", s.config.Core.BaseUrl(), owner.Handle, pull.Repo.Name, pull.PullId), Type: "text/html", Rel: "alternate"}, Created: pull.Created, Author: author, } @@ -492,7 +492,7 @@ func (s *State) createIssueItem(issue *models.Issue, owner *identity.Identity, author *feeds.Author) *feeds.Item { return &feeds.Item{ Title: fmt.Sprintf("%s created issue '%s' in @%s/%s", author.Name, issue.Title, owner.Handle, issue.Repo.Name), - Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s/issues/%d", s.config.Core.AppviewHost, owner.Handle, issue.Repo.Name, issue.IssueId), Type: "text/html", Rel: "alternate"}, + Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s/issues/%d", s.config.Core.BaseUrl(), owner.Handle, issue.Repo.Name, issue.IssueId), Type: "text/html", Rel: "alternate"}, Created: issue.Created, Author: author, } @@ -512,7 +512,7 @@ return &feeds.Item{ Title: title, - Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s", s.config.Core.AppviewHost, author.Name[1:], repo.Repo.Name), Type: "text/html", Rel: "alternate"}, // Remove @ prefix + Link: &feeds.Link{Href: fmt.Sprintf("%s/@%s/%s", s.config.Core.BaseUrl(), author.Name[1:], repo.Repo.Name), Type: "text/html", Rel: "alternate"}, // Remove @ prefix Created: repo.Repo.Created, Author: author, }, nil diff --git a/nix/modules/appview.nix b/nix/modules/appview.nix --- a/nix/modules/appview.nix +++ b/nix/modules/appview.nix @@ -41,8 +41,8 @@ appviewHost = mkOption { type = types.str; - default = "https://tangled.org"; - example = "https://example.com"; + default = "tangled.org"; + example = "example.com"; description = "Public host URL for the appview instance"; }; diff --git a/appview/pages/markup/markdown.go b/appview/pages/markup/markdown.go --- a/appview/pages/markup/markdown.go +++ b/appview/pages/markup/markdown.go @@ -46,12 +46,13 @@ CamoSecret string repoinfo.RepoInfo IsDev bool + Hostname string RendererType RendererType Sanitizer Sanitizer Files fs.FS } -func NewMarkdown() goldmark.Markdown { +func NewMarkdown(hostname string) goldmark.Markdown { md := goldmark.New( goldmark.WithExtensions( extension.GFM, @@ -67,7 +68,7 @@ ), callout.CalloutExtention, textension.AtExt, - textension.NewTangledLinkExt("tangled.org"), + textension.NewTangledLinkExt(hostname), emoji.Emoji, ), goldmark.WithParserOptions( @@ -79,7 +80,7 @@ } func (rctx *RenderContext) RenderMarkdown(source string) string { - return rctx.RenderMarkdownWith(source, NewMarkdown()) + return rctx.RenderMarkdownWith(source, NewMarkdown(rctx.Hostname)) } func (rctx *RenderContext) RenderMarkdownWith(source string, md goldmark.Markdown) string { diff --git a/appview/pages/markup/markdown_test.go b/appview/pages/markup/markdown_test.go --- a/appview/pages/markup/markdown_test.go +++ b/appview/pages/markup/markdown_test.go @@ -50,7 +50,7 @@ for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - md := NewMarkdown() + md := NewMarkdown("tangled.org") var buf bytes.Buffer if err := md.Convert([]byte(tt.markdown), &buf); err != nil { @@ -105,7 +105,7 @@ for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - md := NewMarkdown() + md := NewMarkdown("tangled.org") var buf bytes.Buffer if err := md.Convert([]byte(tt.markdown), &buf); err != nil { diff --git a/appview/pages/markup/reference_link.go b/appview/pages/markup/reference_link.go --- a/appview/pages/markup/reference_link.go +++ b/appview/pages/markup/reference_link.go @@ -18,17 +18,14 @@ // like issues, PRs, comments or even @-mentions // This funciton doesn't actually check for the existence of records in the DB // or the PDS; it merely returns a list of what are presumed to be references. -func FindReferences(baseUrl string, source string) ([]string, []models.ReferenceLink) { +func FindReferences(host string, source string) ([]string, []models.ReferenceLink) { var ( refLinkSet = make(map[models.ReferenceLink]struct{}) mentionsSet = make(map[string]struct{}) - md = NewMarkdown() + md = NewMarkdown(host) sourceBytes = []byte(source) root = md.Parser().Parse(text.NewReader(sourceBytes)) ) - // trim url scheme. the SSL shouldn't matter - baseUrl = strings.TrimPrefix(baseUrl, "https://") - baseUrl = strings.TrimPrefix(baseUrl, "http://") ast.Walk(root, func(n ast.Node, entering bool) (ast.WalkStatus, error) { if !entering { @@ -41,7 +38,7 @@ return ast.WalkSkipChildren, nil case ast.KindLink: dest := string(n.(*ast.Link).Destination) - ref := parseTangledLink(baseUrl, dest) + ref := parseTangledLink(host, dest) if ref != nil { refLinkSet[*ref] = struct{}{} } @@ -50,7 +47,7 @@ an := n.(*ast.AutoLink) if an.AutoLinkType == ast.AutoLinkURL { dest := string(an.URL(sourceBytes)) - ref := parseTangledLink(baseUrl, dest) + ref := parseTangledLink(host, dest) if ref != nil { refLinkSet[*ref] = struct{}{} } diff --git a/appview/pages/markup/reference_link_test.go b/appview/pages/markup/reference_link_test.go --- a/appview/pages/markup/reference_link_test.go +++ b/appview/pages/markup/reference_link_test.go @@ -34,7 +34,7 @@ } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - handles, refLinks := markup.FindReferences("http://127.0.0.1:3000", tt.source) + handles, refLinks := markup.FindReferences("127.0.0.1:3000", tt.source) assert.ElementsMatch(t, tt.wantHandles, handles) assert.ElementsMatch(t, tt.wantRefLinks, refLinks) }) diff --git a/appview/pages/markup/extension/tangledlink.go b/appview/pages/markup/extension/tangledlink.go --- a/appview/pages/markup/extension/tangledlink.go +++ b/appview/pages/markup/extension/tangledlink.go @@ -78,7 +78,7 @@ func (t *tangledLinkTransformer) parseLinkCommitSha(raw string) string { u, err := url.Parse(raw) - if err != nil || u.Host != "tangled.org" { + if err != nil || u.Host != t.host { return "" } diff --git a/appview/pages/markup/extension/tangledlink_test.go b/appview/pages/markup/extension/tangledlink_test.go --- a/appview/pages/markup/extension/tangledlink_test.go +++ b/appview/pages/markup/extension/tangledlink_test.go @@ -36,7 +36,7 @@ } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - md := markup.NewMarkdown() + md := markup.NewMarkdown("tangled.org") var buf bytes.Buffer if err := md.Convert([]byte(tt.markdown), &buf); err != nil { -- tangled.sh