123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- package server
- import (
- "io/fs"
- "net/netip"
- "time"
- "heckel.io/ntfy/v2/user"
- )
- // Defines default config settings (excluding limits, see below)
- const (
- DefaultListenHTTP = ":80"
- DefaultCacheDuration = 12 * time.Hour
- DefaultCacheBatchTimeout = time.Duration(0)
- DefaultKeepaliveInterval = 45 * time.Second // Not too frequently to save battery (Android read timeout used to be 77s!)
- DefaultManagerInterval = time.Minute
- DefaultDelayedSenderInterval = 10 * time.Second
- DefaultMessageDelayMin = 10 * time.Second
- DefaultMessageDelayMax = 3 * 24 * time.Hour
- DefaultFirebaseKeepaliveInterval = 3 * time.Hour // ~control topic (Android), not too frequently to save battery
- DefaultFirebasePollInterval = 20 * time.Minute // ~poll topic (iOS), max. 2-3 times per hour (see docs)
- DefaultFirebaseQuotaExceededPenaltyDuration = 10 * time.Minute // Time that over-users are locked out of Firebase if it returns "quota exceeded"
- DefaultStripePriceCacheDuration = 3 * time.Hour // Time to keep Stripe prices cached in memory before a refresh is needed
- )
- // Defines default Web Push settings
- const (
- DefaultWebPushExpiryWarningDuration = 7 * 24 * time.Hour
- DefaultWebPushExpiryDuration = 9 * 24 * time.Hour
- )
- // Defines all global and per-visitor limits
- // - message size limit: the max number of bytes for a message
- // - total topic limit: max number of topics overall
- // - various attachment limits
- const (
- DefaultMessageSizeLimit = 4096 // Bytes; note that FCM/APNS have a limit of ~4 KB for the entire message
- DefaultTotalTopicLimit = 15000
- DefaultAttachmentTotalSizeLimit = int64(5 * 1024 * 1024 * 1024) // 5 GB
- DefaultAttachmentFileSizeLimit = int64(15 * 1024 * 1024) // 15 MB
- DefaultAttachmentExpiryDuration = 3 * time.Hour
- )
- // Defines all per-visitor limits
- // - per visitor subscription limit: max number of subscriptions (active HTTP connections) per per-visitor/IP
- // - per visitor request limit: max number of PUT/GET/.. requests (here: 60 requests bucket, replenished at a rate of one per 5 seconds)
- // - per visitor email limit: max number of emails (here: 16 email bucket, replenished at a rate of one per hour)
- // - per visitor attachment size limit: total per-visitor attachment size in bytes to be stored on the server
- // - per visitor attachment daily bandwidth limit: number of bytes that can be transferred to/from the server
- const (
- DefaultVisitorSubscriptionLimit = 30
- DefaultVisitorRequestLimitBurst = 60
- DefaultVisitorRequestLimitReplenish = 5 * time.Second
- DefaultVisitorMessageDailyLimit = 0
- DefaultVisitorEmailLimitBurst = 16
- DefaultVisitorEmailLimitReplenish = time.Hour
- DefaultVisitorAccountCreationLimitBurst = 3
- DefaultVisitorAccountCreationLimitReplenish = 24 * time.Hour
- DefaultVisitorAuthFailureLimitBurst = 30
- DefaultVisitorAuthFailureLimitReplenish = time.Minute
- DefaultVisitorAttachmentTotalSizeLimit = 100 * 1024 * 1024 // 100 MB
- DefaultVisitorAttachmentDailyBandwidthLimit = 500 * 1024 * 1024 // 500 MB
- )
- var (
- // DefaultVisitorStatsResetTime defines the time at which visitor stats are reset (wall clock only)
- DefaultVisitorStatsResetTime = time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
- // DefaultDisallowedTopics defines the topics that are forbidden, because they are used elsewhere. This array can be
- // extended using the server.yml config. If updated, also update in Android and web app.
- DefaultDisallowedTopics = []string{"docs", "static", "file", "app", "metrics", "account", "settings", "signup", "login", "v1"}
- )
- // Config is the main config struct for the application. Use New to instantiate a default config struct.
- type Config struct {
- File string // Config file, only used for testing
- BaseURL string
- ListenHTTP string
- ListenHTTPS string
- ListenUnix string
- ListenUnixMode fs.FileMode
- KeyFile string
- CertFile string
- FirebaseKeyFile string
- CacheFile string
- CacheDuration time.Duration
- CacheStartupQueries string
- CacheBatchSize int
- CacheBatchTimeout time.Duration
- AuthFile string
- AuthStartupQueries string
- AuthDefault user.Permission
- AuthBcryptCost int
- AuthStatsQueueWriterInterval time.Duration
- AttachmentCacheDir string
- AttachmentTotalSizeLimit int64
- AttachmentFileSizeLimit int64
- AttachmentExpiryDuration time.Duration
- KeepaliveInterval time.Duration
- ManagerInterval time.Duration
- DisallowedTopics []string
- WebRoot string // empty to disable
- DelayedSenderInterval time.Duration
- FirebaseKeepaliveInterval time.Duration
- FirebasePollInterval time.Duration
- FirebaseQuotaExceededPenaltyDuration time.Duration
- UpstreamBaseURL string
- UpstreamAccessToken string
- SMTPSenderAddr string
- SMTPSenderUser string
- SMTPSenderPass string
- SMTPSenderFrom string
- SMTPServerListen string
- SMTPServerDomain string
- SMTPServerAddrPrefix string
- TwilioAccount string
- TwilioAuthToken string
- TwilioPhoneNumber string
- TwilioCallsBaseURL string
- TwilioVerifyBaseURL string
- TwilioVerifyService string
- MetricsEnable bool
- MetricsListenHTTP string
- ProfileListenHTTP string
- MessageDelayMin time.Duration
- MessageDelayMax time.Duration
- MessageSizeLimit int
- TotalTopicLimit int
- TotalAttachmentSizeLimit int64
- VisitorSubscriptionLimit int
- VisitorAttachmentTotalSizeLimit int64
- VisitorAttachmentDailyBandwidthLimit int64
- VisitorRequestLimitBurst int
- VisitorRequestLimitReplenish time.Duration
- VisitorRequestExemptIPAddrs []netip.Prefix
- VisitorMessageDailyLimit int
- VisitorEmailLimitBurst int
- VisitorEmailLimitReplenish time.Duration
- VisitorAccountCreationLimitBurst int
- VisitorAccountCreationLimitReplenish time.Duration
- VisitorAuthFailureLimitBurst int
- VisitorAuthFailureLimitReplenish time.Duration
- VisitorStatsResetTime time.Time // Time of the day at which to reset visitor stats
- VisitorSubscriberRateLimiting bool // Enable subscriber-based rate limiting for UnifiedPush topics
- BehindProxy bool
- StripeSecretKey string
- StripeWebhookKey string
- StripePriceCacheDuration time.Duration
- BillingContact string
- EnableSignup bool // Enable creation of accounts via API and UI
- EnableLogin bool
- EnableReservations bool // Allow users with role "user" to own/reserve topics
- EnableMetrics bool
- AccessControlAllowOrigin string // CORS header field to restrict access from web clients
- Version string // injected by App
- WebPushPrivateKey string
- WebPushPublicKey string
- WebPushFile string
- WebPushEmailAddress string
- WebPushStartupQueries string
- WebPushExpiryDuration time.Duration
- WebPushExpiryWarningDuration time.Duration
- }
- // NewConfig instantiates a default new server config
- func NewConfig() *Config {
- return &Config{
- File: "", // Only used for testing
- BaseURL: "",
- ListenHTTP: DefaultListenHTTP,
- ListenHTTPS: "",
- ListenUnix: "",
- ListenUnixMode: 0,
- KeyFile: "",
- CertFile: "",
- FirebaseKeyFile: "",
- CacheFile: "",
- CacheDuration: DefaultCacheDuration,
- CacheStartupQueries: "",
- CacheBatchSize: 0,
- CacheBatchTimeout: 0,
- AuthFile: "",
- AuthStartupQueries: "",
- AuthDefault: user.PermissionReadWrite,
- AuthBcryptCost: user.DefaultUserPasswordBcryptCost,
- AuthStatsQueueWriterInterval: user.DefaultUserStatsQueueWriterInterval,
- AttachmentCacheDir: "",
- AttachmentTotalSizeLimit: DefaultAttachmentTotalSizeLimit,
- AttachmentFileSizeLimit: DefaultAttachmentFileSizeLimit,
- AttachmentExpiryDuration: DefaultAttachmentExpiryDuration,
- KeepaliveInterval: DefaultKeepaliveInterval,
- ManagerInterval: DefaultManagerInterval,
- DisallowedTopics: DefaultDisallowedTopics,
- WebRoot: "/",
- DelayedSenderInterval: DefaultDelayedSenderInterval,
- FirebaseKeepaliveInterval: DefaultFirebaseKeepaliveInterval,
- FirebasePollInterval: DefaultFirebasePollInterval,
- FirebaseQuotaExceededPenaltyDuration: DefaultFirebaseQuotaExceededPenaltyDuration,
- UpstreamBaseURL: "",
- UpstreamAccessToken: "",
- SMTPSenderAddr: "",
- SMTPSenderUser: "",
- SMTPSenderPass: "",
- SMTPSenderFrom: "",
- SMTPServerListen: "",
- SMTPServerDomain: "",
- SMTPServerAddrPrefix: "",
- TwilioCallsBaseURL: "https://api.twilio.com", // Override for tests
- TwilioAccount: "",
- TwilioAuthToken: "",
- TwilioPhoneNumber: "",
- TwilioVerifyBaseURL: "https://verify.twilio.com", // Override for tests
- TwilioVerifyService: "",
- MessageSizeLimit: DefaultMessageSizeLimit,
- MessageDelayMin: DefaultMessageDelayMin,
- MessageDelayMax: DefaultMessageDelayMax,
- TotalTopicLimit: DefaultTotalTopicLimit,
- TotalAttachmentSizeLimit: 0,
- VisitorSubscriptionLimit: DefaultVisitorSubscriptionLimit,
- VisitorAttachmentTotalSizeLimit: DefaultVisitorAttachmentTotalSizeLimit,
- VisitorAttachmentDailyBandwidthLimit: DefaultVisitorAttachmentDailyBandwidthLimit,
- VisitorRequestLimitBurst: DefaultVisitorRequestLimitBurst,
- VisitorRequestLimitReplenish: DefaultVisitorRequestLimitReplenish,
- VisitorRequestExemptIPAddrs: make([]netip.Prefix, 0),
- VisitorMessageDailyLimit: DefaultVisitorMessageDailyLimit,
- VisitorEmailLimitBurst: DefaultVisitorEmailLimitBurst,
- VisitorEmailLimitReplenish: DefaultVisitorEmailLimitReplenish,
- VisitorAccountCreationLimitBurst: DefaultVisitorAccountCreationLimitBurst,
- VisitorAccountCreationLimitReplenish: DefaultVisitorAccountCreationLimitReplenish,
- VisitorAuthFailureLimitBurst: DefaultVisitorAuthFailureLimitBurst,
- VisitorAuthFailureLimitReplenish: DefaultVisitorAuthFailureLimitReplenish,
- VisitorStatsResetTime: DefaultVisitorStatsResetTime,
- VisitorSubscriberRateLimiting: false,
- BehindProxy: false,
- StripeSecretKey: "",
- StripeWebhookKey: "",
- StripePriceCacheDuration: DefaultStripePriceCacheDuration,
- BillingContact: "",
- EnableSignup: false,
- EnableLogin: false,
- EnableReservations: false,
- AccessControlAllowOrigin: "*",
- Version: "",
- WebPushPrivateKey: "",
- WebPushPublicKey: "",
- WebPushFile: "",
- WebPushEmailAddress: "",
- WebPushExpiryDuration: DefaultWebPushExpiryDuration,
- WebPushExpiryWarningDuration: DefaultWebPushExpiryWarningDuration,
- }
- }
|