binwiederhier 3 lat temu
rodzic
commit
7007c0a0bd
7 zmienionych plików z 38 dodań i 19 usunięć
  1. 10 8
      cmd/serve.go
  2. 5 0
      docs/config.md
  3. 3 0
      docs/subscribe/api.md
  4. 1 5
      server/server.go
  5. 13 0
      server/server.yml
  6. 1 1
      server/server_account.go
  7. 5 5
      server/types.go

+ 10 - 8
cmd/serve.go

@@ -58,6 +58,10 @@ var flagsServe = append(
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "keepalive-interval", Aliases: []string{"keepalive_interval", "k"}, EnvVars: []string{"NTFY_KEEPALIVE_INTERVAL"}, Value: server.DefaultKeepaliveInterval, Usage: "interval of keepalive messages"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "manager-interval", Aliases: []string{"manager_interval", "m"}, EnvVars: []string{"NTFY_MANAGER_INTERVAL"}, Value: server.DefaultManagerInterval, Usage: "interval of for message pruning and stats printing"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "web-root", Aliases: []string{"web_root"}, EnvVars: []string{"NTFY_WEB_ROOT"}, Value: "app", Usage: "sets web root to landing page (home), web app (app) or disabled (disable)"}),
+	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-signup", Aliases: []string{"enable_signup"}, EnvVars: []string{"NTFY_ENABLE_SIGNUP"}, Value: false, Usage: "allows users to sign up via the web app, or API"}),
+	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-login", Aliases: []string{"enable_login"}, EnvVars: []string{"NTFY_ENABLE_LOGIN"}, Value: false, Usage: "allows users to log in via the web app, or API"}),
+	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-reservations", Aliases: []string{"enable_reservations"}, EnvVars: []string{"NTFY_ENABLE_RESERVATIONS"}, Value: false, Usage: "allows users to reserve topics (if their tier allows it)"}),
+	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-payments", Aliases: []string{"enable_payments"}, EnvVars: []string{"NTFY_ENABLE_PAYMENTS"}, Value: false, Usage: "enables payments integration [preliminary option, may change]"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "upstream-base-url", Aliases: []string{"upstream_base_url"}, EnvVars: []string{"NTFY_UPSTREAM_BASE_URL"}, Value: "", Usage: "forward poll request to an upstream server, this is needed for iOS push notifications for self-hosted servers"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-addr", Aliases: []string{"smtp_sender_addr"}, EnvVars: []string{"NTFY_SMTP_SENDER_ADDR"}, Usage: "SMTP server address (host:port) for outgoing emails"}),
 	altsrc.NewStringFlag(&cli.StringFlag{Name: "smtp-sender-user", Aliases: []string{"smtp_sender_user"}, EnvVars: []string{"NTFY_SMTP_SENDER_USER"}, Usage: "SMTP user (if e-mail sending is enabled)"}),
@@ -76,10 +80,6 @@ var flagsServe = append(
 	altsrc.NewIntFlag(&cli.IntFlag{Name: "visitor-email-limit-burst", Aliases: []string{"visitor_email_limit_burst"}, EnvVars: []string{"NTFY_VISITOR_EMAIL_LIMIT_BURST"}, Value: server.DefaultVisitorEmailLimitBurst, Usage: "initial limit of e-mails per visitor"}),
 	altsrc.NewDurationFlag(&cli.DurationFlag{Name: "visitor-email-limit-replenish", Aliases: []string{"visitor_email_limit_replenish"}, EnvVars: []string{"NTFY_VISITOR_EMAIL_LIMIT_REPLENISH"}, Value: server.DefaultVisitorEmailLimitReplenish, Usage: "interval at which burst limit is replenished (one per x)"}),
 	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "behind-proxy", Aliases: []string{"behind_proxy", "P"}, EnvVars: []string{"NTFY_BEHIND_PROXY"}, Value: false, Usage: "if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting)"}),
