From 5fefefc50fe1b406bc4ae46b8af21ef52c3b4dfc Mon Sep 17 00:00:00 2001 From: SWZ Date: Fri, 11 Nov 2022 16:26:27 +0100 Subject: [PATCH 01/36] Added translation using Weblate (Swedish) --- web/public/static/langs/sv.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 web/public/static/langs/sv.json diff --git a/web/public/static/langs/sv.json b/web/public/static/langs/sv.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/web/public/static/langs/sv.json @@ -0,0 +1 @@ +{} From fea9d10ed22c77a28de190f75da3455e46825e18 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 12 Nov 2022 06:56:40 -0500 Subject: [PATCH 02/36] Thank you @portothree for your sponsorship --- README.md | 1 + docs/integrations.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 7ea7500b..aa41f056 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ appreciated. A big fat **Thank You** to the folks already sponsoring ntfy: + ## License Made with ❤️ by [Philipp C. Heckel](https://heckel.io). diff --git a/docs/integrations.md b/docs/integrations.md index 658e6d79..4bce8c49 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -90,6 +90,7 @@ messages until I finally finish implementing end-to-end encryption. ## Blog + forum posts +- [TLDR Newsletter Daily Update 2022-11-09](https://tldr.tech/tech/newsletter/2022-11-09) - 11/2022 - [Ntfy.sh – Send push notifications to your phone via PUT/POST](https://news.ycombinator.com/item?id=33517944) ⭐ - 11/2022 - [Ntfy et Jeedom : un plugin](https://lunarok-domotique.com/2022/11/ntfy-et-jeedom/) - 11/2022 - [Crea tu propio servidor de notificaciones con Ntfy](https://blog.parravidales.es/crea-tu-propio-servidor-de-notificaciones-con-ntfy/) - 11/2022 From 7470ffde4f160431e6513192cf8aac52365eb6bd Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 12 Nov 2022 07:04:55 -0500 Subject: [PATCH 03/36] Bump deps --- go.mod | 12 ++++--- go.sum | 14 ++++++++ web/package-lock.json | 76 +++++++++++++++++++++---------------------- 3 files changed, 59 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index c8fb103d..81a20a1f 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( github.com/olebedev/when v0.0.0-20211212231525-59bd4edcf9d6 github.com/stretchr/testify v1.8.1 github.com/urfave/cli/v2 v2.23.5 - golang.org/x/crypto v0.1.0 - golang.org/x/oauth2 v0.1.0 // indirect + golang.org/x/crypto v0.2.0 + golang.org/x/oauth2 v0.2.0 // indirect golang.org/x/sync v0.1.0 golang.org/x/term v0.2.0 golang.org/x/time v0.2.0 @@ -25,17 +25,19 @@ require ( require github.com/pkg/errors v0.9.1 // indirect -require firebase.google.com/go/v4 v4.9.0 +require firebase.google.com/go/v4 v4.10.0 require ( - cloud.google.com/go v0.105.0 // indirect + cloud.google.com/go v0.106.0 // indirect cloud.google.com/go/compute v1.12.1 // indirect cloud.google.com/go/compute/metadata v0.2.1 // indirect cloud.google.com/go/iam v0.7.0 // indirect cloud.google.com/go/longrunning v0.3.0 // indirect github.com/AlekSi/pointer v1.2.0 // indirect + github.com/MicahParks/keyfunc v1.5.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead // indirect + github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.9 // indirect @@ -52,7 +54,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine/v2 v2.0.2 // indirect - google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd // indirect + google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ab3dee01..302bdc88 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= +cloud.google.com/go v0.106.0 h1:AWaMWuZb2oFeiV91OfNHZbmwUhMVuXEaLPm9sqDAOl8= +cloud.google.com/go v0.106.0/go.mod h1:5NEGxGuIeMQiPaWLwLYZ7kfNWiP6w1+QJK+xqyIT+dw= cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= @@ -21,12 +23,16 @@ cloud.google.com/go/storage v1.28.0 h1:DLrIZ6xkeZX6K70fU/boWx5INJumt6f+nwwWSHXzz cloud.google.com/go/storage v1.28.0/go.mod h1:qlgZML35PXA3zoEnIkiPLY4/TOkUleufRlu6qmcf7sI= firebase.google.com/go/v4 v4.9.0 h1:VCagv+hYOxUGeuyu7J+o2rKJkDp5JQBbA3Bzlof+LMk= firebase.google.com/go/v4 v4.9.0/go.mod h1:bHhRkM3VtGJx19rQdW7GDNLdnA8/T6SsnN5nXk/xdw8= +firebase.google.com/go/v4 v4.10.0 h1:dgK/8uwfJbzc5LZK/GyRRfIkZEDObN9q0kgEXsjlXN4= +firebase.google.com/go/v4 v4.10.0/go.mod h1:m0gLwPY9fxKggizzglgCNWOGnFnVPifLpqZzo5u3e/A= github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/MicahParks/keyfunc v1.5.3 h1:Y+mv+kX3HtL7/dCXXzK4bIDBHg91eunnGGkdndO0RWk= +github.com/MicahParks/keyfunc v1.5.3/go.mod h1:IdnCilugA0O/99dW+/MkvlyrsX8+L8+x95xuVNtM5jw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -46,6 +52,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q= github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -122,6 +130,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= +golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -142,6 +152,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= +golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= +golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -197,6 +209,8 @@ google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+C google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd h1:1eV6KuDTxraYYsYGWksp1thEGP+8dtX/TINL9h+ppiI= google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= +google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/web/package-lock.json b/web/package-lock.json index d4338d92..2fd105be 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -3370,9 +3370,9 @@ } }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.8.tgz", - "integrity": "sha512-wxXRwf+IQ6zvHSJZ+5T2RQNEsq+kx4jKRXfFvdt3nBIUzJUAvXEFsUeoaohDe/Kr84MTjGwcuIUPNcstNJORsA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.9.tgz", + "integrity": "sha512-7QV4cqUwhkDIHpMAZ9mestSJ2DMIotVTbOUwbiudhjCRTAWWKIaBecELiEM2LT3AHFeOAaHIcFu4dbXjX+9GBA==", "dependencies": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", @@ -3380,7 +3380,7 @@ "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.3", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, @@ -11512,9 +11512,9 @@ } }, "node_modules/loader-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", - "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -12495,9 +12495,9 @@ } }, "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", "funding": [ { "type": "opencollective", @@ -14032,9 +14032,9 @@ } }, "node_modules/react-dev-utils/node_modules/loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", "engines": { "node": ">= 12.13.0" } @@ -15500,9 +15500,9 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/tailwindcss": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", - "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "dependencies": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -16142,9 +16142,9 @@ } }, "node_modules/webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -19204,9 +19204,9 @@ } }, "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.8.tgz", - "integrity": "sha512-wxXRwf+IQ6zvHSJZ+5T2RQNEsq+kx4jKRXfFvdt3nBIUzJUAvXEFsUeoaohDe/Kr84MTjGwcuIUPNcstNJORsA==", + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.9.tgz", + "integrity": "sha512-7QV4cqUwhkDIHpMAZ9mestSJ2DMIotVTbOUwbiudhjCRTAWWKIaBecELiEM2LT3AHFeOAaHIcFu4dbXjX+9GBA==", "requires": { "ansi-html-community": "^0.0.8", "common-path-prefix": "^3.0.0", @@ -19214,7 +19214,7 @@ "error-stack-parser": "^2.0.6", "find-up": "^5.0.0", "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", + "loader-utils": "^2.0.3", "schema-utils": "^3.0.0", "source-map": "^0.7.3" }, @@ -25126,9 +25126,9 @@ "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==" }, "loader-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.3.tgz", - "integrity": "sha512-THWqIsn8QRnvLl0shHYVBN9syumU8pYWEHPTmkiVGd+7K5eFNVSY6AJhRvgGF70gg1Dz+l/k8WicvFCxdEs60A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "requires": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -25831,9 +25831,9 @@ } }, "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", + "version": "8.4.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.19.tgz", + "integrity": "sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==", "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -26762,9 +26762,9 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "loader-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.0.tgz", - "integrity": "sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", + "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==" }, "supports-color": { "version": "7.2.0", @@ -27854,9 +27854,9 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "tailwindcss": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.2.tgz", - "integrity": "sha512-c2GtSdqg+harR4QeoTmex0Ngfg8IIHNeLQH5yr2B9uZbZR1Xt1rYbjWOWTcj3YLTZhrmZnPowoQDbSRFyZHQ5Q==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.2.4.tgz", + "integrity": "sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==", "requires": { "arg": "^5.0.2", "chokidar": "^3.5.3", @@ -28319,9 +28319,9 @@ "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==" }, "webpack": { - "version": "5.74.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz", - "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==", + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", From 019e69ec857ac801749c625688294b272db3f985 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 12 Nov 2022 08:36:05 -0500 Subject: [PATCH 04/36] Added more projects --- docs/integrations.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/integrations.md b/docs/integrations.md index 9e6be590..7275553c 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -88,6 +88,8 @@ messages until I finally finish implementing end-to-end encryption. - [ntfy-to-slack](https://github.com/ozskywalker/ntfy-to-slack) - Tool to subscribe to a ntfy topic and send the messages to a Slack webhook (Go) - [ansible-ntfy](https://github.com/jpmens/ansible-ntfy) - Ansible action plugin to post JSON messages to ntfy (Python) - [ntfy-notification-channel](https://github.com/wijourdil/ntfy-notification-channel) - Laravel Notification channel for ntfy (PHP) +- [ntfy_on_a_chip](https://github.com/gergepalfi/ntfy_on_a_chip) - ESP8266 and ESP32 client code to communicate with ntfy +- [ntfy-sdk](https://gitlab.com/p2kishimoto/ntfy-sdk) - ntfy client library to send notifications (Rust) ## Blog + forum posts From 651c701b9dd7a961c17af2b896cfc90fe7487570 Mon Sep 17 00:00:00 2001 From: SWZ Date: Fri, 11 Nov 2022 15:28:46 +0000 Subject: [PATCH 05/36] Translated using Weblate (Swedish) Currently translated at 21.6% (41 of 189 strings) Translation: ntfy/Web app Translate-URL: https://hosted.weblate.org/projects/ntfy/web/sv/ --- web/public/static/langs/sv.json | 46 ++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/web/public/static/langs/sv.json b/web/public/static/langs/sv.json index 0967ef42..e857ed2b 100644 --- a/web/public/static/langs/sv.json +++ b/web/public/static/langs/sv.json @@ -1 +1,45 @@ -{} +{ + "action_bar_settings": "Inställningar", + "action_bar_send_test_notification": "Skicka test notis", + "action_bar_toggle_action_menu": "Öppna/stäng åtgärdsmeny", + "message_bar_type_message": "Skriv ett meddelande här", + "message_bar_error_publishing": "Fel vid publicering av notis", + "message_bar_show_dialog": "Visa publicerings dialog", + "message_bar_publish": "Publicera meddelande", + "nav_topics_title": "Prenumererade kategorier", + "nav_button_all_notifications": "Alla notiser", + "nav_button_documentation": "Dokumentation", + "nav_button_publish_message": "Publicera notis", + "nav_button_subscribe": "Prenumerera på kategori", + "alert_grant_title": "Notiser är avstängda", + "alert_grant_button": "Bevilja nu", + "alert_not_supported_title": "Notiser stöds inte", + "notifications_list": "Notis-lista", + "notifications_list_item": "Notis", + "notifications_delete": "Radera", + "notifications_copied_to_clipboard": "Kopierat till urklipp", + "notifications_tags": "Taggar", + "notifications_new_indicator": "Ny notis", + "notifications_attachment_copy_url_title": "Kopiera bifogad URL till urklipp", + "notifications_attachment_copy_url_button": "Kopiera URL", + "notifications_attachment_open_title": "Gå till {{url}}", + "notifications_attachment_open_button": "Öppna bilagan", + "notifications_attachment_link_expired": "Nedladdningslänk utgått", + "notifications_priority_x": "Prioritet {{priority}}", + "action_bar_show_menu": "Visa meny", + "action_bar_logo_alt": "ntfy logga", + "action_bar_unsubscribe": "Avprenumerera", + "action_bar_toggle_mute": "Tysta/aktivera notiser", + "action_bar_clear_notifications": "Rensa alla notiser", + "nav_button_connecting": "ansluter", + "notifications_attachment_image": "Bifogad bild", + "nav_button_settings": "Inställningar", + "nav_button_muted": "Notiser tystade", + "notifications_attachment_link_expires": "länken utgår {{date}}", + "notifications_attachment_file_image": "bild fil", + "notifications_attachment_file_audio": "ljud fil", + "alert_grant_description": "Ge din webbläsare behörighet att visa skrivbordsnotiser.", + "alert_not_supported_description": "Notiser stöds inte i din webbläsare.", + "notifications_mark_read": "Markera som läst", + "notifications_attachment_file_video": "video fil" +} From 4bcbea32abe127db4a1cc1d3b99c95a0adf2f7e4 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 12 Nov 2022 14:05:56 -0500 Subject: [PATCH 06/36] Bump --- docs/install.md | 60 +++++++++++++++++++++---------------------- docs/releases.md | 12 ++++++++- go.sum | 37 -------------------------- web/package-lock.json | 12 ++++----- 4 files changed, 47 insertions(+), 74 deletions(-) diff --git a/docs/install.md b/docs/install.md index cc1ef8bc..034c88d3 100644 --- a/docs/install.md +++ b/docs/install.md @@ -26,37 +26,37 @@ deb/rpm packages. === "x86_64/amd64" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_x86_64.tar.gz - tar zxvf ntfy_1.28.0_linux_x86_64.tar.gz - sudo cp -a ntfy_1.28.0_linux_x86_64/ntfy /usr/bin/ntfy - sudo mkdir /etc/ntfy && sudo cp ntfy_1.28.0_linux_x86_64/{client,server}/*.yml /etc/ntfy + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_x86_64.tar.gz + tar zxvf ntfy_1.29.0_linux_x86_64.tar.gz + sudo cp -a ntfy_1.29.0_linux_x86_64/ntfy /usr/bin/ntfy + sudo mkdir /etc/ntfy && sudo cp ntfy_1.29.0_linux_x86_64/{client,server}/*.yml /etc/ntfy sudo ntfy serve ``` === "armv6" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv6.tar.gz - tar zxvf ntfy_1.28.0_linux_armv6.tar.gz - sudo cp -a ntfy_1.28.0_linux_armv6/ntfy /usr/bin/ntfy - sudo mkdir /etc/ntfy && sudo cp ntfy_1.28.0_linux_armv6/{client,server}/*.yml /etc/ntfy + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv6.tar.gz + tar zxvf ntfy_1.29.0_linux_armv6.tar.gz + sudo cp -a ntfy_1.29.0_linux_armv6/ntfy /usr/bin/ntfy + sudo mkdir /etc/ntfy && sudo cp ntfy_1.29.0_linux_armv6/{client,server}/*.yml /etc/ntfy sudo ntfy serve ``` === "armv7/armhf" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv7.tar.gz - tar zxvf ntfy_1.28.0_linux_armv7.tar.gz - sudo cp -a ntfy_1.28.0_linux_armv7/ntfy /usr/bin/ntfy - sudo mkdir /etc/ntfy && sudo cp ntfy_1.28.0_linux_armv7/{client,server}/*.yml /etc/ntfy + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv7.tar.gz + tar zxvf ntfy_1.29.0_linux_armv7.tar.gz + sudo cp -a ntfy_1.29.0_linux_armv7/ntfy /usr/bin/ntfy + sudo mkdir /etc/ntfy && sudo cp ntfy_1.29.0_linux_armv7/{client,server}/*.yml /etc/ntfy sudo ntfy serve ``` === "arm64" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_arm64.tar.gz - tar zxvf ntfy_1.28.0_linux_arm64.tar.gz - sudo cp -a ntfy_1.28.0_linux_arm64/ntfy /usr/bin/ntfy - sudo mkdir /etc/ntfy && sudo cp ntfy_1.28.0_linux_arm64/{client,server}/*.yml /etc/ntfy + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_arm64.tar.gz + tar zxvf ntfy_1.29.0_linux_arm64.tar.gz + sudo cp -a ntfy_1.29.0_linux_arm64/ntfy /usr/bin/ntfy + sudo mkdir /etc/ntfy && sudo cp ntfy_1.29.0_linux_arm64/{client,server}/*.yml /etc/ntfy sudo ntfy serve ``` @@ -106,7 +106,7 @@ Manually installing the .deb file: === "x86_64/amd64" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_amd64.deb + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_amd64.deb sudo dpkg -i ntfy_*.deb sudo systemctl enable ntfy sudo systemctl start ntfy @@ -114,7 +114,7 @@ Manually installing the .deb file: === "armv6" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv6.deb + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv6.deb sudo dpkg -i ntfy_*.deb sudo systemctl enable ntfy sudo systemctl start ntfy @@ -122,7 +122,7 @@ Manually installing the .deb file: === "armv7/armhf" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv7.deb + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv7.deb sudo dpkg -i ntfy_*.deb sudo systemctl enable ntfy sudo systemctl start ntfy @@ -130,7 +130,7 @@ Manually installing the .deb file: === "arm64" ```bash - wget https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_arm64.deb + wget https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_arm64.deb sudo dpkg -i ntfy_*.deb sudo systemctl enable ntfy sudo systemctl start ntfy @@ -140,28 +140,28 @@ Manually installing the .deb file: === "x86_64/amd64" ```bash - sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_amd64.rpm + sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_amd64.rpm sudo systemctl enable ntfy sudo systemctl start ntfy ``` === "armv6" ```bash - sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv6.rpm + sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv6.rpm sudo systemctl enable ntfy sudo systemctl start ntfy ``` === "armv7/armhf" ```bash - sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_armv7.rpm + sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_armv7.rpm sudo systemctl enable ntfy sudo systemctl start ntfy ``` === "arm64" ```bash - sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_linux_arm64.rpm + sudo rpm -ivh https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_linux_arm64.rpm sudo systemctl enable ntfy sudo systemctl start ntfy ``` @@ -189,18 +189,18 @@ NixOS also supports [declarative setup of the ntfy server](https://search.nixos. ## macOS The [ntfy CLI](subscribe/cli.md) (`ntfy publish` and `ntfy subscribe` only) is supported on macOS as well. -To install, please [download the tarball](https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_macOS_all.tar.gz), +To install, please [download the tarball](https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_macOS_all.tar.gz), extract it and place it somewhere in your `PATH` (e.g. `/usr/local/bin/ntfy`). If run as `root`, ntfy will look for its config at `/etc/ntfy/client.yml`. For all other users, it'll look for it at `~/Library/Application Support/ntfy/client.yml` (sample included in the tarball). ```bash -curl -L https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_macOS_all.tar.gz > ntfy_1.28.0_macOS_all.tar.gz -tar zxvf ntfy_1.28.0_macOS_all.tar.gz -sudo cp -a ntfy_1.28.0_macOS_all/ntfy /usr/local/bin/ntfy +curl -L https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_macOS_all.tar.gz > ntfy_1.29.0_macOS_all.tar.gz +tar zxvf ntfy_1.29.0_macOS_all.tar.gz +sudo cp -a ntfy_1.29.0_macOS_all/ntfy /usr/local/bin/ntfy mkdir ~/Library/Application\ Support/ntfy -cp ntfy_1.28.0_macOS_all/client/client.yml ~/Library/Application\ Support/ntfy/client.yml +cp ntfy_1.29.0_macOS_all/client/client.yml ~/Library/Application\ Support/ntfy/client.yml ntfy --help ``` @@ -212,7 +212,7 @@ ntfy --help ## Windows The [ntfy CLI](subscribe/cli.md) (`ntfy publish` and `ntfy subscribe` only) is supported on Windows as well. -To install, please [download the latest ZIP](https://github.com/binwiederhier/ntfy/releases/download/v1.28.0/ntfy_1.28.0_windows_x86_64.zip), +To install, please [download the latest ZIP](https://github.com/binwiederhier/ntfy/releases/download/v1.29.0/ntfy_1.29.0_windows_x86_64.zip), extract it and place the `ntfy.exe` binary somewhere in your `%Path%`. The default path for the client config file is at `%AppData%\ntfy\client.yml` (not created automatically, sample in the ZIP file). diff --git a/docs/releases.md b/docs/releases.md index 08e903c0..d7990a6e 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -2,14 +2,24 @@ Binaries for all releases can be found on the GitHub releases pages for the [ntfy server](https://github.com/binwiederhier/ntfy/releases) and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/releases). + +## ntfy server v1.29.0 +Released November 12, 2022 -## ntfy server v1.29.0 (UNRELEASED) +This release adds the ability to add rate limit exemptions for IP ranges instead of just specific IP addresses. It also fixes +a few bugs in the web app and the CLI and adds lots of new examples and install instructions. + +Thanks to [some love on HN](https://news.ycombinator.com/item?id=33517944), we got so many new ntfy users trying out ntfy +and joining the [chat rooms](https://github.com/binwiederhier/ntfy#chat--forum). **Welcome to the ntfy community to all of you!** +We also got a ton of new **[sponsors and donations](https://github.com/sponsors/binwiederhier)** 💸, which is amazing. I'd like to thank +all of you for believing in the project, and for helping me pay the server cost. The HN spike increased the AWS cost quite a bit. **Features:** diff --git a/go.sum b/go.sum index 302bdc88..8c269ead 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,4 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= -cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM= cloud.google.com/go v0.106.0 h1:AWaMWuZb2oFeiV91OfNHZbmwUhMVuXEaLPm9sqDAOl8= cloud.google.com/go v0.106.0/go.mod h1:5NEGxGuIeMQiPaWLwLYZ7kfNWiP6w1+QJK+xqyIT+dw= cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= @@ -9,20 +7,12 @@ cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22m cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/firestore v1.8.0 h1:HokMB9Io0hAyYzlGFeFVMgE3iaPXNvaIsDx5JzblGLI= cloud.google.com/go/firestore v1.8.0/go.mod h1:r3KB8cAdRIe8znzoPWLw8S6gpDVd9treohhn8b09424= -cloud.google.com/go/iam v0.6.0 h1:nsqQC88kT5Iwlm4MeNGTpfMWddp6NB/UOLFTH6m1QfQ= -cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc= cloud.google.com/go/iam v0.7.0 h1:k4MuwOsS7zGJJ+QfZ5vBK8SgHBAvYN/23BWsiihJ1vs= cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg= -cloud.google.com/go/longrunning v0.2.1 h1:x3E/YapFCMe2G1D9qCv9COrBldOwK/n0OC7w9PLzeX0= -cloud.google.com/go/longrunning v0.2.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE= cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc= -cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= -cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/storage v1.28.0 h1:DLrIZ6xkeZX6K70fU/boWx5INJumt6f+nwwWSHXzzGY= cloud.google.com/go/storage v1.28.0/go.mod h1:qlgZML35PXA3zoEnIkiPLY4/TOkUleufRlu6qmcf7sI= -firebase.google.com/go/v4 v4.9.0 h1:VCagv+hYOxUGeuyu7J+o2rKJkDp5JQBbA3Bzlof+LMk= -firebase.google.com/go/v4 v4.9.0/go.mod h1:bHhRkM3VtGJx19rQdW7GDNLdnA8/T6SsnN5nXk/xdw8= firebase.google.com/go/v4 v4.10.0 h1:dgK/8uwfJbzc5LZK/GyRRfIkZEDObN9q0kgEXsjlXN4= firebase.google.com/go/v4 v4.10.0/go.mod h1:m0gLwPY9fxKggizzglgCNWOGnFnVPifLpqZzo5u3e/A= github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8= @@ -87,8 +77,6 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= -github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= -github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ= github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= @@ -109,27 +97,18 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/urfave/cli/v2 v2.23.0 h1:pkly7gKIeYv3olPAeNajNpLjeJrmTPYCoZWaV+2VfvE= -github.com/urfave/cli/v2 v2.23.0/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -145,13 +124,9 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= -golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -165,13 +140,9 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -180,8 +151,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA= -golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -192,8 +161,6 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= -google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/api v0.103.0 h1:9yuVqlu2JCvcLg9p8S3fcFLZij8EPSyvODIY1rkMizQ= google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -205,10 +172,6 @@ google.golang.org/appengine/v2 v2.0.2/go.mod h1:PkgRUWz4o1XOvbqtWTkBtCitEJ5Tp4Ho google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c h1:QgY/XxIAIeccR+Ca/rDdKubLIU9rcJ3xfy1DC/Wd2Oo= -google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo= -google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd h1:1eV6KuDTxraYYsYGWksp1thEGP+8dtX/TINL9h+ppiI= -google.golang.org/genproto v0.0.0-20221107162902-2d387536bcdd/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/web/package-lock.json b/web/package-lock.json index 2fd105be..3ff6b519 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -5815,9 +5815,9 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -21021,9 +21021,9 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", From a43a4aea5ec437d5ddd00038a7ec038b204ff26d Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 12 Nov 2022 14:41:28 -0500 Subject: [PATCH 07/36] Docs --- docs/integrations.md | 2 ++ server/server.yml | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/integrations.md b/docs/integrations.md index 7275553c..c1ff77d1 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -93,6 +93,8 @@ messages until I finally finish implementing end-to-end encryption. ## Blog + forum posts +- [Envie Push Notifications por POST (de graça e sem cadastro)](https://www.tabnews.com.br/filipedeschamps/envie-push-notifications-por-post-de-graca-e-sem-cadastro) - 11/2022 +- [Push Notifications for KDE](https://volkerkrause.eu/2022/11/12/kde-unifiedpush-push-notifications.html) - 11/2022 - [TLDR Newsletter Daily Update 2022-11-09](https://tldr.tech/tech/newsletter/2022-11-09) - 11/2022 - [Ntfy.sh – Send push notifications to your phone via PUT/POST](https://news.ycombinator.com/item?id=33517944) ⭐ - 11/2022 - [Ntfy et Jeedom : un plugin](https://lunarok-domotique.com/2022/11/ntfy-et-jeedom/) - 11/2022 diff --git a/server/server.yml b/server/server.yml index 245bc4da..9476478f 100644 --- a/server/server.yml +++ b/server/server.yml @@ -173,8 +173,9 @@ # Rate limiting: Allowed GET/PUT/POST requests per second, per visitor: # - visitor-request-limit-burst is the initial bucket of requests each visitor has # - visitor-request-limit-replenish is the rate at which the bucket is refilled -# - visitor-request-limit-exempt-hosts is a comma-separated list of hostnames and IPs to be -# exempt from request rate limiting; hostnames are resolved at the time the server is started +# - visitor-request-limit-exempt-hosts is a comma-separated list of hostnames, IPs or CIDRs to be +# exempt from request rate limiting. Hostnames are resolved at the time the server is started. +# Example: "1.2.3.4,ntfy.example.com,8.7.6.0/24" # # visitor-request-limit-burst: 60 # visitor-request-limit-replenish: "5s" From b103caf9d410b59afbd2f04b1670c1afeaf48f09 Mon Sep 17 00:00:00 2001 From: ksurl Date: Sat, 12 Nov 2022 13:05:19 -0800 Subject: [PATCH 08/36] add github actions example --- docs/examples.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 4ac7a4b2..b9adf443 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -122,6 +122,19 @@ to ntfy at its default URL (`attrs` and other attributes are optional): priority: 1 ``` +## GitHub Actions +You can send a message during a workflow run with curl. Here is an example sending info about the repo, commit and job status. +``` yaml +- name: Actions Ntfy + run: | + curl \ + -u ${{ secrets.NTFY_CRED }} \ + -H "Title: Title here" \ + -H "Content-Type: text/plain" \ + -d $'Repo: ${{ github.repository }}\nCommit: ${{ github.sha }}\nRef: ${{ github.ref }}\nStatus: ${{ job.status}}' \ + ${{ secrets.NTFY_URL }} +``` + ## Watchtower (shoutrrr) You can use [shoutrrr](https://github.com/containrrr/shoutrrr) generic webhook support to send [Watchtower](https://github.com/containrrr/watchtower/) notifications to your ntfy topic. From e236214fd52ac81fd07babf43e29d61c2a7446f5 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 06:24:57 -0500 Subject: [PATCH 09/36] Add post --- docs/integrations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/integrations.md b/docs/integrations.md index c1ff77d1..5329766b 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -93,6 +93,7 @@ messages until I finally finish implementing end-to-end encryption. ## Blog + forum posts +- [Pointer | Issue #367](https://www.pointer.io/archives/a9495a2a6f/) - 11/2022 - [Envie Push Notifications por POST (de graça e sem cadastro)](https://www.tabnews.com.br/filipedeschamps/envie-push-notifications-por-post-de-graca-e-sem-cadastro) - 11/2022 - [Push Notifications for KDE](https://volkerkrause.eu/2022/11/12/kde-unifiedpush-push-notifications.html) - 11/2022 - [TLDR Newsletter Daily Update 2022-11-09](https://tldr.tech/tech/newsletter/2022-11-09) - 11/2022 From bcc20e0aec31eb443d543a3223f44ecb7702680c Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 06:28:10 -0500 Subject: [PATCH 10/36] Release notes --- docs/releases.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/releases.md b/docs/releases.md index d7990a6e..0f5add76 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -5,6 +5,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release +## ntfy server v1.30.0 (UNRELREASED) + +**Documentation:** + +* GitHub Actions example ([#492](https://github.com/binwiederhier/ntfy/pull/492), thanks to [@ksurl](https://github.com/ksurl)) + ## ntfy server v1.29.0 Released November 12, 2022 From 08bb0103e86b302eba5eaddc3e7559600ddd829c Mon Sep 17 00:00:00 2001 From: Jonathan Carroll Date: Sun, 13 Nov 2022 14:07:27 -0800 Subject: [PATCH 12/36] add R wrapper --- docs/integrations.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/integrations.md b/docs/integrations.md index 5329766b..008d37c1 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -47,6 +47,7 @@ messages until I finally finish implementing end-to-end encryption. - [ntfy-middleman](https://github.com/nachotp/ntfy-middleman) - Wraps APIs and send notifications using ntfy.sh on schedule (Python) - [ntfy-dotnet](https://github.com/nwithan8/ntfy-dotnet) - .NET client library to interact with a ntfy server (C# / .NET) - [node-ntfy-publish](https://github.com/cityssm/node-ntfy-publish) - A Node package to publish notifications to an ntfy server (Node) +- [ntfy](https://github.com/jonocarroll/ntfy) - Wraps the ntfy API with pipe-friendly tooling (R) ## CLIs + GUIs From aff193a0036d0120c515e301d7e06f3ce865728a Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 20:59:12 -0500 Subject: [PATCH 13/36] Testing docs workflow (1) --- .github/workflows/docs.yaml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/docs.yaml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 00000000..2a744a3a --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,36 @@ +name: docs +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - + name: Checkout ntfy code + uses: actions/checkout@v3 + with: + path: ntfy + - + name: Checkout docs pages code + uses: actions/checkout@v3 + with: + repository: binwiederhier/ntfy-docs.github.io + path: ntfy-docs.github.io + - + name: Build docs + run: | + pwd + ls + cd ntfy + make docs + rsync -av --delete docs/ ../ntfy-docs.github.io/docs/ + - + name: Publish docs + run: | + pwd + ls + cd ntfy-docs.github.io + git config user.name "GitHub Actions Bot" + git config user.email "<>" + git add docs/ + git commit -m "Updated docs" + git push origin main From 069617eba0f67425c1312622502da0009310dfdd Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:05:03 -0500 Subject: [PATCH 14/36] Testing docs workflow (2) --- .github/workflows/docs.yaml | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 2a744a3a..238b99dd 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -7,28 +7,22 @@ jobs: - name: Checkout ntfy code uses: actions/checkout@v3 - with: - path: ntfy - name: Checkout docs pages code uses: actions/checkout@v3 with: repository: binwiederhier/ntfy-docs.github.io - path: ntfy-docs.github.io + path: build/ntfy-docs.github.io - name: Build docs - run: | - pwd - ls - cd ntfy - make docs - rsync -av --delete docs/ ../ntfy-docs.github.io/docs/ + run: make docs + - + name: Copy generated docs + run: rsync -av --delete docs/ build/ntfy-docs.github.io/docs/ - name: Publish docs run: | - pwd - ls - cd ntfy-docs.github.io + cd build/ntfy-docs.github.io git config user.name "GitHub Actions Bot" git config user.email "<>" git add docs/ From f4cb447f0a57f0cb82f0bcc9a9083d87a7f96761 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:08:25 -0500 Subject: [PATCH 15/36] Testing docs workflow (3) --- .github/workflows/docs.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 238b99dd..88c7cf46 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -15,10 +15,12 @@ jobs: path: build/ntfy-docs.github.io - name: Build docs - run: make docs + run: | + make docs + ls server/docs/ - name: Copy generated docs - run: rsync -av --delete docs/ build/ntfy-docs.github.io/docs/ + run: rsync -av --delete server/docs/ build/ntfy-docs.github.io/docs/ - name: Publish docs run: | From 18d36e1b30c1e6c63a7b42350c99649e41fcce14 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:11:51 -0500 Subject: [PATCH 16/36] Testing docs workflow (4) --- .github/workflows/docs.yaml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 88c7cf46..a974fb68 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,7 +1,7 @@ name: docs on: [push, pull_request] jobs: - build: + docs: runs-on: ubuntu-latest steps: - @@ -20,7 +20,12 @@ jobs: ls server/docs/ - name: Copy generated docs - run: rsync -av --delete server/docs/ build/ntfy-docs.github.io/docs/ + run: | + echo "New docs:" + ls -1 server/docs/ + echo "Existing docs:" + ls -1 build/ntfy-docs.github.io/docs/ + rsync -av --delete server/docs/ build/ntfy-docs.github.io/docs/ - name: Publish docs run: | From b92b5b37fb9ece825283d3ba2da89100570b1843 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:23:25 -0500 Subject: [PATCH 17/36] Testing docs workflow (5) --- .github/workflows/docs.yaml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index a974fb68..2777d301 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -13,19 +13,13 @@ jobs: with: repository: binwiederhier/ntfy-docs.github.io path: build/ntfy-docs.github.io + token: ${{secrets.NTFY_DOCS_PUBLISH_TOKEN}} - name: Build docs - run: | - make docs - ls server/docs/ + run: make docs - name: Copy generated docs - run: | - echo "New docs:" - ls -1 server/docs/ - echo "Existing docs:" - ls -1 build/ntfy-docs.github.io/docs/ - rsync -av --delete server/docs/ build/ntfy-docs.github.io/docs/ + run: rsync -av --exclude CNAME --delete server/docs/ build/ntfy-docs.github.io/docs/ - name: Publish docs run: | From adda27ec577efa9b9e46b89cc3a06b4d5d47abd7 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:33:27 -0500 Subject: [PATCH 18/36] Rename secret token --- .github/workflows/docs.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 2777d301..dee19c6f 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -13,7 +13,9 @@ jobs: with: repository: binwiederhier/ntfy-docs.github.io path: build/ntfy-docs.github.io - token: ${{secrets.NTFY_DOCS_PUBLISH_TOKEN}} + token: ${{secrets.NTFY_DOCS_PUSH_TOKEN}} + # Expires after 1 year, re-generate via + # User -> Settings -> Developer options -> Personal Access Tokens -> Fine Grained Token - name: Build docs run: make docs From 61b2d925950332ceb1a5cd082efe2ddd38050829 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:39:36 -0500 Subject: [PATCH 19/36] Update "on:" config --- .github/workflows/docs.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index dee19c6f..acd637bb 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -1,7 +1,11 @@ name: docs -on: [push, pull_request] +on: + push: + branches: + - main + - publish-docs jobs: - docs: + publish-docs: runs-on: ubuntu-latest steps: - From df45459618ff03c159111eccecd988cb61f50c4d Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sun, 13 Nov 2022 21:40:39 -0500 Subject: [PATCH 20/36] Remove test branch --- .github/workflows/docs.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index acd637bb..2ba9b9c6 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -3,7 +3,6 @@ on: push: branches: - main - - publish-docs jobs: publish-docs: runs-on: ubuntu-latest From a0f2d81337f54fd0ede6679bbff43f60a349f34f Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Mon, 14 Nov 2022 06:52:41 -0500 Subject: [PATCH 21/36] Release notes --- docs/releases.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/releases.md b/docs/releases.md index eaa09841..48c396bd 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -2,7 +2,6 @@ Binaries for all releases can be found on the GitHub releases pages for the [ntfy server](https://github.com/binwiederhier/ntfy/releases) and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/releases). - ## ntfy server v1.30.0 (UNRELREASED) @@ -20,6 +18,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release * GitHub Actions example ([#492](https://github.com/binwiederhier/ntfy/pull/492), thanks to [@ksurl](https://github.com/ksurl)) +**Other things:** + +* Put ntfy.sh/docs assets on GitHub pages to reduce AWS outbound traffic cost ([#491](https://github.com/binwiederhier/ntfy/issues/491)) + ## ntfy server v1.29.0 Released November 12, 2022 From e7b575badcc793c85c9e8c66e62c8a68801a06f4 Mon Sep 17 00:00:00 2001 From: bt90 Date: Mon, 14 Nov 2022 19:38:55 +0100 Subject: [PATCH 22/36] Add UnifiedPush section --- docs/config.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/config.md b/docs/config.md index babb5839..fd367f00 100644 --- a/docs/config.md +++ b/docs/config.md @@ -309,6 +309,22 @@ with the given username/password. Be sure to use HTTPS to avoid eavesdropping an ])); ``` +### UnifiedPush compatibility + +UnifiedPush requires that the [application server](https://unifiedpush.org/spec/definitions/#application-server) (e.g. Synapse, Fediverse Server, …) has anonymous write access to the [topic](https://unifiedpush.org/spec/definitions/#endpoint) used for push messages. The topic names used by UnifiedPush all start with the `up` prefix. You should either allow anonymous write access for the entire prefix or explicitly per topic: + +=== "Prefix" + ``` + $ ntfy access '*' 'up*' write-only + ``` + +=== "Explicitly" + ``` + $ ntfy access '*' 'upYzMtZGZiYTY5' write-only + ``` + +see https://unifiedpush.org/users/distributors/ntfy/#limit-access-to-some-users + ## E-mail notifications To allow forwarding messages via e-mail, you can configure an **SMTP server for outgoing messages**. Once configured, you can set the `X-Email` header to [send messages via e-mail](publish.md#e-mail-notifications) (e.g. From fd7f83378d74864be430e03ee7b3d34015a18d31 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Mon, 14 Nov 2022 15:21:02 -0500 Subject: [PATCH 23/36] Refine UP docs --- docs/config.md | 13 ++++++++----- docs/releases.md | 3 ++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docs/config.md b/docs/config.md index fd367f00..655b56cf 100644 --- a/docs/config.md +++ b/docs/config.md @@ -309,9 +309,14 @@ with the given username/password. Be sure to use HTTPS to avoid eavesdropping an ])); ``` -### UnifiedPush compatibility +### Example: UnifiedPush +[UnifiedPush](https://unifiedpush.org) requires that the [application server](https://unifiedpush.org/spec/definitions/#application-server) (e.g. Synapse, Fediverse Server, …) +has anonymous write access to the [topic](https://unifiedpush.org/spec/definitions/#endpoint) used for push messages. +The topic names used by UnifiedPush all start with the `up*` prefix. Please refer to the +**[UnifiedPush documentation](https://unifiedpush.org/users/distributors/ntfy/#limit-access-to-some-users)** for more details. -UnifiedPush requires that the [application server](https://unifiedpush.org/spec/definitions/#application-server) (e.g. Synapse, Fediverse Server, …) has anonymous write access to the [topic](https://unifiedpush.org/spec/definitions/#endpoint) used for push messages. The topic names used by UnifiedPush all start with the `up` prefix. You should either allow anonymous write access for the entire prefix or explicitly per topic: +To enable support for UnifiedPush for private servers (i.e. `auth-default-access: "deny-all"`), you should either +allow anonymous write access for the entire prefix or explicitly per topic: === "Prefix" ``` @@ -320,11 +325,9 @@ UnifiedPush requires that the [application server](https://unifiedpush.org/spec/ === "Explicitly" ``` - $ ntfy access '*' 'upYzMtZGZiYTY5' write-only + $ ntfy access '*' upYzMtZGZiYTY5 write-only ``` -see https://unifiedpush.org/users/distributors/ntfy/#limit-access-to-some-users - ## E-mail notifications To allow forwarding messages via e-mail, you can configure an **SMTP server for outgoing messages**. Once configured, you can set the `X-Email` header to [send messages via e-mail](publish.md#e-mail-notifications) (e.g. diff --git a/docs/releases.md b/docs/releases.md index 48c396bd..f5fc9a49 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -17,10 +17,11 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release **Documentation:** * GitHub Actions example ([#492](https://github.com/binwiederhier/ntfy/pull/492), thanks to [@ksurl](https://github.com/ksurl)) +* UnifiedPush ACL clarification ([#497](https://github.com/binwiederhier/ntfy/issues/497), thanks to [@bt90](https://github.com/bt90)) **Other things:** -* Put ntfy.sh/docs assets on GitHub pages to reduce AWS outbound traffic cost ([#491](https://github.com/binwiederhier/ntfy/issues/491)) +* Put ntfy.sh docs on GitHub pages to reduce AWS outbound traffic cost ([#491](https://github.com/binwiederhier/ntfy/issues/491)) ## ntfy server v1.29.0 Released November 12, 2022 From 499ac76c4343b728caac5851fcb0fbc5ac288a93 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Tue, 15 Nov 2022 09:09:31 -0500 Subject: [PATCH 24/36] Thank you @finngreig for your sponsorship --- README.md | 1 + docs/integrations.md | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index aa41f056..d9bfae0f 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ appreciated. A big fat **Thank You** to the folks already sponsoring ntfy: + ## License Made with ❤️ by [Philipp C. Heckel](https://heckel.io). diff --git a/docs/integrations.md b/docs/integrations.md index 008d37c1..d6837a3b 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -94,6 +94,7 @@ messages until I finally finish implementing end-to-end encryption. ## Blog + forum posts +- [Tracking layoffs, tech worker demand still high, ntfy, devenv, Markdoc & Mike Bifulco](https://changelog.com/news/tracking-layoffs-tech-worker-demand-still-high-ntfy-devenv-markdoc-mike-bifulco-Y1jW) - 11/2022 - [Pointer | Issue #367](https://www.pointer.io/archives/a9495a2a6f/) - 11/2022 - [Envie Push Notifications por POST (de graça e sem cadastro)](https://www.tabnews.com.br/filipedeschamps/envie-push-notifications-por-post-de-graca-e-sem-cadastro) - 11/2022 - [Push Notifications for KDE](https://volkerkrause.eu/2022/11/12/kde-unifiedpush-push-notifications.html) - 11/2022 From ebfbf7cc8efc627eeb4bf6ffc94da98d7cedd6ff Mon Sep 17 00:00:00 2001 From: Quentin JOLY <82603435+QJoly@users.noreply.github.com> Date: Tue, 15 Nov 2022 14:10:55 +0000 Subject: [PATCH 25/36] Bad indent --- docs/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install.md b/docs/install.md index 034c88d3..2ee0f584 100644 --- a/docs/install.md +++ b/docs/install.md @@ -431,7 +431,7 @@ Configuration is relatively straightforward. As an exmaple, a minimal configurat metadata: name: ntfy data: - server.yml: | + server.yml: | # Template: https://github.com/binwiederhier/ntfy/blob/main/server/server.yml base-url: https://ntfy.sh ``` From b4933a5645f296c519f12a8f78bdeb7cfd3f17b9 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Tue, 15 Nov 2022 14:24:56 -0500 Subject: [PATCH 26/36] WIP: Batch message INSERTs --- server/message_cache.go | 28 +++++++++++++++---- server/server.go | 6 ++-- util/batching_queue.go | 56 +++++++++++++++++++++++++++++++++++++ util/batching_queue_test.go | 25 +++++++++++++++++ 4 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 util/batching_queue.go create mode 100644 util/batching_queue_test.go diff --git a/server/message_cache.go b/server/message_cache.go index f4433399..ec710e4f 100644 --- a/server/message_cache.go +++ b/server/message_cache.go @@ -188,8 +188,9 @@ const ( ) type messageCache struct { - db *sql.DB - nop bool + db *sql.DB + queue *util.BatchingQueue[*message] + nop bool } // newSqliteCache creates a SQLite file-backed cache @@ -201,10 +202,21 @@ func newSqliteCache(filename, startupQueries string, nop bool) (*messageCache, e if err := setupCacheDB(db, startupQueries); err != nil { return nil, err } - return &messageCache{ - db: db, - nop: nop, - }, nil + queue := util.NewBatchingQueue[*message](20, 500*time.Millisecond) + cache := &messageCache{ + db: db, + queue: queue, + nop: nop, + } + go func() { + for messages := range queue.Pop() { + log.Debug("Adding %d messages to cache", len(messages)) + if err := cache.addMessages(messages); err != nil { + log.Error("error: %s", err.Error()) + } + } + }() + return cache, nil } // newMemCache creates an in-memory cache @@ -232,6 +244,10 @@ func (c *messageCache) AddMessage(m *message) error { return c.addMessages([]*message{m}) } +func (c *messageCache) QueueMessage(m *message) { + c.queue.Push(m) +} + func (c *messageCache) addMessages(ms []*message) error { if c.nop { return nil diff --git a/server/server.go b/server/server.go index ef09100d..b90b7630 100644 --- a/server/server.go +++ b/server/server.go @@ -491,9 +491,11 @@ func (s *Server) handlePublishWithoutResponse(r *http.Request, v *visitor) (*mes log.Debug("%s Message delayed, will process later", logMessagePrefix(v, m)) } if cache { - if err := s.messageCache.AddMessage(m); err != nil { + log.Trace("%s Queuing for cache", logMessagePrefix(v, m)) + s.messageCache.QueueMessage(m) + /*if err := s.messageCache.AddMessage(m); err != nil { return nil, err - } + }*/ } s.mu.Lock() s.messages++ diff --git a/util/batching_queue.go b/util/batching_queue.go new file mode 100644 index 00000000..78116470 --- /dev/null +++ b/util/batching_queue.go @@ -0,0 +1,56 @@ +package util + +import ( + "sync" + "time" +) + +type BatchingQueue[T any] struct { + batchSize int + timeout time.Duration + in []T + out chan []T + mu sync.Mutex +} + +func NewBatchingQueue[T any](batchSize int, timeout time.Duration) *BatchingQueue[T] { + q := &BatchingQueue[T]{ + batchSize: batchSize, + timeout: timeout, + in: make([]T, 0), + out: make(chan []T), + } + ticker := time.NewTicker(timeout) + go func() { + for range ticker.C { + elements := q.popAll() + if len(elements) > 0 { + q.out <- elements + } + } + }() + return q +} + +func (c *BatchingQueue[T]) Push(element T) { + c.mu.Lock() + c.in = append(c.in, element) + limitReached := len(c.in) == c.batchSize + c.mu.Unlock() + if limitReached { + c.out <- c.popAll() + } +} + +func (c *BatchingQueue[T]) Pop() <-chan []T { + return c.out +} + +func (c *BatchingQueue[T]) popAll() []T { + c.mu.Lock() + defer c.mu.Unlock() + elements := make([]T, len(c.in)) + copy(elements, c.in) + c.in = c.in[:0] + return elements +} diff --git a/util/batching_queue_test.go b/util/batching_queue_test.go new file mode 100644 index 00000000..46bc06b8 --- /dev/null +++ b/util/batching_queue_test.go @@ -0,0 +1,25 @@ +package util_test + +import ( + "fmt" + "heckel.io/ntfy/util" + "math/rand" + "testing" + "time" +) + +func TestConcurrentQueue_Next(t *testing.T) { + q := util.NewBatchingQueue[int](25, 200*time.Millisecond) + go func() { + for batch := range q.Pop() { + fmt.Printf("Batch of %d items\n", len(batch)) + } + }() + for i := 0; i < 1000; i++ { + go func(i int) { + time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) + q.Push(i) + }(i) + } + time.Sleep(2 * time.Second) +} From ad860afb8b3715794d7a6d6d6bd3e25440895c12 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 10:28:20 -0500 Subject: [PATCH 27/36] Polish async batching --- cmd/serve.go | 6 +++ server/config.go | 4 ++ server/message_cache.go | 80 +++++++++++++++++++++++++++--------- server/message_cache_test.go | 10 ++--- server/server.go | 9 ++-- server/server.yml | 2 + util/batching_queue.go | 73 +++++++++++++++++++++----------- util/batching_queue_test.go | 43 +++++++++++++++---- 8 files changed, 166 insertions(+), 61 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index aff7c7c8..ecc4d4a1 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -44,6 +44,8 @@ var flagsServe = append( altsrc.NewStringFlag(&cli.StringFlag{Name: "firebase-key-file", Aliases: []string{"firebase_key_file", "F"}, EnvVars: []string{"NTFY_FIREBASE_KEY_FILE"}, Usage: "Firebase credentials file; if set additionally publish to FCM topic"}), altsrc.NewStringFlag(&cli.StringFlag{Name: "cache-file", Aliases: []string{"cache_file", "C"}, EnvVars: []string{"NTFY_CACHE_FILE"}, Usage: "cache file used for message caching"}), altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-duration", Aliases: []string{"cache_duration", "b"}, EnvVars: []string{"NTFY_CACHE_DURATION"}, Value: server.DefaultCacheDuration, Usage: "buffer messages for this time to allow `since` requests"}), + altsrc.NewIntFlag(&cli.IntFlag{Name: "cache-batch-size", Aliases: []string{"cache_batch_size"}, EnvVars: []string{"NTFY_BATCH_SIZE"}, Usage: "max size of messages to batch together when writing to message cache (if zero, writes are synchronous)"}), + altsrc.NewDurationFlag(&cli.DurationFlag{Name: "cache-batch-timeout", Aliases: []string{"cache_batch_timeout"}, EnvVars: []string{"NTFY_CACHE_BATCH_TIMEOUT"}, Usage: "timeout for batched async writes to the message cache (if zero, writes are synchronous)"}), altsrc.NewStringFlag(&cli.StringFlag{Name: "cache-startup-queries", Aliases: []string{"cache_startup_queries"}, EnvVars: []string{"NTFY_CACHE_STARTUP_QUERIES"}, Usage: "queries run when the cache database is initialized"}), altsrc.NewStringFlag(&cli.StringFlag{Name: "auth-file", Aliases: []string{"auth_file", "H"}, EnvVars: []string{"NTFY_AUTH_FILE"}, Usage: "auth database file used for access control"}), altsrc.NewStringFlag(&cli.StringFlag{Name: "auth-default-access", Aliases: []string{"auth_default_access", "p"}, EnvVars: []string{"NTFY_AUTH_DEFAULT_ACCESS"}, Value: "read-write", Usage: "default permissions if no matching entries in the auth database are found"}), @@ -110,6 +112,8 @@ func execServe(c *cli.Context) error { cacheFile := c.String("cache-file") cacheDuration := c.Duration("cache-duration") cacheStartupQueries := c.String("cache-startup-queries") + cacheBatchSize := c.Int("cache-batch-size") + cacheBatchTimeout := c.Duration("cache-batch-timeout") authFile := c.String("auth-file") authDefaultAccess := c.String("auth-default-access") attachmentCacheDir := c.String("attachment-cache-dir") @@ -233,6 +237,8 @@ func execServe(c *cli.Context) error { conf.CacheFile = cacheFile conf.CacheDuration = cacheDuration conf.CacheStartupQueries = cacheStartupQueries + conf.CacheBatchSize = cacheBatchSize + conf.CacheBatchTimeout = cacheBatchTimeout conf.AuthFile = authFile conf.AuthDefaultRead = authDefaultRead conf.AuthDefaultWrite = authDefaultWrite diff --git a/server/config.go b/server/config.go index d8fd429e..1e2b517c 100644 --- a/server/config.go +++ b/server/config.go @@ -61,6 +61,8 @@ type Config struct { CacheFile string CacheDuration time.Duration CacheStartupQueries string + CacheBatchSize int + CacheBatchTimeout time.Duration AuthFile string AuthDefaultRead bool AuthDefaultWrite bool @@ -114,6 +116,8 @@ func NewConfig() *Config { FirebaseKeyFile: "", CacheFile: "", CacheDuration: DefaultCacheDuration, + CacheBatchSize: 0, + CacheBatchTimeout: 0, AuthFile: "", AuthDefaultRead: true, AuthDefaultWrite: true, diff --git a/server/message_cache.go b/server/message_cache.go index ec710e4f..7eb37cf9 100644 --- a/server/message_cache.go +++ b/server/message_cache.go @@ -44,6 +44,7 @@ const ( published INT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_mid ON messages (mid); + CREATE INDEX IF NOT EXISTS idx_time ON messages (time); CREATE INDEX IF NOT EXISTS idx_topic ON messages (topic); COMMIT; ` @@ -92,7 +93,7 @@ const ( // Schema management queries const ( - currentSchemaVersion = 8 + currentSchemaVersion = 9 createSchemaVersionTableQuery = ` CREATE TABLE IF NOT EXISTS schemaVersion ( id INT PRIMARY KEY, @@ -185,6 +186,11 @@ const ( migrate7To8AlterMessagesTableQuery = ` ALTER TABLE messages ADD COLUMN icon TEXT NOT NULL DEFAULT(''); ` + + // 8 -> 9 + migrate8To9AlterMessagesTableQuery = ` + CREATE INDEX IF NOT EXISTS idx_time ON messages (time); + ` ) type messageCache struct { @@ -194,7 +200,7 @@ type messageCache struct { } // newSqliteCache creates a SQLite file-backed cache -func newSqliteCache(filename, startupQueries string, nop bool) (*messageCache, error) { +func newSqliteCache(filename, startupQueries string, batchSize int, batchTimeout time.Duration, nop bool) (*messageCache, error) { db, err := sql.Open("sqlite3", filename) if err != nil { return nil, err @@ -202,32 +208,28 @@ func newSqliteCache(filename, startupQueries string, nop bool) (*messageCache, e if err := setupCacheDB(db, startupQueries); err != nil { return nil, err } - queue := util.NewBatchingQueue[*message](20, 500*time.Millisecond) + var queue *util.BatchingQueue[*message] + if batchSize > 0 || batchTimeout > 0 { + queue = util.NewBatchingQueue[*message](batchSize, batchTimeout) + } cache := &messageCache{ db: db, queue: queue, nop: nop, } - go func() { - for messages := range queue.Pop() { - log.Debug("Adding %d messages to cache", len(messages)) - if err := cache.addMessages(messages); err != nil { - log.Error("error: %s", err.Error()) - } - } - }() + go cache.processMessageBatches() return cache, nil } // newMemCache creates an in-memory cache func newMemCache() (*messageCache, error) { - return newSqliteCache(createMemoryFilename(), "", false) + return newSqliteCache(createMemoryFilename(), "", 0, 0, false) } // newNopCache creates an in-memory cache that discards all messages; // it is always empty and can be used if caching is entirely disabled func newNopCache() (*messageCache, error) { - return newSqliteCache(createMemoryFilename(), "", true) + return newSqliteCache(createMemoryFilename(), "", 0, 0, true) } // createMemoryFilename creates a unique memory filename to use for the SQLite backend. @@ -240,18 +242,23 @@ func createMemoryFilename() string { return fmt.Sprintf("file:%s?mode=memory&cache=shared", util.RandomString(10)) } +// AddMessage stores a message to the message cache synchronously, or queues it to be stored at a later date asyncronously. +// The message is queued only if "batchSize" or "batchTimeout" are passed to the constructor. func (c *messageCache) AddMessage(m *message) error { + if c.queue != nil { + c.queue.Enqueue(m) + return nil + } return c.addMessages([]*message{m}) } -func (c *messageCache) QueueMessage(m *message) { - c.queue.Push(m) -} - +// addMessages synchronously stores a match of messages. If the database is locked, the transaction waits until +// SQLite's busy_timeout is exceeded before erroring out. func (c *messageCache) addMessages(ms []*message) error { if c.nop { return nil } + start := time.Now() tx, err := c.db.Begin() if err != nil { return err @@ -305,7 +312,12 @@ func (c *messageCache) addMessages(ms []*message) error { return err } } - return tx.Commit() + if err := tx.Commit(); err != nil { + log.Warn("Cache: Writing %d message(s) failed (took %v)", len(ms), time.Since(start)) + return err + } + log.Debug("Cache: Wrote %d message(s) in %v", len(ms), time.Since(start)) + return nil } func (c *messageCache) Messages(topic string, since sinceMarker, scheduled bool) ([]*message, error) { @@ -411,8 +423,12 @@ func (c *messageCache) Topics() (map[string]*topic, error) { } func (c *messageCache) Prune(olderThan time.Time) error { - _, err := c.db.Exec(pruneMessagesQuery, olderThan.Unix()) - return err + start := time.Now() + if _, err := c.db.Exec(pruneMessagesQuery, olderThan.Unix()); err != nil { + log.Warn("Cache: Pruning failed (after %v): %s", time.Since(start), err.Error()) + } + log.Debug("Cache: Pruning successful (took %v)", time.Since(start)) + return nil } func (c *messageCache) AttachmentBytesUsed(sender string) (int64, error) { @@ -433,6 +449,17 @@ func (c *messageCache) AttachmentBytesUsed(sender string) (int64, error) { return size, nil } +func (c *messageCache) processMessageBatches() { + if c.queue == nil { + return + } + for messages := range c.queue.Dequeue() { + if err := c.addMessages(messages); err != nil { + log.Error("Cache: %s", err.Error()) + } + } +} + func readMessages(rows *sql.Rows) ([]*message, error) { defer rows.Close() messages := make([]*message, 0) @@ -558,6 +585,8 @@ func setupCacheDB(db *sql.DB, startupQueries string) error { return migrateFrom6(db) } else if schemaVersion == 7 { return migrateFrom7(db) + } else if schemaVersion == 8 { + return migrateFrom8(db) } return fmt.Errorf("unexpected schema version found: %d", schemaVersion) } @@ -663,5 +692,16 @@ func migrateFrom7(db *sql.DB) error { if _, err := db.Exec(updateSchemaVersion, 8); err != nil { return err } + return migrateFrom8(db) +} + +func migrateFrom8(db *sql.DB) error { + log.Info("Migrating cache database schema: from 8 to 9") + if _, err := db.Exec(migrate8To9AlterMessagesTableQuery); err != nil { + return err + } + if _, err := db.Exec(updateSchemaVersion, 9); err != nil { + return err + } return nil // Update this when a new version is added } diff --git a/server/message_cache_test.go b/server/message_cache_test.go index c72debca..c3b7305e 100644 --- a/server/message_cache_test.go +++ b/server/message_cache_test.go @@ -450,7 +450,7 @@ func TestSqliteCache_StartupQueries_WAL(t *testing.T) { startupQueries := `pragma journal_mode = WAL; pragma synchronous = normal; pragma temp_store = memory;` - db, err := newSqliteCache(filename, startupQueries, false) + db, err := newSqliteCache(filename, startupQueries, 0, 0, false) require.Nil(t, err) require.Nil(t, db.AddMessage(newDefaultMessage("mytopic", "some message"))) require.FileExists(t, filename) @@ -461,7 +461,7 @@ pragma temp_store = memory;` func TestSqliteCache_StartupQueries_None(t *testing.T) { filename := newSqliteTestCacheFile(t) startupQueries := "" - db, err := newSqliteCache(filename, startupQueries, false) + db, err := newSqliteCache(filename, startupQueries, 0, 0, false) require.Nil(t, err) require.Nil(t, db.AddMessage(newDefaultMessage("mytopic", "some message"))) require.FileExists(t, filename) @@ -472,7 +472,7 @@ func TestSqliteCache_StartupQueries_None(t *testing.T) { func TestSqliteCache_StartupQueries_Fail(t *testing.T) { filename := newSqliteTestCacheFile(t) startupQueries := `xx error` - _, err := newSqliteCache(filename, startupQueries, false) + _, err := newSqliteCache(filename, startupQueries, 0, 0, false) require.Error(t, err) } @@ -501,7 +501,7 @@ func TestMemCache_NopCache(t *testing.T) { } func newSqliteTestCache(t *testing.T) *messageCache { - c, err := newSqliteCache(newSqliteTestCacheFile(t), "", false) + c, err := newSqliteCache(newSqliteTestCacheFile(t), "", 0, 0, false) if err != nil { t.Fatal(err) } @@ -513,7 +513,7 @@ func newSqliteTestCacheFile(t *testing.T) string { } func newSqliteTestCacheFromFile(t *testing.T, filename, startupQueries string) *messageCache { - c, err := newSqliteCache(filename, startupQueries, false) + c, err := newSqliteCache(filename, startupQueries, 0, 0, false) if err != nil { t.Fatal(err) } diff --git a/server/server.go b/server/server.go index b90b7630..fe729b1b 100644 --- a/server/server.go +++ b/server/server.go @@ -159,7 +159,7 @@ func createMessageCache(conf *Config) (*messageCache, error) { if conf.CacheDuration == 0 { return newNopCache() } else if conf.CacheFile != "" { - return newSqliteCache(conf.CacheFile, conf.CacheStartupQueries, false) + return newSqliteCache(conf.CacheFile, conf.CacheStartupQueries, conf.CacheBatchSize, conf.CacheBatchTimeout, false) } return newMemCache() } @@ -491,11 +491,10 @@ func (s *Server) handlePublishWithoutResponse(r *http.Request, v *visitor) (*mes log.Debug("%s Message delayed, will process later", logMessagePrefix(v, m)) } if cache { - log.Trace("%s Queuing for cache", logMessagePrefix(v, m)) - s.messageCache.QueueMessage(m) - /*if err := s.messageCache.AddMessage(m); err != nil { + log.Debug("%s Adding message to cache", logMessagePrefix(v, m)) + if err := s.messageCache.AddMessage(m); err != nil { return nil, err - }*/ + } } s.mu.Lock() s.messages++ diff --git a/server/server.yml b/server/server.yml index 9476478f..4b08129b 100644 --- a/server/server.yml +++ b/server/server.yml @@ -65,6 +65,8 @@ # cache-file: # cache-duration: "12h" # cache-startup-queries: +# cache-batch-size: 0 +# cache-batch-timeout: "0ms" # If set, access to the ntfy server and API can be controlled on a granular level using # the 'ntfy user' and 'ntfy access' commands. See the --help pages for details, or check the docs. diff --git a/util/batching_queue.go b/util/batching_queue.go index 78116470..86901bcd 100644 --- a/util/batching_queue.go +++ b/util/batching_queue.go @@ -5,6 +5,24 @@ import ( "time" ) +// BatchingQueue is a queue that creates batches of the enqueued elements based on a +// max batch size and a batch timeout. +// +// Example: +// +// q := NewBatchingQueue[int](2, 500 * time.Millisecond) +// go func() { +// for batch := range q.Dequeue() { +// fmt.Println(batch) +// } +// }() +// q.Enqueue(1) +// q.Enqueue(2) +// q.Enqueue(3) +// time.Sleep(time.Second) +// +// This example will emit batch [1, 2] immediately (because the batch size is 2), and +// a batch [3] after 500ms. type BatchingQueue[T any] struct { batchSize int timeout time.Duration @@ -13,6 +31,7 @@ type BatchingQueue[T any] struct { mu sync.Mutex } +// NewBatchingQueue creates a new BatchingQueue func NewBatchingQueue[T any](batchSize int, timeout time.Duration) *BatchingQueue[T] { q := &BatchingQueue[T]{ batchSize: batchSize, @@ -20,37 +39,45 @@ func NewBatchingQueue[T any](batchSize int, timeout time.Duration) *BatchingQueu in: make([]T, 0), out: make(chan []T), } - ticker := time.NewTicker(timeout) - go func() { - for range ticker.C { - elements := q.popAll() - if len(elements) > 0 { - q.out <- elements - } - } - }() + go q.timeoutTicker() return q } -func (c *BatchingQueue[T]) Push(element T) { - c.mu.Lock() - c.in = append(c.in, element) - limitReached := len(c.in) == c.batchSize - c.mu.Unlock() +// Enqueue enqueues an element to the queue. If the configured batch size is reached, +// the batch will be emitted immediately. +func (q *BatchingQueue[T]) Enqueue(element T) { + q.mu.Lock() + q.in = append(q.in, element) + limitReached := len(q.in) == q.batchSize + q.mu.Unlock() if limitReached { - c.out <- c.popAll() + q.out <- q.dequeueAll() } } -func (c *BatchingQueue[T]) Pop() <-chan []T { - return c.out +// Dequeue returns a channel emitting batches of elements +func (q *BatchingQueue[T]) Dequeue() <-chan []T { + return q.out } -func (c *BatchingQueue[T]) popAll() []T { - c.mu.Lock() - defer c.mu.Unlock() - elements := make([]T, len(c.in)) - copy(elements, c.in) - c.in = c.in[:0] +func (q *BatchingQueue[T]) dequeueAll() []T { + q.mu.Lock() + defer q.mu.Unlock() + elements := make([]T, len(q.in)) + copy(elements, q.in) + q.in = q.in[:0] return elements } + +func (q *BatchingQueue[T]) timeoutTicker() { + if q.timeout == 0 { + return + } + ticker := time.NewTicker(q.timeout) + for range ticker.C { + elements := q.dequeueAll() + if len(elements) > 0 { + q.out <- elements + } + } +} diff --git a/util/batching_queue_test.go b/util/batching_queue_test.go index 46bc06b8..28764f18 100644 --- a/util/batching_queue_test.go +++ b/util/batching_queue_test.go @@ -2,24 +2,51 @@ package util_test import ( "fmt" + "github.com/stretchr/testify/require" "heckel.io/ntfy/util" "math/rand" "testing" "time" ) -func TestConcurrentQueue_Next(t *testing.T) { - q := util.NewBatchingQueue[int](25, 200*time.Millisecond) +func TestBatchingQueue_InfTimeout(t *testing.T) { + q := util.NewBatchingQueue[int](25, 1*time.Hour) + batches := make([][]int, 0) + total := 0 go func() { - for batch := range q.Pop() { - fmt.Printf("Batch of %d items\n", len(batch)) + for batch := range q.Dequeue() { + batches = append(batches, batch) + total += len(batch) } }() - for i := 0; i < 1000; i++ { + for i := 0; i < 101; i++ { + go q.Enqueue(i) + } + time.Sleep(500 * time.Millisecond) + require.Equal(t, 100, total) // One is missing, stuck in the last batch! + require.Equal(t, 4, len(batches)) +} + +func TestBatchingQueue_WithTimeout(t *testing.T) { + q := util.NewBatchingQueue[int](25, 100*time.Millisecond) + batches := make([][]int, 0) + total := 0 + go func() { + for batch := range q.Dequeue() { + batches = append(batches, batch) + total += len(batch) + } + }() + for i := 0; i < 101; i++ { go func(i int) { - time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) - q.Push(i) + time.Sleep(time.Duration(rand.Intn(700)) * time.Millisecond) + q.Enqueue(i) }(i) } - time.Sleep(2 * time.Second) + time.Sleep(time.Second) + fmt.Println(len(batches)) + fmt.Println(batches) + require.Equal(t, 101, total) + require.True(t, len(batches) > 4) // 101/25 + require.True(t, len(batches) < 21) } From 497f871447a9b0f8f9e802831e8a4eb8c47401a7 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 10:33:12 -0500 Subject: [PATCH 28/36] Docs --- server/message_cache.go | 2 +- server/server.yml | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/server/message_cache.go b/server/message_cache.go index 7eb37cf9..bce94220 100644 --- a/server/message_cache.go +++ b/server/message_cache.go @@ -313,7 +313,7 @@ func (c *messageCache) addMessages(ms []*message) error { } } if err := tx.Commit(); err != nil { - log.Warn("Cache: Writing %d message(s) failed (took %v)", len(ms), time.Since(start)) + log.Error("Cache: Writing %d message(s) failed (took %v)", len(ms), time.Since(start)) return err } log.Debug("Cache: Wrote %d message(s) in %v", len(ms), time.Since(start)) diff --git a/server/server.yml b/server/server.yml index 4b08129b..1b268995 100644 --- a/server/server.yml +++ b/server/server.yml @@ -53,6 +53,12 @@ # pragma journal_mode = WAL; # pragma synchronous = normal; # pragma temp_store = memory; +# pragma busy_timeout = 15000; +# vacuum; +# +# The "cache-batch-size" and "cache-batch-timeout" parameter allow enabling async batch writing +# of messages. If set, messages will be queued and written to the database in batches of the given +# size, or after the given timeout. This is only required for high volume servers. # # Debian/RPM package users: # Use /var/cache/ntfy/cache.db as cache file to avoid permission issues. The package From e147a41f928241f8497ead40d6aada293cd6255d Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 10:44:10 -0500 Subject: [PATCH 29/36] Fix race in tests --- util/batching_queue_test.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/util/batching_queue_test.go b/util/batching_queue_test.go index 28764f18..f7dccfab 100644 --- a/util/batching_queue_test.go +++ b/util/batching_queue_test.go @@ -1,40 +1,46 @@ package util_test import ( - "fmt" "github.com/stretchr/testify/require" "heckel.io/ntfy/util" "math/rand" + "sync" "testing" "time" ) func TestBatchingQueue_InfTimeout(t *testing.T) { q := util.NewBatchingQueue[int](25, 1*time.Hour) - batches := make([][]int, 0) - total := 0 + batches, total := make([][]int, 0), 0 + var mu sync.Mutex go func() { for batch := range q.Dequeue() { + mu.Lock() batches = append(batches, batch) total += len(batch) + mu.Unlock() } }() for i := 0; i < 101; i++ { go q.Enqueue(i) } time.Sleep(500 * time.Millisecond) + mu.Lock() require.Equal(t, 100, total) // One is missing, stuck in the last batch! require.Equal(t, 4, len(batches)) + mu.Unlock() } func TestBatchingQueue_WithTimeout(t *testing.T) { q := util.NewBatchingQueue[int](25, 100*time.Millisecond) - batches := make([][]int, 0) - total := 0 + batches, total := make([][]int, 0), 0 + var mu sync.Mutex go func() { for batch := range q.Dequeue() { + mu.Lock() batches = append(batches, batch) total += len(batch) + mu.Unlock() } }() for i := 0; i < 101; i++ { @@ -44,9 +50,9 @@ func TestBatchingQueue_WithTimeout(t *testing.T) { }(i) } time.Sleep(time.Second) - fmt.Println(len(batches)) - fmt.Println(batches) + mu.Lock() require.Equal(t, 101, total) require.True(t, len(batches) > 4) // 101/25 require.True(t, len(batches) < 21) + mu.Unlock() } From db9ca80b69978e33154dc0c22b5631fe62ac8348 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 11:16:07 -0500 Subject: [PATCH 30/36] Fix race condition making it possible for batches to be >batchSize --- util/batching_queue.go | 13 ++++++++----- util/batching_queue_test.go | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/util/batching_queue.go b/util/batching_queue.go index 86901bcd..85ba9be9 100644 --- a/util/batching_queue.go +++ b/util/batching_queue.go @@ -48,10 +48,13 @@ func NewBatchingQueue[T any](batchSize int, timeout time.Duration) *BatchingQueu func (q *BatchingQueue[T]) Enqueue(element T) { q.mu.Lock() q.in = append(q.in, element) - limitReached := len(q.in) == q.batchSize + var elements []T + if len(q.in) == q.batchSize { + elements = q.dequeueAll() + } q.mu.Unlock() - if limitReached { - q.out <- q.dequeueAll() + if len(elements) > 0 { + q.out <- elements } } @@ -61,8 +64,6 @@ func (q *BatchingQueue[T]) Dequeue() <-chan []T { } func (q *BatchingQueue[T]) dequeueAll() []T { - q.mu.Lock() - defer q.mu.Unlock() elements := make([]T, len(q.in)) copy(elements, q.in) q.in = q.in[:0] @@ -75,7 +76,9 @@ func (q *BatchingQueue[T]) timeoutTicker() { } ticker := time.NewTicker(q.timeout) for range ticker.C { + q.mu.Lock() elements := q.dequeueAll() + q.mu.Unlock() if len(elements) > 0 { q.out <- elements } diff --git a/util/batching_queue_test.go b/util/batching_queue_test.go index f7dccfab..b3c41a4c 100644 --- a/util/batching_queue_test.go +++ b/util/batching_queue_test.go @@ -24,7 +24,7 @@ func TestBatchingQueue_InfTimeout(t *testing.T) { for i := 0; i < 101; i++ { go q.Enqueue(i) } - time.Sleep(500 * time.Millisecond) + time.Sleep(time.Second) mu.Lock() require.Equal(t, 100, total) // One is missing, stuck in the last batch! require.Equal(t, 4, len(batches)) From 4a91da60dd3373c791575025901c659d0bf19203 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 11:27:46 -0500 Subject: [PATCH 31/36] Docs --- docs/config.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/config.md b/docs/config.md index 655b56cf..a127a5ac 100644 --- a/docs/config.md +++ b/docs/config.md @@ -825,19 +825,27 @@ out [this discussion on Reddit](https://www.reddit.com/r/golang/comments/r9u4ee/ Depending on *how you run it*, here are a few limits that are relevant: -### WAL for message cache +### Message cache By default, the [message cache](#message-cache) (defined by `cache-file`) uses the SQLite default settings, which means it syncs to disk on every write. For personal servers, this is perfectly adequate. For larger installations, such as ntfy.sh, the [write-ahead log (WAL)](https://sqlite.org/wal.html) should be enabled, and the sync mode should be adjusted. See [this article](https://phiresky.github.io/blog/2020/sqlite-performance-tuning/) for details. +In addition to that, for very high load servers (such as ntfy.sh), it may be beneficial to write messages to the cache +in batches, and asynchronously. This can be enabled with the `cache-batch-size` and `cache-batch-timeout`. If you start +seeing `database locked` messages in the logs, you should probably enable that. + Here's how ntfy.sh has been tuned in the `server.yml` file: ``` yaml +cache-batch-size: 25 +cache-batch-timeout: "1s" cache-startup-queries: | pragma journal_mode = WAL; pragma synchronous = normal; pragma temp_store = memory; + pragma busy_timeout = 15000; + vacuum; ``` ### For systemd services @@ -990,6 +998,8 @@ variable before running the `ntfy` command (e.g. `export NTFY_LISTEN_HTTP=:80`). | `cache-file` | `NTFY_CACHE_FILE` | *filename* | - | If set, messages are cached in a local SQLite database instead of only in-memory. This allows for service restarts without losing messages in support of the since= parameter. See [message cache](#message-cache). | | `cache-duration` | `NTFY_CACHE_DURATION` | *duration* | 12h | Duration for which messages will be buffered before they are deleted. This is required to support the `since=...` and `poll=1` parameter. Set this to `0` to disable the cache entirely. | | `cache-startup-queries` | `NTFY_CACHE_STARTUP_QUERIES` | *string (SQL queries)* | - | SQL queries to run during database startup; this is useful for tuning and [enabling WAL mode](#wal-for-message-cache) | +| `cache-batch-size` | `NTFY_CACHE_BATCH_SIZE` | *int* | 0 | Max size of messages to batch together when writing to message cache (if zero, writes are synchronous) | +| `cache-batch-timeout` | `NTFY_CACHE_BATCH_TIMEOUT` | *duration* | 0s | Timeout for batched async writes to the message cache (if zero, writes are synchronous) | | `auth-file` | `NTFY_AUTH_FILE` | *filename* | - | Auth database file used for access control. If set, enables authentication and access control. See [access control](#access-control). | | `auth-default-access` | `NTFY_AUTH_DEFAULT_ACCESS` | `read-write`, `read-only`, `write-only`, `deny-all` | `read-write` | Default permissions if no matching entries in the auth database are found. Default is `read-write`. | | `behind-proxy` | `NTFY_BEHIND_PROXY` | *bool* | false | If set, the X-Forwarded-For header is used to determine the visitor IP address instead of the remote address of the connection. | @@ -1054,6 +1064,8 @@ OPTIONS: --behind-proxy, --behind_proxy, -P if set, use X-Forwarded-For header to determine visitor IP address (for rate limiting) (default: false) [$NTFY_BEHIND_PROXY] --cache-duration since, --cache_duration since, -b since buffer messages for this time to allow since requests (default: 12h0m0s) [$NTFY_CACHE_DURATION] --cache-file value, --cache_file value, -C value cache file used for message caching [$NTFY_CACHE_FILE] + --cache-batch-size value, --cache_batch_size value max size of messages to batch together when writing to message cache (if zero, writes are synchronous) (default: 0) [$NTFY_BATCH_SIZE] + --cache-batch-timeout value, --cache_batch_timeout value timeout for batched async writes to the message cache (if zero, writes are synchronous) (default: 0s) [$NTFY_CACHE_BATCH_TIMEOUT] --cache-startup-queries value, --cache_startup_queries value queries run when the cache database is initialized [$NTFY_CACHE_STARTUP_QUERIES] --cert-file value, --cert_file value, -E value certificate file, if listen-https is set [$NTFY_CERT_FILE] --config value, -c value config file (default: /etc/ntfy/server.yml) [$NTFY_CONFIG_FILE] From 978118a4007456b1393c68da902ab254a0764f5e Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 11:31:29 -0500 Subject: [PATCH 32/36] Release notes --- docs/releases.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/releases.md b/docs/releases.md index f5fc9a49..e662faec 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -14,6 +14,10 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release ## ntfy server v1.30.0 (UNRELREASED) +**Features:** + +* High-load servers: Allow asynchronous batch-writing of messages to cache via `cache-batch-*` options ([#498](https://github.com/binwiederhier/ntfy/issues/498)/[#502](https://github.com/binwiederhier/ntfy/pull/502)) + **Documentation:** * GitHub Actions example ([#492](https://github.com/binwiederhier/ntfy/pull/492), thanks to [@ksurl](https://github.com/ksurl)) @@ -22,6 +26,7 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release **Other things:** * Put ntfy.sh docs on GitHub pages to reduce AWS outbound traffic cost ([#491](https://github.com/binwiederhier/ntfy/issues/491)) +* The ntfy.sh server hardware was upgraded to a bigger box. If you'd like to help out carrying the server cost, **[sponsorships and donations](https://github.com/sponsors/binwiederhier)** 💸 would be very much appreciated ## ntfy server v1.29.0 Released November 12, 2022 From 755155479aafe2af911c2669b4b4436f630473e8 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 14:26:54 -0500 Subject: [PATCH 33/36] Thank you @skrollme for your sponsorship --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d9bfae0f..a00d062c 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ appreciated. A big fat **Thank You** to the folks already sponsoring ntfy: + ## License Made with ❤️ by [Philipp C. Heckel](https://heckel.io). From 5b2fe66903581d847edc9a3ab8ff7ffb69830423 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 21:12:52 -0500 Subject: [PATCH 34/36] Fix test --- cmd/publish_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/publish_test.go b/cmd/publish_test.go index dde279da..f818cdc3 100644 --- a/cmd/publish_test.go +++ b/cmd/publish_test.go @@ -17,6 +17,7 @@ func TestCLI_Publish_Subscribe_Poll_Real_Server(t *testing.T) { app, _, _, _ := newTestApp() require.Nil(t, app.Run([]string{"ntfy", "publish", "ntfytest", "ntfy unit test " + testMessage})) + time.Sleep(3 * time.Second) // Since #502, ntfy.sh writes messages to the cache asynchronously, after a timeout of ~1.5s app2, _, stdout, _ := newTestApp() require.Nil(t, app2.Run([]string{"ntfy", "subscribe", "--poll", "ntfytest"})) From aee791a17d629f92ad5f750d1f67e146807fe62a Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Wed, 16 Nov 2022 21:21:41 -0500 Subject: [PATCH 35/36] Bump versions --- go.mod | 6 +- go.sum | 6 + web/package-lock.json | 651 +++++++++++++++++++++--------------------- 3 files changed, 336 insertions(+), 327 deletions(-) diff --git a/go.mod b/go.mod index 81a20a1f..e1f3261d 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/olebedev/when v0.0.0-20211212231525-59bd4edcf9d6 github.com/stretchr/testify v1.8.1 github.com/urfave/cli/v2 v2.23.5 - golang.org/x/crypto v0.2.0 + golang.org/x/crypto v0.3.0 golang.org/x/oauth2 v0.2.0 // indirect golang.org/x/sync v0.1.0 golang.org/x/term v0.2.0 @@ -28,7 +28,7 @@ require github.com/pkg/errors v0.9.1 // indirect require firebase.google.com/go/v4 v4.10.0 require ( - cloud.google.com/go v0.106.0 // indirect + cloud.google.com/go v0.107.0 // indirect cloud.google.com/go/compute v1.12.1 // indirect cloud.google.com/go/compute/metadata v0.2.1 // indirect cloud.google.com/go/iam v0.7.0 // indirect @@ -54,7 +54,7 @@ require ( golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine/v2 v2.0.2 // indirect - google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e // indirect + google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472 // indirect google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 8c269ead..168bcd42 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.106.0 h1:AWaMWuZb2oFeiV91OfNHZbmwUhMVuXEaLPm9sqDAOl8= cloud.google.com/go v0.106.0/go.mod h1:5NEGxGuIeMQiPaWLwLYZ7kfNWiP6w1+QJK+xqyIT+dw= +cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= @@ -111,6 +113,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -174,6 +178,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e h1:azcyH5lGzGy7pkLCbhPe0KkKxsM7c6UA/FZIXImKE7M= google.golang.org/genproto v0.0.0-20221111202108-142d8a6fa32e/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= +google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472 h1:kIfItBRE5gkUKpH4H5lNGciZbka1JrmRli3ArqrKFkA= +google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/web/package-lock.json b/web/package-lock.json index 3ff6b519..da6edf3d 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -3069,14 +3069,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.105", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.105.tgz", - "integrity": "sha512-4IPBcJQIgVVXQvN6DQMoCHed52GBtwSqYs0jD0dDcMR3o76AodQtpEeWFz3p7mJoc6f/IHBl9U6jEfL1r/kM4g==", + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", "dependencies": { - "@babel/runtime": "^7.19.0", + "@babel/runtime": "^7.20.1", "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "@popperjs/core": "^2.11.6", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -3101,20 +3101,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.13.tgz", - "integrity": "sha512-zWkWPV/SaNdsIdxAWiuVGZ+Ue3BkfSIlU/BFIrJmuUcwiIa7gQsbI/DOpj1KzLvqZhdEe2wC1aG4nCHfzgc1Hg==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" } }, "node_modules/@mui/icons-material": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.9.tgz", - "integrity": "sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", "dependencies": { - "@babel/runtime": "^7.19.0" + "@babel/runtime": "^7.20.1" }, "engines": { "node": ">=12.0.0" @@ -3135,16 +3135,16 @@ } }, "node_modules/@mui/material": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.13.tgz", - "integrity": "sha512-TkkT1rNc0/hhL4/+zv4gYcA6egNWBH/1Tz+azoTnQIUdZ32fgwFI2pFX2KVJNTt30xnLznxDWtTv7ilmJQ52xw==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/base": "5.0.0-alpha.105", - "@mui/core-downloads-tracker": "^5.10.13", - "@mui/system": "^5.10.13", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "@types/react-transition-group": "^4.4.5", "clsx": "^1.2.1", "csstype": "^3.1.1", @@ -3179,12 +3179,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.9.tgz", - "integrity": "sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", "prop-types": "^15.8.1" }, "engines": { @@ -3205,12 +3205,12 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.10.8", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.8.tgz", - "integrity": "sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", "dependencies": { - "@babel/runtime": "^7.19.0", - "@emotion/cache": "^11.10.3", + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" }, @@ -3236,15 +3236,15 @@ } }, "node_modules/@mui/system": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.13.tgz", - "integrity": "sha512-Xzx26Asu5fVlm0ucm+gnJmeX4Y1isrpVDvqxX4yJaOT7Fzmd8Lfq9ih3QMfZajns5LMtUiOuCQlVFRtUG5IY7A==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", "dependencies": { - "@babel/runtime": "^7.19.0", - "@mui/private-theming": "^5.10.9", - "@mui/styled-engine": "^5.10.8", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "clsx": "^1.2.1", "csstype": "^3.1.1", "prop-types": "^15.8.1" @@ -3275,9 +3275,9 @@ } }, "node_modules/@mui/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz", - "integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", "peerDependencies": { "@types/react": "*" }, @@ -3288,11 +3288,11 @@ } }, "node_modules/@mui/utils": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz", - "integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", "dependencies": { - "@babel/runtime": "^7.19.0", + "@babel/runtime": "^7.20.1", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -4090,13 +4090,13 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", - "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.43.0.tgz", + "integrity": "sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA==", "dependencies": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/type-utils": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/type-utils": "5.43.0", + "@typescript-eslint/utils": "5.43.0", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -4136,11 +4136,11 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.42.1.tgz", - "integrity": "sha512-qona75z2MLpeZADEuCet5Pwvh1g/0cWScEEDy43chuUPc4klgDiwz5hLFk5dHcjFEETSYQHRPYiiHKW24EMPjw==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.43.0.tgz", + "integrity": "sha512-WkT637CumTJbm/hRbFfnHBMgfUYTKr08LitVsD7gQId7bi6rnkx3pu3jac67lmp5ObW4MpJ9SNFZAIOUB/Qbsw==", "dependencies": { - "@typescript-eslint/utils": "5.42.1" + "@typescript-eslint/utils": "5.43.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4154,13 +4154,13 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", - "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.43.0.tgz", + "integrity": "sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug==", "dependencies": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/typescript-estree": "5.43.0", "debug": "^4.3.4" }, "engines": { @@ -4180,12 +4180,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", - "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.43.0.tgz", + "integrity": "sha512-XNWnGaqAtTJsUiZaoiGIrdJYHsUOd3BZ3Qj5zKp9w6km6HsrjPk/TGZv0qMTWyWj0+1QOqpHQ2gZOLXaGA9Ekw==", "dependencies": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1" + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/visitor-keys": "5.43.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4196,12 +4196,12 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", - "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.43.0.tgz", + "integrity": "sha512-K21f+KY2/VvYggLf5Pk4tgBOPs2otTaIHy2zjclo7UZGLyFH86VfUOm5iq+OtDtxq/Zwu2I3ujDBykVW4Xtmtg==", "dependencies": { - "@typescript-eslint/typescript-estree": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/typescript-estree": "5.43.0", + "@typescript-eslint/utils": "5.43.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4222,9 +4222,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", - "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.43.0.tgz", + "integrity": "sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4234,12 +4234,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", - "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.43.0.tgz", + "integrity": "sha512-BZ1WVe+QQ+igWal2tDbNg1j2HWUkAa+CVqdU79L4HP9izQY6CNhXfkNwd1SS4+sSZAP/EthI1uiCSY/+H0pROg==", "dependencies": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/visitor-keys": "5.43.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4274,15 +4274,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", - "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.43.0.tgz", + "integrity": "sha512-8nVpA6yX0sCjf7v/NDfeaOlyaIIqL7OaIGOWSPFqUKK59Gnumd3Wa+2l8oAaYO2lk0sO+SbWFWRSvhu8gLGv4A==", "dependencies": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/typescript-estree": "5.43.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -4333,11 +4333,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", - "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.43.0.tgz", + "integrity": "sha512-icl1jNH/d18OVHLfcwdL3bWUKsBeIiKYTGxMJCoGe7xFht+E4QgzOqoWYrU8XSLJWhVw8nTacbm03v23J/hFTg==", "dependencies": { - "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/types": "5.43.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -4645,9 +4645,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -4897,9 +4897,9 @@ } }, "node_modules/axe-core": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.1.tgz", - "integrity": "sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==", "engines": { "node": ">=4" } @@ -5543,9 +5543,12 @@ } }, "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.6.1.tgz", + "integrity": "sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==", + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -5778,9 +5781,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5788,9 +5791,9 @@ } }, "node_modules/core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "dependencies": { "browserslist": "^4.21.4" }, @@ -5800,9 +5803,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", - "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5904,18 +5907,18 @@ } }, "node_modules/css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", + "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", "dependencies": { "icss-utils": "^5.1.0", - "postcss": "^8.4.7", + "postcss": "^8.4.18", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" + "semver": "^7.3.8" }, "engines": { "node": ">= 12.13.0" @@ -5980,9 +5983,9 @@ } }, "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7302,9 +7305,9 @@ } }, "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -10222,9 +10225,9 @@ } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "engines": { "node": ">=6" }, @@ -11265,9 +11268,9 @@ } }, "node_modules/js-base64": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", - "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.3.tgz", + "integrity": "sha512-PAr6Xg2jvd7MCR6Ld9Jg3BmTcjYsHEBx1VlwEwULb/qowPf5VD9kEMagj23Gm7JRnSvE/Da/57nChZjnvL8v6A==" }, "node_modules/js-sdsl": { "version": "4.1.5", @@ -11642,9 +11645,9 @@ } }, "node_modules/memfs": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.10.tgz", - "integrity": "sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.11.tgz", + "integrity": "sha512-GvsCITGAyDCxxsJ+X6prJexFQEhOCJaIlUbsAvjzSI5o5O7j2dle3jWvz5Z5aOdpOxW6ol3vI1+0ut+641F1+w==", "dependencies": { "fs-monkey": "^1.0.3" }, @@ -11729,9 +11732,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", - "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.0.tgz", + "integrity": "sha512-auqtVo8KhTScMsba7MbijqZTfibbXiBNlPAQbsVt7enQfcDYLdgG57eGxMqwVU3mfeWANY4F1wUg+rMF+ycZgw==", "dependencies": { "schema-utils": "^4.0.0" }, @@ -11747,9 +11750,9 @@ } }, "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -13435,11 +13438,11 @@ } }, "node_modules/postcss-preset-env": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz", - "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", "dependencies": { - "@csstools/postcss-cascade-layers": "^1.1.0", + "@csstools/postcss-cascade-layers": "^1.1.1", "@csstools/postcss-color-function": "^1.1.1", "@csstools/postcss-font-format-keywords": "^1.0.1", "@csstools/postcss-hwb-function": "^1.0.2", @@ -13453,19 +13456,19 @@ "@csstools/postcss-text-decoration-shorthand": "^1.0.0", "@csstools/postcss-trigonometric-functions": "^1.0.2", "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.11", - "browserslist": "^4.21.3", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", "css-blank-pseudo": "^3.0.3", "css-has-pseudo": "^3.0.4", "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.0.1", + "cssdb": "^7.1.0", "postcss-attribute-case-insensitive": "^5.0.2", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^4.2.4", "postcss-color-hex-alpha": "^8.0.4", "postcss-color-rebeccapurple": "^7.1.1", "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.9", + "postcss-custom-properties": "^12.1.10", "postcss-custom-selectors": "^6.0.3", "postcss-dir-pseudo-class": "^6.0.5", "postcss-double-position-gradients": "^3.1.2", @@ -14348,16 +14351,16 @@ } }, "node_modules/regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "dependencies": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { "node": ">=4" @@ -15863,9 +15866,9 @@ } }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "peer": true, "bin": { "tsc": "bin/tsc", @@ -15910,9 +15913,9 @@ } }, "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", "engines": { "node": ">=4" } @@ -16210,9 +16213,9 @@ } }, "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16313,9 +16316,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16631,9 +16634,9 @@ } }, "node_modules/workbox-build/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -19056,14 +19059,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "@mui/base": { - "version": "5.0.0-alpha.105", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.105.tgz", - "integrity": "sha512-4IPBcJQIgVVXQvN6DQMoCHed52GBtwSqYs0jD0dDcMR3o76AodQtpEeWFz3p7mJoc6f/IHBl9U6jEfL1r/kM4g==", + "version": "5.0.0-alpha.106", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.106.tgz", + "integrity": "sha512-xJQQtwPCPwr6hGWTBdvDwHYwExn3Bw7nPQkN8Fuz8kHpZqoMVWQvvaFS557AIkkI2AFLV3DxVIMjbCvrIntBWg==", "requires": { - "@babel/runtime": "^7.19.0", + "@babel/runtime": "^7.20.1", "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "@popperjs/core": "^2.11.6", "clsx": "^1.2.1", "prop-types": "^15.8.1", @@ -19071,29 +19074,29 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.13.tgz", - "integrity": "sha512-zWkWPV/SaNdsIdxAWiuVGZ+Ue3BkfSIlU/BFIrJmuUcwiIa7gQsbI/DOpj1KzLvqZhdEe2wC1aG4nCHfzgc1Hg==" + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.14.tgz", + "integrity": "sha512-qLgIJNOR9Dre8JiZ/neVzOf4jf88J6YtOkQqugtMrleLjbfRVUSS4LWl9CSOjNq76quYdmYWnSDgfQqOooT2cQ==" }, "@mui/icons-material": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.9.tgz", - "integrity": "sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.14.tgz", + "integrity": "sha512-qtH60slQa+7MZRn6kyui8rKuoGDglPqaHX+pzBKNvd8JCOlrnfY5DmGGDdToTXyXl8xJ8nhANZbrbpg7UVKq/Q==", "requires": { - "@babel/runtime": "^7.19.0" + "@babel/runtime": "^7.20.1" } }, "@mui/material": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.13.tgz", - "integrity": "sha512-TkkT1rNc0/hhL4/+zv4gYcA6egNWBH/1Tz+azoTnQIUdZ32fgwFI2pFX2KVJNTt30xnLznxDWtTv7ilmJQ52xw==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.10.14.tgz", + "integrity": "sha512-HWzKVAykePMx54WtxVwZyL1W4k3xlHYIqwMw0CaXAvgB3UE9yjABZuuGr8vG5Z6CSNWamzd+s1x8u7pQPFl9og==", "requires": { - "@babel/runtime": "^7.19.0", - "@mui/base": "5.0.0-alpha.105", - "@mui/core-downloads-tracker": "^5.10.13", - "@mui/system": "^5.10.13", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/base": "5.0.0-alpha.106", + "@mui/core-downloads-tracker": "^5.10.14", + "@mui/system": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "@types/react-transition-group": "^4.4.5", "clsx": "^1.2.1", "csstype": "^3.1.1", @@ -19103,53 +19106,53 @@ } }, "@mui/private-theming": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.9.tgz", - "integrity": "sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.14.tgz", + "integrity": "sha512-3aIBe8WK65CwAPDY8nB11hYnzE1CZMymi76UnaFrA/DdGDwl5Y8F6uB+StKrkVmsqF1po7Mp2odqVkHj320gXw==", "requires": { - "@babel/runtime": "^7.19.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/utils": "^5.10.14", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.10.8", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.8.tgz", - "integrity": "sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.14.tgz", + "integrity": "sha512-bgKdM57ExogWpIfhL/ngSlzF4FhbH00vYF+Y5VALTob4uslFqje0xzoWmbfcCn4cZt2NXxZJIwhsq4vzo5itlw==", "requires": { - "@babel/runtime": "^7.19.0", - "@emotion/cache": "^11.10.3", + "@babel/runtime": "^7.20.1", + "@emotion/cache": "^11.10.5", "csstype": "^3.1.1", "prop-types": "^15.8.1" } }, "@mui/system": { - "version": "5.10.13", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.13.tgz", - "integrity": "sha512-Xzx26Asu5fVlm0ucm+gnJmeX4Y1isrpVDvqxX4yJaOT7Fzmd8Lfq9ih3QMfZajns5LMtUiOuCQlVFRtUG5IY7A==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.10.14.tgz", + "integrity": "sha512-2de7XCjRb1j8Od0Stmo0LwFMLpOMNT4wzfINuExXI1TVSuyxXIXUxiC5FEgJW3GMvf/a7SUR8VOiMoKlKWzukw==", "requires": { - "@babel/runtime": "^7.19.0", - "@mui/private-theming": "^5.10.9", - "@mui/styled-engine": "^5.10.8", - "@mui/types": "^7.2.0", - "@mui/utils": "^5.10.9", + "@babel/runtime": "^7.20.1", + "@mui/private-theming": "^5.10.14", + "@mui/styled-engine": "^5.10.14", + "@mui/types": "^7.2.1", + "@mui/utils": "^5.10.14", "clsx": "^1.2.1", "csstype": "^3.1.1", "prop-types": "^15.8.1" } }, "@mui/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz", - "integrity": "sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.1.tgz", + "integrity": "sha512-c5mSM7ivD8EsqK6HUi9hQPr5V7TJ/IRThUQ9nWNYPdhCGriTSQV4vL6DflT99LkM+wLiIS1rVjphpEWxERep7A==", "requires": {} }, "@mui/utils": { - "version": "5.10.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz", - "integrity": "sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA==", + "version": "5.10.14", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.10.14.tgz", + "integrity": "sha512-12p59+wDZpA++XVJmKwqsZmrA1nmUQ5d0a1yQWtcDjxNyER1EDzozYN/db+FY2i5ceQh2TynPTEwGms2mXDwFg==", "requires": { - "@babel/runtime": "^7.19.0", + "@babel/runtime": "^7.20.1", "@types/prop-types": "^15.7.5", "@types/react-is": "^16.7.1 || ^17.0.0", "prop-types": "^15.8.1", @@ -19753,13 +19756,13 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@typescript-eslint/eslint-plugin": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.42.1.tgz", - "integrity": "sha512-LyR6x784JCiJ1j6sH5Y0K6cdExqCCm8DJUTcwG5ThNXJj/G8o5E56u5EdG4SLy+bZAwZBswC+GYn3eGdttBVCg==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.43.0.tgz", + "integrity": "sha512-wNPzG+eDR6+hhW4yobEmpR36jrqqQv1vxBq5LJO3fBAktjkvekfr4BRl+3Fn1CM/A+s8/EiGUbOMDoYqWdbtXA==", "requires": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/type-utils": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/type-utils": "5.43.0", + "@typescript-eslint/utils": "5.43.0", "debug": "^4.3.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", @@ -19779,56 +19782,56 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.42.1.tgz", - "integrity": "sha512-qona75z2MLpeZADEuCet5Pwvh1g/0cWScEEDy43chuUPc4klgDiwz5hLFk5dHcjFEETSYQHRPYiiHKW24EMPjw==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.43.0.tgz", + "integrity": "sha512-WkT637CumTJbm/hRbFfnHBMgfUYTKr08LitVsD7gQId7bi6rnkx3pu3jac67lmp5ObW4MpJ9SNFZAIOUB/Qbsw==", "requires": { - "@typescript-eslint/utils": "5.42.1" + "@typescript-eslint/utils": "5.43.0" } }, "@typescript-eslint/parser": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.42.1.tgz", - "integrity": "sha512-kAV+NiNBWVQDY9gDJDToTE/NO8BHi4f6b7zTsVAJoTkmB/zlfOpiEVBzHOKtlgTndCKe8vj9F/PuolemZSh50Q==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.43.0.tgz", + "integrity": "sha512-2iHUK2Lh7PwNUlhFxxLI2haSDNyXvebBO9izhjhMoDC+S3XI9qt2DGFUsiJ89m2k7gGYch2aEpYqV5F/+nwZug==", "requires": { - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/typescript-estree": "5.43.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.42.1.tgz", - "integrity": "sha512-QAZY/CBP1Emx4rzxurgqj3rUinfsh/6mvuKbLNMfJMMKYLRBfweus8brgXF8f64ABkIZ3zdj2/rYYtF8eiuksQ==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.43.0.tgz", + "integrity": "sha512-XNWnGaqAtTJsUiZaoiGIrdJYHsUOd3BZ3Qj5zKp9w6km6HsrjPk/TGZv0qMTWyWj0+1QOqpHQ2gZOLXaGA9Ekw==", "requires": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1" + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/visitor-keys": "5.43.0" } }, "@typescript-eslint/type-utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.42.1.tgz", - "integrity": "sha512-WWiMChneex5w4xPIX56SSnQQo0tEOy5ZV2dqmj8Z371LJ0E+aymWD25JQ/l4FOuuX+Q49A7pzh/CGIQflxMVXg==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.43.0.tgz", + "integrity": "sha512-K21f+KY2/VvYggLf5Pk4tgBOPs2otTaIHy2zjclo7UZGLyFH86VfUOm5iq+OtDtxq/Zwu2I3ujDBykVW4Xtmtg==", "requires": { - "@typescript-eslint/typescript-estree": "5.42.1", - "@typescript-eslint/utils": "5.42.1", + "@typescript-eslint/typescript-estree": "5.43.0", + "@typescript-eslint/utils": "5.43.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.42.1.tgz", - "integrity": "sha512-Qrco9dsFF5lhalz+lLFtxs3ui1/YfC6NdXu+RAGBa8uSfn01cjO7ssCsjIsUs484vny9Xm699FSKwpkCcqwWwA==" + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.43.0.tgz", + "integrity": "sha512-jpsbcD0x6AUvV7tyOlyvon0aUsQpF8W+7TpJntfCUWU1qaIKu2K34pMwQKSzQH8ORgUrGYY6pVIh1Pi8TNeteg==" }, "@typescript-eslint/typescript-estree": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.42.1.tgz", - "integrity": "sha512-qElc0bDOuO0B8wDhhW4mYVgi/LZL+igPwXtV87n69/kYC/7NG3MES0jHxJNCr4EP7kY1XVsRy8C/u3DYeTKQmw==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.43.0.tgz", + "integrity": "sha512-BZ1WVe+QQ+igWal2tDbNg1j2HWUkAa+CVqdU79L4HP9izQY6CNhXfkNwd1SS4+sSZAP/EthI1uiCSY/+H0pROg==", "requires": { - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/visitor-keys": "5.42.1", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/visitor-keys": "5.43.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -19847,15 +19850,15 @@ } }, "@typescript-eslint/utils": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.42.1.tgz", - "integrity": "sha512-Gxvf12xSp3iYZd/fLqiQRD4uKZjDNR01bQ+j8zvhPjpsZ4HmvEFL/tC4amGNyxN9Rq+iqvpHLhlqx6KTxz9ZyQ==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.43.0.tgz", + "integrity": "sha512-8nVpA6yX0sCjf7v/NDfeaOlyaIIqL7OaIGOWSPFqUKK59Gnumd3Wa+2l8oAaYO2lk0sO+SbWFWRSvhu8gLGv4A==", "requires": { "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.42.1", - "@typescript-eslint/types": "5.42.1", - "@typescript-eslint/typescript-estree": "5.42.1", + "@typescript-eslint/scope-manager": "5.43.0", + "@typescript-eslint/types": "5.43.0", + "@typescript-eslint/typescript-estree": "5.43.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0", "semver": "^7.3.7" @@ -19886,11 +19889,11 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.42.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.42.1.tgz", - "integrity": "sha512-LOQtSF4z+hejmpUvitPlc4hA7ERGoj2BVkesOcG91HCn8edLGUXbTrErmutmPbl8Bo9HjAvOO/zBKQHExXNA2A==", + "version": "5.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.43.0.tgz", + "integrity": "sha512-icl1jNH/d18OVHLfcwdL3bWUKsBeIiKYTGxMJCoGe7xFht+E4QgzOqoWYrU8XSLJWhVw8nTacbm03v23J/hFTg==", "requires": { - "@typescript-eslint/types": "5.42.1", + "@typescript-eslint/types": "5.43.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -20146,9 +20149,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -20321,9 +20324,9 @@ } }, "axe-core": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.1.tgz", - "integrity": "sha512-1exVbW0X1O/HSr/WMwnaweyqcWOgZgLiVxdLG34pvSQk4NlYQr9OUy0JLwuhFfuVNQzzqgH57eYzkFBCb3bIsQ==" + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.5.2.tgz", + "integrity": "sha512-u2MVsXfew5HBvjsczCv+xlwdNnB1oQR9HlAcsejZttNjKKSkeDNVwB1vMThIUIFI9GoT57Vtk8iQLwqOfAkboA==" }, "axobject-query": { "version": "2.2.0", @@ -20802,9 +20805,9 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==" + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.6.1.tgz", + "integrity": "sha512-up5ggbaDqOqJ4UqLKZ2naVkyqSJQgJi5lwD6b6mM748ysrghDBX0bx/qJTUHzw7zu6Mq4gycviSF5hJnwceD8w==" }, "cjs-module-lexer": { "version": "1.2.2", @@ -20998,22 +21001,22 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.0.tgz", - "integrity": "sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==" + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.26.1.tgz", + "integrity": "sha512-21491RRQVzUn0GGM9Z1Jrpr6PNPxPi+Za8OM9q4tksTSnlbXXGKK1nXNg/QvwFYettXvSX6zWKCtHHfjN4puyA==" }, "core-js-compat": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.0.tgz", - "integrity": "sha512-piOX9Go+Z4f9ZiBFLnZ5VrOpBl0h7IGCkiFUN11QTe6LjAvOT3ifL/5TdoizMh99hcGy5SoLyWbapIY/PIb/3A==", + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz", + "integrity": "sha512-622/KzTudvXCDLRw70iHW4KKs1aGpcRcowGWyYJr2DEBfRrd6hNJybxSWJFuZYD4ma86xhrwDDHxmDaIq4EA8A==", "requires": { "browserslist": "^4.21.4" } }, "core-js-pure": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz", - "integrity": "sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==" + "version": "3.26.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.1.tgz", + "integrity": "sha512-VVXcDpp/xJ21KdULRq/lXdLzQAtX7+37LzpyfFM973il0tWSsDEoyzG38G14AjTpK9VTfiNM9jnFauq/CpaWGQ==" }, "core-util-is": { "version": "1.0.3", @@ -21078,18 +21081,18 @@ } }, "css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.2.tgz", + "integrity": "sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==", "requires": { "icss-utils": "^5.1.0", - "postcss": "^8.4.7", + "postcss": "^8.4.18", "postcss-modules-extract-imports": "^3.0.0", "postcss-modules-local-by-default": "^4.0.0", "postcss-modules-scope": "^3.0.0", "postcss-modules-values": "^4.0.0", "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" + "semver": "^7.3.8" }, "dependencies": { "semver": { @@ -21116,9 +21119,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -22159,9 +22162,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -24172,9 +24175,9 @@ } }, "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "requires": {} }, "jest-regex-util": { @@ -24938,9 +24941,9 @@ } }, "js-base64": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", - "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.3.tgz", + "integrity": "sha512-PAr6Xg2jvd7MCR6Ld9Jg3BmTcjYsHEBx1VlwEwULb/qowPf5VD9kEMagj23Gm7JRnSvE/Da/57nChZjnvL8v6A==" }, "js-sdsl": { "version": "4.1.5", @@ -25232,9 +25235,9 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memfs": { - "version": "3.4.10", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.10.tgz", - "integrity": "sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ==", + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.11.tgz", + "integrity": "sha512-GvsCITGAyDCxxsJ+X6prJexFQEhOCJaIlUbsAvjzSI5o5O7j2dle3jWvz5Z5aOdpOxW6ol3vI1+0ut+641F1+w==", "requires": { "fs-monkey": "^1.0.3" } @@ -25292,17 +25295,17 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mini-css-extract-plugin": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz", - "integrity": "sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.0.tgz", + "integrity": "sha512-auqtVo8KhTScMsba7MbijqZTfibbXiBNlPAQbsVt7enQfcDYLdgG57eGxMqwVU3mfeWANY4F1wUg+rMF+ycZgw==", "requires": { "schema-utils": "^4.0.0" }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -26328,11 +26331,11 @@ } }, "postcss-preset-env": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.2.tgz", - "integrity": "sha512-rSMUEaOCnovKnwc5LvBDHUDzpGP+nrUeWZGWt9M72fBvckCi45JmnJigUr4QG4zZeOHmOCNCZnd2LKDvP++ZuQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-7.8.3.tgz", + "integrity": "sha512-T1LgRm5uEVFSEF83vHZJV2z19lHg4yJuZ6gXZZkqVsqv63nlr6zabMH3l4Pc01FQCyfWVrh2GaUeCVy9Po+Aag==", "requires": { - "@csstools/postcss-cascade-layers": "^1.1.0", + "@csstools/postcss-cascade-layers": "^1.1.1", "@csstools/postcss-color-function": "^1.1.1", "@csstools/postcss-font-format-keywords": "^1.0.1", "@csstools/postcss-hwb-function": "^1.0.2", @@ -26346,19 +26349,19 @@ "@csstools/postcss-text-decoration-shorthand": "^1.0.0", "@csstools/postcss-trigonometric-functions": "^1.0.2", "@csstools/postcss-unset-value": "^1.0.2", - "autoprefixer": "^10.4.11", - "browserslist": "^4.21.3", + "autoprefixer": "^10.4.13", + "browserslist": "^4.21.4", "css-blank-pseudo": "^3.0.3", "css-has-pseudo": "^3.0.4", "css-prefers-color-scheme": "^6.0.3", - "cssdb": "^7.0.1", + "cssdb": "^7.1.0", "postcss-attribute-case-insensitive": "^5.0.2", "postcss-clamp": "^4.1.0", "postcss-color-functional-notation": "^4.2.4", "postcss-color-hex-alpha": "^8.0.4", "postcss-color-rebeccapurple": "^7.1.1", "postcss-custom-media": "^8.0.2", - "postcss-custom-properties": "^12.1.9", + "postcss-custom-properties": "^12.1.10", "postcss-custom-selectors": "^6.0.3", "postcss-dir-pseudo-class": "^6.0.5", "postcss-double-position-gradients": "^3.1.2", @@ -26991,16 +26994,16 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, "regexpu-core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.1.tgz", - "integrity": "sha512-HrnlNtpvqP1Xkb28tMhBUO2EbyUHdQlsnlAhzWcwHy8WJR53UWr7/MAvqrsQKMbV4qdpv03oTMG8iIhfsPFktQ==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.2.2.tgz", + "integrity": "sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw==", "requires": { "regenerate": "^1.4.2", "regenerate-unicode-properties": "^10.1.0", "regjsgen": "^0.7.1", "regjsparser": "^0.9.1", "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" + "unicode-match-property-value-ecmascript": "^2.1.0" } }, "regjsgen": { @@ -28120,9 +28123,9 @@ } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "peer": true }, "unbox-primitive": { @@ -28151,9 +28154,9 @@ } }, "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", + "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==" }, "unicode-property-aliases-ecmascript": { "version": "2.1.0", @@ -28383,9 +28386,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -28456,9 +28459,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -28684,9 +28687,9 @@ } }, "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", From fcbf71dad7149abb3d7d45c9e54fafbcfb9cf808 Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Thu, 17 Nov 2022 06:40:59 -0500 Subject: [PATCH 36/36] Thank you @gergepalfi for your sponsorship! --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a00d062c..c42f349a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ appreciated. A big fat **Thank You** to the folks already sponsoring ntfy: + ## License Made with ❤️ by [Philipp C. Heckel](https://heckel.io).