mirror of
https://github.com/multipleof4/ntfy.git
synced 2026-10-08 21:05:21 +00:00
Review
This commit is contained in:
+13
-14
@@ -545,7 +545,7 @@ func (s *Server) handleError(w http.ResponseWriter, r *http.Request, v *visitor,
|
|||||||
|
|
||||||
func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
if r.Method == http.MethodGet && r.URL.Path == "/" && s.config.WebRoot == "/" {
|
if r.Method == http.MethodGet && r.URL.Path == "/" && s.config.WebRoot == "/" {
|
||||||
return s.ensureWebEnabled(s.handleRoot)(w, r, v)
|
return s.ensureWebEnabled(s.handleWebApp)(w, r, v)
|
||||||
} else if r.Method == http.MethodHead && r.URL.Path == "/" {
|
} else if r.Method == http.MethodHead && r.URL.Path == "/" {
|
||||||
return s.ensureWebEnabled(s.handleEmpty)(w, r, v)
|
return s.ensureWebEnabled(s.handleEmpty)(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && r.URL.Path == apiHealthPath {
|
} else if r.Method == http.MethodGet && r.URL.Path == apiHealthPath {
|
||||||
@@ -671,27 +671,27 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
|||||||
} else if r.Method == http.MethodGet && authPathRegex.MatchString(r.URL.Path) {
|
} else if r.Method == http.MethodGet && authPathRegex.MatchString(r.URL.Path) {
|
||||||
return s.limitRequests(s.authorizeTopicRead(s.handleTopicAuth))(w, r, v)
|
return s.limitRequests(s.authorizeTopicRead(s.handleTopicAuth))(w, r, v)
|
||||||
} else if r.Method == http.MethodGet && (webAppEmailVerifyRegex.MatchString(r.URL.Path) || webAppPasswordResetRegex.MatchString(r.URL.Path)) {
|
} else if r.Method == http.MethodGet && (webAppEmailVerifyRegex.MatchString(r.URL.Path) || webAppPasswordResetRegex.MatchString(r.URL.Path)) {
|
||||||
return s.ensureWebEnabled(s.handleWebAppIndex)(w, r, v) // Magic-link landing pages (client-side routes)
|
return s.ensureWebEnabled(s.handleWebAppNoIndex)(w, r, v) // Magic-link landing pages (client-side routes)
|
||||||
} else if r.Method == http.MethodGet && (topicPathRegex.MatchString(r.URL.Path) || externalTopicPathRegex.MatchString(r.URL.Path)) {
|
} else if r.Method == http.MethodGet && (topicPathRegex.MatchString(r.URL.Path) || externalTopicPathRegex.MatchString(r.URL.Path)) {
|
||||||
return s.ensureWebEnabled(s.handleTopic)(w, r, v)
|
return s.ensureWebEnabled(s.handleTopic)(w, r, v)
|
||||||
}
|
}
|
||||||
return errHTTPNotFound
|
return errHTTPNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleWebAppIndex serves the embedded web app's index for client-side (SPA) routes the
|
// handleWebApp serves the embedded web app's index for client-side (SPA) routes that the
|
||||||
// browser router resolves, such as the magic-link landing pages. Because these URLs carry a
|
// browser router resolves, so the app shell loads and the client-side router takes over.
|
||||||
// one-time token in the path, the response is marked no-referrer (so the token can't leak to
|
func (s *Server) handleWebApp(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
// third parties via the Referer header) and noindex (so it never gets indexed).
|
|
||||||
func (s *Server) handleWebAppIndex(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
|
||||||
w.Header().Set("Referrer-Policy", "no-referrer")
|
|
||||||
w.Header().Set("X-Robots-Tag", "noindex")
|
|
||||||
r.URL.Path = webAppIndex
|
r.URL.Path = webAppIndex
|
||||||
return s.handleStatic(w, r, v)
|
return s.handleStatic(w, r, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleRoot(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
// handleWebAppNoIndex serves the web app index for the magic-link landing pages, whose path
|
||||||
r.URL.Path = webAppIndex
|
// carries a one-time token. The response is marked no-referrer (so the token can't leak to third
|
||||||
return s.handleStatic(w, r, v)
|
// parties via the Referer header) and noindex (so it never gets indexed).
|
||||||
|
func (s *Server) handleWebAppNoIndex(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
|
w.Header().Set("Referrer-Policy", "no-referrer")
|
||||||
|
w.Header().Set("X-Robots-Tag", "noindex")
|
||||||
|
return s.handleWebApp(w, r, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleTopic(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
func (s *Server) handleTopic(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
@@ -702,8 +702,7 @@ func (s *Server) handleTopic(w http.ResponseWriter, r *http.Request, v *visitor)
|
|||||||
_, err := io.WriteString(w, `{"unifiedpush":{"version":1}}`+"\n")
|
_, err := io.WriteString(w, `{"unifiedpush":{"version":1}}`+"\n")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r.URL.Path = webAppIndex
|
return s.handleWebApp(w, r, v)
|
||||||
return s.handleStatic(w, r, v)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleEmpty(_ http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
func (s *Server) handleEmpty(_ http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
||||||
|
|||||||
@@ -264,6 +264,27 @@ func TestServer_StaticSites(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestServer_WebApp_MagicLinkLandingPagesNoIndexHeaders(t *testing.T) {
|
||||||
|
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||||
|
s := newTestServer(t, newTestConfig(t, databaseURL))
|
||||||
|
|
||||||
|
// Magic-link landing pages carry a one-time token in the path, so the response must not
|
||||||
|
// leak the token via the Referer header and must not be indexed
|
||||||
|
for _, path := range []string{"/account/email/verify/sometoken", "/account/password/reset/sometoken"} {
|
||||||
|
rr := request(t, s, "GET", path, "", nil)
|
||||||
|
require.Equal(t, 200, rr.Code, path)
|
||||||
|
require.Equal(t, "no-referrer", rr.Header().Get("Referrer-Policy"), path)
|
||||||
|
require.Equal(t, "noindex", rr.Header().Get("X-Robots-Tag"), path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ordinary web app routes do not set these headers
|
||||||
|
rr := request(t, s, "GET", "/", "", nil)
|
||||||
|
require.Equal(t, 200, rr.Code)
|
||||||
|
require.Empty(t, rr.Header().Get("Referrer-Policy"))
|
||||||
|
require.Empty(t, rr.Header().Get("X-Robots-Tag"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestServer_WebEnabled(t *testing.T) {
|
func TestServer_WebEnabled(t *testing.T) {
|
||||||
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
forEachBackend(t, func(t *testing.T, databaseURL string) {
|
||||||
conf := newTestConfig(t, databaseURL)
|
conf := newTestConfig(t, databaseURL)
|
||||||
|
|||||||
Reference in New Issue
Block a user