-	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-signup", Aliases: []string{"enable_signup"}, EnvVars: []string{"NTFY_ENABLE_SIGNUP"}, Value: false, Usage: "xxx"}),
-	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-login", Aliases: []string{"enable_login"}, EnvVars: []string{"NTFY_ENABLE_LOGIN"}, Value: false, Usage: "xxx"}),
-	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-payments", Aliases: []string{"enable_payments"}, EnvVars: []string{"NTFY_ENABLE_PAYMENTS"}, Value: false, Usage: "xxx"}),
-	altsrc.NewBoolFlag(&cli.BoolFlag{Name: "enable-reservations", Aliases: []string{"enable_reservations"}, EnvVars: []string{"NTFY_ENABLE_RESERVATIONS"}, Value: false, Usage: "xxx"}),
 )
 
 var cmdServe = &cli.Command{
@@ -130,6 +130,10 @@ func execServe(c *cli.Context) error {
 	keepaliveInterval := c.Duration("keepalive-interval")
 	managerInterval := c.Duration("manager-interval")
 	webRoot := c.String("web-root")
+	enableSignup := c.Bool("enable-signup")
+	enableLogin := c.Bool("enable-login")
+	enablePayments := c.Bool("enable-payments")
+	enableReservations := c.Bool("enable-reservations")
 	upstreamBaseURL := c.String("upstream-base-url")
 	smtpSenderAddr := c.String("smtp-sender-addr")
 	smtpSenderUser := c.String("smtp-sender-user")
@@ -148,10 +152,6 @@ func execServe(c *cli.Context) error {
 	visitorEmailLimitBurst := c.Int("visitor-email-limit-burst")
 	visitorEmailLimitReplenish := c.Duration("visitor-email-limit-replenish")
 	behindProxy := c.Bool("behind-proxy")
-	enableSignup := c.Bool("enable-signup")
-	enableLogin := c.Bool("enable-login")
-	enablePayments := c.Bool("enable-payments")
-	enableReservations := c.Bool("enable-reservations")
 
 	// Check values
 	if firebaseKeyFile != "" && !util.FileExists(firebaseKeyFile) {
@@ -190,6 +190,8 @@ func execServe(c *cli.Context) error {
 		return errors.New("base-url and upstream-base-url cannot be identical, you'll likely want to set upstream-base-url to https://ntfy.sh, see https://ntfy.sh/docs/config/#ios-instant-notifications")
 	} else if authFile == "" && (enableSignup || enableLogin || enableReservations || enablePayments) {
 		return errors.New("cannot set enable-signup, enable-login, enable-reserve-topics, or enable-payments if auth-file is not set")
+	} else if enableSignup && !enableLogin {
+		return errors.New("cannot set enable-signup without also setting enable-login")
 	}
 
 	webRootIsApp := webRoot == "app"

+ 5 - 0
docs/config.md

@@ -1034,6 +1034,11 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
 | `visitor-request-limit-exempt-hosts`       | `NTFY_VISITOR_REQUEST_LIMIT_EXEMPT_HOSTS`       | *comma-separated host/IP list*                      | -                 | Rate limiting: List of hostnames and IPs to be exempt from request rate limiting                                                                                                                                                |
 | `visitor-subscription-limit`               | `NTFY_VISITOR_SUBSCRIPTION_LIMIT`               | *number*                                            | 30                | Rate limiting: Number of subscriptions per visitor (IP address)                                                                                                                                                                 |
 | `web-root`                                 | `NTFY_WEB_ROOT`                                 | `app`, `home` or `disable`                          | `app`             | Sets web root to landing page (home), web app (app) or disables the web app entirely (disable)                                                                                                                                  |
+| `enable-signup`                            | `NTFY_SIGNUP`                                   | *boolean* (`true` or `false`)                       | `false`           | Allows users to sign up via the web app, or API                                                                                                                                                                                 |
+| `enable-login`                             | `NTFY_LOGIN`                                    | *boolean* (`true` or `false`)                       | `false`           | Allows users to log in via the web app, or API                                                                                                                                                                                  |
+| `enable-reservations`                      | `NTFY_RESERVATIONS`                             | *boolean* (`true` or `false`)                       | `false`           | Allows users to reserve topics (if their tier allows it)                                                                                                                                                                        |
+| `enable-payments`                          | `NTFY_PAYMENTS`                                 | *boolean* (`true` or `false`)                       | `false`           | Enables payments integration (_preliminary option, may change_)                                                                                                                                                                 |
+
 
 The format for a *duration* is: `<number>(smh)`, e.g. 30s, 20m or 1h.   
 The format for a *size* is: `<number>(GMK)`, e.g. 1G, 200M or 4000k.

+ 3 - 0
docs/subscribe/api.md

@@ -319,6 +319,7 @@ format of the message. It's very straight forward:
 |--------------|----------|---------------------------------------------------|-------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|
 | `id`         | ✔️       | *string*                                          | `hwQ2YpKdmg`                                          | Randomly chosen message identifier                                                                                                   |
 | `time`       | ✔️       | *number*                                          | `1635528741`                                          | Message date time, as Unix time stamp                                                                                                |  
+| `expires`    | ✔️       | *number*                                          | `1673542291`                                          | Unix time stamp indicating when the message will be deleted                                                                          |  
 | `event`      | ✔️       | `open`, `keepalive`, `message`, or `poll_request` | `message`                                             | Message type, typically you'd be only interested in `message`                                                                        |
 | `topic`      | ✔️       | *string*                                          | `topic1,topic2`                                       | Comma-separated list of topics the message is associated with; only one for all `message` events, but may be a list in `open` events |
 | `message`    | -        | *string*                                          | `Some message`                                        | Message body; always present in `message` events                                                                                     |
@@ -346,6 +347,7 @@ Here's an example for each message type:
     {
         "id": "sPs71M8A2T",
         "time": 1643935928,
+        "expires": 1643936928,
         "event": "message",
         "topic": "mytopic",
         "priority": 5,
@@ -372,6 +374,7 @@ Here's an example for each message type:
     {
         "id": "wze9zgqK41",
         "time": 1638542110,
+        "expires": 1638543112,
         "event": "message",
         "topic": "phil_alerts",
         "message": "Remote access to phils-laptop detected. Act right away."

+ 1 - 5
server/server.go

@@ -47,18 +47,14 @@ import (
 		- flicker of upgrade banner
 		- JS constants
 		Sync:
-			- "account topic" sync mechanism
-				- subscribe to sync topic in UI
 			- "mute" setting
 			- figure out what settings are "web" or "phone"
+			- sync problems with "deleteAfter=0" and "displayName="
 		Delete visitor when tier is changed to refresh rate limiters
 		Tests:
 		- Change tier from higher to lower tier (delete reservations)
 		- Message rate limiting and reset tests
 		- test that the visitor is based on the IP address when a user has no tier
-		Docs:
-		- "expires" field in message
-		- server.yml: enable-X flags
 */
 
 // Server is the main server, providing the UI and API for ntfy

+ 13 - 0
server/server.yml

@@ -158,6 +158,19 @@
 #
 # web-root: app
 
+# Various feature flags used to control the web app, and API access, mainly around user and
+# account management.
+#
+# - enable-signup allows users to sign up via the web app, or API
+# - enable-login allows users to log in via the web app, or API
+# - enable-reservations allows users to reserve topics (if their tier allows it)
+# - enable-payments enables payments integration [preliminary option, may change]
+#
+# enable-signup: false
+# enable-login: false
+# enable-reservations: false
+# enable-payments: false
+
 # Server URL of a Firebase/APNS-connected ntfy server (likely "https://ntfy.sh").
 #
 # iOS users:

+ 1 - 1
server/server_account.go

@@ -320,7 +320,7 @@ func (s *Server) handleAccountReservationAdd(w http.ResponseWriter, r *http.Requ
 	if v.user != nil && v.user.Role == user.RoleAdmin {
 		return errHTTPBadRequestMakesNoSenseForAdmin
 	}
-	req, err := readJSONWithLimit[apiAccountAccessRequest](r.Body, jsonBodyBytesLimit)
+	req, err := readJSONWithLimit[apiAccountReservationRequest](r.Body, jsonBodyBytesLimit)
 	if err != nil {
 		return err
 	}

+ 5 - 5
server/types.go

@@ -23,10 +23,10 @@ const (
 
 // message represents a message published to a topic
 type message struct {
-	ID         string      `json:"id"`      // Random message ID
-	Time       int64       `json:"time"`    // Unix time in seconds
-	Expires    int64       `json:"expires"` // Unix time in seconds
-	Event      string      `json:"event"`   // One of the above
+	ID         string      `json:"id"`                // Random message ID
+	Time       int64       `json:"time"`              // Unix time in seconds
+	Expires    int64       `json:"expires,omitempty"` // Unix time in seconds (not required for open/keepalive)
+	Event      string      `json:"event"`             // One of the above
 	Topic      string      `json:"topic"`
 	Title      string      `json:"title,omitempty"`
 	Message    string      `json:"message,omitempty"`
@@ -281,7 +281,7 @@ type apiAccountResponse struct {
 	Stats         *apiAccountStats         `json:"stats,omitempty"`
 }
 
-type apiAccountAccessRequest struct {
+type apiAccountReservationRequest struct {
 	Topic    string `json:"topic"`
 	Everyone string `json:"everyone"`
 }