Docs
This commit is contained in:
		
							parent
							
								
									24529bd0ad
								
							
						
					
					
						commit
						7007c0a0bd
					
				
					 7 changed files with 38 additions and 19 deletions
				
			
		
							
								
								
									
										18
									
								
								cmd/serve.go
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								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" | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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." | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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 | ||||
| 	} | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ const ( | |||
| 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 | ||||
| 	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"` | ||||
|  | @ -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"` | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue