mirror of
https://github.com/binwiederhier/ntfy.git
synced 2026-07-15 05:47:03 -06:00
94 lines
3.7 KiB
Go
94 lines
3.7 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"heckel.io/ntfy/v2/util"
|
|
)
|
|
|
|
// handleWebApp serves the embedded web app's index for client-side (SPA) routes that the
|
|
// browser router resolves, so the app shell loads and the client-side router takes over.
|
|
func (s *Server) handleWebApp(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
|
r.URL.Path = webAppIndex
|
|
return s.handleStatic(w, r, v)
|
|
}
|
|
|
|
// handleWebAppNoIndex serves the web app index for the magic-link landing pages, whose path
|
|
// carries a one-time token. The response is marked no-referrer (so the token can't leak to third
|
|
// 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) handleConfig(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
return s.writeJSON(w, s.configResponse())
|
|
}
|
|
|
|
func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
|
b, err := json.MarshalIndent(s.configResponse(), "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
w.Header().Set("Content-Type", "text/javascript")
|
|
w.Header().Set("Cache-Control", "no-cache")
|
|
_, err = io.WriteString(w, fmt.Sprintf("// Generated server configuration\nvar config = %s;\n", string(b)))
|
|
return err
|
|
}
|
|
|
|
// handleWebManifest serves the web app manifest for the progressive web app (PWA)
|
|
func (s *Server) handleWebManifest(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
|
response := &webManifestResponse{
|
|
Name: "ntfy",
|
|
Description: "ntfy lets you send push notifications via scripts from any computer or phone",
|
|
ShortName: "ntfy",
|
|
Scope: "/",
|
|
StartURL: s.config.WebRoot,
|
|
Display: "standalone",
|
|
BackgroundColor: "#ffffff",
|
|
ThemeColor: "#317f6f",
|
|
Icons: []*webManifestIcon{
|
|
{SRC: "/static/images/pwa-192x192.png", Sizes: "192x192", Type: "image/png"},
|
|
{SRC: "/static/images/pwa-512x512.png", Sizes: "512x512", Type: "image/png"},
|
|
},
|
|
}
|
|
return s.writeJSONWithContentType(w, response, "application/manifest+json")
|
|
}
|
|
|
|
// handleStatic returns all static resources (excluding the docs), including the web app
|
|
func (s *Server) handleStatic(w http.ResponseWriter, r *http.Request, _ *visitor) error {
|
|
r.URL.Path = webSiteDir + r.URL.Path
|
|
util.Gzip(http.FileServer(http.FS(webFsCached))).ServeHTTP(w, r)
|
|
return nil
|
|
}
|
|
|
|
// handleDocs returns static resources related to the docs
|
|
func (s *Server) handleDocs(w http.ResponseWriter, r *http.Request, _ *visitor) error {
|
|
util.Gzip(http.FileServer(http.FS(docsStaticCached))).ServeHTTP(w, r)
|
|
return nil
|
|
}
|
|
|
|
func (s *Server) configResponse() *apiConfigResponse {
|
|
return &apiConfigResponse{
|
|
BaseURL: "", // Will translate to window.location.origin
|
|
AppRoot: s.config.WebRoot,
|
|
EnableLogin: s.config.EnableLogin,
|
|
RequireLogin: s.config.RequireLogin,
|
|
EnableSignup: s.config.EnableSignup,
|
|
EnablePayments: s.config.StripeSecretKey != "",
|
|
EnableCalls: s.config.TwilioAccount != "",
|
|
EnableEmails: s.config.SMTPSenderFrom != "",
|
|
EnableResetPassword: s.config.SMTPSenderFrom != "" && s.config.BaseURL != "", // Reset links need SMTP + an absolute base-url
|
|
EnableReservations: s.config.EnableReservations,
|
|
EnableWebPush: s.config.WebPushPublicKey != "",
|
|
BillingContact: s.config.BillingContact,
|
|
WebPushPublicKey: s.config.WebPushPublicKey,
|
|
DisallowedTopics: s.config.DisallowedTopics,
|
|
ConfigHash: s.config.Hash(),
|
|
}
|
|
}
|