Update checker
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/netip"
|
||||
"text/template"
|
||||
@@ -275,3 +278,87 @@ func NewConfig() *Config {
|
||||
WebPushExpiryWarningDuration: DefaultWebPushExpiryWarningDuration,
|
||||
}
|
||||
}
|
||||
|
||||
// configHashData is a subset of Config fields used for computing the config hash.
|
||||
// It excludes sensitive fields (keys, passwords, tokens) and runtime-only fields.
|
||||
type configHashData struct {
|
||||
BaseURL string
|
||||
ListenHTTP string
|
||||
ListenHTTPS string
|
||||
ListenUnix string
|
||||
CacheDuration time.Duration
|
||||
AttachmentTotalSizeLimit int64
|
||||
AttachmentFileSizeLimit int64
|
||||
AttachmentExpiryDuration time.Duration
|
||||
KeepaliveInterval time.Duration
|
||||
ManagerInterval time.Duration
|
||||
DisallowedTopics []string
|
||||
WebRoot string
|
||||
MessageDelayMin time.Duration
|
||||
MessageDelayMax time.Duration
|
||||
MessageSizeLimit int
|
||||
TotalTopicLimit int
|
||||
VisitorSubscriptionLimit int
|
||||
VisitorAttachmentTotalSizeLimit int64
|
||||
VisitorAttachmentDailyBandwidthLimit int64
|
||||
VisitorRequestLimitBurst int
|
||||
VisitorRequestLimitReplenish time.Duration
|
||||
VisitorMessageDailyLimit int
|
||||
VisitorEmailLimitBurst int
|
||||
VisitorEmailLimitReplenish time.Duration
|
||||
EnableSignup bool
|
||||
EnableLogin bool
|
||||
RequireLogin bool
|
||||
EnableReservations bool
|
||||
EnableMetrics bool
|
||||
EnablePayments bool
|
||||
EnableCalls bool
|
||||
EnableEmails bool
|
||||
EnableWebPush bool
|
||||
BillingContact string
|
||||
Version string
|
||||
}
|
||||
|
||||
// Hash computes a SHA-256 hash of the configuration. This is used to detect
|
||||
// configuration changes for the web app version check feature.
|
||||
func (c *Config) Hash() string {
|
||||
data := configHashData{
|
||||
BaseURL: c.BaseURL,
|
||||
ListenHTTP: c.ListenHTTP,
|
||||
ListenHTTPS: c.ListenHTTPS,
|
||||
ListenUnix: c.ListenUnix,
|
||||
CacheDuration: c.CacheDuration,
|
||||
AttachmentTotalSizeLimit: c.AttachmentTotalSizeLimit,
|
||||
AttachmentFileSizeLimit: c.AttachmentFileSizeLimit,
|
||||
AttachmentExpiryDuration: c.AttachmentExpiryDuration,
|
||||
KeepaliveInterval: c.KeepaliveInterval,
|
||||
ManagerInterval: c.ManagerInterval,
|
||||
DisallowedTopics: c.DisallowedTopics,
|
||||
WebRoot: c.WebRoot,
|
||||
MessageDelayMin: c.MessageDelayMin,
|
||||
MessageDelayMax: c.MessageDelayMax,
|
||||
MessageSizeLimit: c.MessageSizeLimit,
|
||||
TotalTopicLimit: c.TotalTopicLimit,
|
||||
VisitorSubscriptionLimit: c.VisitorSubscriptionLimit,
|
||||
VisitorAttachmentTotalSizeLimit: c.VisitorAttachmentTotalSizeLimit,
|
||||
VisitorAttachmentDailyBandwidthLimit: c.VisitorAttachmentDailyBandwidthLimit,
|
||||
VisitorRequestLimitBurst: c.VisitorRequestLimitBurst,
|
||||
VisitorRequestLimitReplenish: c.VisitorRequestLimitReplenish,
|
||||
VisitorMessageDailyLimit: c.VisitorMessageDailyLimit,
|
||||
VisitorEmailLimitBurst: c.VisitorEmailLimitBurst,
|
||||
VisitorEmailLimitReplenish: c.VisitorEmailLimitReplenish,
|
||||
EnableSignup: c.EnableSignup,
|
||||
EnableLogin: c.EnableLogin,
|
||||
RequireLogin: c.RequireLogin,
|
||||
EnableReservations: c.EnableReservations,
|
||||
EnableMetrics: c.EnableMetrics,
|
||||
EnablePayments: c.StripeSecretKey != "",
|
||||
EnableCalls: c.TwilioAccount != "",
|
||||
EnableEmails: c.SMTPSenderFrom != "",
|
||||
EnableWebPush: c.WebPushPublicKey != "",
|
||||
BillingContact: c.BillingContact,
|
||||
Version: c.Version,
|
||||
}
|
||||
b, _ := json.Marshal(data)
|
||||
return fmt.Sprintf("%x", sha256.Sum256(b))
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ var (
|
||||
matrixPushPath = "/_matrix/push/v1/notify"
|
||||
metricsPath = "/metrics"
|
||||
apiHealthPath = "/v1/health"
|
||||
apiVersionPath = "/v1/version"
|
||||
apiStatsPath = "/v1/stats"
|
||||
apiWebPushPath = "/v1/webpush"
|
||||
apiTiersPath = "/v1/tiers"
|
||||
@@ -460,6 +461,8 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit
|
||||
return s.ensureWebEnabled(s.handleEmpty)(w, r, v)
|
||||
} else if r.Method == http.MethodGet && r.URL.Path == apiHealthPath {
|
||||
return s.handleHealth(w, r, v)
|
||||
} else if r.Method == http.MethodGet && r.URL.Path == apiVersionPath {
|
||||
return s.handleVersion(w, r, v)
|
||||
} else if r.Method == http.MethodGet && r.URL.Path == webConfigPath {
|
||||
return s.ensureWebEnabled(s.handleWebConfig)(w, r, v)
|
||||
} else if r.Method == http.MethodGet && r.URL.Path == webManifestPath {
|
||||
@@ -600,6 +603,14 @@ func (s *Server) handleHealth(w http.ResponseWriter, _ *http.Request, _ *visitor
|
||||
return s.writeJSON(w, response)
|
||||
}
|
||||
|
||||
func (s *Server) handleVersion(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
||||
response := &apiVersionResponse{
|
||||
Version: s.config.Version,
|
||||
ConfigHash: s.config.Hash(),
|
||||
}
|
||||
return s.writeJSON(w, response)
|
||||
}
|
||||
|
||||
func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visitor) error {
|
||||
response := &apiConfigResponse{
|
||||
BaseURL: "", // Will translate to window.location.origin
|
||||
@@ -615,6 +626,7 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visi
|
||||
BillingContact: s.config.BillingContact,
|
||||
WebPushPublicKey: s.config.WebPushPublicKey,
|
||||
DisallowedTopics: s.config.DisallowedTopics,
|
||||
ConfigHash: s.config.Hash(),
|
||||
}
|
||||
b, err := json.MarshalIndent(response, "", " ")
|
||||
if err != nil {
|
||||
|
||||
@@ -317,6 +317,11 @@ type apiHealthResponse struct {
|
||||
Healthy bool `json:"healthy"`
|
||||
}
|
||||
|
||||
type apiVersionResponse struct {
|
||||
Version string `json:"version"`
|
||||
ConfigHash string `json:"config_hash"`
|
||||
}
|
||||
|
||||
type apiStatsResponse struct {
|
||||
Messages int64 `json:"messages"`
|
||||
MessagesRate float64 `json:"messages_rate"` // Average number of messages per second
|
||||
@@ -482,6 +487,7 @@ type apiConfigResponse struct {
|
||||
BillingContact string `json:"billing_contact"`
|
||||
WebPushPublicKey string `json:"web_push_public_key"`
|
||||
DisallowedTopics []string `json:"disallowed_topics"`
|
||||
ConfigHash string `json:"config_hash"`
|
||||
}
|
||||
|
||||
type apiAccountBillingPrices struct {
|
||||
|
||||
Reference in New Issue
Block a user