web-push-startup-queries
parent
88c6b4adae
commit
dc7dd836c6
|
@ -98,6 +98,7 @@ var flagsServe = append(
|
||||||
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-private-key", Aliases: []string{"web_push_private_key"}, EnvVars: []string{"NTFY_WEB_PUSH_PRIVATE_KEY"}, Usage: "private key used for web push notifications"}),
|
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-private-key", Aliases: []string{"web_push_private_key"}, EnvVars: []string{"NTFY_WEB_PUSH_PRIVATE_KEY"}, Usage: "private key used for web push notifications"}),
|
||||||
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-file", Aliases: []string{"web_push_file"}, EnvVars: []string{"NTFY_WEB_PUSH_FILE"}, Usage: "file used to store web push subscriptions"}),
|
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-file", Aliases: []string{"web_push_file"}, EnvVars: []string{"NTFY_WEB_PUSH_FILE"}, Usage: "file used to store web push subscriptions"}),
|
||||||
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-email-address", Aliases: []string{"web_push_email_address"}, EnvVars: []string{"NTFY_WEB_PUSH_EMAIL_ADDRESS"}, Usage: "e-mail address of sender, required to use browser push services"}),
|
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-email-address", Aliases: []string{"web_push_email_address"}, EnvVars: []string{"NTFY_WEB_PUSH_EMAIL_ADDRESS"}, Usage: "e-mail address of sender, required to use browser push services"}),
|
||||||
|
altsrc.NewStringFlag(&cli.StringFlag{Name: "web-push-startup-queries", Aliases: []string{"web_push_startup-queries"}, EnvVars: []string{"NTFY_WEB_PUSH_STARTUP_QUERIES"}, Usage: "queries run when the web push database is initialized"}),
|
||||||
)
|
)
|
||||||
|
|
||||||
var cmdServe = &cli.Command{
|
var cmdServe = &cli.Command{
|
||||||
|
@ -137,6 +138,7 @@ func execServe(c *cli.Context) error {
|
||||||
webPushPublicKey := c.String("web-push-public-key")
|
webPushPublicKey := c.String("web-push-public-key")
|
||||||
webPushFile := c.String("web-push-file")
|
webPushFile := c.String("web-push-file")
|
||||||
webPushEmailAddress := c.String("web-push-email-address")
|
webPushEmailAddress := c.String("web-push-email-address")
|
||||||
|
webPushStartupQueries := c.String("web-push-startup-queries")
|
||||||
cacheFile := c.String("cache-file")
|
cacheFile := c.String("cache-file")
|
||||||
cacheDuration := c.Duration("cache-duration")
|
cacheDuration := c.Duration("cache-duration")
|
||||||
cacheStartupQueries := c.String("cache-startup-queries")
|
cacheStartupQueries := c.String("cache-startup-queries")
|
||||||
|
@ -361,6 +363,7 @@ func execServe(c *cli.Context) error {
|
||||||
conf.WebPushPublicKey = webPushPublicKey
|
conf.WebPushPublicKey = webPushPublicKey
|
||||||
conf.WebPushFile = webPushFile
|
conf.WebPushFile = webPushFile
|
||||||
conf.WebPushEmailAddress = webPushEmailAddress
|
conf.WebPushEmailAddress = webPushEmailAddress
|
||||||
|
conf.WebPushStartupQueries = webPushStartupQueries
|
||||||
|
|
||||||
// Set up hot-reloading of config
|
// Set up hot-reloading of config
|
||||||
go sigHandlerConfigReload(config)
|
go sigHandlerConfigReload(config)
|
||||||
|
|
|
@ -803,6 +803,7 @@ a database to keep track of the browser's subscriptions, and an admin email addr
|
||||||
- `web-push-private-key` is the generated VAPID private key, e.g. AA2BB1234567890abcdefzxcvbnm1234567890
|
- `web-push-private-key` is the generated VAPID private key, e.g. AA2BB1234567890abcdefzxcvbnm1234567890
|
||||||
- `web-push-file` is a database file to keep track of browser subscription endpoints, e.g. `/var/cache/ntfy/webpush.db`
|
- `web-push-file` is a database file to keep track of browser subscription endpoints, e.g. `/var/cache/ntfy/webpush.db`
|
||||||
- `web-push-email-address` is the admin email address send to the push provider, e.g. `sysadmin@example.com`
|
- `web-push-email-address` is the admin email address send to the push provider, e.g. `sysadmin@example.com`
|
||||||
|
- `web-push-startup-queries` is an optional list of queries to run on startup`
|
||||||
|
|
||||||
Limitations:
|
Limitations:
|
||||||
|
|
||||||
|
@ -1339,6 +1340,7 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`).
|
||||||
| `web-push-private-key` | `NTFY_WEB_PUSH_PRIVATE_KEY` | *string* | - | Web Push: Private Key. Run `ntfy webpush keys` to generate |
|
| `web-push-private-key` | `NTFY_WEB_PUSH_PRIVATE_KEY` | *string* | - | Web Push: Private Key. Run `ntfy webpush keys` to generate |
|
||||||
| `web-push-file` | `NTFY_WEB_PUSH_FILE` | *string* | - | Web Push: Database file that stores subscriptions |
|
| `web-push-file` | `NTFY_WEB_PUSH_FILE` | *string* | - | Web Push: Database file that stores subscriptions |
|
||||||
| `web-push-email-address` | `NTFY_WEB_PUSH_EMAIL_ADDRESS` | *string* | - | Web Push: Sender email address |
|
| `web-push-email-address` | `NTFY_WEB_PUSH_EMAIL_ADDRESS` | *string* | - | Web Push: Sender email address |
|
||||||
|
| `web-push-startup-queries` | `NTFY_WEB_PUSH_STARTUP_QUERIES` | *string* | - | Web Push: SQL queries to run against subscription database at startup |
|
||||||
|
|
||||||
The format for a *duration* is: `<number>(smh)`, e.g. 30s, 20m or 1h.
|
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.
|
The format for a *size* is: `<number>(GMK)`, e.g. 1G, 200M or 4000k.
|
||||||
|
@ -1435,5 +1437,6 @@ OPTIONS:
|
||||||
--web-push-private-key value, --web_push_private_key value private key used for web push notifications [$NTFY_WEB_PUSH_PRIVATE_KEY]
|
--web-push-private-key value, --web_push_private_key value private key used for web push notifications [$NTFY_WEB_PUSH_PRIVATE_KEY]
|
||||||
--web-push-file value, --web_push_file value file used to store web push subscriptions [$NTFY_WEB_PUSH_FILE]
|
--web-push-file value, --web_push_file value file used to store web push subscriptions [$NTFY_WEB_PUSH_FILE]
|
||||||
--web-push-email-address value, --web_push_email_address value e-mail address of sender, required to use browser push services [$NTFY_WEB_PUSH_EMAIL_ADDRESS]
|
--web-push-email-address value, --web_push_email_address value e-mail address of sender, required to use browser push services [$NTFY_WEB_PUSH_EMAIL_ADDRESS]
|
||||||
|
--web-push-startup-queries value, --web_push_startup-queries value queries run when the web push database is initialized [$NTFY_WEB_PUSH_STARTUP_QUERIES]
|
||||||
--help, -h show help
|
--help, -h show help
|
||||||
```
|
```
|
||||||
|
|
|
@ -157,6 +157,7 @@ type Config struct {
|
||||||
WebPushPublicKey string
|
WebPushPublicKey string
|
||||||
WebPushFile string
|
WebPushFile string
|
||||||
WebPushEmailAddress string
|
WebPushEmailAddress string
|
||||||
|
WebPushStartupQueries string
|
||||||
WebPushExpiryDuration time.Duration
|
WebPushExpiryDuration time.Duration
|
||||||
WebPushExpiryWarningDuration time.Duration
|
WebPushExpiryWarningDuration time.Duration
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ func New(conf *Config) (*Server, error) {
|
||||||
}
|
}
|
||||||
var webPush *webPushStore
|
var webPush *webPushStore
|
||||||
if conf.WebPushPublicKey != "" {
|
if conf.WebPushPublicKey != "" {
|
||||||
webPush, err = newWebPushStore(conf.WebPushFile)
|
webPush, err = newWebPushStore(conf.WebPushFile, conf.WebPushStartupQueries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,18 +150,20 @@
|
||||||
# can enable background notifications in the web app. Once enabled, ntfy will forward published messages to the push
|
# can enable background notifications in the web app. Once enabled, ntfy will forward published messages to the push
|
||||||
# endpoint, which will then forward it to the browser.
|
# endpoint, which will then forward it to the browser.
|
||||||
#
|
#
|
||||||
# You must configure all settings below to enable Web Push.
|
# You must configure web-push-public/private key, web-push-file, and web-push-email-address below to enable Web Push.
|
||||||
# Run "ntfy webpush keys" to generate the keys.
|
# Run "ntfy webpush keys" to generate the keys.
|
||||||
#
|
#
|
||||||
# - web-push-public-key is the generated VAPID public key, e.g. AA1234BBCCddvveekaabcdfqwertyuiopasdfghjklzxcvbnm1234567890
|
# - web-push-public-key is the generated VAPID public key, e.g. AA1234BBCCddvveekaabcdfqwertyuiopasdfghjklzxcvbnm1234567890
|
||||||
# - web-push-private-key is the generated VAPID private key, e.g. AA2BB1234567890abcdefzxcvbnm1234567890
|
# - web-push-private-key is the generated VAPID private key, e.g. AA2BB1234567890abcdefzxcvbnm1234567890
|
||||||
# - web-push-file is a database file to keep track of browser subscription endpoints, e.g. `/var/cache/ntfy/webpush.db`
|
# - web-push-file is a database file to keep track of browser subscription endpoints, e.g. `/var/cache/ntfy/webpush.db`
|
||||||
# - web-push-email-address is the admin email address send to the push provider, e.g. `sysadmin@example.com`
|
# - web-push-email-address is the admin email address send to the push provider, e.g. `sysadmin@example.com`
|
||||||
|
# - web-push-startup-queries is an optional list of queries to run on startup`
|
||||||
#
|
#
|
||||||
# web-push-public-key:
|
# web-push-public-key:
|
||||||
# web-push-private-key:
|
# web-push-private-key:
|
||||||
# web-push-file:
|
# web-push-file:
|
||||||
# web-push-email-address:
|
# web-push-email-address:
|
||||||
|
# web-push-startup-queries:
|
||||||
|
|
||||||
# If enabled, ntfy can perform voice calls via Twilio via the "X-Call" header.
|
# If enabled, ntfy can perform voice calls via Twilio via the "X-Call" header.
|
||||||
#
|
#
|
||||||
|
|
|
@ -431,41 +431,6 @@ func TestAccount_Delete_Not_Allowed(t *testing.T) {
|
||||||
require.Equal(t, 40026, toHTTPError(t, rr.Body.String()).Code)
|
require.Equal(t, 40026, toHTTPError(t, rr.Body.String()).Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccount_Delete_Success_WithWebPush(t *testing.T) {
|
|
||||||
conf := configureAuth(t, newTestConfigWithWebPush(t))
|
|
||||||
conf.EnableSignup = true
|
|
||||||
s := newTestServer(t, conf)
|
|
||||||
|
|
||||||
// Add account
|
|
||||||
rr := request(t, s, "POST", "/v1/account", `{"username":"phil", "password":"mypass"}`, nil)
|
|
||||||
require.Equal(t, 200, rr.Code)
|
|
||||||
|
|
||||||
// Add web push subscription
|
|
||||||
rr = request(t, s, "POST", "/v1/webpush", payloadForTopics(t, []string{"mytopic"}, testWebPushEndpoint), map[string]string{
|
|
||||||
"Authorization": util.BasicAuth("phil", "mypass"),
|
|
||||||
})
|
|
||||||
require.Equal(t, 200, rr.Code)
|
|
||||||
|
|
||||||
u, err := s.userManager.User("phil")
|
|
||||||
require.Nil(t, err)
|
|
||||||
|
|
||||||
subs, err := s.webPush.SubscriptionsForTopic("mytopic")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.Len(t, subs, 1)
|
|
||||||
require.Equal(t, u.ID, subs[0].UserID)
|
|
||||||
|
|
||||||
// Delete account
|
|
||||||
rr = request(t, s, "DELETE", "/v1/account", `{"password":"mypass"}`, map[string]string{
|
|
||||||
"Authorization": util.BasicAuth("phil", "mypass"),
|
|
||||||
})
|
|
||||||
require.Equal(t, 200, rr.Code)
|
|
||||||
|
|
||||||
// Make sure web push subscription was deleted
|
|
||||||
subs, err = s.webPush.SubscriptionsForTopic("mytopic")
|
|
||||||
require.Nil(t, err)
|
|
||||||
require.Len(t, subs, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAccount_Reservation_AddWithoutTierFails(t *testing.T) {
|
func TestAccount_Reservation_AddWithoutTierFails(t *testing.T) {
|
||||||
conf := newTestConfigWithAuthFile(t)
|
conf := newTestConfigWithAuthFile(t)
|
||||||
conf.EnableSignup = true
|
conf.EnableSignup = true
|
||||||
|
|
|
@ -94,7 +94,7 @@ type webPushStore struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWebPushStore(filename string) (*webPushStore, error) {
|
func newWebPushStore(filename, startupQueries string) (*webPushStore, error) {
|
||||||
db, err := sql.Open("sqlite3", filename)
|
db, err := sql.Open("sqlite3", filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -102,7 +102,7 @@ func newWebPushStore(filename string) (*webPushStore, error) {
|
||||||
if err := setupWebPushDB(db); err != nil {
|
if err := setupWebPushDB(db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := runWebPushStartupQueries(db); err != nil {
|
if err := runWebPushStartupQueries(db, startupQueries); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &webPushStore{
|
return &webPushStore{
|
||||||
|
@ -129,9 +129,14 @@ func setupNewWebPushDB(db *sql.DB) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runWebPushStartupQueries(db *sql.DB) error {
|
func runWebPushStartupQueries(db *sql.DB, startupQueries string) error {
|
||||||
_, err := db.Exec(builtinStartupQueries)
|
if _, err := db.Exec(startupQueries); err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
if _, err := db.Exec(builtinStartupQueries); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpsertSubscription adds or updates Web Push subscriptions for the given topics and user ID. It always first deletes all
|
// UpsertSubscription adds or updates Web Push subscriptions for the given topics and user ID. It always first deletes all
|
||||||
|
|
|
@ -193,7 +193,7 @@ func TestWebPushStore_RemoveExpiredSubscriptions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestWebPushStore(t *testing.T) *webPushStore {
|
func newTestWebPushStore(t *testing.T) *webPushStore {
|
||||||
webPush, err := newWebPushStore(filepath.Join(t.TempDir(), "webpush.db"))
|
webPush, err := newWebPushStore(filepath.Join(t.TempDir(), "webpush.db"), "")
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
return webPush
|
return webPush
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue