diff --git a/CHANGELOG.md b/CHANGELOG.md index c98abd8c..b7d4b36e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # CHANGELOG +## v0.4.33 + +CHANGE: Updated react-bootstrap to version 2.10.2. + +CHANGE: Updated @mui/material to version 5.15.18. + +CHANGE: Updated react and react-dom to version 18.3.1. + +## v0.4.32 + +FEATURE: New permission mode support for public frontends. Open permission mode frontends are available to all users in the service instance. Closed permission mode frontends reference the new `frontend_grants` table that can be used to control which accounts are allowed to create shares using that frontend. `zrok admin create frontend` now supports `--closed` flag to create closed permission mode frontends (https://github.com/openziti/zrok/issues/539) + +FEATURE: New config `defaultFrontend` that specifies the default frontend to be used for an environment. Provides the default `--frontend` for `zrok share public` and `zrok reserve public` (https://github.com/openziti/zrok/issues/663) + +FEATURE: Resource count limits now include `share_frontends` to limit the number of frontends that are allowed to make connections to a share (https://github.com/openziti/zrok/issues/650) + +CHANGE: The frontend selection flag used by `zrok share public` and `zrok reserve public` has been changed from `--frontends` to `--frontend` + +FIX: use controller config spec v4 in the Docker instance + ## v0.4.31 FEATURE: New "limits classes" limits implementation (https://github.com/openziti/zrok/issues/606). This new feature allows for extensive limits customization on a per-user basis, with fallback to the global defaults in the controller configuration. diff --git a/cmd/zrok/adminCreateFrontend.go b/cmd/zrok/adminCreateFrontend.go index 430ecc59..20dc9831 100644 --- a/cmd/zrok/adminCreateFrontend.go +++ b/cmd/zrok/adminCreateFrontend.go @@ -4,6 +4,7 @@ import ( "github.com/openziti/zrok/environment" "github.com/openziti/zrok/rest_client_zrok/admin" "github.com/openziti/zrok/rest_model_zrok" + "github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/tui" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -15,7 +16,8 @@ func init() { } type adminCreateFrontendCommand struct { - cmd *cobra.Command + cmd *cobra.Command + closed bool } func newAdminCreateFrontendCommand() *adminCreateFrontendCommand { @@ -25,6 +27,7 @@ func newAdminCreateFrontendCommand() *adminCreateFrontendCommand { Args: cobra.ExactArgs(3), } command := &adminCreateFrontendCommand{cmd: cmd} + cmd.Flags().BoolVar(&command.closed, "closed", false, "Enabled closed permission mode") cmd.Run = command.run return command } @@ -44,11 +47,16 @@ func (cmd *adminCreateFrontendCommand) run(_ *cobra.Command, args []string) { panic(err) } + permissionMode := sdk.OpenPermissionMode + if cmd.closed { + permissionMode = sdk.ClosedPermissionMode + } req := admin.NewCreateFrontendParams() req.Body = &rest_model_zrok.CreateFrontendRequest{ - ZID: zId, - PublicName: publicName, - URLTemplate: urlTemplate, + ZID: zId, + PublicName: publicName, + URLTemplate: urlTemplate, + PermissionMode: string(permissionMode), } resp, err := zrok.Admin.CreateFrontend(req, mustGetAdminAuth()) diff --git a/cmd/zrok/configGet.go b/cmd/zrok/configGet.go index 45480da4..0d1905d0 100644 --- a/cmd/zrok/configGet.go +++ b/cmd/zrok/configGet.go @@ -40,6 +40,12 @@ func (cmd *configGetCommand) run(_ *cobra.Command, args []string) { } else { fmt.Println("apiEndpoint = ") } + case "defaultFrontend": + if env.Config() != nil && env.Config().DefaultFrontend != "" { + fmt.Printf("defaultFrontend = %v\n", env.Config().DefaultFrontend) + } else { + fmt.Println("defaultFrontend = ") + } default: fmt.Printf("unknown config name '%v'\n", configName) } diff --git a/cmd/zrok/configSet.go b/cmd/zrok/configSet.go index 553102e9..44773fbf 100644 --- a/cmd/zrok/configSet.go +++ b/cmd/zrok/configSet.go @@ -63,6 +63,20 @@ func (cmd *configSetCommand) run(_ *cobra.Command, args []string) { fmt.Printf("\n[%v]: because you have a %v-d environment, you won't see your config change until you run %v first!\n\n", tui.WarningLabel, tui.Code.Render("zrok enable"), tui.Code.Render("zrok disable")) } + case "defaultFrontend": + if env.Config() == nil { + if err := env.SetConfig(&env_core.Config{DefaultFrontend: value}); err != nil { + tui.Error("unable to save config", err) + } + } else { + cfg := env.Config() + cfg.DefaultFrontend = value + if err := env.SetConfig(cfg); err != nil { + tui.Error("unable to save config", err) + } + } + fmt.Println("zrok configuration updated") + default: fmt.Printf("unknown config name '%v'\n", configName) os.Exit(1) diff --git a/cmd/zrok/configUnset.go b/cmd/zrok/configUnset.go index a7cb6930..34e5d292 100644 --- a/cmd/zrok/configUnset.go +++ b/cmd/zrok/configUnset.go @@ -3,7 +3,6 @@ package main import ( "fmt" "github.com/openziti/zrok/environment" - "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/tui" "github.com/spf13/cobra" "os" @@ -36,18 +35,25 @@ func (cmd *configUnsetCommand) run(_ *cobra.Command, args []string) { panic(err) } - switch configName { - case "apiEndpoint": - if err := env.SetConfig(&env_core.Config{}); err != nil { + if env.Config() != nil { + cfg := env.Config() + switch configName { + case "apiEndpoint": + cfg.ApiEndpoint = "" + if env.IsEnabled() { + fmt.Printf("\n[%v]: because you have a %v-d environment, you won't see your config change until you run %v first!\n\n", tui.WarningLabel, tui.Code.Render("zrok enable"), tui.Code.Render("zrok disable")) + } + + case "defaultFrontend": + cfg.DefaultFrontend = "" + + default: + fmt.Printf("unknown config name '%v'\n", configName) + os.Exit(1) + } + if err := env.SetConfig(cfg); err != nil { tui.Error("unable to save config", err) } fmt.Println("zrok configuration updated") - if env.IsEnabled() { - fmt.Printf("\n[%v]: because you have a %v-d environment, you won't see your config change until you run %v first!\n\n", tui.WarningLabel, tui.Code.Render("zrok enable"), tui.Code.Render("zrok disable")) - } - - default: - fmt.Printf("unknown config name '%v'\n", configName) - os.Exit(1) } } diff --git a/cmd/zrok/reserve.go b/cmd/zrok/reserve.go index 43890584..7aba8f6a 100644 --- a/cmd/zrok/reserve.go +++ b/cmd/zrok/reserve.go @@ -40,8 +40,13 @@ func newReserveCommand() *reserveCommand { Args: cobra.RangeArgs(1, 2), } command := &reserveCommand{cmd: cmd} + defaultFrontends := []string{"public"} + if root, err := environment.LoadRoot(); err == nil { + defaultFrontend, _ := root.DefaultFrontend() + defaultFrontends = []string{defaultFrontend} + } cmd.Flags().StringVarP(&command.uniqueName, "unique-name", "n", "", "A unique name for the reserved share (defaults to generated identifier)") - cmd.Flags().StringArrayVar(&command.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share") + cmd.Flags().StringArrayVar(&command.frontendSelection, "frontend", defaultFrontends, "Selected frontends to use for the share") cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode (public|private: proxy, web, caddy, drive) (private: tcpTunnel, udpTunnel, socks, vpn)") cmd.Flags().BoolVarP(&command.jsonOutput, "json-output", "j", false, "Emit JSON describing the created reserved share") cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (,...)") diff --git a/cmd/zrok/sharePublic.go b/cmd/zrok/sharePublic.go index 931365a5..d66867df 100644 --- a/cmd/zrok/sharePublic.go +++ b/cmd/zrok/sharePublic.go @@ -45,7 +45,12 @@ func newSharePublicCommand() *sharePublicCommand { Args: cobra.ExactArgs(1), } command := &sharePublicCommand{cmd: cmd} - cmd.Flags().StringArrayVar(&command.frontendSelection, "frontends", []string{"public"}, "Selected frontends to use for the share") + defaultFrontends := []string{"public"} + if root, err := environment.LoadRoot(); err == nil { + defaultFrontend, _ := root.DefaultFrontend() + defaultFrontends = []string{defaultFrontend} + } + cmd.Flags().StringArrayVar(&command.frontendSelection, "frontend", defaultFrontends, "Selected frontends to use for the share") cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, caddy, drive}") cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for ") diff --git a/cmd/zrok/status.go b/cmd/zrok/status.go index fe6d00be..f54f83cb 100644 --- a/cmd/zrok/status.go +++ b/cmd/zrok/status.go @@ -48,8 +48,10 @@ func (cmd *statusCommand) run(_ *cobra.Command, _ []string) { t.SetOutputMirror(os.Stdout) t.SetStyle(table.StyleColoredDark) t.AppendHeader(table.Row{"Config", "Value", "Source"}) - apiEndpoint, from := env.ApiEndpoint() - t.AppendRow(table.Row{"apiEndpoint", apiEndpoint, from}) + apiEndpoint, apiEndpointFrom := env.ApiEndpoint() + t.AppendRow(table.Row{"apiEndpoint", apiEndpoint, apiEndpointFrom}) + defaultFrontend, defaultFrontendFrom := env.DefaultFrontend() + t.AppendRow(table.Row{"defaultFrontend", defaultFrontend, defaultFrontendFrom}) t.Render() _, _ = fmt.Fprintf(os.Stderr, "\n") diff --git a/controller/createFrontend.go b/controller/createFrontend.go index 45767387..882b753d 100644 --- a/controller/createFrontend.go +++ b/controller/createFrontend.go @@ -2,7 +2,6 @@ package controller import ( "errors" - "github.com/go-openapi/runtime/middleware" "github.com/lib/pq" "github.com/mattn/go-sqlite3" @@ -57,11 +56,12 @@ func (h *createFrontendHandler) Handle(params admin.CreateFrontendParams, princi } fe := &store.Frontend{ - Token: feToken, - ZId: params.Body.ZID, - PublicName: ¶ms.Body.PublicName, - UrlTemplate: ¶ms.Body.URLTemplate, - Reserved: true, + Token: feToken, + ZId: params.Body.ZID, + PublicName: ¶ms.Body.PublicName, + UrlTemplate: ¶ms.Body.URLTemplate, + Reserved: true, + PermissionMode: store.PermissionMode(params.Body.PermissionMode), } if _, err := str.CreateGlobalFrontend(fe, tx); err != nil { perr := &pq.Error{} diff --git a/controller/limits/agent.go b/controller/limits/agent.go index bd14d8af..78835056 100644 --- a/controller/limits/agent.go +++ b/controller/limits/agent.go @@ -163,30 +163,47 @@ func (a *Agent) CanAccessShare(shrId int, trx *sqlx.Tx) (bool, error) { return false, err } if env.AccountId != nil { + if err := a.str.LimitCheckLock(*env.AccountId, trx); err != nil { + return false, err + } + ul, err := a.getUserLimits(*env.AccountId, trx) if err != nil { return false, err } - if ul.resource.IsGlobal() { - if empty, err := a.str.IsBandwidthLimitJournalEmptyForGlobal(*env.AccountId, trx); err == nil && !empty { - lj, err := a.str.FindLatestBandwidthLimitJournalForGlobal(*env.AccountId, trx) + if scopedBwc, found := ul.scopes[sdk.BackendMode(shr.BackendMode)]; found { + latestScopedJe, err := a.isBandwidthClassLimitedForAccount(*env.AccountId, scopedBwc, trx) + if err != nil { + return false, err + } + if latestScopedJe != nil { + return false, nil + } + } else { + for _, bwc := range ul.bandwidth { + latestJe, err := a.isBandwidthClassLimitedForAccount(*env.AccountId, bwc, trx) if err != nil { return false, err } - if lj.Action == store.LimitLimitAction { + if latestJe != nil { return false, nil } } - } else { - if empty, err := a.str.IsBandwidthLimitJournalEmptyForLimitClass(*env.AccountId, ul.resource.GetLimitClassId(), trx); err == nil && !empty { - lj, err := a.str.FindLatestBandwidthLimitJournalForLimitClass(*env.AccountId, ul.resource.GetLimitClassId(), trx) - if err != nil { - return false, err - } - if lj.Action == store.LimitLimitAction { - return false, nil - } + } + + rc := ul.resource + if scopeRc, found := ul.scopes[sdk.BackendMode(shr.BackendMode)]; found { + rc = scopeRc + } + if rc.GetShareFrontends() > store.Unlimited { + fes, err := a.str.FindFrontendsForPrivateShare(shr.Id, trx) + if err != nil { + return false, err + } + if len(fes)+1 > rc.GetShareFrontends() { + logrus.Infof("account '#%d' over frontends per share limit '%d'", *env.AccountId, rc.GetReservedShares()) + return false, nil } } } else { diff --git a/controller/limits/config.go b/controller/limits/config.go index 2bc0c8a8..c6d69796 100644 --- a/controller/limits/config.go +++ b/controller/limits/config.go @@ -10,6 +10,7 @@ type Config struct { Shares int ReservedShares int UniqueNames int + ShareFrontends int Bandwidth *BandwidthPerPeriod Cycle time.Duration Enforcing bool @@ -49,6 +50,7 @@ func DefaultConfig() *Config { Shares: store.Unlimited, ReservedShares: store.Unlimited, UniqueNames: store.Unlimited, + ShareFrontends: store.Unlimited, Bandwidth: DefaultBandwidthPerPeriod(), Enforcing: false, Cycle: 15 * time.Minute, diff --git a/controller/limits/resourceCountClass.go b/controller/limits/resourceCountClass.go index ca9a6a91..1f888583 100644 --- a/controller/limits/resourceCountClass.go +++ b/controller/limits/resourceCountClass.go @@ -37,6 +37,10 @@ func (rcc *configResourceCountClass) GetUniqueNames() int { return rcc.cfg.UniqueNames } -func (rcc *configResourceCountClass) String() string { - return fmt.Sprintf("Config", rcc.cfg.Environments, rcc.cfg.Shares, rcc.cfg.ReservedShares, rcc.cfg.UniqueNames) +func (rcc *configResourceCountClass) GetShareFrontends() int { + return rcc.cfg.ShareFrontends +} + +func (rcc *configResourceCountClass) String() string { + return fmt.Sprintf("Config", rcc.cfg.Environments, rcc.cfg.Shares, rcc.cfg.ReservedShares, rcc.cfg.UniqueNames, rcc.cfg.ShareFrontends) } diff --git a/controller/limits/userLimits.go b/controller/limits/userLimits.go index 3b40e256..5be269a9 100644 --- a/controller/limits/userLimits.go +++ b/controller/limits/userLimits.go @@ -42,7 +42,6 @@ func (ul *userLimits) ignoreBackends(bwc store.BandwidthClass) map[sdk.BackendMo } return ignoreBackends } - return nil } func (a *Agent) getUserLimits(acctId int, trx *sqlx.Tx) (*userLimits, error) { @@ -85,7 +84,7 @@ func (a *Agent) isResourceCountClass(alc *store.LimitClass) bool { if alc.BackendMode != nil { return false } - if alc.Environments == store.Unlimited && alc.Shares == store.Unlimited && alc.ReservedShares == store.Unlimited && alc.UniqueNames == store.Unlimited { + if alc.Environments == store.Unlimited && alc.Shares == store.Unlimited && alc.ReservedShares == store.Unlimited && alc.UniqueNames == store.Unlimited && alc.ShareFrontends == store.Unlimited { return false } return true @@ -95,7 +94,7 @@ func (a *Agent) isUnscopedBandwidthClass(alc *store.LimitClass) bool { if alc.BackendMode != nil { return false } - if alc.Environments > store.Unlimited || alc.Shares > store.Unlimited || alc.ReservedShares > store.Unlimited || alc.UniqueNames > store.Unlimited { + if alc.Environments > store.Unlimited || alc.Shares > store.Unlimited || alc.ReservedShares > store.Unlimited || alc.UniqueNames > store.Unlimited || alc.ShareFrontends > store.Unlimited { return false } if alc.PeriodMinutes < 1 { diff --git a/controller/share.go b/controller/share.go index f3a244bf..b5dc286b 100644 --- a/controller/share.go +++ b/controller/share.go @@ -116,6 +116,17 @@ func (h *shareHandler) Handle(params share.ShareParams, principal *rest_model_zr logrus.Error(err) return share.NewShareNotFound() } + if sfe.PermissionMode == store.ClosedPermissionMode { + granted, err := str.IsFrontendGrantedToAccount(int(principal.ID), sfe.Id, trx) + if err != nil { + logrus.Error(err) + return share.NewShareInternalServerError() + } + if !granted { + logrus.Errorf("'%v' is not granted access to frontend '%v'", principal.Email, frontendSelection) + return share.NewShareNotFound() + } + } if sfe != nil && sfe.UrlTemplate != nil { frontendZIds = append(frontendZIds, sfe.ZId) frontendTemplates = append(frontendTemplates, *sfe.UrlTemplate) diff --git a/controller/store/frontend.go b/controller/store/frontend.go index 8d34145e..d4b55faf 100644 --- a/controller/store/frontend.go +++ b/controller/store/frontend.go @@ -14,28 +14,28 @@ type Frontend struct { PublicName *string UrlTemplate *string Reserved bool - Deleted bool + PermissionMode PermissionMode } func (str *Store) CreateFrontend(envId int, f *Frontend, tx *sqlx.Tx) (int, error) { - stmt, err := tx.Prepare("insert into frontends (environment_id, private_share_id, token, z_id, public_name, url_template, reserved) values ($1, $2, $3, $4, $5, $6, $7) returning id") + stmt, err := tx.Prepare("insert into frontends (environment_id, private_share_id, token, z_id, public_name, url_template, reserved, permission_mode) values ($1, $2, $3, $4, $5, $6, $7, $8) returning id") if err != nil { return 0, errors.Wrap(err, "error preparing frontends insert statement") } var id int - if err := stmt.QueryRow(envId, f.PrivateShareId, f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved).Scan(&id); err != nil { + if err := stmt.QueryRow(envId, f.PrivateShareId, f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved, f.PermissionMode).Scan(&id); err != nil { return 0, errors.Wrap(err, "error executing frontends insert statement") } return id, nil } func (str *Store) CreateGlobalFrontend(f *Frontend, tx *sqlx.Tx) (int, error) { - stmt, err := tx.Prepare("insert into frontends (token, z_id, public_name, url_template, reserved) values ($1, $2, $3, $4, $5) returning id") + stmt, err := tx.Prepare("insert into frontends (token, z_id, public_name, url_template, reserved, permission_mode) values ($1, $2, $3, $4, $5, $6) returning id") if err != nil { return 0, errors.Wrap(err, "error preparing global frontends insert statement") } var id int - if err := stmt.QueryRow(f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved).Scan(&id); err != nil { + if err := stmt.QueryRow(f.Token, f.ZId, f.PublicName, f.UrlTemplate, f.Reserved, f.PermissionMode).Scan(&id); err != nil { return 0, errors.Wrap(err, "error executing global frontends insert statement") } return id, nil @@ -122,12 +122,12 @@ func (str *Store) FindFrontendsForPrivateShare(shrId int, tx *sqlx.Tx) ([]*Front } func (str *Store) UpdateFrontend(fe *Frontend, tx *sqlx.Tx) error { - sql := "update frontends set environment_id = $1, private_share_id = $2, token = $3, z_id = $4, public_name = $5, url_template = $6, reserved = $7, updated_at = current_timestamp where id = $8" + sql := "update frontends set environment_id = $1, private_share_id = $2, token = $3, z_id = $4, public_name = $5, url_template = $6, reserved = $7, permission_mode = $8, updated_at = current_timestamp where id = $9" stmt, err := tx.Prepare(sql) if err != nil { return errors.Wrap(err, "error preparing frontends update statement") } - _, err = stmt.Exec(fe.EnvironmentId, fe.PrivateShareId, fe.Token, fe.ZId, fe.PublicName, fe.UrlTemplate, fe.Reserved, fe.Id) + _, err = stmt.Exec(fe.EnvironmentId, fe.PrivateShareId, fe.Token, fe.ZId, fe.PublicName, fe.UrlTemplate, fe.Reserved, fe.PermissionMode, fe.Id) if err != nil { return errors.Wrap(err, "error executing frontends update statement") } diff --git a/controller/store/frontendGrant.go b/controller/store/frontendGrant.go new file mode 100644 index 00000000..d676653f --- /dev/null +++ b/controller/store/frontendGrant.go @@ -0,0 +1,18 @@ +package store + +import ( + "github.com/jmoiron/sqlx" + "github.com/pkg/errors" +) + +func (str *Store) IsFrontendGrantedToAccount(acctId, frontendId int, trx *sqlx.Tx) (bool, error) { + stmt, err := trx.Prepare("select count(0) from frontend_grants where account_id = $1 AND frontend_id = $2") + if err != nil { + return false, errors.Wrap(err, "error preparing frontend_grants select statement") + } + var count int + if err := stmt.QueryRow(acctId, frontendId).Scan(&count); err != nil { + return false, errors.Wrap(err, "error querying frontend_grants count") + } + return count > 0, nil +} diff --git a/controller/store/limitClass.go b/controller/store/limitClass.go index a41eb2de..fbef43e8 100644 --- a/controller/store/limitClass.go +++ b/controller/store/limitClass.go @@ -22,6 +22,7 @@ type ResourceCountClass interface { GetShares() int GetReservedShares() int GetUniqueNames() int + GetShareFrontends() int } type BandwidthClass interface { @@ -37,11 +38,13 @@ type BandwidthClass interface { type LimitClass struct { Model + Label *string BackendMode *sdk.BackendMode Environments int Shares int ReservedShares int UniqueNames int + ShareFrontends int PeriodMinutes int RxBytes int64 TxBytes int64 @@ -77,6 +80,10 @@ func (lc LimitClass) GetUniqueNames() int { return lc.UniqueNames } +func (lc LimitClass) GetShareFrontends() int { + return lc.ShareFrontends +} + func (lc LimitClass) GetBackendMode() sdk.BackendMode { if lc.BackendMode == nil { return "" @@ -105,7 +112,12 @@ func (lc LimitClass) GetLimitAction() LimitAction { } func (lc LimitClass) String() string { - out := fmt.Sprintf("LimitClass<#%d", lc.Id) + out := "LimitClass<" + if lc.Label != nil && *lc.Label != "" { + out += "'" + *lc.Label + "'" + } else { + out += fmt.Sprintf("#%d", lc.Id) + } if lc.BackendMode != nil { out += fmt.Sprintf(", backendMode: '%s'", *lc.BackendMode) } @@ -121,6 +133,9 @@ func (lc LimitClass) String() string { if lc.UniqueNames > Unlimited { out += fmt.Sprintf(", uniqueNames: %d", lc.UniqueNames) } + if lc.ShareFrontends > Unlimited { + out += fmt.Sprintf(", shareFrontends: %d", lc.ShareFrontends) + } if lc.RxBytes > Unlimited || lc.TxBytes > Unlimited || lc.TotalBytes > Unlimited { out += fmt.Sprintf(", periodMinutes: %d", lc.PeriodMinutes) } @@ -140,12 +155,12 @@ func (lc LimitClass) String() string { var _ BandwidthClass = (*LimitClass)(nil) func (str *Store) CreateLimitClass(lc *LimitClass, trx *sqlx.Tx) (int, error) { - stmt, err := trx.Prepare("insert into limit_classes (backend_mode, environments, shares, reserved_shares, unique_names, period_minutes, rx_bytes, tx_bytes, total_bytes, limit_action) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) returning id") + stmt, err := trx.Prepare("insert into limit_classes (label, backend_mode, environments, shares, reserved_shares, unique_names, share_frontends, period_minutes, rx_bytes, tx_bytes, total_bytes, limit_action) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) returning id") if err != nil { return 0, errors.Wrap(err, "error preparing limit_classes insert statement") } var id int - if err := stmt.QueryRow(lc.BackendMode, lc.Environments, lc.Shares, lc.ReservedShares, lc.UniqueNames, lc.PeriodMinutes, lc.RxBytes, lc.TxBytes, lc.TotalBytes, lc.LimitAction).Scan(&id); err != nil { + if err := stmt.QueryRow(lc.Label, lc.BackendMode, lc.Environments, lc.Shares, lc.ReservedShares, lc.UniqueNames, lc.ShareFrontends, lc.PeriodMinutes, lc.RxBytes, lc.TxBytes, lc.TotalBytes, lc.LimitAction).Scan(&id); err != nil { return 0, errors.Wrap(err, "error executing limit_classes insert statement") } return id, nil diff --git a/controller/store/model.go b/controller/store/model.go index e4e0d6ab..f4980a1c 100644 --- a/controller/store/model.go +++ b/controller/store/model.go @@ -7,14 +7,6 @@ const ( WarningLimitAction LimitAction = "warning" ) -type LimitScope string - -const ( - AccountLimitScope LimitScope = "account" - EnvironmentLimitScope LimitScope = "environment" - ShareLimitScope LimitScope = "share" -) - type PermissionMode string const ( diff --git a/controller/store/share.go b/controller/store/share.go index c12aa529..cd8257e9 100644 --- a/controller/store/share.go +++ b/controller/store/share.go @@ -18,7 +18,6 @@ type Share struct { Reserved bool UniqueName bool PermissionMode PermissionMode - Deleted bool } func (str *Store) CreateShare(envId int, shr *Share, tx *sqlx.Tx) (int, error) { diff --git a/controller/store/sql/postgresql/026_v0_4_32_frontend_count.sql b/controller/store/sql/postgresql/026_v0_4_32_frontend_count.sql new file mode 100644 index 00000000..5de4c3eb --- /dev/null +++ b/controller/store/sql/postgresql/026_v0_4_32_frontend_count.sql @@ -0,0 +1,3 @@ +-- +migrate Up + +alter table limit_classes add column share_frontends int not null default (-1); \ No newline at end of file diff --git a/controller/store/sql/postgresql/027_v0_4_32_frontend_grants.sql b/controller/store/sql/postgresql/027_v0_4_32_frontend_grants.sql new file mode 100644 index 00000000..ba4c3d51 --- /dev/null +++ b/controller/store/sql/postgresql/027_v0_4_32_frontend_grants.sql @@ -0,0 +1,17 @@ +-- +migrate Up + +alter table frontends add column permission_mode permission_mode_type not null default('open'); + +create table frontend_grants ( + id serial primary key, + + account_id integer references accounts (id) not null, + frontend_id integer references frontends (id) not null, + + created_at timestamptz not null default(current_timestamp), + updated_at timestamptz not null default(current_timestamp), + deleted boolean not null default(false) +); + +create index frontend_grants_account_id_idx on frontend_grants (account_id); +create index frontend_grants_frontend_id_idx on frontend_grants (frontend_id); \ No newline at end of file diff --git a/controller/store/sql/postgresql/028_v0_4_32_limit_classes_label.sql b/controller/store/sql/postgresql/028_v0_4_32_limit_classes_label.sql new file mode 100644 index 00000000..23dd9efb --- /dev/null +++ b/controller/store/sql/postgresql/028_v0_4_32_limit_classes_label.sql @@ -0,0 +1,3 @@ +-- +migrate Up + +alter table limit_classes add column label varchar(32); \ No newline at end of file diff --git a/controller/store/sql/sqlite3/026_v0_4_32_frontend_count.sql b/controller/store/sql/sqlite3/026_v0_4_32_frontend_count.sql new file mode 100644 index 00000000..5de4c3eb --- /dev/null +++ b/controller/store/sql/sqlite3/026_v0_4_32_frontend_count.sql @@ -0,0 +1,3 @@ +-- +migrate Up + +alter table limit_classes add column share_frontends int not null default (-1); \ No newline at end of file diff --git a/controller/store/sql/sqlite3/027_v0_4_32_frontend_grants.sql b/controller/store/sql/sqlite3/027_v0_4_32_frontend_grants.sql new file mode 100644 index 00000000..1ad99dd3 --- /dev/null +++ b/controller/store/sql/sqlite3/027_v0_4_32_frontend_grants.sql @@ -0,0 +1,17 @@ +-- +migrate Up + +alter table frontends add column permission_mode string not null default('open'); + +create table frontend_grants ( + id integer primary key, + + account_id integer references accounts (id) not null, + frontend_id integer references frontends (id) not null, + + created_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), + updated_at datetime not null default(strftime('%Y-%m-%d %H:%M:%f', 'now')), + deleted boolean not null default(false) +); + +create index frontend_grants_account_id_idx on frontend_grants (account_id); +create index frontend_grants_frontend_id_idx on frontend_grants (frontend_id); \ No newline at end of file diff --git a/controller/store/sql/sqlite3/028_v0_4_32_limit_classes_label.sql b/controller/store/sql/sqlite3/028_v0_4_32_limit_classes_label.sql new file mode 100644 index 00000000..23dd9efb --- /dev/null +++ b/controller/store/sql/sqlite3/028_v0_4_32_limit_classes_label.sql @@ -0,0 +1,3 @@ +-- +migrate Up + +alter table limit_classes add column label varchar(32); \ No newline at end of file diff --git a/docker/compose/zrok-instance/README.md b/docker/compose/zrok-instance/README.md index 1cdf2b02..8d56d167 100644 --- a/docker/compose/zrok-instance/README.md +++ b/docker/compose/zrok-instance/README.md @@ -90,9 +90,9 @@ ZROK_OAUTH_GOOGLE_CLIENT_ID=abcd1234 ZROK_OAUTH_GOOGLE_CLIENT_SECRET=abcd1234 # zrok version, e.g., 1.0.0 -ZROK_IMAGE_TAG=latest +ZROK_CLI_TAG=latest # ziti version, e.g., 1.0.0 -ZITI_IMAGE_TAG=latest +ZITI_CLI_TAG=latest ``` ### Start the Docker Compose Project diff --git a/docker/compose/zrok-instance/zrok-controller-config.yml.envsubst b/docker/compose/zrok-instance/zrok-controller-config.yml.envsubst index 389f4bce..cbdfe639 100644 --- a/docker/compose/zrok-instance/zrok-controller-config.yml.envsubst +++ b/docker/compose/zrok-instance/zrok-controller-config.yml.envsubst @@ -4,7 +4,7 @@ # /___|_| \___/|_|\_\ # controller configuration -v: 3 +v: 4 admin: # generate these admin tokens from a source of randomness, e.g. # LC_ALL=C tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c32 diff --git a/docs/guides/self-hosting/metrics-and-limits/configuring-limits.md b/docs/guides/self-hosting/metrics-and-limits/configuring-limits.md index b233eb9d..3c3af05c 100644 --- a/docs/guides/self-hosting/metrics-and-limits/configuring-limits.md +++ b/docs/guides/self-hosting/metrics-and-limits/configuring-limits.md @@ -20,7 +20,7 @@ The limits agent is responsible for controlling the number of resources in use ( ### Types of Limits -Limits can be specified that control the number of environments, shares, reserved shares, and unique names that can be created by an account. Limits that control the allowed number of resources are called _resource count limits_. +Limits can be specified that control the number of environments, shares, reserved shares, unique names, and frontends per-share that can be created by an account. Limits that control the allowed number of resources are called _resource count limits_. Limits can be specified to control the amount of data that can be transferred within a time period. Limits that control the amount of data that can be transferred are called _bandwidth limits_. @@ -40,6 +40,7 @@ limits: shares: -1 reserved_shares: -1 unique_names: -1 + share_frontends: -1 bandwidth: period: 5m warning: @@ -64,7 +65,7 @@ The `cycle` value controls how frequently the limits agent will evaluate enforce ### Global Resouce Count Limits -The `environments`, `shares`, `reserved_shares`, and `unique_names` specify the resource count limits, globally for the service instance. +The `environments`, `shares`, `reserved_shares`, `unique_names`, and `share_frontends` specify the resource count limits, globally for the service instance. These resource counts will be applied to all users in the service instance by default. @@ -91,11 +92,13 @@ Limit classes are created by creating a record in the `limit_classes` table in t ```sql CREATE TABLE public.limit_classes ( id integer NOT NULL, + label VARCHAR(32), backend_mode public.backend_mode, environments integer DEFAULT '-1'::integer NOT NULL, shares integer DEFAULT '-1'::integer NOT NULL, reserved_shares integer DEFAULT '-1'::integer NOT NULL, unique_names integer DEFAULT '-1'::integer NOT NULL, + share_frontends integer DEFAULT '-1'::integer NOT NULL, period_minutes integer DEFAULT 1440 NOT NULL, rx_bytes bigint DEFAULT '-1'::integer NOT NULL, tx_bytes bigint DEFAULT '-1'::integer NOT NULL, @@ -130,7 +133,7 @@ Create a row in this table linking the `account_id` to the `limit_class_id` to a To support overriding the resource count limits defined in the global limits configuration, a site administrator can create a limit class by inserting a row into the `limit_classes` table structured like this: ```sql -insert into limit_classes (environments, shares, reserved_shares, unique_names) values (1, 1, 1, 1); +insert into limit_classes (environments, shares, reserved_shares, unique_names, share_frontends) values (1, 1, 1, 1, 1); ``` This creates a limit class that sets the `environments`, `shares`, `reserved_shares`, and `unique_names` all to `1`. diff --git a/drives/sync/filesystem.go b/drives/sync/filesystem.go index 153f929c..b5d721b0 100644 --- a/drives/sync/filesystem.go +++ b/drives/sync/filesystem.go @@ -124,6 +124,7 @@ func (t *FilesystemTarget) WriteStream(path string, stream io.Reader, mode os.Fi if err != nil { return err } + defer f.Close() _, err = io.Copy(f, stream) if err != nil { return err diff --git a/environment/env_core/model.go b/environment/env_core/model.go index 8c838429..ebb1df34 100644 --- a/environment/env_core/model.go +++ b/environment/env_core/model.go @@ -13,6 +13,7 @@ type Root interface { Client() (*rest_client_zrok.Zrok, error) ApiEndpoint() (string, string) + DefaultFrontend() (string, string) IsEnabled() bool Environment() *Environment @@ -34,7 +35,8 @@ type Environment struct { } type Config struct { - ApiEndpoint string + ApiEndpoint string + DefaultFrontend string } type Metadata struct { diff --git a/environment/env_v0_3/api.go b/environment/env_v0_3/api.go index b7bd285c..61a03296 100644 --- a/environment/env_v0_3/api.go +++ b/environment/env_v0_3/api.go @@ -85,6 +85,24 @@ func (r *Root) ApiEndpoint() (string, string) { return apiEndpoint, from } +func (r *Root) DefaultFrontend() (string, string) { + defaultFrontend := "public" + from := "binary" + + if r.Config() != nil && r.Config().DefaultFrontend != "" { + defaultFrontend = r.Config().DefaultFrontend + from = "config" + } + + env := os.Getenv("ZROK_DEFAULT_FRONTEND") + if env != "" { + defaultFrontend = env + from = "ZROK_DEFAULT_FRONTEND" + } + + return defaultFrontend, from +} + func (r *Root) Environment() *env_core.Environment { return r.env } diff --git a/environment/env_v0_4/api.go b/environment/env_v0_4/api.go index 3e08202b..35db06c5 100644 --- a/environment/env_v0_4/api.go +++ b/environment/env_v0_4/api.go @@ -85,6 +85,24 @@ func (r *Root) ApiEndpoint() (string, string) { return apiEndpoint, from } +func (r *Root) DefaultFrontend() (string, string) { + defaultFrontend := "public" + from := "binary" + + if r.Config() != nil && r.Config().DefaultFrontend != "" { + defaultFrontend = r.Config().DefaultFrontend + from = "config" + } + + env := os.Getenv("ZROK_DEFAULT_FRONTEND") + if env != "" { + defaultFrontend = env + from = "ZROK_DEFAULT_FRONTEND" + } + + return defaultFrontend, from +} + func (r *Root) Environment() *env_core.Environment { return r.env } diff --git a/environment/env_v0_4/root.go b/environment/env_v0_4/root.go index 28804bac..f085f3f6 100644 --- a/environment/env_v0_4/root.go +++ b/environment/env_v0_4/root.go @@ -223,13 +223,14 @@ func loadConfig() (*env_core.Config, error) { return nil, errors.Wrapf(err, "error unmarshaling config file '%v'", cf) } out := &env_core.Config{ - ApiEndpoint: cfg.ApiEndpoint, + ApiEndpoint: cfg.ApiEndpoint, + DefaultFrontend: cfg.DefaultFrontend, } return out, nil } func saveConfig(cfg *env_core.Config) error { - in := &config{ApiEndpoint: cfg.ApiEndpoint} + in := &config{ApiEndpoint: cfg.ApiEndpoint, DefaultFrontend: cfg.DefaultFrontend} data, err := json.MarshalIndent(in, "", " ") if err != nil { return errors.Wrap(err, "error marshaling config") @@ -323,7 +324,8 @@ type metadata struct { } type config struct { - ApiEndpoint string `json:"api_endpoint"` + ApiEndpoint string `json:"api_endpoint"` + DefaultFrontend string `json:"default_frontend"` } type environment struct { diff --git a/etc/ctrl.yml b/etc/ctrl.yml index 0c680b8d..d9b0efd0 100644 --- a/etc/ctrl.yml +++ b/etc/ctrl.yml @@ -83,6 +83,7 @@ limits: shares: -1 reserved_shares: -1 unique_names: -1 + share_frontends: -1 bandwidth: period: 5m warning: diff --git a/rest_model_zrok/create_frontend_request.go b/rest_model_zrok/create_frontend_request.go index fdf6b515..183b65ea 100644 --- a/rest_model_zrok/create_frontend_request.go +++ b/rest_model_zrok/create_frontend_request.go @@ -7,9 +7,12 @@ package rest_model_zrok import ( "context" + "encoding/json" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" + "github.com/go-openapi/validate" ) // CreateFrontendRequest create frontend request @@ -17,6 +20,10 @@ import ( // swagger:model createFrontendRequest type CreateFrontendRequest struct { + // permission mode + // Enum: [open closed] + PermissionMode string `json:"permissionMode,omitempty"` + // public name PublicName string `json:"public_name,omitempty"` @@ -29,6 +36,57 @@ type CreateFrontendRequest struct { // Validate validates this create frontend request func (m *CreateFrontendRequest) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validatePermissionMode(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +var createFrontendRequestTypePermissionModePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["open","closed"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + createFrontendRequestTypePermissionModePropEnum = append(createFrontendRequestTypePermissionModePropEnum, v) + } +} + +const ( + + // CreateFrontendRequestPermissionModeOpen captures enum value "open" + CreateFrontendRequestPermissionModeOpen string = "open" + + // CreateFrontendRequestPermissionModeClosed captures enum value "closed" + CreateFrontendRequestPermissionModeClosed string = "closed" +) + +// prop value enum +func (m *CreateFrontendRequest) validatePermissionModeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, createFrontendRequestTypePermissionModePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *CreateFrontendRequest) validatePermissionMode(formats strfmt.Registry) error { + if swag.IsZero(m.PermissionMode) { // not required + return nil + } + + // value enum + if err := m.validatePermissionModeEnum("permissionMode", "body", m.PermissionMode); err != nil { + return err + } + return nil } diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index e74a4198..9afdfdd3 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -1200,6 +1200,13 @@ func init() { "createFrontendRequest": { "type": "object", "properties": { + "permissionMode": { + "type": "string", + "enum": [ + "open", + "closed" + ] + }, "public_name": { "type": "string" }, @@ -2956,6 +2963,13 @@ func init() { "createFrontendRequest": { "type": "object", "properties": { + "permissionMode": { + "type": "string", + "enum": [ + "open", + "closed" + ] + }, "public_name": { "type": "string" }, diff --git a/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/VERSION b/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/VERSION index ba7f754d..93c8ddab 100644 --- a/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/VERSION +++ b/sdk/nodejs/sdk/src/zrok/api/.openapi-generator/VERSION @@ -1 +1 @@ -7.4.0 +7.6.0 diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts index 75d9842e..35b425ef 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts @@ -16,6 +16,7 @@ export class CreateFrontendRequest { 'zId'?: string; 'urlTemplate'?: string; 'publicName'?: string; + 'permissionMode'?: CreateFrontendRequest.PermissionModeEnum; static discriminator: string | undefined = undefined; @@ -34,6 +35,11 @@ export class CreateFrontendRequest { "name": "publicName", "baseName": "public_name", "type": "string" + }, + { + "name": "permissionMode", + "baseName": "permissionMode", + "type": "CreateFrontendRequest.PermissionModeEnum" } ]; static getAttributeTypeMap() { @@ -41,3 +47,9 @@ export class CreateFrontendRequest { } } +export namespace CreateFrontendRequest { + export enum PermissionModeEnum { + Open = 'open', + Closed = 'closed' + } +} diff --git a/sdk/nodejs/sdk/src/zrok/api/model/models.ts b/sdk/nodejs/sdk/src/zrok/api/model/models.ts index c5fb9183..13a6a25e 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/models.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/models.ts @@ -108,6 +108,7 @@ let primitives = [ ]; let enumsMap: {[index: string]: any} = { + "CreateFrontendRequest.PermissionModeEnum": CreateFrontendRequest.PermissionModeEnum, "ShareRequest.ShareModeEnum": ShareRequest.ShareModeEnum, "ShareRequest.BackendModeEnum": ShareRequest.BackendModeEnum, "ShareRequest.OauthProviderEnum": ShareRequest.OauthProviderEnum, diff --git a/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts index 83205cb0..086ba7d8 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts @@ -120,7 +120,8 @@ export namespace ShareRequest { UdpTunnel = 'udpTunnel', Caddy = 'caddy', Drive = 'drive', - Socks = 'socks' + Socks = 'socks', + Vpn = 'vpn' } export enum OauthProviderEnum { Github = 'github', diff --git a/sdk/python/sdk/zrok/zrok_api/models/create_frontend_request.py b/sdk/python/sdk/zrok/zrok_api/models/create_frontend_request.py index 946c0ccc..f6a0cf01 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/create_frontend_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/create_frontend_request.py @@ -30,20 +30,23 @@ class CreateFrontendRequest(object): swagger_types = { 'z_id': 'str', 'url_template': 'str', - 'public_name': 'str' + 'public_name': 'str', + 'permission_mode': 'str' } attribute_map = { 'z_id': 'zId', 'url_template': 'url_template', - 'public_name': 'public_name' + 'public_name': 'public_name', + 'permission_mode': 'permissionMode' } - def __init__(self, z_id=None, url_template=None, public_name=None): # noqa: E501 + def __init__(self, z_id=None, url_template=None, public_name=None, permission_mode=None): # noqa: E501 """CreateFrontendRequest - a model defined in Swagger""" # noqa: E501 self._z_id = None self._url_template = None self._public_name = None + self._permission_mode = None self.discriminator = None if z_id is not None: self.z_id = z_id @@ -51,6 +54,8 @@ class CreateFrontendRequest(object): self.url_template = url_template if public_name is not None: self.public_name = public_name + if permission_mode is not None: + self.permission_mode = permission_mode @property def z_id(self): @@ -115,6 +120,33 @@ class CreateFrontendRequest(object): self._public_name = public_name + @property + def permission_mode(self): + """Gets the permission_mode of this CreateFrontendRequest. # noqa: E501 + + + :return: The permission_mode of this CreateFrontendRequest. # noqa: E501 + :rtype: str + """ + return self._permission_mode + + @permission_mode.setter + def permission_mode(self, permission_mode): + """Sets the permission_mode of this CreateFrontendRequest. + + + :param permission_mode: The permission_mode of this CreateFrontendRequest. # noqa: E501 + :type: str + """ + allowed_values = ["open", "closed"] # noqa: E501 + if permission_mode not in allowed_values: + raise ValueError( + "Invalid value for `permission_mode` ({0}), must be one of {1}" # noqa: E501 + .format(permission_mode, allowed_values) + ) + + self._permission_mode = permission_mode + def to_dict(self): """Returns the model properties as a dict""" result = {} diff --git a/specs/zrok.yml b/specs/zrok.yml index da0a1a36..0f37b6f0 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -766,6 +766,9 @@ definitions: type: string public_name: type: string + permissionMode: + type: string + enum: ["open", "closed"] createFrontendResponse: type: object diff --git a/ui/package-lock.json b/ui/package-lock.json index f4d7cb91..7a8f69dd 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -12,16 +12,16 @@ "@emotion/styled": "^11.10.4", "@mdi/js": "^7.0.96", "@mdi/react": "^1.6.1", - "@mui/material": "^5.10.4", + "@mui/material": "^5.15.18", "bootstrap": "^5.2.3", "dagre": "^0.8.5", "eslint-config-react-app": "^7.0.1", "humanize-duration": "^3.27.3", "moment": "^2.29.4", - "react": "^18.2.0", - "react-bootstrap": "^2.7.0", + "react": "^18.3.1", + "react-bootstrap": "^2.10.2", "react-data-table-component": "^7.5.2", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-force-graph": "^1.43.0", "react-router-dom": "^6.4.0", "react-sizeme": "^3.0.2", @@ -1758,16 +1758,23 @@ } }, "node_modules/@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", + "license": "MIT", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/@babel/template": { "version": "7.20.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", @@ -2130,17 +2137,24 @@ } }, "node_modules/@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, + "node_modules/@emotion/cache/node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/@emotion/hash": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", @@ -2155,9 +2169,10 @@ } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "license": "MIT" }, "node_modules/@emotion/react": { "version": "11.10.5", @@ -2199,9 +2214,10 @@ } }, "node_modules/@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==", + "license": "MIT" }, "node_modules/@emotion/styled": { "version": "11.10.5", @@ -2248,14 +2264,16 @@ } }, "node_modules/@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==", + "license": "MIT" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==", + "license": "MIT" }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", @@ -2304,6 +2322,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz", + "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", + "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", + "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", + "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==", + "license": "MIT" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -3166,25 +3222,25 @@ } }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.116", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz", - "integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==", + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3198,28 +3254,30 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz", - "integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.20.tgz", + "integrity": "sha512-DoL2ppgldL16utL8nNyj/P12f8mCNdx/Hb/AJnX9rLY4b52hCMIx1kH83pbXQ6uMy6n54M3StmEbvSGoj2OFuA==", + "license": "MIT", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/material": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz", - "integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==", + "version": "5.15.18", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.18.tgz", + "integrity": "sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/base": "5.0.0-alpha.116", - "@mui/core-downloads-tracker": "^5.11.7", - "@mui/system": "^5.11.7", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.18", + "@mui/system": "^5.15.15", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" @@ -3229,7 +3287,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3251,12 +3309,13 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz", - "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.20.tgz", + "integrity": "sha512-BK8F94AIqSrnaPYXf2KAOjGZJgWfvqAVQ2gVR3EryvQFtuBnG6RwodxrCvd3B48VuMy6Wsk897+lQMUxJyk+6g==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.7", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.20", "prop-types": "^15.8.1" }, "engines": { @@ -3264,7 +3323,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3277,13 +3336,14 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz", - "integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==", + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.6", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -3291,7 +3351,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -3308,17 +3368,18 @@ } }, "node_modules/@mui/system": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz", - "integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.20.tgz", + "integrity": "sha512-LoMq4IlAAhxzL2VNUDBTQxAb4chnBe8JvRINVNDiMtHE2PiPOoHlhOPutSxEbaL5mkECPVWSv6p8JEV+uykwIA==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", - "@mui/private-theming": "^5.11.7", - "@mui/styled-engine": "^5.11.0", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.20", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.20", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -3326,7 +3387,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3347,11 +3408,12 @@ } }, "node_modules/@mui/types": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz", - "integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", + "license": "MIT", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3360,13 +3422,13 @@ } }, "node_modules/@mui/utils": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz", - "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.20.tgz", + "integrity": "sha512-mAbYx0sovrnpAu1zHc3MDIhPqL8RPVC5W5xcO1b7PiSCJPtckIZmBkp8hefamAvUiAV8gpfMOM6Zb+eSisbI2A==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -3375,10 +3437,16 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -3501,20 +3569,25 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@react-aria/ssr": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.4.1.tgz", - "integrity": "sha512-NmhoilMDyIfQiOSdQgxpVH2tC2u85Y0mVijtBNbI9kcDYLEiW/r6vKYVKtkyU+C4qobXhGMPfZ70PTc0lysSVA==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", + "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", + "license": "Apache-2.0", "dependencies": { - "@swc/helpers": "^0.4.14" + "@swc/helpers": "^0.5.0" + }, + "engines": { + "node": ">= 12" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" @@ -3529,29 +3602,31 @@ } }, "node_modules/@restart/hooks": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.8.tgz", - "integrity": "sha512-Ivvp1FZ0Lja80iUTYAhbzy+stxwO7FbPHP95ypCtIh0wyOLiayQywXhVJ2ZYP5S1AjW2GmKHeRU4UglMwTG2sA==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", + "license": "MIT", "dependencies": { - "dequal": "^2.0.2" + "dequal": "^2.0.3" }, "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@restart/ui": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.5.4.tgz", - "integrity": "sha512-ziNtXY2PrjXrRUfR1D/ry1v1i5IF+kfMcH9d1kIcU2lOELfmDsVb+fzbyEDz3yKvKuqkphTunVDuLdYRJ0YsAg==", + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.9.tgz", + "integrity": "sha512-mUbygUsJcRurjZCt1f77gg4DpheD1D+Sc7J3JjAkysUj7t8m4EBJVOqWC9788Qtbc69cJ+HlJc6jBguKwS8Mcw==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.4.1", - "@restart/hooks": "^0.4.7", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", "@types/warning": "^3.0.0", "dequal": "^2.0.3", "dom-helpers": "^5.2.0", - "uncontrollable": "^7.2.1", + "uncontrollable": "^8.0.1", "warning": "^4.0.3" }, "peerDependencies": { @@ -3559,6 +3634,15 @@ "react-dom": ">=16.14.0" } }, + "node_modules/@restart/ui/node_modules/uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.14.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -4038,9 +4122,10 @@ } }, "node_modules/@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", + "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", + "license": "Apache-2.0", "dependencies": { "tslib": "^2.4.0" } @@ -4331,9 +4416,10 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", + "license": "MIT" }, "node_modules/@types/q": { "version": "1.5.5", @@ -4363,18 +4449,11 @@ "csstype": "^3.0.2" } }, - "node_modules/@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "license": "MIT", "dependencies": { "@types/react": "*" } @@ -4445,9 +4524,10 @@ "dev": true }, "node_modules/@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==", + "license": "MIT" }, "node_modules/@types/ws": { "version": "8.5.4", @@ -6384,9 +6464,10 @@ } }, "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -7112,9 +7193,10 @@ "dev": true }, "node_modules/csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/custom-event-polyfill": { "version": "1.0.7", @@ -7548,6 +7630,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } @@ -16060,9 +16143,10 @@ } }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -16088,20 +16172,21 @@ } }, "node_modules/react-bootstrap": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.7.0.tgz", - "integrity": "sha512-Jcrn6aUuRVBeSB6dzKODKZU1TONOdhAxu0IDm4Sv74SJUm98dMdhSotF2SNvFEADANoR+stV+7TK6SNX1wWu5w==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.2.tgz", + "integrity": "sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA==", + "license": "MIT", "dependencies": { - "@babel/runtime": "^7.17.2", - "@restart/hooks": "^0.4.6", - "@restart/ui": "^1.4.1", - "@types/react-transition-group": "^4.4.4", - "classnames": "^2.3.1", + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.8", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", "prop-types": "^15.8.1", "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.2", + "react-transition-group": "^4.4.5", "uncontrollable": "^7.2.1", "warning": "^4.0.3" }, @@ -16243,15 +16328,16 @@ } }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-error-overlay": { @@ -16598,7 +16684,8 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true }, "node_modules/regenerator-transform": { "version": "0.15.1", @@ -17071,9 +17158,10 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } @@ -18505,6 +18593,7 @@ "version": "7.2.1", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.6.3", "@types/react": ">=16.9.11", @@ -20984,11 +21073,18 @@ } }, "@babel/runtime": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz", - "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", + "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + } } }, "@babel/template": { @@ -21196,15 +21292,22 @@ } }, "@emotion/cache": { - "version": "11.10.5", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz", - "integrity": "sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "requires": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.3" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + }, + "dependencies": { + "stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + } } }, "@emotion/hash": { @@ -21221,9 +21324,9 @@ } }, "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/react": { "version": "11.10.5", @@ -21253,9 +21356,9 @@ } }, "@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "@emotion/styled": { "version": "11.10.5", @@ -21287,14 +21390,14 @@ "requires": {} }, "@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@eslint/eslintrc": { "version": "1.4.1", @@ -21327,6 +21430,36 @@ } } }, + "@floating-ui/core": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz", + "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==", + "requires": { + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/dom": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz", + "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==", + "requires": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/react-dom": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", + "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", + "requires": { + "@floating-ui/dom": "^1.0.0" + } + }, + "@floating-ui/utils": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", + "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -21987,94 +22120,92 @@ } }, "@mui/base": { - "version": "5.0.0-alpha.116", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.116.tgz", - "integrity": "sha512-VwhifWdrfHc4/ZdqRZ4Gf+7P39sovNN24By1YVZdvJ9fvp0Sr8sNftGUCjYXXz+xCXVBQDXvhfxMwZrj2MvJvA==", + "version": "5.0.0-beta.40", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.40.tgz", + "integrity": "sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==", "requires": { - "@babel/runtime": "^7.20.7", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "@popperjs/core": "^2.11.6", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" } }, "@mui/core-downloads-tracker": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.11.7.tgz", - "integrity": "sha512-lZgX7XQTk0zVcpwEa80r+T4y09dosnUxWvFPSikU/2Hh5wnyNOek8WfJwGCNsaRiXJHMi5eHY+z8oku4u5lgNw==" + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.20.tgz", + "integrity": "sha512-DoL2ppgldL16utL8nNyj/P12f8mCNdx/Hb/AJnX9rLY4b52hCMIx1kH83pbXQ6uMy6n54M3StmEbvSGoj2OFuA==" }, "@mui/material": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.11.7.tgz", - "integrity": "sha512-wDv7Pc6kMe9jeWkmCLt4JChd1lPc2u23JQHpB35L2VwQowpNFoDfIwqi0sYCnZTMKlRc7lza8LqwSwHl2G52Rw==", + "version": "5.15.18", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.18.tgz", + "integrity": "sha512-n+/dsiqux74fFfcRUJjok+ieNQ7+BEk6/OwX9cLcLvriZrZb+/7Y8+Fd2HlUUbn5N0CDurgAHm0VH1DqyJ9HAw==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/base": "5.0.0-alpha.116", - "@mui/core-downloads-tracker": "^5.11.7", - "@mui/system": "^5.11.7", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.40", + "@mui/core-downloads-tracker": "^5.15.18", + "@mui/system": "^5.15.15", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.14", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" } }, "@mui/private-theming": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.11.7.tgz", - "integrity": "sha512-XzRTSZdc8bhuUdjablTNv3kFkZ/XIMlKkOqqJCU0G8W3tWGXpau2DXkafPd1ddjPhF9zF3qLKNGgKCChYItjgA==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.20.tgz", + "integrity": "sha512-BK8F94AIqSrnaPYXf2KAOjGZJgWfvqAVQ2gVR3EryvQFtuBnG6RwodxrCvd3B48VuMy6Wsk897+lQMUxJyk+6g==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/utils": "^5.11.7", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.20", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.11.0.tgz", - "integrity": "sha512-AF06K60Zc58qf0f7X+Y/QjaHaZq16znliLnGc9iVrV/+s8Ln/FCoeNuFvhlCbZZQ5WQcJvcy59zp0nXrklGGPQ==", + "version": "5.15.14", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.14.tgz", + "integrity": "sha512-RILkuVD8gY6PvjZjqnWhz8fu68dVkqhM5+jYWfB5yhlSQKg+2rHkmEwm75XIeAqI3qwOndK6zELK5H6Zxn4NHw==", "requires": { - "@babel/runtime": "^7.20.6", - "@emotion/cache": "^11.10.5", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" } }, "@mui/system": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.11.7.tgz", - "integrity": "sha512-uGB6hBxGlAdlmbLdTtUZYNPXkgQGGnKxHdkRATqsu7UlCxNsc/yS5NCEWy/3c4pnelD1LDLD39WrntP9mwhfkQ==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.20.tgz", + "integrity": "sha512-LoMq4IlAAhxzL2VNUDBTQxAb4chnBe8JvRINVNDiMtHE2PiPOoHlhOPutSxEbaL5mkECPVWSv6p8JEV+uykwIA==", "requires": { - "@babel/runtime": "^7.20.7", - "@mui/private-theming": "^5.11.7", - "@mui/styled-engine": "^5.11.0", - "@mui/types": "^7.2.3", - "@mui/utils": "^5.11.7", - "clsx": "^1.2.1", - "csstype": "^3.1.1", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.20", + "@mui/styled-engine": "^5.15.14", + "@mui/types": "^7.2.14", + "@mui/utils": "^5.15.20", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" } }, "@mui/types": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.3.tgz", - "integrity": "sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==", + "version": "7.2.14", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.14.tgz", + "integrity": "sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ==", "requires": {} }, "@mui/utils": { - "version": "5.11.7", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.11.7.tgz", - "integrity": "sha512-8uyNDeVHZA804Ego20Erv8TpxlbqTe/EbhTI2H1UYr4/RiIbBprat8W4Qqr2UQIsC/b3DLz+0RQ6R/E5BxEcLA==", + "version": "5.15.20", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.20.tgz", + "integrity": "sha512-mAbYx0sovrnpAu1zHc3MDIhPqL8RPVC5W5xcO1b7PiSCJPtckIZmBkp8hefamAvUiAV8gpfMOM6Zb+eSisbI2A==", "requires": { - "@babel/runtime": "^7.20.7", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" } @@ -22152,16 +22283,16 @@ } }, "@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@react-aria/ssr": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.4.1.tgz", - "integrity": "sha512-NmhoilMDyIfQiOSdQgxpVH2tC2u85Y0mVijtBNbI9kcDYLEiW/r6vKYVKtkyU+C4qobXhGMPfZ70PTc0lysSVA==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.4.tgz", + "integrity": "sha512-4jmAigVq409qcJvQyuorsmBR4+9r3+JEC60wC+Y0MZV0HCtTmm8D9guYXlJMdx0SSkgj0hHAyFm/HvPNFofCoQ==", "requires": { - "@swc/helpers": "^0.4.14" + "@swc/helpers": "^0.5.0" } }, "@remix-run/router": { @@ -22170,27 +22301,35 @@ "integrity": "sha512-+eun1Wtf72RNRSqgU7qM2AMX/oHp+dnx7BHk1qhK5ZHzdHTUU4LA1mGG1vT+jMc8sbhG3orvsfOmryjzx2PzQw==" }, "@restart/hooks": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.8.tgz", - "integrity": "sha512-Ivvp1FZ0Lja80iUTYAhbzy+stxwO7FbPHP95ypCtIh0wyOLiayQywXhVJ2ZYP5S1AjW2GmKHeRU4UglMwTG2sA==", + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz", + "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==", "requires": { - "dequal": "^2.0.2" + "dequal": "^2.0.3" } }, "@restart/ui": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.5.4.tgz", - "integrity": "sha512-ziNtXY2PrjXrRUfR1D/ry1v1i5IF+kfMcH9d1kIcU2lOELfmDsVb+fzbyEDz3yKvKuqkphTunVDuLdYRJ0YsAg==", + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.9.tgz", + "integrity": "sha512-mUbygUsJcRurjZCt1f77gg4DpheD1D+Sc7J3JjAkysUj7t8m4EBJVOqWC9788Qtbc69cJ+HlJc6jBguKwS8Mcw==", "requires": { - "@babel/runtime": "^7.20.7", + "@babel/runtime": "^7.21.0", "@popperjs/core": "^2.11.6", - "@react-aria/ssr": "^3.4.1", - "@restart/hooks": "^0.4.7", + "@react-aria/ssr": "^3.5.0", + "@restart/hooks": "^0.4.9", "@types/warning": "^3.0.0", "dequal": "^2.0.3", "dom-helpers": "^5.2.0", - "uncontrollable": "^7.2.1", + "uncontrollable": "^8.0.1", "warning": "^4.0.3" + }, + "dependencies": { + "uncontrollable": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz", + "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==", + "requires": {} + } } }, "@rollup/plugin-babel": { @@ -22530,9 +22669,9 @@ } }, "@swc/helpers": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.14.tgz", - "integrity": "sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.11.tgz", + "integrity": "sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==", "requires": { "tslib": "^2.4.0" } @@ -22817,9 +22956,9 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "@types/q": { "version": "1.5.5", @@ -22849,18 +22988,10 @@ "csstype": "^3.0.2" } }, - "@types/react-is": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", - "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", - "requires": { - "@types/react": "*" - } - }, "@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "requires": { "@types/react": "*" } @@ -22931,9 +23062,9 @@ "dev": true }, "@types/warning": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz", - "integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz", + "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==" }, "@types/ws": { "version": "8.5.4", @@ -24375,9 +24506,9 @@ } }, "clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, "co": { "version": "4.6.0", @@ -24907,9 +25038,9 @@ } }, "csstype": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", - "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "custom-event-polyfill": { "version": "1.0.7", @@ -31395,9 +31526,9 @@ } }, "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "requires": { "loose-envify": "^1.1.0" } @@ -31417,20 +31548,20 @@ } }, "react-bootstrap": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.7.0.tgz", - "integrity": "sha512-Jcrn6aUuRVBeSB6dzKODKZU1TONOdhAxu0IDm4Sv74SJUm98dMdhSotF2SNvFEADANoR+stV+7TK6SNX1wWu5w==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.2.tgz", + "integrity": "sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA==", "requires": { - "@babel/runtime": "^7.17.2", - "@restart/hooks": "^0.4.6", - "@restart/ui": "^1.4.1", - "@types/react-transition-group": "^4.4.4", - "classnames": "^2.3.1", + "@babel/runtime": "^7.22.5", + "@restart/hooks": "^0.4.9", + "@restart/ui": "^1.6.8", + "@types/react-transition-group": "^4.4.6", + "classnames": "^2.3.2", "dom-helpers": "^5.2.1", "invariant": "^2.2.4", "prop-types": "^15.8.1", "prop-types-extra": "^1.1.0", - "react-transition-group": "^4.4.2", + "react-transition-group": "^4.4.5", "uncontrollable": "^7.2.1", "warning": "^4.0.3" } @@ -31533,12 +31664,12 @@ } }, "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "requires": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" } }, "react-error-overlay": { @@ -31805,7 +31936,8 @@ "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", + "dev": true }, "regenerator-transform": { "version": "0.15.1", @@ -32119,9 +32251,9 @@ } }, "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "requires": { "loose-envify": "^1.1.0" } diff --git a/ui/package.json b/ui/package.json index 6a07f7a7..ba5e5358 100644 --- a/ui/package.json +++ b/ui/package.json @@ -7,16 +7,16 @@ "@emotion/styled": "^11.10.4", "@mdi/js": "^7.0.96", "@mdi/react": "^1.6.1", - "@mui/material": "^5.10.4", + "@mui/material": "^5.15.18", "bootstrap": "^5.2.3", "dagre": "^0.8.5", "eslint-config-react-app": "^7.0.1", "humanize-duration": "^3.27.3", "moment": "^2.29.4", - "react": "^18.2.0", - "react-bootstrap": "^2.7.0", + "react": "^18.3.1", + "react-bootstrap": "^2.10.2", "react-data-table-component": "^7.5.2", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-force-graph": "^1.43.0", "react-router-dom": "^6.4.0", "react-sizeme": "^3.0.2", diff --git a/ui/src/api/types.js b/ui/src/api/types.js index 153ff723..625431a6 100644 --- a/ui/src/api/types.js +++ b/ui/src/api/types.js @@ -53,6 +53,7 @@ * @property {string} zId * @property {string} url_template * @property {string} public_name + * @property {string} permissionMode */ /** diff --git a/ui/src/console/detail/account/ActionsTab.js b/ui/src/console/detail/account/ActionsTab.js index 4a3a3605..0b623b92 100644 --- a/ui/src/console/detail/account/ActionsTab.js +++ b/ui/src/console/detail/account/ActionsTab.js @@ -14,7 +14,7 @@ const ActionsTab = (props) => { return (
-
+

Change Password?

Change the password used to log into the zrok web console.