diff --git a/cmd/serve.go b/cmd/serve.go index c281f3ec..b28bf46e 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -152,8 +152,8 @@ func execServe(c *cli.Context) error { return errors.New("if smtp-server-listen is set, smtp-server-domain must also be set") } else if attachmentCacheDir != "" && baseURL == "" { return errors.New("if attachment-cache-dir is set, base-url must also be set") - } else if baseURL != "" && !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") { - return errors.New("if set, base-url must start with http:// or https://") + } else if baseURL != "" && !strings.HasPrefix(baseURL, "http://") && !strings.HasPrefix(baseURL, "https://") && strings.HasSuffix(baseURL, "/") { + return errors.New("if set, base-url must start with http:// or https://, and must not end with a slash (/)") } else if !util.InStringList([]string{"read-write", "read-only", "write-only", "deny-all"}, authDefaultAccess) { return errors.New("if set, auth-default-access must start set to 'read-write', 'read-only', 'write-only' or 'deny-all'") } else if !util.InStringList([]string{"app", "home", "disable"}, webRoot) { diff --git a/docs/examples.md b/docs/examples.md index 6183b670..fc4bc1a2 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -9,7 +9,9 @@ those out, too. [create a pull request](https://github.com/binwiederhier/ntfy/pulls), and I'll happily include it. Also note, that I cannot guarantee that all of these examples are functional. Many of them I have not tried myself. -## A long process is done: backups, copying data, pipelines, ... +## Cronjobs +ntfy is perfect for any kind of cronjobs or just when long processes are done (backups, pipelines, rsync copy commands, ...). + I started adding notifications pretty much all of my scripts. Typically, I just chain the curl call directly to the command I'm running. The following example will either send Laptop backup succeeded or ⚠️ Laptop backup failed directly to my phone: @@ -21,6 +23,15 @@ rsync -a root@laptop /backups/laptop \ || curl -H tags:warning -H prio:high -d "Laptop backup failed" ntfy.sh/backups ``` +Here's one for the history books. I desperately want the `github.com/ntfy` organization, but all my tickets with +GitHub have been hopeless. In case it ever becomes available, I want to know immediately. + +``` cron +# Check github/ntfy user +*/6 * * * * if curl -s https://api.github.com/users/ntfy | grep "Not Found"; then curl -d "github.com/ntfy is available" -H "Tags: tada" -H "Prio: high" ntfy.sh/my-alerts; fi +``` + + ## Low disk space alerts Here's a simple cronjob that I use to alert me when the disk space on the root disk is running low. It's simple, but effective. @@ -42,11 +53,7 @@ if [ -n "$avail" ]; then fi ``` -## Server-sent messages in your web app -Just as you can [subscribe to topics in the Web UI](subscribe/web.md), you can use ntfy in your own -web application. Check out the live example. - -## Notify on SSH login +## SSH login alerts Years ago my home server was broken into. That shook me hard, so every time someone logs into any machine that I own, I now message myself. Here's an example of how to use PAM to notify yourself on SSH login. @@ -102,7 +109,7 @@ One of my co-workers uses the following Ansible task to let him know when things body: "{{ inventory_hostname }} reseeding complete" ``` -## Watchtower notifications (shoutrrr) +## 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. @@ -121,16 +128,7 @@ Or, if you only want to send notifications using shoutrrr: shoutrrr send -u "generic+https://ntfy.sh/my_watchtower_topic?title=WatchtowerUpdates" -m "testMessage" ``` -## Random cronjobs -Alright, here's one for the history books. I desperately want the `github.com/ntfy` organization, but all my tickets with -GitHub have been hopeless. In case it ever becomes available, I want to know immediately. - -``` cron -# Check github/ntfy user -*/6 * * * * if curl -s https://api.github.com/users/ntfy | grep "Not Found"; then curl -d "github.com/ntfy is available" -H "Tags: tada" -H "Prio: high" ntfy.sh/my-alerts; fi -``` - -## Download notifications (Sonarr, Radarr, Lidarr, Readarr, Prowlarr, SABnzbd) +## Sonarr, Radarr, Lidarr, Readarr, Prowlarr, SABnzbd It's possible to use custom scripts for all the *arr services, plus SABnzbd. Notifications for downloads, warnings, grabs etc. Some simple bash scripts to achieve this are kindly provided in [nickexyz's repository](https://github.com/nickexyz/ntfy-shellscripts). @@ -343,7 +341,7 @@ You can use the HTTP request node to send messages with [Node-RED](https://noder ![Node red picture flow](static/img/nodered-picture.png) -## Gatus service health check +## Gatus An example for a custom alert with [Gatus](https://github.com/TwiN/gatus): ``` yaml @@ -435,11 +433,37 @@ notify: ``` ## Uptime Kuma -- Go to your [Uptime Kuma](https://github.com/louislam/uptime-kuma) Settings > Notifications, click on **Setup Notification** -- ![Uptime Kuma Settings](static/img/uptimekuma-settings.png) -- Set your desired **title** (e.g. "Uptime Kuma"), **ntfy topic**, **Server URL** and **priority (1-5)** -- ![Uptime Kuma Setup](static/img/uptimekuma-setup.png) -- You can now test the notifications and apply them to monitors. -- ![Uptime Kuma iOS Test](static/img/uptimekuma-ios-test.jpg) -- ![Uptime Kuma iOS Down](static/img/uptimekuma-ios-down.jpg) -- ![Uptime Kuma iOS Up](static/img/uptimekuma-ios-up.jpg) \ No newline at end of file +Go to your [Uptime Kuma](https://github.com/louislam/uptime-kuma) Settings > Notifications, click on **Setup Notification**. +Then set your desired **title** (e.g. "Uptime Kuma"), **ntfy topic**, **Server URL** and **priority (1-5)**: + +
+ + +
+ +You can now test the notifications and apply them to monitors: + +
+ + + +
+ +## Apprise +ntfy is integrated natively into [Apprise](https://github.com/caronc/apprise) (also check out the +[Apprise/ntfy wiki page](https://github.com/caronc/apprise/wiki/Notify_ntfy)). + +You can use it like this: + +``` +apprise -vv -t "Test Message Title" -b "Test Message Body" \ + ntfy://mytopic +``` + +Or with your own server like this: + +``` +apprise -vv -t "Test Message Title" -b "Test Message Body" \ + ntfy://ntfy.example.com/mytopic +``` + diff --git a/docs/faq.md b/docs/faq.md index 9846170b..cc3e59c0 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -42,3 +42,10 @@ decent now. [Instant delivery](subscribe/phone.md#instant-delivery) is a feature in the Android app. If turned on, the app maintains a constant connection to the server and listens for incoming notifications. This consumes additional battery (see above), but delivers notifications instantly. + +## Where can I donate? +Many people have asked (thanks for that!), but I am currently not accepting any donations. The cost is manageable +($25/month for hosting, and $99/year for the Apple cert) right now, and I don't want to have to feel obligated to +anyone by accepting their money. + +I may ask for donations in the future, though. After all, $400 per year isn't nothing... diff --git a/docs/publish.md b/docs/publish.md index 5f0ae585..82f7beb0 100644 --- a/docs/publish.md +++ b/docs/publish.md @@ -2735,6 +2735,22 @@ parameter (or any of its aliases `unifiedpush` or `up`) to `1` to [disable Fireb option is mostly equivalent to `Firebase: no`, but was introduced to allow future flexibility. The flag additionally enables auto-detection of the message encoding. If the message is binary, it'll be encoded as base64. +### Matrix Gateway +The ntfy server implements a [Matrix Push Gateway](https://spec.matrix.org/v1.2/push-gateway-api/) (in combination with +[UnifiedPush](https://unifiedpush.org) as the [Provider Push Protocol](https://unifiedpush.org/developers/gateway/)). This makes it easier to integrate +with self-hosted [Matrix](https://matrix.org/) servers (such as [synapse](https://github.com/matrix-org/synapse)), since +you don't have to set up a separate push proxy (such as [common-proxies](https://github.com/UnifiedPush/common-proxies)). + +In short, ntfy accepts Matrix messages on the `/_matrix/push/v1/notify` endpoint (see [Push Gateway API](https://spec.matrix.org/v1.2/push-gateway-api/)), +and forwards them to the ntfy topic defined in the `pushkey` of the message. The message will then be forwarded to the +ntfy Android app, and passed on to the Matrix client there. + +There is a nice diagram in the [Push Gateway docs](https://spec.matrix.org/v1.2/push-gateway-api/). In this diagram, the +ntfy server plays the role of the Push Gateway, as well as the Push Provider. UnifiedPush is the Provider Push Protocol. + +!!! info + This is not a generic Matrix Push Gateway. It only works in combination with UnifiedPush and ntfy. + ## Public topics Obviously all topics on ntfy.sh are public, but there are a few designated topics that are used in examples, and topics that you can use to try out what [authentication and access control](#authentication) looks like. diff --git a/docs/releases.md b/docs/releases.md index 56e7fe1f..9150251a 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -13,16 +13,17 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release ## ntfy server v1.26.0 (UNRELEASED) -**Bugs:** - -* Web app: Show "notifications not supported" alert on HTTP ([#323](https://github.com/binwiederhier/ntfy/issues/323), thanks to [@milksteakjellybeans](https://github.com/milksteakjellybeans) for reporting) - **Features:** +* ntfy now is a [Matrix Push Gateway](https://spec.matrix.org/v1.2/push-gateway-api/) (in combination with [UnifiedPush](https://unifiedpush.org) as the [Provider Push Protocol](https://unifiedpush.org/developers/gateway/), [#319](https://github.com/binwiederhier/ntfy/issues/319)/[#326](https://github.com/binwiederhier/ntfy/pull/326), thanks to [@MayeulC](https://github.com/MayeulC) for reporting) * Windows CLI is now available via [Scoop](https://scoop.sh) ([ScoopInstaller#3594](https://github.com/ScoopInstaller/Main/pull/3594), [#311](https://github.com/binwiederhier/ntfy/pull/311), [#269](https://github.com/binwiederhier/ntfy/issues/269), thanks to [@kzshantonu](https://github.com/kzshantonu)) * [Uptime Kuma](https://github.com/louislam/uptime-kuma) now allows publishing to ntfy ([uptime-kuma#1674](https://github.com/louislam/uptime-kuma/pull/1674), thanks to [@philippdormann](https://github.com/philippdormann)) * Display ntfy version in `ntfy serve` command ([#314](https://github.com/binwiederhier/ntfy/issues/314), thanks to [@poblabs](https://github.com/poblabs)) +**Bugs:** + +* Web app: Show "notifications not supported" alert on HTTP ([#323](https://github.com/binwiederhier/ntfy/issues/323), thanks to [@milksteakjellybeans](https://github.com/milksteakjellybeans) for reporting) + **Documentation** * Added [example](examples.md) for [Uptime Kuma](https://github.com/louislam/uptime-kuma) integration ([#315](https://github.com/binwiederhier/ntfy/pull/315), thanks to [@philippdormann](https://github.com/philippdormann)) diff --git a/docs/static/css/extra.css b/docs/static/css/extra.css index a7370399..6ac0b7e7 100644 --- a/docs/static/css/extra.css +++ b/docs/static/css/extra.css @@ -60,7 +60,8 @@ figure video { } .screenshots img { - height: 230px; + max-height: 230px; + max-width: 300px; margin: 3px; border-radius: 5px; filter: drop-shadow(2px 2px 2px #ddd); diff --git a/docs/subscribe/api.md b/docs/subscribe/api.md index 7eb3a95e..4c46d221 100644 --- a/docs/subscribe/api.md +++ b/docs/subscribe/api.md @@ -87,7 +87,7 @@ recommended way to subscribe to a topic**. The notable exception is JavaScript, ### Subscribe as SSE stream Using [EventSource](https://developer.mozilla.org/en-US/docs/Web/API/EventSource) in JavaScript, you can consume notifications via a [Server-Sent Events (SSE)](https://en.wikipedia.org/wiki/Server-sent_events) stream. It's incredibly -easy to use. Here's what it looks like. You may also want to check out the [live example](/example.html). +easy to use. Here's what it looks like. You may also want to check out the [full example on GitHub](https://github.com/binwiederhier/ntfy/tree/main/examples/web-example-eventsource). === "Command line (curl)" ``` diff --git a/go.mod b/go.mod index f022c731..a5caea5f 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 golang.org/x/time v0.0.0-20220609170525-579cf78fd858 - google.golang.org/api v0.83.0 + google.golang.org/api v0.84.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -38,19 +38,20 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-cmp v0.5.8 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect - golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d // indirect + golang.org/x/net v0.0.0-20220615171555-694bf12d69de // indirect + golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine/v2 v2.0.1 // indirect - google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac // indirect + google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 // indirect google.golang.org/grpc v1.47.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect diff --git a/go.sum b/go.sum index 941fa920..0eaa090a 100644 --- a/go.sum +++ b/go.sum @@ -192,6 +192,9 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -341,11 +344,10 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220526153639-5463443f8c37/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA= -golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220615171555-694bf12d69de h1:ogOG2+P6LjO2j55AkRScrkB2BFpd+Z8TY2wcM0Z3MGo= +golang.org/x/net v0.0.0-20220615171555-694bf12d69de/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -366,7 +368,6 @@ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw= golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb h1:8tDJ3aechhddbdPAxpycgXHJRMLpk/Ab+aa4OgdN5/g= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= @@ -381,7 +382,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -443,10 +443,11 @@ golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM= @@ -464,8 +465,6 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= -golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -524,7 +523,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= @@ -571,10 +569,10 @@ google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRR google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.82.0 h1:h6EGeZuzhoKSS7BUznzkW+2wHZ+4Ubd6rsVvvh3dRkw= -google.golang.org/api v0.82.0/go.mod h1:Ld58BeTlL9DIYr2M2ajvoSqmGLei0BMn+kVBmkam1os= google.golang.org/api v0.83.0 h1:pMvST+6v+46Gabac4zlJlalxZjCeRcepwg2EdBU+nCc= google.golang.org/api v0.83.0/go.mod h1:CNywQoj/AfhTw26ZWAa6LwOv+6WFxHmeLPZq2uncLZk= +google.golang.org/api v0.84.0 h1:NMB9J4cCxs9xEm+1Z9QiO3eFvn7EnQj3Eo3hN6ugVlg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -669,11 +667,11 @@ google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 h1:qRu95HZ148xXw+XeZ3dvqe85PxH4X8+jIo0iRPKcEnM= google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac h1:ByeiW1F67iV9o8ipGskA+HWzSkMbRJuKLlwCdPxzn7A= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90 h1:4SPz2GL2CXJt28MTF8V6Ap/9ZiVbQlJeGSd9qtA7DLs= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= diff --git a/server/errors.go b/server/errors.go index 32c1b3b9..28dbca3a 100644 --- a/server/errors.go +++ b/server/errors.go @@ -50,10 +50,13 @@ var ( errHTTPBadRequestWebSocketsUpgradeHeaderMissing = &errHTTP{40016, http.StatusBadRequest, "invalid request: client not using the websocket protocol", "https://ntfy.sh/docs/subscribe/api/#websockets"} errHTTPBadRequestJSONInvalid = &errHTTP{40017, http.StatusBadRequest, "invalid request: request body must be message JSON", "https://ntfy.sh/docs/publish/#publish-as-json"} errHTTPBadRequestActionsInvalid = &errHTTP{40018, http.StatusBadRequest, "invalid request: actions invalid", "https://ntfy.sh/docs/publish/#action-buttons"} + errHTTPBadRequestMatrixMessageInvalid = &errHTTP{40019, http.StatusBadRequest, "invalid request: Matrix JSON invalid", "https://ntfy.sh/docs/publish/#matrix-gateway"} + errHTTPBadRequestMatrixPushkeyBaseURLMismatch = &errHTTP{40020, http.StatusBadRequest, "invalid request: push key must be prefixed with base URL", "https://ntfy.sh/docs/publish/#matrix-gateway"} errHTTPNotFound = &errHTTP{40401, http.StatusNotFound, "page not found", ""} errHTTPUnauthorized = &errHTTP{40101, http.StatusUnauthorized, "unauthorized", "https://ntfy.sh/docs/publish/#authentication"} errHTTPForbidden = &errHTTP{40301, http.StatusForbidden, "forbidden", "https://ntfy.sh/docs/publish/#authentication"} errHTTPEntityTooLargeAttachmentTooLarge = &errHTTP{41301, http.StatusRequestEntityTooLarge, "attachment too large, or bandwidth limit reached", "https://ntfy.sh/docs/publish/#limitations"} + errHTTPEntityTooLargeMatrixRequestTooLarge = &errHTTP{41302, http.StatusRequestEntityTooLarge, "Matrix request is larger than the max allowed length", ""} errHTTPTooManyRequestsLimitRequests = &errHTTP{42901, http.StatusTooManyRequests, "limit reached: too many requests, please be nice", "https://ntfy.sh/docs/publish/#limitations"} errHTTPTooManyRequestsLimitEmails = &errHTTP{42902, http.StatusTooManyRequests, "limit reached: too many emails, please be nice", "https://ntfy.sh/docs/publish/#limitations"} errHTTPTooManyRequestsLimitSubscriptions = &errHTTP{42903, http.StatusTooManyRequests, "limit reached: too many active subscriptions, please be nice", "https://ntfy.sh/docs/publish/#limitations"} @@ -61,4 +64,5 @@ var ( errHTTPTooManyRequestsAttachmentBandwidthLimit = &errHTTP{42905, http.StatusTooManyRequests, "too many requests: daily bandwidth limit reached", "https://ntfy.sh/docs/publish/#limitations"} errHTTPInternalError = &errHTTP{50001, http.StatusInternalServerError, "internal server error", ""} errHTTPInternalErrorInvalidFilePath = &errHTTP{50002, http.StatusInternalServerError, "internal server error: invalid file path", ""} + errHTTPInternalErrorMissingBaseURL = &errHTTP{50003, http.StatusInternalServerError, "internal server error: base-url must be be configured for this feature", "https://ntfy.sh/docs/config/"} ) diff --git a/server/example.html b/server/example.html deleted file mode 100644 index e558ef12..00000000 --- a/server/example.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - ntfy.sh: EventSource Example - - - - -

