Link to source

This commit is contained in:
2026-09-13 12:38:22 +02:00
parent 000f9d6984
commit 27be685834
5 changed files with 108 additions and 1 deletions
+4 -1
View File
@@ -241,6 +241,9 @@ type page struct {
// case the markup carries no link rather than one that 404s.
Favicon string
// Source is where the footer links; empty means no footer.
Source string
// Wide widens the page for content that is a table rather than a form.
// The reading measure that suits the upload page is far too narrow for a
// listing, which otherwise ends up behind a horizontal scrollbar.
@@ -250,7 +253,7 @@ type page struct {
// page builds the common fields, resolving the session so the header can show
// who is logged in and offer only the links they can use.
func (s *Server) page(r *http.Request, title string, script bool) page {
p := page{Base: s.cfg.BasePath, Title: title, Script: script}
p := page{Base: s.cfg.BasePath, Title: title, Script: script, Source: s.cfg.SourceURL}
if s.favicon != "" {
p.Favicon = s.cfg.BasePath + "static/" + s.favicon
}
+43
View File
@@ -1146,6 +1146,49 @@ func TestNoFaviconMeansNoLink(t *testing.T) {
}
}
// --- the footer ------------------------------------------------------------
// The footer names where the source lives, and an instance that would rather
// not say so can drop it. A fork gets to point at its own.
func TestSourceLinkIsOptional(t *testing.T) {
shown := newHarness(t, nil)
resp := shown.get(t, "/", "")
page, _ := io.ReadAll(resp.Body)
resp.Body.Close()
if !strings.Contains(string(page), `<footer><a href="https://git.uncensored.hu/thayol/uncensored-send">Source</a>`) {
t.Error("the default build does not link its source")
}
forked := newHarness(t, func(c *config.Config) { c.SourceURL = "https://example.org/me/fork" })
resp = forked.get(t, "/login", "")
page, _ = io.ReadAll(resp.Body)
resp.Body.Close()
if !strings.Contains(string(page), `href="https://example.org/me/fork"`) {
t.Error("a fork's own source URL is not used")
}
quiet := newHarness(t, func(c *config.Config) { c.SourceURL = "" })
for _, path := range []string{"/", "/login", "/files"} {
resp := quiet.get(t, path, "")
page, _ := io.ReadAll(resp.Body)
resp.Body.Close()
if strings.Contains(string(page), "<footer>") {
t.Errorf("GET %s still carries a footer with the source link switched off", path)
}
}
}
// The footer is the one link that leaves this origin, so the header that keeps
// it from naming this instance to the far end has to stay put.
func TestOutboundRequestsCarryNoReferrer(t *testing.T) {
h := newHarness(t, nil)
resp := h.get(t, "/", "")
resp.Body.Close()
if got := resp.Header.Get("Referrer-Policy"); got != "no-referrer" {
t.Errorf("Referrer-Policy = %q, want no-referrer", got)
}
}
// --- content security policy ---------------------------------------------
// The page's own behaviour and its CSP have to agree, and nothing in a Go test