ntfy.sh: EventSource Example

-

- This is an example showing how to use ntfy.sh with - EventSource.
- This example doesn't need a server. You can just save the HTML page and run it from anywhere. -

- -

Log:

-
- - - - - diff --git a/server/server.go b/server/server.go index 2f01b07f..21a6c584 100644 --- a/server/server.go +++ b/server/server.go @@ -68,15 +68,13 @@ var ( webConfigPath = "/config.js" userStatsPath = "/user/stats" + matrixPushPath = "/_matrix/push/v1/notify" staticRegex = regexp.MustCompile(`^/static/.+`) docsRegex = regexp.MustCompile(`^/docs(|/.*)$`) fileRegex = regexp.MustCompile(`^/file/([-_A-Za-z0-9]{1,64})(?:\.[A-Za-z0-9]{1,16})?$`) disallowedTopics = []string{"docs", "static", "file", "app", "settings"} // If updated, also update in Android app attachURLRegex = regexp.MustCompile(`^https?://`) - //go:embed "example.html" - exampleSource string - //go:embed site webFs embed.FS webFsCached = &util.CachingEmbedFS{ModTime: time.Now(), FS: webFs} @@ -258,6 +256,10 @@ func (s *Server) handle(w http.ResponseWriter, r *http.Request) { } return // Do not attempt to write to upgraded connection } + if matrixErr, ok := err.(*errMatrix); ok { + writeMatrixError(w, r, v, matrixErr) + return + } httpErr, ok := err.(*errHTTP) if !ok { httpErr = errHTTPInternalError @@ -278,14 +280,14 @@ func (s *Server) handle(w http.ResponseWriter, r *http.Request) { func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visitor) error { if r.Method == http.MethodGet && r.URL.Path == "/" { return s.ensureWebEnabled(s.handleHome)(w, r, v) - } else if r.Method == http.MethodGet && r.URL.Path == "/example.html" { - return s.ensureWebEnabled(s.handleExample)(w, r, v) } else if r.Method == http.MethodHead && r.URL.Path == "/" { return s.ensureWebEnabled(s.handleEmpty)(w, r, v) } else if r.Method == http.MethodGet && r.URL.Path == webConfigPath { return s.ensureWebEnabled(s.handleWebConfig)(w, r, v) } else if r.Method == http.MethodGet && r.URL.Path == userStatsPath { return s.handleUserStats(w, r, v) + } else if r.Method == http.MethodGet && r.URL.Path == matrixPushPath { + return s.handleMatrixDiscovery(w) } else if r.Method == http.MethodGet && staticRegex.MatchString(r.URL.Path) { return s.ensureWebEnabled(s.handleStatic)(w, r, v) } else if r.Method == http.MethodGet && docsRegex.MatchString(r.URL.Path) { @@ -296,6 +298,8 @@ func (s *Server) handleInternal(w http.ResponseWriter, r *http.Request, v *visit return s.ensureWebEnabled(s.handleOptions)(w, r, v) } else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && r.URL.Path == "/" { return s.limitRequests(s.transformBodyJSON(s.authWrite(s.handlePublish)))(w, r, v) + } else if r.Method == http.MethodPost && r.URL.Path == matrixPushPath { + return s.limitRequests(s.transformMatrixJSON(s.authWrite(s.handlePublishMatrix)))(w, r, v) } else if (r.Method == http.MethodPut || r.Method == http.MethodPost) && topicPathRegex.MatchString(r.URL.Path) { return s.limitRequests(s.authWrite(s.handlePublish))(w, r, v) } else if r.Method == http.MethodGet && publishPathRegex.MatchString(r.URL.Path) { @@ -348,11 +352,6 @@ func (s *Server) handleTopicAuth(w http.ResponseWriter, _ *http.Request, _ *visi return err } -func (s *Server) handleExample(w http.ResponseWriter, _ *http.Request, _ *visitor) error { - _, err := io.WriteString(w, exampleSource) - return err -} - func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visitor) error { appRoot := "/" if !s.config.WebRootIsApp { @@ -425,25 +424,29 @@ func (s *Server) handleFile(w http.ResponseWriter, r *http.Request, v *visitor) return nil } -func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visitor) error { +func (s *Server) handleMatrixDiscovery(w http.ResponseWriter) error { + return writeMatrixDiscoveryResponse(w) +} + +func (s *Server) handlePublishWithoutResponse(r *http.Request, v *visitor) (*message, error) { t, err := s.topicFromPath(r.URL.Path) if err != nil { - return err + return nil, err } body, err := util.Peek(r.Body, s.config.MessageLimit) if err != nil { - return err + return nil, err } m := newDefaultMessage(t.ID, "") cache, firebase, email, unifiedpush, err := s.parsePublishParams(r, v, m) if err != nil { - return err + return nil, err } if m.PollID != "" { m = newPollRequestMessage(t.ID, m.PollID) } if err := s.handlePublishBody(r, v, m, body, unifiedpush); err != nil { - return err + return nil, err } if m.Message == "" { m.Message = emptyMessageBody @@ -456,7 +459,7 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visito } if !delayed { if err := t.Publish(v, m); err != nil { - return err + return nil, err } if s.firebaseClient != nil && firebase { go s.sendToFirebase(v, m) @@ -472,20 +475,36 @@ func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visito } if cache { if err := s.messageCache.AddMessage(m); err != nil { - return err + return nil, err } } + s.mu.Lock() + s.messages++ + s.mu.Unlock() + return m, nil +} + +func (s *Server) handlePublish(w http.ResponseWriter, r *http.Request, v *visitor) error { + m, err := s.handlePublishWithoutResponse(r, v) + if err != nil { + return err + } w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") // CORS, allow cross-origin requests if err := json.NewEncoder(w).Encode(m); err != nil { return err } - s.mu.Lock() - s.messages++ - s.mu.Unlock() return nil } +func (s *Server) handlePublishMatrix(w http.ResponseWriter, r *http.Request, v *visitor) error { + _, err := s.handlePublishWithoutResponse(r, v) + if err != nil { + return &errMatrix{pushKey: r.Header.Get(matrixPushKeyHeader), err: err} + } + return writeMatrixSuccess(w) +} + func (s *Server) sendToFirebase(v *visitor, m *message) { log.Debug("%s Publishing to Firebase", logMessagePrefix(v, m)) if err := s.firebaseClient.Send(v, m); err != nil { @@ -1286,6 +1305,19 @@ func (s *Server) transformBodyJSON(next handleFunc) handleFunc { } } +func (s *Server) transformMatrixJSON(next handleFunc) handleFunc { + return func(w http.ResponseWriter, r *http.Request, v *visitor) error { + newRequest, err := newRequestFromMatrixJSON(r, s.config.BaseURL, s.config.MessageLimit) + if err != nil { + return err + } + if err := next(w, newRequest, v); err != nil { + return &errMatrix{pushKey: newRequest.Header.Get(matrixPushKeyHeader), err: err} + } + return nil + } +} + func (s *Server) authWrite(next handleFunc) handleFunc { return s.withAuth(next, auth.PermissionWrite) } diff --git a/server/server.yml b/server/server.yml index 01a212d0..65f1db3c 100644 --- a/server/server.yml +++ b/server/server.yml @@ -4,8 +4,12 @@ # All options also support underscores (_) instead of dashes (-) to comply with the YAML spec. # Public facing base URL of the service (e.g. https://ntfy.sh or https://ntfy.example.com) -# This setting is currently only used by attachments, e-mail sending (outgoing mail only), as well -# as in combination with upstream-base-url (for iOS push notifications for self-hosted servers). +# +# This setting is required for any of the following features: +# - attachments (to return a download URL) +# - e-mail sending (for the topic URL in the email footer) +# - iOS push notifications for self-hosted servers (to calculate the Firebase poll_request topic) +# - Matrix Push Gateway (to validate that the pushkey is correct) # # base-url: diff --git a/server/server_matrix.go b/server/server_matrix.go new file mode 100644 index 00000000..2113c5ac --- /dev/null +++ b/server/server_matrix.go @@ -0,0 +1,175 @@ +package server + +import ( + "bytes" + "encoding/json" + "fmt" + "heckel.io/ntfy/log" + "heckel.io/ntfy/util" + "io" + "net/http" + "strings" +) + +// Matrix Push Gateway / UnifiedPush / ntfy integration: +// +// ntfy implements a Matrix Push Gateway (as defined in https://spec.matrix.org/v1.2/push-gateway-api/), +// in combination with UnifiedPush as the Provider Push Protocol (as defined in https://unifiedpush.org/developers/gateway/). +// +// In the picture below, ntfy is the Push Gateway (mostly in this file), as well as the Push Provider (ntfy's +// main functionality). UnifiedPush is the Provider Push Protocol, as implemented by the ntfy server and the +// ntfy Android app. +// +// +--------------------+ +-------------------+ +// Matrix HTTP | | | | +// Notification Protocol | App Developer | | Device Vendor | +// | | | | +// +-------------------+ | +----------------+ | | +---------------+ | +// | | | | | | | | | | +// | Matrix homeserver +-----> Push Gateway +------> Push Provider | | +// | | | | | | | | | | +// +-^-----------------+ | +----------------+ | | +----+----------+ | +// | | | | | | +// Matrix | | | | | | +// Client/Server API + | | | | | +// | | +--------------------+ +-------------------+ +// | +--+-+ | +// | | <-------------------------------------------+ +// +---+ | +// | | Provider Push Protocol +// +----+ +// +// Mobile Device or Client +// + +// matrixRequest represents a Matrix message, as it is sent to a Push Gateway (as per +// this spec: https://spec.matrix.org/v1.2/push-gateway-api/). +// +// From the message, we only require the "pushkey", as it represents our target topic URL. +// A message may look like this (excerpt): +// { +// "notification": { +// "devices": [ +// { +// "pushkey": "https://ntfy.sh/upDAHJKFFDFD?up=1", +// ... +// } +// ] +// } +// } +// +type matrixRequest struct { + Notification *struct { + Devices []*struct { + PushKey string `json:"pushkey"` + } `json:"devices"` + } `json:"notification"` +} + +// matrixResponse represents the response to a Matrix push gateway message, as defined +// in the spec (https://spec.matrix.org/v1.2/push-gateway-api/). +type matrixResponse struct { + Rejected []string `json:"rejected"` +} + +// errMatrix represents an error when handing Matrix gateway messages +type errMatrix struct { + pushKey string + err error +} + +func (e errMatrix) Error() string { + if e.err != nil { + return fmt.Sprintf("message with push key %s rejected: %s", e.pushKey, e.err.Error()) + } + return fmt.Sprintf("message with push key %s rejected", e.pushKey) +} + +const ( + // matrixPushKeyHeader is a header that's used internally to pass the Matrix push key (from the matrixRequest) + // along with the request. The push key is only used if an error occurs down the line. + matrixPushKeyHeader = "X-Matrix-Pushkey" +) + +// newRequestFromMatrixJSON reads the request body as a Matrix JSON message, parses the "pushkey", and creates a new +// HTTP request that looks like a normal ntfy request from it. +// +// It basically converts a Matrix push gatewqy request: +// +// POST /_matrix/push/v1/notify HTTP/1.1 +// { "notification": { "devices": [ { "pushkey": "https://ntfy.sh/upDAHJKFFDFD?up=1", ... } ] } } +// +// to a ntfy request, looking like this: +// +// POST /upDAHJKFFDFD?up=1 HTTP/1.1 +// { "notification": { "devices": [ { "pushkey": "https://ntfy.sh/upDAHJKFFDFD?up=1", ... } ] } } +// +func newRequestFromMatrixJSON(r *http.Request, baseURL string, messageLimit int) (*http.Request, error) { + if baseURL == "" { + return nil, errHTTPInternalErrorMissingBaseURL + } + body, err := util.Peek(r.Body, messageLimit) + if err != nil { + return nil, err + } + defer r.Body.Close() + if body.LimitReached { + return nil, errHTTPEntityTooLargeMatrixRequestTooLarge + } + var m matrixRequest + if err := json.Unmarshal(body.PeekedBytes, &m); err != nil { + return nil, errHTTPBadRequestMatrixMessageInvalid + } else if m.Notification == nil || len(m.Notification.Devices) == 0 || m.Notification.Devices[0].PushKey == "" { + return nil, errHTTPBadRequestMatrixMessageInvalid + } + pushKey := m.Notification.Devices[0].PushKey // We ignore other devices for now, see discussion in #316 + if !strings.HasPrefix(pushKey, baseURL+"/") { + return nil, &errMatrix{pushKey: pushKey, err: errHTTPBadRequestMatrixPushkeyBaseURLMismatch} + } + newRequest, err := http.NewRequest(http.MethodPost, pushKey, io.NopCloser(bytes.NewReader(body.PeekedBytes))) + if err != nil { + return nil, &errMatrix{pushKey: pushKey, err: err} + } + newRequest.RemoteAddr = r.RemoteAddr // Not strictly necessary, since visitor was already extracted + if r.Header.Get("X-Forwarded-For") != "" { + newRequest.Header.Set("X-Forwarded-For", r.Header.Get("X-Forwarded-For")) + } + newRequest.Header.Set(matrixPushKeyHeader, pushKey) + return newRequest, nil +} + +// writeMatrixDiscoveryResponse writes the UnifiedPush Matrix Gateway Discovery response to the given http.ResponseWriter, +// as per the spec (https://unifiedpush.org/developers/gateway/). +func writeMatrixDiscoveryResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + _, err := io.WriteString(w, `{"unifiedpush":{"gateway":"matrix"}}`+"\n") + return err +} + +// writeMatrixError logs and writes the errMatrix to the given http.ResponseWriter as a matrixResponse +func writeMatrixError(w http.ResponseWriter, r *http.Request, v *visitor, err *errMatrix) error { + log.Debug("%s Matrix gateway error: %s", logHTTPPrefix(v, r), err.Error()) + return writeMatrixResponse(w, err.pushKey) +} + +// writeMatrixSuccess writes a successful matrixResponse (no rejected push key) to the given http.ResponseWriter +func writeMatrixSuccess(w http.ResponseWriter) error { + return writeMatrixResponse(w, "") +} + +// writeMatrixResponse writes a matrixResponse to the given http.ResponseWriter, as defined in +// the spec (https://spec.matrix.org/v1.2/push-gateway-api/) +func writeMatrixResponse(w http.ResponseWriter, rejectedPushKey string) error { + rejected := make([]string, 0) + if rejectedPushKey != "" { + rejected = append(rejected, rejectedPushKey) + } + response := &matrixResponse{ + Rejected: rejected, + } + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(response); err != nil { + return err + } + return nil +} diff --git a/server/server_matrix_test.go b/server/server_matrix_test.go new file mode 100644 index 00000000..9129d6c4 --- /dev/null +++ b/server/server_matrix_test.go @@ -0,0 +1,84 @@ +package server + +import ( + "github.com/stretchr/testify/require" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestMatrix_NewRequestFromMatrixJSON_Success(t *testing.T) { + baseURL := "https://ntfy.sh" + maxLength := 4096 + body := `{"notification":{"content":{"body":"I'm floating in a most peculiar way.","msgtype":"m.text"},"counts":{"missed_calls":1,"unread":2},"devices":[{"app_id":"org.matrix.matrixConsole.ios","data":{},"pushkey":"https://ntfy.sh/upABCDEFGHI?up=1","pushkey_ts":12345678,"tweaks":{"sound":"bing"}}],"event_id":"$3957tyerfgewrf384","prio":"high","room_alias":"#exampleroom:matrix.org","room_id":"!slw48wfj34rtnrf:example.com","room_name":"Mission Control","sender":"@exampleuser:matrix.org","sender_display_name":"Major Tom","type":"m.room.message"}}` + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body)) + newRequest, err := newRequestFromMatrixJSON(r, baseURL, maxLength) + require.Nil(t, err) + require.Equal(t, "POST", newRequest.Method) + require.Equal(t, "https://ntfy.sh/upABCDEFGHI?up=1", newRequest.URL.String()) + require.Equal(t, "https://ntfy.sh/upABCDEFGHI?up=1", newRequest.Header.Get("X-Matrix-Pushkey")) + require.Equal(t, body, readAll(t, newRequest.Body)) +} + +func TestMatrix_NewRequestFromMatrixJSON_TooLarge(t *testing.T) { + baseURL := "https://ntfy.sh" + maxLength := 10 // Small + body := `{"notification":{"content":{"body":"I'm floating in a most peculiar way.","msgtype":"m.text"},"counts":{"missed_calls":1,"unread":2},"devices":[{"app_id":"org.matrix.matrixConsole.ios","data":{},"pushkey":"https://ntfy.sh/upABCDEFGHI?up=1","pushkey_ts":12345678,"tweaks":{"sound":"bing"}}],"event_id":"$3957tyerfgewrf384","prio":"high","room_alias":"#exampleroom:matrix.org","room_id":"!slw48wfj34rtnrf:example.com","room_name":"Mission Control","sender":"@exampleuser:matrix.org","sender_display_name":"Major Tom","type":"m.room.message"}}` + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body)) + _, err := newRequestFromMatrixJSON(r, baseURL, maxLength) + require.Equal(t, errHTTPEntityTooLargeMatrixRequestTooLarge, err) +} + +func TestMatrix_NewRequestFromMatrixJSON_InvalidJSON(t *testing.T) { + baseURL := "https://ntfy.sh" + maxLength := 4096 + body := `this is not json` + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body)) + _, err := newRequestFromMatrixJSON(r, baseURL, maxLength) + require.Equal(t, errHTTPBadRequestMatrixMessageInvalid, err) +} + +func TestMatrix_NewRequestFromMatrixJSON_NotAMatrixMessage(t *testing.T) { + baseURL := "https://ntfy.sh" + maxLength := 4096 + body := `{"message":"this is not a matrix message, but valid json"}` + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body)) + _, err := newRequestFromMatrixJSON(r, baseURL, maxLength) + require.Equal(t, errHTTPBadRequestMatrixMessageInvalid, err) +} + +func TestMatrix_NewRequestFromMatrixJSON_MismatchingPushKey(t *testing.T) { + baseURL := "https://ntfy.sh" // Mismatch! + maxLength := 4096 + body := `{"notification":{"content":{"body":"I'm floating in a most peculiar way.","msgtype":"m.text"},"counts":{"missed_calls":1,"unread":2},"devices":[{"app_id":"org.matrix.matrixConsole.ios","data":{},"pushkey":"https://ntfy.example.com/upABCDEFGHI?up=1","pushkey_ts":12345678,"tweaks":{"sound":"bing"}}],"event_id":"$3957tyerfgewrf384","prio":"high","room_alias":"#exampleroom:matrix.org","room_id":"!slw48wfj34rtnrf:example.com","room_name":"Mission Control","sender":"@exampleuser:matrix.org","sender_display_name":"Major Tom","type":"m.room.message"}}` + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", strings.NewReader(body)) + _, err := newRequestFromMatrixJSON(r, baseURL, maxLength) + matrixErr, ok := err.(*errMatrix) + require.True(t, ok) + require.Equal(t, errHTTPBadRequestMatrixPushkeyBaseURLMismatch, matrixErr.err) + require.Equal(t, "https://ntfy.example.com/upABCDEFGHI?up=1", matrixErr.pushKey) +} + +func TestMatrix_WriteMatrixDiscoveryResponse(t *testing.T) { + w := httptest.NewRecorder() + require.Nil(t, writeMatrixDiscoveryResponse(w)) + require.Equal(t, 200, w.Result().StatusCode) + require.Equal(t, `{"unifiedpush":{"gateway":"matrix"}}`+"\n", w.Body.String()) +} + +func TestMatrix_WriteMatrixError(t *testing.T) { + w := httptest.NewRecorder() + r, _ := http.NewRequest("POST", "http://ntfy.example.com/_matrix/push/v1/notify", nil) + v := newVisitor(newTestConfig(t), nil, "1.2.3.4") + require.Nil(t, writeMatrixError(w, r, v, &errMatrix{"https://ntfy.example.com/upABCDEFGHI?up=1", errHTTPBadRequestMatrixPushkeyBaseURLMismatch})) + require.Equal(t, 200, w.Result().StatusCode) + require.Equal(t, `{"rejected":["https://ntfy.example.com/upABCDEFGHI?up=1"]}`+"\n", w.Body.String()) +} + +func TestMatrix_WriteMatrixSuccess(t *testing.T) { + w := httptest.NewRecorder() + require.Nil(t, writeMatrixSuccess(w)) + require.Equal(t, 200, w.Result().StatusCode) + require.Equal(t, `{"rejected":[]}`+"\n", w.Body.String()) +} diff --git a/server/server_test.go b/server/server_test.go index 32f4fc2d..55125c3e 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -6,6 +6,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "io" "math/rand" "net/http" "net/http/httptest" @@ -171,10 +172,6 @@ func TestServer_StaticSites(t *testing.T) { require.Equal(t, 301, rr.Code) // Docs test removed, it was failing annoyingly. - - rr = request(t, s, "GET", "/example.html", "", nil) - require.Equal(t, 200, rr.Code) - require.Contains(t, rr.Body.String(), "") } func TestServer_WebEnabled(t *testing.T) { @@ -185,9 +182,6 @@ func TestServer_WebEnabled(t *testing.T) { rr := request(t, s, "GET", "/", "", nil) require.Equal(t, 404, rr.Code) - rr = request(t, s, "GET", "/example.html", "", nil) - require.Equal(t, 404, rr.Code) - rr = request(t, s, "GET", "/config.js", "", nil) require.Equal(t, 404, rr.Code) @@ -201,9 +195,6 @@ func TestServer_WebEnabled(t *testing.T) { rr = request(t, s2, "GET", "/", "", nil) require.Equal(t, 200, rr.Code) - rr = request(t, s2, "GET", "/example.html", "", nil) - require.Equal(t, 200, rr.Code) - rr = request(t, s2, "GET", "/config.js", "", nil) require.Equal(t, 200, rr.Code) @@ -916,6 +907,60 @@ func TestServer_PublishUnifiedPushText(t *testing.T) { require.Equal(t, "this is a unifiedpush text message", m.Message) } +func TestServer_MatrixGateway_Discovery(t *testing.T) { + s := newTestServer(t, newTestConfig(t)) + response := request(t, s, "GET", "/_matrix/push/v1/notify", "", nil) + require.Equal(t, 200, response.Code) + require.Equal(t, `{"unifiedpush":{"gateway":"matrix"}}`+"\n", response.Body.String()) +} + +func TestServer_MatrixGateway_Push_Success(t *testing.T) { + s := newTestServer(t, newTestConfig(t)) + notification := `{"notification":{"devices":[{"pushkey":"http://127.0.0.1:12345/mytopic?up=1"}]}}` + response := request(t, s, "POST", "/_matrix/push/v1/notify", notification, nil) + require.Equal(t, 200, response.Code) + require.Equal(t, `{"rejected":[]}`+"\n", response.Body.String()) + + response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil) + require.Equal(t, 200, response.Code) + m := toMessage(t, response.Body.String()) + require.Equal(t, notification, m.Message) +} + +func TestServer_MatrixGateway_Push_Failure_InvalidPushkey(t *testing.T) { + s := newTestServer(t, newTestConfig(t)) + notification := `{"notification":{"devices":[{"pushkey":"http://wrong-base-url.com/mytopic?up=1"}]}}` + response := request(t, s, "POST", "/_matrix/push/v1/notify", notification, nil) + require.Equal(t, 200, response.Code) + require.Equal(t, `{"rejected":["http://wrong-base-url.com/mytopic?up=1"]}`+"\n", response.Body.String()) + + response = request(t, s, "GET", "/mytopic/json?poll=1", "", nil) + require.Equal(t, 200, response.Code) + require.Equal(t, "", response.Body.String()) // Empty! +} + +func TestServer_MatrixGateway_Push_Failure_EverythingIsWrong(t *testing.T) { + s := newTestServer(t, newTestConfig(t)) + notification := `{"message":"this is not really a Matrix message"}` + response := request(t, s, "POST", "/_matrix/push/v1/notify", notification, nil) + require.Equal(t, 400, response.Code) + err := toHTTPError(t, response.Body.String()) + require.Equal(t, 40019, err.Code) + require.Equal(t, 400, err.HTTPCode) +} + +func TestServer_MatrixGateway_Push_Failure_Unconfigured(t *testing.T) { + c := newTestConfig(t) + c.BaseURL = "" + s := newTestServer(t, c) + notification := `{"notification":{"devices":[{"pushkey":"http://127.0.0.1:12345/mytopic?up=1"}]}}` + response := request(t, s, "POST", "/_matrix/push/v1/notify", notification, nil) + require.Equal(t, 500, response.Code) + err := toHTTPError(t, response.Body.String()) + require.Equal(t, 50003, err.Code) + require.Equal(t, 500, err.HTTPCode) +} + func TestServer_PublishActions_AndPoll(t *testing.T) { s := newTestServer(t, newTestConfig(t)) response := request(t, s, "PUT", "/mytopic", "my message", map[string]string{ @@ -1348,3 +1393,11 @@ func toHTTPError(t *testing.T, s string) *errHTTP { func basicAuth(s string) string { return fmt.Sprintf("Basic %s", base64.StdEncoding.EncodeToString([]byte(s))) } + +func readAll(t *testing.T, rc io.ReadCloser) string { + b, err := io.ReadAll(rc) + if err != nil { + t.Fatal(err) + } + return string(b) +} diff --git a/server/smtp_server_test.go b/server/smtp_server_test.go index 8e9d5892..c0de7079 100644 --- a/server/smtp_server_test.go +++ b/server/smtp_server_test.go @@ -3,7 +3,6 @@ package server import ( "github.com/emersion/go-smtp" "github.com/stretchr/testify/require" - "io" "net" "net/http" "strings" @@ -304,14 +303,6 @@ func newTestBackend(t *testing.T, handler func(http.ResponseWriter, *http.Reques return conf, backend } -func readAll(t *testing.T, rc io.ReadCloser) string { - b, err := io.ReadAll(rc) - if err != nil { - t.Fatal(err) - } - return string(b) -} - func fakeConnState(t *testing.T, remoteAddr string) *smtp.ConnectionState { ip, err := net.ResolveIPAddr("ip", remoteAddr) if err != nil { diff --git a/util/peek.go b/util/peek.go index f7219253..40150cbc 100644 --- a/util/peek.go +++ b/util/peek.go @@ -18,7 +18,8 @@ type PeekedReadCloser struct { closed bool } -// Peek reads the underlying ReadCloser into memory up until the limit and returns a PeekedReadCloser +// Peek reads the underlying ReadCloser into memory up until the limit and returns a PeekedReadCloser. +// It does not return an error if limit is reached. Instead, LimitReached will be set to true. func Peek(underlying io.ReadCloser, limit int) (*PeekedReadCloser, error) { if underlying == nil { underlying = io.NopCloser(strings.NewReader("")) diff --git a/web/package-lock.json b/web/package-lock.json index f4d0bb5a..dc733ba5 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -52,17 +52,17 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", + "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", - "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", + "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -70,10 +70,10 @@ "@babel/helper-compilation-targets": "^7.18.2", "@babel/helper-module-transforms": "^7.18.0", "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", + "@babel/parser": "^7.18.5", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", + "@babel/traverse": "^7.18.5", + "@babel/types": "^7.18.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -471,9 +471,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", + "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", "bin": { "parser": "bin/babel-parser.js" }, @@ -1276,9 +1276,9 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", - "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.5.tgz", + "integrity": "sha512-SEewrhPpcqMF1V7DhnEbhVJLrC+nnYfe1E0piZMZXBpxi9WvZqWGwpsk7JYP7wPWeqaBh4gyKlBhHJu3uz5g4Q==", "dependencies": { "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-module-transforms": "^7.18.0", @@ -1324,9 +1324,9 @@ } }, "node_modules/@babel/plugin-transform-new-target": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", - "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.5.tgz", + "integrity": "sha512-TuRL5uGW4KXU6OsRj+mLp9BM7pO8e7SGNTEokQRRxHFkXYMFiy2jlKSZPFtI/mKORDzciH+hneskcSOp0gU8hg==", "dependencies": { "@babel/helper-plugin-utils": "^7.17.12" }, @@ -1485,9 +1485,9 @@ } }, "node_modules/@babel/plugin-transform-runtime": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", - "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.5.tgz", + "integrity": "sha512-Q17hHxXr2fplrE+5BSC1j1Fo5cOA8YeP8XW3/1paI8MzF/faZGh0MaH1KC4jLAvqLPamQWHB5/B7KqSLY1kuHA==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/helper-plugin-utils": "^7.17.12", @@ -1794,9 +1794,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", + "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", "dependencies": { "@babel/code-frame": "^7.16.7", "@babel/generator": "^7.18.2", @@ -1804,8 +1804,8 @@ "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "@babel/parser": "^7.18.5", + "@babel/types": "^7.18.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -3007,14 +3007,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.84", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.84.tgz", - "integrity": "sha512-uDx+wGVytS+ZHiWHyzUyijY83GSIXJpzSJ0PGc/8/s+8nBzeHvaPKrAyJz15ASLr52hYRA6PQGqn0eRAsB7syQ==", + "version": "5.0.0-alpha.85", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.85.tgz", + "integrity": "sha512-ONlQJOmQrxmR+pYF9AqH69FOG4ofwzVzNltwb2xKAQIW3VbsNZahcHIpzhFd70W6EIU+QHzB9TzamSM+Fg/U7w==", "dependencies": { "@babel/runtime": "^7.17.2", "@emotion/is-prop-valid": "^1.1.2", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "@popperjs/core": "^2.11.5", "clsx": "^1.1.1", "prop-types": "^15.8.1", @@ -3039,9 +3039,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.3.tgz", - "integrity": "sha512-dAdhimSLKOV0Q8FR7AYGEaCrTUh9OV7zU4Ueo5REoUt4cC3Vy+UBKDjZk66x5ezaYb63AFgQIFwtnZj3B/QDbQ==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz", + "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==", "dependencies": { "@babel/runtime": "^7.17.2" }, @@ -3064,19 +3064,18 @@ } }, "node_modules/@mui/material": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.3.tgz", - "integrity": "sha512-8UecY/W9SMtEZm5PMCUcMbujajVP6fobu0BgBPiIWwwWRblZVEzqprY6v1P2me7qCyrve4L4V/rqAKPKhVHOSg==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.4.tgz", + "integrity": "sha512-KlOJS1JGhwuhdoF4fulmz41h/YxyMdZSc+ncz+HAah0GKn8ovAs5774f1w0lIasxbtI1Ziunwvmnu9PvvUKdMw==", "dependencies": { "@babel/runtime": "^7.17.2", - "@mui/base": "5.0.0-alpha.84", - "@mui/system": "^5.8.3", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/base": "5.0.0-alpha.85", + "@mui/system": "^5.8.4", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "@types/react-transition-group": "^4.4.4", "clsx": "^1.1.1", "csstype": "^3.1.0", - "hoist-non-react-statics": "^3.3.2", "prop-types": "^15.8.1", "react-is": "^17.0.2", "react-transition-group": "^4.4.2" @@ -3108,12 +3107,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.8.0.tgz", - "integrity": "sha512-MjRAneTmCKLR9u2S4jtjLUe6gpHxlbb4g2bqpDJ2PdwlvwsWIUzbc/gVB4dvccljXeWxr5G2M/Co2blXisvFIw==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.8.4.tgz", + "integrity": "sha512-3Lp0VAEjtQygJ70MWEyHkKvg327O6YoBH6ZNEy6fIsrK6gmRIj+YrlvJ7LQCbowY+qDGnbdMrTBd1hfThlI8lg==", "dependencies": { "@babel/runtime": "^7.17.2", - "@mui/utils": "^5.8.0", + "@mui/utils": "^5.8.4", "prop-types": "^15.8.1" }, "engines": { @@ -3164,15 +3163,15 @@ } }, "node_modules/@mui/system": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.8.3.tgz", - "integrity": "sha512-/tyGQcYqZT0nl98qV9XnGiedTO+V7VHc28k4POfhMJNedB1CRrwWRm767DeEdc5f/8CU2See3WD16ikP6pYiOA==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.8.4.tgz", + "integrity": "sha512-eeYZXlOn4p+tYwqqDlci6wW4knJ68aGx5A24YU9ubYZ5o0IwveoNP3LC9sHAMxigk/mUTqL4bpSMJ2HbTn2aQg==", "dependencies": { "@babel/runtime": "^7.17.2", - "@mui/private-theming": "^5.8.0", + "@mui/private-theming": "^5.8.4", "@mui/styled-engine": "^5.8.0", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "clsx": "^1.1.1", "csstype": "^3.1.0", "prop-types": "^15.8.1" @@ -3203,9 +3202,9 @@ } }, "node_modules/@mui/types": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.3.tgz", - "integrity": "sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.4.tgz", + "integrity": "sha512-uveM3byMbthO+6tXZ1n2zm0W3uJCQYtwt/v5zV5I77v2v18u0ITkb8xwhsDD2i3V2Kye7SaNR6FFJ6lMuY/WqQ==", "peerDependencies": { "@types/react": "*" }, @@ -3216,9 +3215,9 @@ } }, "node_modules/@mui/utils": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.8.0.tgz", - "integrity": "sha512-7LgUtCvz78676iC0wpTH7HizMdCrTphhBmRWimIMFrp5Ph6JbDFVuKS1CwYnWWxRyYKL0QzXrDL0lptAU90EXg==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.8.4.tgz", + "integrity": "sha512-BHYErfrjqqh76KaDAm8wZlhEip1Uj7Cmco65NcsF3BWrAl3FWngACpaPZeEbTgmaEwyWAQEE6LZhsmy43hfyqQ==", "dependencies": { "@babel/runtime": "^7.17.2", "@types/prop-types": "^15.7.5", @@ -3805,9 +3804,9 @@ } }, "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3872,9 +3871,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "node_modules/@types/node": { - "version": "17.0.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.42.tgz", - "integrity": "sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ==" + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -3907,9 +3906,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/react": { - "version": "18.0.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.12.tgz", - "integrity": "sha512-duF1OTASSBQtcigUvhuiTB1Ya3OvSy+xORCiEf20H0P0lzx+/KeVsA99U5UjLXSbyo1DRJDlLKqTeM1ngosqtg==", + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.13.tgz", + "integrity": "sha512-psqptIYQxGUFuGYwP3KCFVtPTkMpIcrqFmtKblWEUQhLuYLpHBwJkXhjp6eHfDM5IbyskY4x7qQpLedEsPkHlA==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -4007,13 +4006,13 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz", - "integrity": "sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.28.0.tgz", + "integrity": "sha512-DXVU6Cg29H2M6EybqSg2A+x8DgO9TCUBRp4QEXQHJceLS7ogVDP0g3Lkg/SZCqcvkAP/RruuQqK0gdlkgmhSUA==", "dependencies": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/type-utils": "5.27.1", - "@typescript-eslint/utils": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/type-utils": "5.28.0", + "@typescript-eslint/utils": "5.28.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -4053,11 +4052,11 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.27.1.tgz", - "integrity": "sha512-Vd8uewIixGP93sEnmTRIH6jHZYRQRkGPDPpapACMvitJKX8335VHNyqKTE+mZ+m3E2c5VznTZfSsSsS5IF7vUA==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.28.0.tgz", + "integrity": "sha512-pPQ1Ng4qezQijXBBfYlogcOPnMs1q14l8C4fWJJ4PnFla4MA2b2oBfdkf02r1lNak2tpBVNJxvey9oWlPQWc4w==", "dependencies": { - "@typescript-eslint/utils": "5.27.1" + "@typescript-eslint/utils": "5.28.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4071,13 +4070,13 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.1.tgz", - "integrity": "sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.28.0.tgz", + "integrity": "sha512-ekqoNRNK1lAcKhZESN/PdpVsWbP9jtiNqzFWkp/yAUdZvJalw2heCYuqRmM5eUJSIYEkgq5sGOjq+ZqsLMjtRA==", "dependencies": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/typescript-estree": "5.28.0", "debug": "^4.3.4" }, "engines": { @@ -4097,12 +4096,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.1.tgz", - "integrity": "sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.28.0.tgz", + "integrity": "sha512-LeBLTqF/he1Z+boRhSqnso6YrzcKMTQ8bO/YKEe+6+O/JGof9M0g3IJlIsqfrK/6K03MlFIlycbf1uQR1IjE+w==", "dependencies": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1" + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/visitor-keys": "5.28.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4113,11 +4112,11 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.1.tgz", - "integrity": "sha512-+UC1vVUWaDHRnC2cQrCJ4QtVjpjjCgjNFpg8b03nERmkHv9JV9X5M19D7UFMd+/G7T/sgFwX2pGmWK38rqyvXw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.28.0.tgz", + "integrity": "sha512-SyKjKh4CXPglueyC6ceAFytjYWMoPHMswPQae236zqe1YbhvCVQyIawesYywGiu98L9DwrxsBN69vGIVxJ4mQQ==", "dependencies": { - "@typescript-eslint/utils": "5.27.1", + "@typescript-eslint/utils": "5.28.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -4138,9 +4137,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.1.tgz", - "integrity": "sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.28.0.tgz", + "integrity": "sha512-2OOm8ZTOQxqkPbf+DAo8oc16sDlVR5owgJfKheBkxBKg1vAfw2JsSofH9+16VPlN9PWtv8Wzhklkqw3k/zCVxA==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4150,12 +4149,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.1.tgz", - "integrity": "sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.28.0.tgz", + "integrity": "sha512-9GX+GfpV+F4hdTtYc6OV9ZkyYilGXPmQpm6AThInpBmKJEyRSIjORJd1G9+bknb7OTFYL+Vd4FBJAO6T78OVqA==", "dependencies": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/visitor-keys": "5.28.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -4190,14 +4189,14 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.1.tgz", - "integrity": "sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.28.0.tgz", + "integrity": "sha512-E60N5L0fjv7iPJV3UGc4EC+A3Lcj4jle9zzR0gW7vXhflO7/J29kwiTGITA2RlrmPokKiZbBy2DgaclCaEUs6g==", "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/typescript-estree": "5.28.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -4233,11 +4232,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.1.tgz", - "integrity": "sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.28.0.tgz", + "integrity": "sha512-BtfP1vCor8cWacovzzPFOoeW4kBQxzmhxGoOpt0v1SFvG+nJ0cWaVdJk7cky1ArTcFHHKNIxyo2LLr3oNkSuXA==", "dependencies": { - "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/types": "5.28.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -5375,9 +5374,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001352", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz", - "integrity": "sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==", + "version": "1.0.30001355", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", + "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==", "funding": [ { "type": "opencollective", @@ -5485,9 +5484,9 @@ } }, "node_modules/ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==" }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -5577,9 +5576,9 @@ "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==" }, "node_modules/colorette": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.17.tgz", - "integrity": "sha512-hJo+3Bkn0NCHybn9Tu35fIeoOKGOk5OCC32y4Hz2It+qlCO2Q3DeQ1hRn/tDDMQKRYUEzqsl7jbF6dYKjlE60g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "node_modules/combined-stream": { "version": "1.0.8", @@ -5737,9 +5736,9 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/core-js": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", - "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", + "integrity": "sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -5747,11 +5746,11 @@ } }, "node_modules/core-js-compat": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.8.tgz", - "integrity": "sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", + "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", "dependencies": { - "browserslist": "^4.20.3", + "browserslist": "^4.20.4", "semver": "7.0.0" }, "funding": { @@ -5768,9 +5767,9 @@ } }, "node_modules/core-js-pure": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.8.tgz", - "integrity": "sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.1.tgz", + "integrity": "sha512-3qNgf6TqI3U1uhuSYRzJZGfFd4T+YlbyVPl+jgRiKjdZopvG4keZQwWZDAWpu1UH9nCgTpUzIV3GFawC7cJsqg==", "hasInstallScript": true, "funding": { "type": "opencollective", @@ -6480,9 +6479,9 @@ "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "node_modules/dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -6635,9 +6634,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.152", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.152.tgz", - "integrity": "sha512-jk4Ju5SGZAQQJ1iI4Rgru7dDlvkQPLpNPWH9gIZmwCD4YteA5Bbk1xPcPDUf5jUYs3e1e80RXdi8XgKQZaigeg==" + "version": "1.4.158", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", + "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==" }, "node_modules/emittery": { "version": "0.8.1", @@ -7197,9 +7196,9 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "engines": { "node": ">=10" }, @@ -8653,9 +8652,9 @@ } }, "node_modules/i18next": { - "version": "21.8.9", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.9.tgz", - "integrity": "sha512-PY9a/8ADVmnju1tETeglbbVQi+nM5pcJQWm9kvKMTE3GPgHHtpDsHy5HQ/hccz2/xtW7j3vuso23JdQSH0EttA==", + "version": "21.8.10", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.10.tgz", + "integrity": "sha512-7xRb6y4QlSqZRZ3uA5BIEsLuZpmxpzHLizQyKjDDThOcvdfgICOX7aFoBnh4BSWcLtJamTqSweaOuK22A2xqkA==", "funding": [ { "type": "individual", @@ -8737,9 +8736,9 @@ } }, "node_modules/immer": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz", - "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==", + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -11003,9 +11002,9 @@ } }, "node_modules/jest-watch-typeahead/node_modules/react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/jest-watch-typeahead/node_modules/slash": { "version": "4.0.0", @@ -11653,9 +11652,9 @@ } }, "node_modules/mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "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==", "dependencies": { "schema-utils": "^4.0.0" }, @@ -13810,9 +13809,9 @@ } }, "node_modules/react": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", - "integrity": "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -13943,15 +13942,15 @@ } }, "node_modules/react-dom": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", - "integrity": "sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.22.0" + "scheduler": "^0.23.0" }, "peerDependencies": { - "react": "^18.1.0" + "react": "^18.2.0" } }, "node_modules/react-error-overlay": { @@ -13960,9 +13959,9 @@ "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "node_modules/react-i18next": { - "version": "11.17.1", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.1.tgz", - "integrity": "sha512-4H4fK9vWsQtPP0iAdqzGfdPKLaSXpCjuh1xaGsejX/CO8tx8zCnrOnlQhMgrJf+OlUfzth5YaDPXYGp3RHxV1g==", + "version": "11.17.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.2.tgz", + "integrity": "sha512-/HG4XSResWDY450cFmoUqLgCYDu8VYMFISGcMnZlxRSV05naj3+F7DoebwnPu6z/akA3Wd0Xe7KGTYdywL9z9g==", "dependencies": { "@babel/runtime": "^7.14.5", "html-escaper": "^2.0.2", @@ -14623,9 +14622,9 @@ } }, "node_modules/scheduler": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz", - "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "dependencies": { "loose-envify": "^1.1.0" } @@ -15386,11 +15385,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/tailwindcss": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.2.tgz", - "integrity": "sha512-yJ6L5s1U5AeS5g7HHy212zdQfjwD426FBfm59pet/JsyneuZuD4C2W7PpJEg4ppisiB21uLqtNagv8KXury3+Q==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.3.tgz", + "integrity": "sha512-PRJNYdSIthrb8hjmAyymEyEN8Yo61TMXpzyFUpxULeeyRn3Y3gpvuw6FlRTKrJvK7thSGKRnhT36VovVx4WeMA==", "dependencies": { - "arg": "^5.0.1", + "arg": "^5.0.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", "detective": "^5.2.1", @@ -16866,14 +16865,14 @@ } }, "@babel/compat-data": { - "version": "7.17.10", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", - "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==" + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz", + "integrity": "sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg==" }, "@babel/core": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", - "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz", + "integrity": "sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ==", "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -16881,10 +16880,10 @@ "@babel/helper-compilation-targets": "^7.18.2", "@babel/helper-module-transforms": "^7.18.0", "@babel/helpers": "^7.18.2", - "@babel/parser": "^7.18.0", + "@babel/parser": "^7.18.5", "@babel/template": "^7.16.7", - "@babel/traverse": "^7.18.2", - "@babel/types": "^7.18.2", + "@babel/traverse": "^7.18.5", + "@babel/types": "^7.18.4", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -17173,9 +17172,9 @@ } }, "@babel/parser": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.4.tgz", - "integrity": "sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==" + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", + "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==" }, "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.17.12", @@ -17675,9 +17674,9 @@ } }, "@babel/plugin-transform-modules-systemjs": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz", - "integrity": "sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.5.tgz", + "integrity": "sha512-SEewrhPpcqMF1V7DhnEbhVJLrC+nnYfe1E0piZMZXBpxi9WvZqWGwpsk7JYP7wPWeqaBh4gyKlBhHJu3uz5g4Q==", "requires": { "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-module-transforms": "^7.18.0", @@ -17705,9 +17704,9 @@ } }, "@babel/plugin-transform-new-target": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.17.12.tgz", - "integrity": "sha512-CaOtzk2fDYisbjAD4Sd1MTKGVIpRtx9bWLyj24Y/k6p4s4gQ3CqDGJauFJxt8M/LEx003d0i3klVqnN73qvK3w==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.5.tgz", + "integrity": "sha512-TuRL5uGW4KXU6OsRj+mLp9BM7pO8e7SGNTEokQRRxHFkXYMFiy2jlKSZPFtI/mKORDzciH+hneskcSOp0gU8hg==", "requires": { "@babel/helper-plugin-utils": "^7.17.12" } @@ -17800,9 +17799,9 @@ } }, "@babel/plugin-transform-runtime": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.2.tgz", - "integrity": "sha512-mr1ufuRMfS52ttq+1G1PD8OJNqgcTFjq3hwn8SZ5n1x1pBhi0E36rYMdTK0TsKtApJ4lDEdfXJwtGobQMHSMPg==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.18.5.tgz", + "integrity": "sha512-Q17hHxXr2fplrE+5BSC1j1Fo5cOA8YeP8XW3/1paI8MzF/faZGh0MaH1KC4jLAvqLPamQWHB5/B7KqSLY1kuHA==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/helper-plugin-utils": "^7.17.12", @@ -18025,9 +18024,9 @@ } }, "@babel/traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.2.tgz", - "integrity": "sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA==", + "version": "7.18.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", + "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", "requires": { "@babel/code-frame": "^7.16.7", "@babel/generator": "^7.18.2", @@ -18035,8 +18034,8 @@ "@babel/helper-function-name": "^7.17.9", "@babel/helper-hoist-variables": "^7.16.7", "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.0", - "@babel/types": "^7.18.2", + "@babel/parser": "^7.18.5", + "@babel/types": "^7.18.4", "debug": "^4.1.0", "globals": "^11.1.0" } @@ -18883,14 +18882,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, "@mui/base": { - "version": "5.0.0-alpha.84", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.84.tgz", - "integrity": "sha512-uDx+wGVytS+ZHiWHyzUyijY83GSIXJpzSJ0PGc/8/s+8nBzeHvaPKrAyJz15ASLr52hYRA6PQGqn0eRAsB7syQ==", + "version": "5.0.0-alpha.85", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.85.tgz", + "integrity": "sha512-ONlQJOmQrxmR+pYF9AqH69FOG4ofwzVzNltwb2xKAQIW3VbsNZahcHIpzhFd70W6EIU+QHzB9TzamSM+Fg/U7w==", "requires": { "@babel/runtime": "^7.17.2", "@emotion/is-prop-valid": "^1.1.2", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "@popperjs/core": "^2.11.5", "clsx": "^1.1.1", "prop-types": "^15.8.1", @@ -18898,39 +18897,38 @@ } }, "@mui/icons-material": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.3.tgz", - "integrity": "sha512-dAdhimSLKOV0Q8FR7AYGEaCrTUh9OV7zU4Ueo5REoUt4cC3Vy+UBKDjZk66x5ezaYb63AFgQIFwtnZj3B/QDbQ==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.8.4.tgz", + "integrity": "sha512-9Z/vyj2szvEhGWDvb+gG875bOGm8b8rlHBKOD1+nA3PcgC3fV6W1AU6pfOorPeBfH2X4mb9Boe97vHvaSndQvA==", "requires": { "@babel/runtime": "^7.17.2" } }, "@mui/material": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.3.tgz", - "integrity": "sha512-8UecY/W9SMtEZm5PMCUcMbujajVP6fobu0BgBPiIWwwWRblZVEzqprY6v1P2me7qCyrve4L4V/rqAKPKhVHOSg==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.8.4.tgz", + "integrity": "sha512-KlOJS1JGhwuhdoF4fulmz41h/YxyMdZSc+ncz+HAah0GKn8ovAs5774f1w0lIasxbtI1Ziunwvmnu9PvvUKdMw==", "requires": { "@babel/runtime": "^7.17.2", - "@mui/base": "5.0.0-alpha.84", - "@mui/system": "^5.8.3", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/base": "5.0.0-alpha.85", + "@mui/system": "^5.8.4", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "@types/react-transition-group": "^4.4.4", "clsx": "^1.1.1", "csstype": "^3.1.0", - "hoist-non-react-statics": "^3.3.2", "prop-types": "^15.8.1", "react-is": "^17.0.2", "react-transition-group": "^4.4.2" } }, "@mui/private-theming": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.8.0.tgz", - "integrity": "sha512-MjRAneTmCKLR9u2S4jtjLUe6gpHxlbb4g2bqpDJ2PdwlvwsWIUzbc/gVB4dvccljXeWxr5G2M/Co2blXisvFIw==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.8.4.tgz", + "integrity": "sha512-3Lp0VAEjtQygJ70MWEyHkKvg327O6YoBH6ZNEy6fIsrK6gmRIj+YrlvJ7LQCbowY+qDGnbdMrTBd1hfThlI8lg==", "requires": { "@babel/runtime": "^7.17.2", - "@mui/utils": "^5.8.0", + "@mui/utils": "^5.8.4", "prop-types": "^15.8.1" } }, @@ -18945,30 +18943,30 @@ } }, "@mui/system": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.8.3.tgz", - "integrity": "sha512-/tyGQcYqZT0nl98qV9XnGiedTO+V7VHc28k4POfhMJNedB1CRrwWRm767DeEdc5f/8CU2See3WD16ikP6pYiOA==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.8.4.tgz", + "integrity": "sha512-eeYZXlOn4p+tYwqqDlci6wW4knJ68aGx5A24YU9ubYZ5o0IwveoNP3LC9sHAMxigk/mUTqL4bpSMJ2HbTn2aQg==", "requires": { "@babel/runtime": "^7.17.2", - "@mui/private-theming": "^5.8.0", + "@mui/private-theming": "^5.8.4", "@mui/styled-engine": "^5.8.0", - "@mui/types": "^7.1.3", - "@mui/utils": "^5.8.0", + "@mui/types": "^7.1.4", + "@mui/utils": "^5.8.4", "clsx": "^1.1.1", "csstype": "^3.1.0", "prop-types": "^15.8.1" } }, "@mui/types": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.3.tgz", - "integrity": "sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.4.tgz", + "integrity": "sha512-uveM3byMbthO+6tXZ1n2zm0W3uJCQYtwt/v5zV5I77v2v18u0ITkb8xwhsDD2i3V2Kye7SaNR6FFJ6lMuY/WqQ==", "requires": {} }, "@mui/utils": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.8.0.tgz", - "integrity": "sha512-7LgUtCvz78676iC0wpTH7HizMdCrTphhBmRWimIMFrp5Ph6JbDFVuKS1CwYnWWxRyYKL0QzXrDL0lptAU90EXg==", + "version": "5.8.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.8.4.tgz", + "integrity": "sha512-BHYErfrjqqh76KaDAm8wZlhEip1Uj7Cmco65NcsF3BWrAl3FWngACpaPZeEbTgmaEwyWAQEE6LZhsmy43hfyqQ==", "requires": { "@babel/runtime": "^7.17.2", "@types/prop-types": "^15.7.5", @@ -19366,9 +19364,9 @@ } }, "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", "requires": { "@types/node": "*", "@types/qs": "*", @@ -19433,9 +19431,9 @@ "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, "@types/node": { - "version": "17.0.42", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.42.tgz", - "integrity": "sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ==" + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" }, "@types/parse-json": { "version": "4.0.0", @@ -19468,9 +19466,9 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/react": { - "version": "18.0.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.12.tgz", - "integrity": "sha512-duF1OTASSBQtcigUvhuiTB1Ya3OvSy+xORCiEf20H0P0lzx+/KeVsA99U5UjLXSbyo1DRJDlLKqTeM1ngosqtg==", + "version": "18.0.13", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.13.tgz", + "integrity": "sha512-psqptIYQxGUFuGYwP3KCFVtPTkMpIcrqFmtKblWEUQhLuYLpHBwJkXhjp6eHfDM5IbyskY4x7qQpLedEsPkHlA==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -19568,13 +19566,13 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@typescript-eslint/eslint-plugin": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz", - "integrity": "sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.28.0.tgz", + "integrity": "sha512-DXVU6Cg29H2M6EybqSg2A+x8DgO9TCUBRp4QEXQHJceLS7ogVDP0g3Lkg/SZCqcvkAP/RruuQqK0gdlkgmhSUA==", "requires": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/type-utils": "5.27.1", - "@typescript-eslint/utils": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/type-utils": "5.28.0", + "@typescript-eslint/utils": "5.28.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -19594,55 +19592,55 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.27.1.tgz", - "integrity": "sha512-Vd8uewIixGP93sEnmTRIH6jHZYRQRkGPDPpapACMvitJKX8335VHNyqKTE+mZ+m3E2c5VznTZfSsSsS5IF7vUA==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.28.0.tgz", + "integrity": "sha512-pPQ1Ng4qezQijXBBfYlogcOPnMs1q14l8C4fWJJ4PnFla4MA2b2oBfdkf02r1lNak2tpBVNJxvey9oWlPQWc4w==", "requires": { - "@typescript-eslint/utils": "5.27.1" + "@typescript-eslint/utils": "5.28.0" } }, "@typescript-eslint/parser": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.1.tgz", - "integrity": "sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.28.0.tgz", + "integrity": "sha512-ekqoNRNK1lAcKhZESN/PdpVsWbP9jtiNqzFWkp/yAUdZvJalw2heCYuqRmM5eUJSIYEkgq5sGOjq+ZqsLMjtRA==", "requires": { - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/typescript-estree": "5.28.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.1.tgz", - "integrity": "sha512-fQEOSa/QroWE6fAEg+bJxtRZJTH8NTskggybogHt4H9Da8zd4cJji76gA5SBlR0MgtwF7rebxTbDKB49YUCpAg==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.28.0.tgz", + "integrity": "sha512-LeBLTqF/he1Z+boRhSqnso6YrzcKMTQ8bO/YKEe+6+O/JGof9M0g3IJlIsqfrK/6K03MlFIlycbf1uQR1IjE+w==", "requires": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1" + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/visitor-keys": "5.28.0" } }, "@typescript-eslint/type-utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.1.tgz", - "integrity": "sha512-+UC1vVUWaDHRnC2cQrCJ4QtVjpjjCgjNFpg8b03nERmkHv9JV9X5M19D7UFMd+/G7T/sgFwX2pGmWK38rqyvXw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.28.0.tgz", + "integrity": "sha512-SyKjKh4CXPglueyC6ceAFytjYWMoPHMswPQae236zqe1YbhvCVQyIawesYywGiu98L9DwrxsBN69vGIVxJ4mQQ==", "requires": { - "@typescript-eslint/utils": "5.27.1", + "@typescript-eslint/utils": "5.28.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.1.tgz", - "integrity": "sha512-LgogNVkBhCTZU/m8XgEYIWICD6m4dmEDbKXESCbqOXfKZxRKeqpiJXQIErv66sdopRKZPo5l32ymNqibYEH/xg==" + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.28.0.tgz", + "integrity": "sha512-2OOm8ZTOQxqkPbf+DAo8oc16sDlVR5owgJfKheBkxBKg1vAfw2JsSofH9+16VPlN9PWtv8Wzhklkqw3k/zCVxA==" }, "@typescript-eslint/typescript-estree": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.1.tgz", - "integrity": "sha512-DnZvvq3TAJ5ke+hk0LklvxwYsnXpRdqUY5gaVS0D4raKtbznPz71UJGnPTHEFo0GDxqLOLdMkkmVZjSpET1hFw==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.28.0.tgz", + "integrity": "sha512-9GX+GfpV+F4hdTtYc6OV9ZkyYilGXPmQpm6AThInpBmKJEyRSIjORJd1G9+bknb7OTFYL+Vd4FBJAO6T78OVqA==", "requires": { - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/visitor-keys": "5.27.1", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/visitor-keys": "5.28.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -19661,14 +19659,14 @@ } }, "@typescript-eslint/utils": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.1.tgz", - "integrity": "sha512-mZ9WEn1ZLDaVrhRaYgzbkXBkTPghPFsup8zDbbsYTxC5OmqrFE7skkKS/sraVsLP3TcT3Ki5CSyEFBRkLH/H/w==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.28.0.tgz", + "integrity": "sha512-E60N5L0fjv7iPJV3UGc4EC+A3Lcj4jle9zzR0gW7vXhflO7/J29kwiTGITA2RlrmPokKiZbBy2DgaclCaEUs6g==", "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.1", - "@typescript-eslint/types": "5.27.1", - "@typescript-eslint/typescript-estree": "5.27.1", + "@typescript-eslint/scope-manager": "5.28.0", + "@typescript-eslint/types": "5.28.0", + "@typescript-eslint/typescript-estree": "5.28.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -19690,11 +19688,11 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.27.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.1.tgz", - "integrity": "sha512-xYs6ffo01nhdJgPieyk7HAOpjhTsx7r/oB9LWEhwAXgwn33tkr+W8DI2ChboqhZlC4q3TC6geDYPoiX8ROqyOQ==", + "version": "5.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.28.0.tgz", + "integrity": "sha512-BtfP1vCor8cWacovzzPFOoeW4kBQxzmhxGoOpt0v1SFvG+nJ0cWaVdJk7cky1ArTcFHHKNIxyo2LLr3oNkSuXA==", "requires": { - "@typescript-eslint/types": "5.27.1", + "@typescript-eslint/types": "5.28.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -20572,9 +20570,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001352", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001352.tgz", - "integrity": "sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==" + "version": "1.0.30001355", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001355.tgz", + "integrity": "sha512-Sd6pjJHF27LzCB7pT7qs+kuX2ndurzCzkpJl6Qct7LPSZ9jn0bkOA8mdgMgmqnQAWLVOOGjLpc+66V57eLtb1g==" }, "case-sensitive-paths-webpack-plugin": { "version": "2.4.0", @@ -20644,9 +20642,9 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" }, "ci-info": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", - "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==" }, "cjs-module-lexer": { "version": "1.2.2", @@ -20722,9 +20720,9 @@ "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==" }, "colorette": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.17.tgz", - "integrity": "sha512-hJo+3Bkn0NCHybn9Tu35fIeoOKGOk5OCC32y4Hz2It+qlCO2Q3DeQ1hRn/tDDMQKRYUEzqsl7jbF6dYKjlE60g==" + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==" }, "combined-stream": { "version": "1.0.8", @@ -20845,16 +20843,16 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz", - "integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==" + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz", + "integrity": "sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w==" }, "core-js-compat": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.8.tgz", - "integrity": "sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg==", + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz", + "integrity": "sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A==", "requires": { - "browserslist": "^4.20.3", + "browserslist": "^4.20.4", "semver": "7.0.0" }, "dependencies": { @@ -20866,9 +20864,9 @@ } }, "core-js-pure": { - "version": "3.22.8", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.22.8.tgz", - "integrity": "sha512-bOxbZIy9S5n4OVH63XaLVXZ49QKicjowDx/UELyJ68vxfCRpYsbyh/WNZNfEfAk+ekA8vSjt+gCDpvh672bc3w==" + "version": "3.23.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.1.tgz", + "integrity": "sha512-3qNgf6TqI3U1uhuSYRzJZGfFd4T+YlbyVPl+jgRiKjdZopvG4keZQwWZDAWpu1UH9nCgTpUzIV3GFawC7cJsqg==" }, "core-util-is": { "version": "1.0.3", @@ -21361,9 +21359,9 @@ "integrity": "sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==" }, "dns-packet": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.3.1.tgz", - "integrity": "sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz", + "integrity": "sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==", "requires": { "@leichtgewicht/ip-codec": "^2.0.1" } @@ -21479,9 +21477,9 @@ } }, "electron-to-chromium": { - "version": "1.4.152", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.152.tgz", - "integrity": "sha512-jk4Ju5SGZAQQJ1iI4Rgru7dDlvkQPLpNPWH9gIZmwCD4YteA5Bbk1xPcPDUf5jUYs3e1e80RXdi8XgKQZaigeg==" + "version": "1.4.158", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.158.tgz", + "integrity": "sha512-gppO3/+Y6sP432HtvwvuU8S+YYYLH4PmAYvQwqUtt9HDOmEsBwQfLnK9T8+1NIKwAS1BEygIjTaATC4H5EzvxQ==" }, "emittery": { "version": "0.8.1", @@ -21996,9 +21994,9 @@ } }, "eslint-plugin-react-hooks": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz", - "integrity": "sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", "requires": {} }, "eslint-plugin-testing-library": { @@ -22949,9 +22947,9 @@ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==" }, "i18next": { - "version": "21.8.9", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.9.tgz", - "integrity": "sha512-PY9a/8ADVmnju1tETeglbbVQi+nM5pcJQWm9kvKMTE3GPgHHtpDsHy5HQ/hccz2/xtW7j3vuso23JdQSH0EttA==", + "version": "21.8.10", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.8.10.tgz", + "integrity": "sha512-7xRb6y4QlSqZRZ3uA5BIEsLuZpmxpzHLizQyKjDDThOcvdfgICOX7aFoBnh4BSWcLtJamTqSweaOuK22A2xqkA==", "requires": { "@babel/runtime": "^7.17.2" } @@ -23005,9 +23003,9 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" }, "immer": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.14.tgz", - "integrity": "sha512-ubBeqQutOSLIFCUBN03jGeOS6a3DoYlSYwYJTa+gSKEZKU5redJIqkIdZ3JVv/4RZpfcXdAWH5zCNLWPRv2WDw==" + "version": "9.0.15", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.15.tgz", + "integrity": "sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ==" }, "import-fresh": { "version": "3.3.0", @@ -24631,9 +24629,9 @@ } }, "react-is": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", - "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==" + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "slash": { "version": "4.0.0", @@ -25115,9 +25113,9 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "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==", "requires": { "schema-utils": "^4.0.0" }, @@ -26491,9 +26489,9 @@ } }, "react": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.1.0.tgz", - "integrity": "sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "requires": { "loose-envify": "^1.1.0" } @@ -26593,12 +26591,12 @@ } }, "react-dom": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.1.0.tgz", - "integrity": "sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==", + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "requires": { "loose-envify": "^1.1.0", - "scheduler": "^0.22.0" + "scheduler": "^0.23.0" } }, "react-error-overlay": { @@ -26607,9 +26605,9 @@ "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" }, "react-i18next": { - "version": "11.17.1", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.1.tgz", - "integrity": "sha512-4H4fK9vWsQtPP0iAdqzGfdPKLaSXpCjuh1xaGsejX/CO8tx8zCnrOnlQhMgrJf+OlUfzth5YaDPXYGp3RHxV1g==", + "version": "11.17.2", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.17.2.tgz", + "integrity": "sha512-/HG4XSResWDY450cFmoUqLgCYDu8VYMFISGcMnZlxRSV05naj3+F7DoebwnPu6z/akA3Wd0Xe7KGTYdywL9z9g==", "requires": { "@babel/runtime": "^7.14.5", "html-escaper": "^2.0.2", @@ -27066,9 +27064,9 @@ } }, "scheduler": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz", - "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==", + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", "requires": { "loose-envify": "^1.1.0" } @@ -27678,11 +27676,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "tailwindcss": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.2.tgz", - "integrity": "sha512-yJ6L5s1U5AeS5g7HHy212zdQfjwD426FBfm59pet/JsyneuZuD4C2W7PpJEg4ppisiB21uLqtNagv8KXury3+Q==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.3.tgz", + "integrity": "sha512-PRJNYdSIthrb8hjmAyymEyEN8Yo61TMXpzyFUpxULeeyRn3Y3gpvuw6FlRTKrJvK7thSGKRnhT36VovVx4WeMA==", "requires": { - "arg": "^5.0.1", + "arg": "^5.0.2", "chokidar": "^3.5.3", "color-name": "^1.1.4", "detective": "^5.2.1",