diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 9f1569a12..d13131b38 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -29,19 +29,29 @@ jobs: - name: setup-node uses: actions/setup-node@v4 with: - node-version: 18.x + node-version: 20.x - name: install ui node modules shell: bash run: npm install working-directory: ui - - name: build node ui + - name: build ui shell: bash run: npm run build working-directory: ui env: CI: "true" + + - name: install agent ui node modules + shell: bash + run: npm install + working-directory: agent/agentUi + + - name: build agent ui + shell: bash + run: npm run build + working-directory: agent/agentUi - name: go install shell: bash diff --git a/CHANGELOG.md b/CHANGELOG.md index 26c1a0b40..6f808109e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # CHANGELOG +## v1.0.0 + +MAJOR RELEASE: zrok reaches version 1.0.0! + +FEATURE: New "zrok Agent", a background manager process for your zrok environments, which allows you to easily manage and work with multiple `zrok share` and `zrok access` processes. New `--subordinate` flag added to `zrok share [public|private|reserved]` and `zrok access private` to operate in a mode that allows an Agent to manage shares and accesses (https://github.com/openziti/zrok/issues/463) + +FEATURE: New "zrok Agent UI" a web-based user interface for the zrok Agent, which allows creating and releasing shares and accesses through a web browser. This is just an initial chunk of the new Agent UI, and is considered a "minimum viable" version of this interface (https://github.com/openziti/zrok/issues/221) + +FEATURE: `zrok share [public|private|reserved]` and `zrok access private` now auto-detect if the zrok Agent is running in an environment and will automatically service share and access requests through the Agent, rather than in-process if the Agent is running. If the Agent is not running, operation remains as it was in `v0.4.x` and the share or access is handled in-process. New `--force-agent` and `--force-local` flags exist to skip Agent detection and manually select an operating mode (https://github.com/openziti/zrok/issues/751) + +FEATURE `zrok access private` supports a new `--auto` mode, which can automatically find an available open address/port to bind the frontend listener on. Also includes `--auto-address`, `--auto-start-port`, and `--auto-end-port` features with sensible defaults. Supported by both the agent and local operating modes (https://github.com/openziti/zrok/issues/780) + ## v0.4.47 CHANGE: the Docker instance will wait for the ziti container healthy status (contribution from Ben Wong @bwong365 - https://github.com/openziti/zrok/pull/790) @@ -11,7 +23,7 @@ CHANGE: Add usage hint in `zrok config get --help` to clarify how to list all va CHANGE: The Python SDK's `Overview()` function was refactored as a class method (https://github.com/openziti/zrok/pull/846). FEATURE: The Python SDK now includes a `ProxyShare` class providing an HTTP proxy for public and private shares and a - Jupyter notebook example (https://github.com/openziti/zrok/pull/847). +Jupyter notebook example (https://github.com/openziti/zrok/pull/847). FIX: PyPi publishing was failing due to a CI issue (https://github.com/openziti/zrok/issues/849) diff --git a/agent/access.go b/agent/access.go new file mode 100644 index 000000000..45a4da664 --- /dev/null +++ b/agent/access.go @@ -0,0 +1,30 @@ +package agent + +import ( + "github.com/michaelquigley/pfxlog" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" +) + +type access struct { + frontendToken string + token string + bindAddress string + autoMode bool + autoAddress string + autoStartPort uint16 + autoEndPort uint16 + responseHeaders []string + + process *proctree.Child + sub *subordinate.MessageHandler + + agent *Agent +} + +func (a *access) monitor() { + if err := proctree.WaitChild(a.process); err != nil { + pfxlog.ChannelLogger(a.token).Error(err) + } + a.agent.rmAccess <- a +} diff --git a/agent/accessPrivate.go b/agent/accessPrivate.go new file mode 100644 index 000000000..5cb9b9ae2 --- /dev/null +++ b/agent/accessPrivate.go @@ -0,0 +1,93 @@ +package agent + +import ( + "context" + "errors" + "fmt" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" + "github.com/openziti/zrok/environment" + "github.com/sirupsen/logrus" + "os" +) + +func (i *agentGrpcImpl) AccessPrivate(_ context.Context, req *agentGrpc.AccessPrivateRequest) (*agentGrpc.AccessPrivateResponse, error) { + root, err := environment.LoadRoot() + if err != nil { + return nil, err + } + + if !root.IsEnabled() { + return nil, errors.New("unable to load environment; did you 'zrok enable'?") + } + + accCmd := []string{os.Args[0], "access", "private", "--subordinate", "-b", req.BindAddress, req.Token} + if req.AutoMode { + accCmd = append(accCmd, "--auto", "--auto-address", req.AutoAddress, "--auto-start-port", fmt.Sprintf("%v", req.AutoStartPort)) + accCmd = append(accCmd, "--auto-end-port", fmt.Sprintf("%v", req.AutoEndPort)) + } + logrus.Info(accCmd) + + acc := &access{ + token: req.Token, + bindAddress: req.BindAddress, + autoMode: req.AutoMode, + autoAddress: req.AutoAddress, + autoStartPort: uint16(req.AutoStartPort), + autoEndPort: uint16(req.AutoEndPort), + responseHeaders: req.ResponseHeaders, + sub: subordinate.NewMessageHandler(), + agent: i.agent, + } + acc.sub.MessageHandler = func(msg subordinate.Message) { + logrus.Info(msg) + } + var bootErr error + acc.sub.BootHandler = func(msgType string, msg subordinate.Message) { + switch msgType { + case subordinate.BootMessage: + if v, found := msg["frontend_token"]; found { + if str, ok := v.(string); ok { + acc.frontendToken = str + } + } + if v, found := msg["bind_address"]; found { + if sr, ok := v.(string); ok { + acc.bindAddress = sr + } + } + + case subordinate.ErrorMessage: + if v, found := msg[subordinate.ErrorMessage]; found { + if str, ok := v.(string); ok { + bootErr = errors.New(str) + } + } + } + } + acc.sub.MalformedHandler = func(msg subordinate.Message) { + logrus.Error(msg) + } + + logrus.Infof("executing '%v'", accCmd) + + acc.process, err = proctree.StartChild(acc.sub.Tail, accCmd...) + if err != nil { + return nil, err + } + + <-acc.sub.BootComplete + + if bootErr == nil { + go acc.monitor() + i.agent.addAccess <- acc + return &agentGrpc.AccessPrivateResponse{FrontendToken: acc.frontendToken}, nil + + } else { + if err := proctree.WaitChild(acc.process); err != nil { + logrus.Errorf("error joining: %v", err) + } + return nil, fmt.Errorf("unable to start access: %v", bootErr) + } +} diff --git a/agent/agent.go b/agent/agent.go new file mode 100644 index 000000000..7d9d616a4 --- /dev/null +++ b/agent/agent.go @@ -0,0 +1,197 @@ +package agent + +import ( + "context" + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/agentUi" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/environment/env_core" + "github.com/openziti/zrok/sdk/golang/sdk" + "github.com/openziti/zrok/util" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "net" + "net/http" + "os" +) + +type Agent struct { + cfg *AgentConfig + httpEndpoint string + root env_core.Root + agentSocket string + shares map[string]*share + addShare chan *share + rmShare chan *share + accesses map[string]*access + addAccess chan *access + rmAccess chan *access +} + +func NewAgent(cfg *AgentConfig, root env_core.Root) (*Agent, error) { + if !root.IsEnabled() { + return nil, errors.Errorf("unable to load environment; did you 'zrok enable'?") + } + return &Agent{ + cfg: cfg, + root: root, + shares: make(map[string]*share), + addShare: make(chan *share), + rmShare: make(chan *share), + accesses: make(map[string]*access), + addAccess: make(chan *access), + rmAccess: make(chan *access), + }, nil +} + +func (a *Agent) Run() error { + logrus.Infof("started") + + if err := proctree.Init("zrok Agent"); err != nil { + return err + } + + agentSocket, err := a.root.AgentSocket() + if err != nil { + return err + } + l, err := net.Listen("unix", agentSocket) + if err != nil { + return err + } + a.agentSocket = agentSocket + + go a.manager() + go a.gateway(a.cfg) + + srv := grpc.NewServer() + agentGrpc.RegisterAgentServer(srv, &agentGrpcImpl{agent: a}) + if err := srv.Serve(l); err != nil { + return err + } + + return nil +} + +func (a *Agent) Shutdown() { + logrus.Infof("stopping") + + if err := os.Remove(a.agentSocket); err != nil { + logrus.Warnf("unable to remove agent socket: %v", err) + } + for _, shr := range a.shares { + logrus.Debugf("stopping share '%v'", shr.token) + a.rmShare <- shr + } + for _, acc := range a.accesses { + logrus.Debugf("stopping access '%v'", acc.token) + a.rmAccess <- acc + } +} + +func (a *Agent) Config() *AgentConfig { + return a.cfg +} + +func (a *Agent) gateway(cfg *AgentConfig) { + logrus.Info("started") + defer logrus.Warn("exited") + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + mux := runtime.NewServeMux() + opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} + endpoint := "unix:" + a.agentSocket + logrus.Debugf("endpoint: '%v'", endpoint) + if err := agentGrpc.RegisterAgentHandlerFromEndpoint(ctx, mux, "unix:"+a.agentSocket, opts); err != nil { + logrus.Fatalf("unable to register gateway: %v", err) + } + + listener, err := util.AutoListener("tcp", cfg.ConsoleAddress, cfg.ConsoleStartPort, cfg.ConsoleEndPort) + if err != nil { + logrus.Fatalf("unable to create a listener: %v", err) + } + a.httpEndpoint = listener.Addr().String() + + if err := http.Serve(listener, agentUi.Middleware(mux)); err != nil { + logrus.Error(err) + } +} + +func (a *Agent) manager() { + logrus.Info("started") + defer logrus.Warn("exited") + + for { + select { + case inShare := <-a.addShare: + logrus.Infof("adding new share '%v'", inShare.token) + a.shares[inShare.token] = inShare + + case outShare := <-a.rmShare: + if shr, found := a.shares[outShare.token]; found { + logrus.Infof("removing share '%v'", shr.token) + if err := proctree.StopChild(shr.process); err != nil { + logrus.Errorf("error stopping share '%v': %v", shr.token, err) + } + if err := proctree.WaitChild(shr.process); err != nil { + logrus.Errorf("error joining share '%v': %v", shr.token, err) + } + if !shr.reserved { + if err := a.deleteShare(shr.token); err != nil { + logrus.Errorf("error deleting share '%v': %v", shr.token, err) + } + } + delete(a.shares, shr.token) + } else { + logrus.Debug("skipping unidentified (orphaned) share removal") + } + + case inAccess := <-a.addAccess: + logrus.Infof("adding new access '%v'", inAccess.frontendToken) + a.accesses[inAccess.frontendToken] = inAccess + + case outAccess := <-a.rmAccess: + if acc, found := a.accesses[outAccess.frontendToken]; found { + logrus.Infof("removing access '%v'", acc.frontendToken) + if err := proctree.StopChild(acc.process); err != nil { + logrus.Errorf("error stopping access '%v': %v", acc.frontendToken, err) + } + if err := proctree.WaitChild(acc.process); err != nil { + logrus.Errorf("error joining access '%v': %v", acc.frontendToken, err) + } + if err := a.deleteAccess(acc.token, acc.frontendToken); err != nil { + logrus.Errorf("error deleting access '%v': %v", acc.frontendToken, err) + } + delete(a.accesses, acc.frontendToken) + } else { + logrus.Debug("skipping unidentified (orphaned) access removal") + } + } + } +} + +func (a *Agent) deleteShare(token string) error { + logrus.Debugf("deleting share '%v'", token) + if err := sdk.DeleteShare(a.root, &sdk.Share{Token: token}); err != nil { + return err + } + return nil +} + +func (a *Agent) deleteAccess(token, frontendToken string) error { + logrus.Debugf("deleting access '%v'", frontendToken) + if err := sdk.DeleteAccess(a.root, &sdk.Access{Token: frontendToken, ShareToken: token}); err != nil { + return err + } + return nil +} + +type agentGrpcImpl struct { + agentGrpc.UnimplementedAgentServer + agent *Agent +} diff --git a/agent/agentClient/agentClient.go b/agent/agentClient/agentClient.go new file mode 100644 index 000000000..110eef0a9 --- /dev/null +++ b/agent/agentClient/agentClient.go @@ -0,0 +1,51 @@ +package agentClient + +import ( + "context" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/build" + "github.com/openziti/zrok/environment/env_core" + "github.com/pkg/errors" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/resolver" + "net" + "strings" +) + +func NewClient(root env_core.Root) (client agentGrpc.AgentClient, conn *grpc.ClientConn, err error) { + agentSocket, err := root.AgentSocket() + if err != nil { + return nil, nil, err + } + + opts := []grpc.DialOption{ + grpc.WithContextDialer(func(_ context.Context, addr string) (net.Conn, error) { + return net.Dial("unix", addr) + }), + grpc.WithTransportCredentials(insecure.NewCredentials()), + } + resolver.SetDefaultScheme("passthrough") + conn, err = grpc.NewClient(agentSocket, opts...) + if err != nil { + return nil, nil, err + } + + return agentGrpc.NewAgentClient(conn), conn, nil +} + +func IsAgentRunning(root env_core.Root) (bool, error) { + client, conn, err := NewClient(root) + if err != nil { + return false, err + } + defer func() { _ = conn.Close() }() + resp, err := client.Version(context.Background(), &agentGrpc.VersionRequest{}) + if err != nil { + return false, nil + } + if !strings.HasPrefix(resp.GetV(), build.Series) { + return false, errors.Errorf("agent reported version '%v'; we expected version '%v'", resp.GetV(), build.Series) + } + return true, nil +} diff --git a/agent/agentGrpc/agent.pb.go b/agent/agentGrpc/agent.pb.go new file mode 100644 index 000000000..e787e3bb4 --- /dev/null +++ b/agent/agentGrpc/agent.pb.go @@ -0,0 +1,1625 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.2 +// protoc v5.27.3 +// source: agent/agentGrpc/agent.proto + +package agentGrpc + +import ( + _ "google.golang.org/genproto/googleapis/api/annotations" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AccessDetail struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FrontendToken string `protobuf:"bytes,1,opt,name=frontendToken,proto3" json:"frontendToken,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + BindAddress string `protobuf:"bytes,3,opt,name=bindAddress,proto3" json:"bindAddress,omitempty"` + ResponseHeaders []string `protobuf:"bytes,4,rep,name=responseHeaders,proto3" json:"responseHeaders,omitempty"` +} + +func (x *AccessDetail) Reset() { + *x = AccessDetail{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessDetail) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessDetail) ProtoMessage() {} + +func (x *AccessDetail) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessDetail.ProtoReflect.Descriptor instead. +func (*AccessDetail) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{0} +} + +func (x *AccessDetail) GetFrontendToken() string { + if x != nil { + return x.FrontendToken + } + return "" +} + +func (x *AccessDetail) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *AccessDetail) GetBindAddress() string { + if x != nil { + return x.BindAddress + } + return "" +} + +func (x *AccessDetail) GetResponseHeaders() []string { + if x != nil { + return x.ResponseHeaders + } + return nil +} + +type AccessPrivateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FrontendToken string `protobuf:"bytes,1,opt,name=frontendToken,proto3" json:"frontendToken,omitempty"` +} + +func (x *AccessPrivateResponse) Reset() { + *x = AccessPrivateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessPrivateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessPrivateResponse) ProtoMessage() {} + +func (x *AccessPrivateResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessPrivateResponse.ProtoReflect.Descriptor instead. +func (*AccessPrivateResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{1} +} + +func (x *AccessPrivateResponse) GetFrontendToken() string { + if x != nil { + return x.FrontendToken + } + return "" +} + +type AccessPrivateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + BindAddress string `protobuf:"bytes,2,opt,name=bindAddress,proto3" json:"bindAddress,omitempty"` + AutoMode bool `protobuf:"varint,3,opt,name=autoMode,proto3" json:"autoMode,omitempty"` + AutoAddress string `protobuf:"bytes,4,opt,name=autoAddress,proto3" json:"autoAddress,omitempty"` + AutoStartPort uint32 `protobuf:"varint,5,opt,name=autoStartPort,proto3" json:"autoStartPort,omitempty"` + AutoEndPort uint32 `protobuf:"varint,6,opt,name=autoEndPort,proto3" json:"autoEndPort,omitempty"` + ResponseHeaders []string `protobuf:"bytes,7,rep,name=responseHeaders,proto3" json:"responseHeaders,omitempty"` +} + +func (x *AccessPrivateRequest) Reset() { + *x = AccessPrivateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AccessPrivateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AccessPrivateRequest) ProtoMessage() {} + +func (x *AccessPrivateRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AccessPrivateRequest.ProtoReflect.Descriptor instead. +func (*AccessPrivateRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{2} +} + +func (x *AccessPrivateRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *AccessPrivateRequest) GetBindAddress() string { + if x != nil { + return x.BindAddress + } + return "" +} + +func (x *AccessPrivateRequest) GetAutoMode() bool { + if x != nil { + return x.AutoMode + } + return false +} + +func (x *AccessPrivateRequest) GetAutoAddress() string { + if x != nil { + return x.AutoAddress + } + return "" +} + +func (x *AccessPrivateRequest) GetAutoStartPort() uint32 { + if x != nil { + return x.AutoStartPort + } + return 0 +} + +func (x *AccessPrivateRequest) GetAutoEndPort() uint32 { + if x != nil { + return x.AutoEndPort + } + return 0 +} + +func (x *AccessPrivateRequest) GetResponseHeaders() []string { + if x != nil { + return x.ResponseHeaders + } + return nil +} + +type ReleaseAccessRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FrontendToken string `protobuf:"bytes,1,opt,name=frontendToken,proto3" json:"frontendToken,omitempty"` +} + +func (x *ReleaseAccessRequest) Reset() { + *x = ReleaseAccessRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseAccessRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseAccessRequest) ProtoMessage() {} + +func (x *ReleaseAccessRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReleaseAccessRequest.ProtoReflect.Descriptor instead. +func (*ReleaseAccessRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{3} +} + +func (x *ReleaseAccessRequest) GetFrontendToken() string { + if x != nil { + return x.FrontendToken + } + return "" +} + +type ReleaseAccessResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReleaseAccessResponse) Reset() { + *x = ReleaseAccessResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseAccessResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseAccessResponse) ProtoMessage() {} + +func (x *ReleaseAccessResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReleaseAccessResponse.ProtoReflect.Descriptor instead. +func (*ReleaseAccessResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{4} +} + +type ReleaseShareRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *ReleaseShareRequest) Reset() { + *x = ReleaseShareRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseShareRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseShareRequest) ProtoMessage() {} + +func (x *ReleaseShareRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReleaseShareRequest.ProtoReflect.Descriptor instead. +func (*ReleaseShareRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{5} +} + +func (x *ReleaseShareRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type ReleaseShareResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ReleaseShareResponse) Reset() { + *x = ReleaseShareResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReleaseShareResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReleaseShareResponse) ProtoMessage() {} + +func (x *ReleaseShareResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReleaseShareResponse.ProtoReflect.Descriptor instead. +func (*ReleaseShareResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{6} +} + +type ShareDetail struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + ShareMode string `protobuf:"bytes,2,opt,name=shareMode,proto3" json:"shareMode,omitempty"` + BackendMode string `protobuf:"bytes,3,opt,name=backendMode,proto3" json:"backendMode,omitempty"` + Reserved bool `protobuf:"varint,4,opt,name=reserved,proto3" json:"reserved,omitempty"` + FrontendEndpoint []string `protobuf:"bytes,5,rep,name=frontendEndpoint,proto3" json:"frontendEndpoint,omitempty"` + BackendEndpoint string `protobuf:"bytes,6,opt,name=backendEndpoint,proto3" json:"backendEndpoint,omitempty"` + Closed bool `protobuf:"varint,7,opt,name=closed,proto3" json:"closed,omitempty"` + Status string `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"` +} + +func (x *ShareDetail) Reset() { + *x = ShareDetail{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareDetail) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareDetail) ProtoMessage() {} + +func (x *ShareDetail) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareDetail.ProtoReflect.Descriptor instead. +func (*ShareDetail) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{7} +} + +func (x *ShareDetail) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ShareDetail) GetShareMode() string { + if x != nil { + return x.ShareMode + } + return "" +} + +func (x *ShareDetail) GetBackendMode() string { + if x != nil { + return x.BackendMode + } + return "" +} + +func (x *ShareDetail) GetReserved() bool { + if x != nil { + return x.Reserved + } + return false +} + +func (x *ShareDetail) GetFrontendEndpoint() []string { + if x != nil { + return x.FrontendEndpoint + } + return nil +} + +func (x *ShareDetail) GetBackendEndpoint() string { + if x != nil { + return x.BackendEndpoint + } + return "" +} + +func (x *ShareDetail) GetClosed() bool { + if x != nil { + return x.Closed + } + return false +} + +func (x *ShareDetail) GetStatus() string { + if x != nil { + return x.Status + } + return "" +} + +type SharePrivateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + BackendMode string `protobuf:"bytes,2,opt,name=backendMode,proto3" json:"backendMode,omitempty"` + Insecure bool `protobuf:"varint,3,opt,name=insecure,proto3" json:"insecure,omitempty"` + Closed bool `protobuf:"varint,4,opt,name=closed,proto3" json:"closed,omitempty"` + AccessGrants []string `protobuf:"bytes,5,rep,name=accessGrants,proto3" json:"accessGrants,omitempty"` +} + +func (x *SharePrivateRequest) Reset() { + *x = SharePrivateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SharePrivateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SharePrivateRequest) ProtoMessage() {} + +func (x *SharePrivateRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SharePrivateRequest.ProtoReflect.Descriptor instead. +func (*SharePrivateRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{8} +} + +func (x *SharePrivateRequest) GetTarget() string { + if x != nil { + return x.Target + } + return "" +} + +func (x *SharePrivateRequest) GetBackendMode() string { + if x != nil { + return x.BackendMode + } + return "" +} + +func (x *SharePrivateRequest) GetInsecure() bool { + if x != nil { + return x.Insecure + } + return false +} + +func (x *SharePrivateRequest) GetClosed() bool { + if x != nil { + return x.Closed + } + return false +} + +func (x *SharePrivateRequest) GetAccessGrants() []string { + if x != nil { + return x.AccessGrants + } + return nil +} + +type SharePrivateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *SharePrivateResponse) Reset() { + *x = SharePrivateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SharePrivateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SharePrivateResponse) ProtoMessage() {} + +func (x *SharePrivateResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SharePrivateResponse.ProtoReflect.Descriptor instead. +func (*SharePrivateResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{9} +} + +func (x *SharePrivateResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type SharePublicRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target string `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + BasicAuth []string `protobuf:"bytes,2,rep,name=basicAuth,proto3" json:"basicAuth,omitempty"` + FrontendSelection []string `protobuf:"bytes,3,rep,name=frontendSelection,proto3" json:"frontendSelection,omitempty"` + BackendMode string `protobuf:"bytes,4,opt,name=backendMode,proto3" json:"backendMode,omitempty"` + Insecure bool `protobuf:"varint,5,opt,name=insecure,proto3" json:"insecure,omitempty"` + OauthProvider string `protobuf:"bytes,6,opt,name=oauthProvider,proto3" json:"oauthProvider,omitempty"` + OauthEmailAddressPatterns []string `protobuf:"bytes,7,rep,name=oauthEmailAddressPatterns,proto3" json:"oauthEmailAddressPatterns,omitempty"` + OauthCheckInterval string `protobuf:"bytes,8,opt,name=oauthCheckInterval,proto3" json:"oauthCheckInterval,omitempty"` + Closed bool `protobuf:"varint,9,opt,name=closed,proto3" json:"closed,omitempty"` + AccessGrants []string `protobuf:"bytes,10,rep,name=accessGrants,proto3" json:"accessGrants,omitempty"` +} + +func (x *SharePublicRequest) Reset() { + *x = SharePublicRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SharePublicRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SharePublicRequest) ProtoMessage() {} + +func (x *SharePublicRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SharePublicRequest.ProtoReflect.Descriptor instead. +func (*SharePublicRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{10} +} + +func (x *SharePublicRequest) GetTarget() string { + if x != nil { + return x.Target + } + return "" +} + +func (x *SharePublicRequest) GetBasicAuth() []string { + if x != nil { + return x.BasicAuth + } + return nil +} + +func (x *SharePublicRequest) GetFrontendSelection() []string { + if x != nil { + return x.FrontendSelection + } + return nil +} + +func (x *SharePublicRequest) GetBackendMode() string { + if x != nil { + return x.BackendMode + } + return "" +} + +func (x *SharePublicRequest) GetInsecure() bool { + if x != nil { + return x.Insecure + } + return false +} + +func (x *SharePublicRequest) GetOauthProvider() string { + if x != nil { + return x.OauthProvider + } + return "" +} + +func (x *SharePublicRequest) GetOauthEmailAddressPatterns() []string { + if x != nil { + return x.OauthEmailAddressPatterns + } + return nil +} + +func (x *SharePublicRequest) GetOauthCheckInterval() string { + if x != nil { + return x.OauthCheckInterval + } + return "" +} + +func (x *SharePublicRequest) GetClosed() bool { + if x != nil { + return x.Closed + } + return false +} + +func (x *SharePublicRequest) GetAccessGrants() []string { + if x != nil { + return x.AccessGrants + } + return nil +} + +type SharePublicResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + FrontendEndpoints []string `protobuf:"bytes,2,rep,name=frontendEndpoints,proto3" json:"frontendEndpoints,omitempty"` +} + +func (x *SharePublicResponse) Reset() { + *x = SharePublicResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SharePublicResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SharePublicResponse) ProtoMessage() {} + +func (x *SharePublicResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SharePublicResponse.ProtoReflect.Descriptor instead. +func (*SharePublicResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{11} +} + +func (x *SharePublicResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *SharePublicResponse) GetFrontendEndpoints() []string { + if x != nil { + return x.FrontendEndpoints + } + return nil +} + +type ShareReservedRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + OverrideEndpoint string `protobuf:"bytes,2,opt,name=overrideEndpoint,proto3" json:"overrideEndpoint,omitempty"` + Insecure bool `protobuf:"varint,3,opt,name=insecure,proto3" json:"insecure,omitempty"` +} + +func (x *ShareReservedRequest) Reset() { + *x = ShareReservedRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareReservedRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareReservedRequest) ProtoMessage() {} + +func (x *ShareReservedRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareReservedRequest.ProtoReflect.Descriptor instead. +func (*ShareReservedRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{12} +} + +func (x *ShareReservedRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ShareReservedRequest) GetOverrideEndpoint() string { + if x != nil { + return x.OverrideEndpoint + } + return "" +} + +func (x *ShareReservedRequest) GetInsecure() bool { + if x != nil { + return x.Insecure + } + return false +} + +type ShareReservedResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + BackendMode string `protobuf:"bytes,2,opt,name=backendMode,proto3" json:"backendMode,omitempty"` + ShareMode string `protobuf:"bytes,3,opt,name=shareMode,proto3" json:"shareMode,omitempty"` + FrontendEndpoints []string `protobuf:"bytes,4,rep,name=frontendEndpoints,proto3" json:"frontendEndpoints,omitempty"` + Target string `protobuf:"bytes,5,opt,name=target,proto3" json:"target,omitempty"` +} + +func (x *ShareReservedResponse) Reset() { + *x = ShareReservedResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ShareReservedResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ShareReservedResponse) ProtoMessage() {} + +func (x *ShareReservedResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ShareReservedResponse.ProtoReflect.Descriptor instead. +func (*ShareReservedResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{13} +} + +func (x *ShareReservedResponse) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ShareReservedResponse) GetBackendMode() string { + if x != nil { + return x.BackendMode + } + return "" +} + +func (x *ShareReservedResponse) GetShareMode() string { + if x != nil { + return x.ShareMode + } + return "" +} + +func (x *ShareReservedResponse) GetFrontendEndpoints() []string { + if x != nil { + return x.FrontendEndpoints + } + return nil +} + +func (x *ShareReservedResponse) GetTarget() string { + if x != nil { + return x.Target + } + return "" +} + +type StatusRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *StatusRequest) Reset() { + *x = StatusRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusRequest) ProtoMessage() {} + +func (x *StatusRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. +func (*StatusRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{14} +} + +type StatusResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Accesses []*AccessDetail `protobuf:"bytes,1,rep,name=accesses,proto3" json:"accesses,omitempty"` + Shares []*ShareDetail `protobuf:"bytes,2,rep,name=shares,proto3" json:"shares,omitempty"` +} + +func (x *StatusResponse) Reset() { + *x = StatusResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusResponse) ProtoMessage() {} + +func (x *StatusResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. +func (*StatusResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{15} +} + +func (x *StatusResponse) GetAccesses() []*AccessDetail { + if x != nil { + return x.Accesses + } + return nil +} + +func (x *StatusResponse) GetShares() []*ShareDetail { + if x != nil { + return x.Shares + } + return nil +} + +type VersionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *VersionRequest) Reset() { + *x = VersionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionRequest) ProtoMessage() {} + +func (x *VersionRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionRequest.ProtoReflect.Descriptor instead. +func (*VersionRequest) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{16} +} + +type VersionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + V string `protobuf:"bytes,1,opt,name=v,proto3" json:"v,omitempty"` + ConsoleEndpoint string `protobuf:"bytes,2,opt,name=consoleEndpoint,proto3" json:"consoleEndpoint,omitempty"` +} + +func (x *VersionResponse) Reset() { + *x = VersionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VersionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VersionResponse) ProtoMessage() {} + +func (x *VersionResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_agentGrpc_agent_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. +func (*VersionResponse) Descriptor() ([]byte, []int) { + return file_agent_agentGrpc_agent_proto_rawDescGZIP(), []int{17} +} + +func (x *VersionResponse) GetV() string { + if x != nil { + return x.V + } + return "" +} + +func (x *VersionResponse) GetConsoleEndpoint() string { + if x != nil { + return x.ConsoleEndpoint + } + return "" +} + +var File_agent_agentGrpc_agent_proto protoreflect.FileDescriptor + +var file_agent_agentGrpc_agent_proto_rawDesc = []byte{ + 0x0a, 0x1b, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x70, + 0x63, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x96, 0x01, 0x0a, 0x0c, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x12, 0x24, 0x0a, 0x0d, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x64, + 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, + 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x22, 0x3d, 0x0a, 0x15, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, + 0x0d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0xfe, 0x01, 0x0a, 0x14, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x75, 0x74, 0x6f, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x53, 0x74, 0x61, 0x72, 0x74, 0x50, + 0x6f, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x6f, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x61, 0x75, 0x74, 0x6f, + 0x45, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x61, + 0x75, 0x74, 0x6f, 0x45, 0x6e, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x22, 0x3c, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, + 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x6b, + 0x65, 0x6e, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x0a, 0x13, 0x52, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x65, + 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x85, 0x02, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, + 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, + 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x28, + 0x0a, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, + 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x13, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x12, 0x22, + 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x22, 0x2c, 0x0a, 0x14, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x22, 0x86, 0x03, 0x0a, 0x12, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x12, 0x2c, 0x0a, + 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x0a, + 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6f, 0x61, 0x75, + 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, + 0x3c, 0x0a, 0x19, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x19, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x73, 0x12, 0x2e, 0x0a, + 0x12, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6f, 0x61, 0x75, 0x74, 0x68, + 0x43, 0x68, 0x65, 0x63, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x16, 0x0a, + 0x06, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x59, 0x0a, 0x13, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x22, 0x74, 0x0a, 0x14, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, + 0x65, 0x6e, 0x12, 0x2a, 0x0a, 0x10, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x22, 0xb3, 0x01, 0x0a, 0x15, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x61, + 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x68, 0x61, 0x72, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x66, 0x72, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x64, 0x45, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x61, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x44, 0x65, + 0x74, 0x61, 0x69, 0x6c, 0x52, 0x08, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x24, + 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x44, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x52, 0x06, 0x73, 0x68, + 0x61, 0x72, 0x65, 0x73, 0x22, 0x10, 0x0a, 0x0e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x76, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x01, 0x76, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x6f, + 0x6c, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x32, 0xac, 0x05, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x5f, 0x0a, 0x0d, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x5f, 0x0a, 0x0d, + 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x15, 0x2e, + 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, + 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x5b, 0x0a, + 0x0c, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x14, 0x2e, + 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x18, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x15, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0c, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x14, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, + 0x18, 0x22, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x73, 0x68, 0x61, + 0x72, 0x65, 0x50, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x57, 0x0a, 0x0b, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x12, 0x13, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x65, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x22, 0x15, 0x2f, 0x76, 0x31, + 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x73, 0x68, 0x61, 0x72, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x12, 0x43, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0f, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x47, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x0f, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, + 0x76, 0x31, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, + 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x7a, 0x72, 0x6f, 0x6b, 0x2f, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_agent_agentGrpc_agent_proto_rawDescOnce sync.Once + file_agent_agentGrpc_agent_proto_rawDescData = file_agent_agentGrpc_agent_proto_rawDesc +) + +func file_agent_agentGrpc_agent_proto_rawDescGZIP() []byte { + file_agent_agentGrpc_agent_proto_rawDescOnce.Do(func() { + file_agent_agentGrpc_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_agentGrpc_agent_proto_rawDescData) + }) + return file_agent_agentGrpc_agent_proto_rawDescData +} + +var file_agent_agentGrpc_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_agent_agentGrpc_agent_proto_goTypes = []any{ + (*AccessDetail)(nil), // 0: AccessDetail + (*AccessPrivateResponse)(nil), // 1: AccessPrivateResponse + (*AccessPrivateRequest)(nil), // 2: AccessPrivateRequest + (*ReleaseAccessRequest)(nil), // 3: ReleaseAccessRequest + (*ReleaseAccessResponse)(nil), // 4: ReleaseAccessResponse + (*ReleaseShareRequest)(nil), // 5: ReleaseShareRequest + (*ReleaseShareResponse)(nil), // 6: ReleaseShareResponse + (*ShareDetail)(nil), // 7: ShareDetail + (*SharePrivateRequest)(nil), // 8: SharePrivateRequest + (*SharePrivateResponse)(nil), // 9: SharePrivateResponse + (*SharePublicRequest)(nil), // 10: SharePublicRequest + (*SharePublicResponse)(nil), // 11: SharePublicResponse + (*ShareReservedRequest)(nil), // 12: ShareReservedRequest + (*ShareReservedResponse)(nil), // 13: ShareReservedResponse + (*StatusRequest)(nil), // 14: StatusRequest + (*StatusResponse)(nil), // 15: StatusResponse + (*VersionRequest)(nil), // 16: VersionRequest + (*VersionResponse)(nil), // 17: VersionResponse +} +var file_agent_agentGrpc_agent_proto_depIdxs = []int32{ + 0, // 0: StatusResponse.accesses:type_name -> AccessDetail + 7, // 1: StatusResponse.shares:type_name -> ShareDetail + 2, // 2: Agent.AccessPrivate:input_type -> AccessPrivateRequest + 3, // 3: Agent.ReleaseAccess:input_type -> ReleaseAccessRequest + 5, // 4: Agent.ReleaseShare:input_type -> ReleaseShareRequest + 12, // 5: Agent.ShareReserved:input_type -> ShareReservedRequest + 8, // 6: Agent.SharePrivate:input_type -> SharePrivateRequest + 10, // 7: Agent.SharePublic:input_type -> SharePublicRequest + 14, // 8: Agent.Status:input_type -> StatusRequest + 16, // 9: Agent.Version:input_type -> VersionRequest + 1, // 10: Agent.AccessPrivate:output_type -> AccessPrivateResponse + 4, // 11: Agent.ReleaseAccess:output_type -> ReleaseAccessResponse + 6, // 12: Agent.ReleaseShare:output_type -> ReleaseShareResponse + 13, // 13: Agent.ShareReserved:output_type -> ShareReservedResponse + 9, // 14: Agent.SharePrivate:output_type -> SharePrivateResponse + 11, // 15: Agent.SharePublic:output_type -> SharePublicResponse + 15, // 16: Agent.Status:output_type -> StatusResponse + 17, // 17: Agent.Version:output_type -> VersionResponse + 10, // [10:18] is the sub-list for method output_type + 2, // [2:10] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_agent_agentGrpc_agent_proto_init() } +func file_agent_agentGrpc_agent_proto_init() { + if File_agent_agentGrpc_agent_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_agent_agentGrpc_agent_proto_msgTypes[0].Exporter = func(v any, i int) any { + switch v := v.(*AccessDetail); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[1].Exporter = func(v any, i int) any { + switch v := v.(*AccessPrivateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[2].Exporter = func(v any, i int) any { + switch v := v.(*AccessPrivateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[3].Exporter = func(v any, i int) any { + switch v := v.(*ReleaseAccessRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[4].Exporter = func(v any, i int) any { + switch v := v.(*ReleaseAccessResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[5].Exporter = func(v any, i int) any { + switch v := v.(*ReleaseShareRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[6].Exporter = func(v any, i int) any { + switch v := v.(*ReleaseShareResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[7].Exporter = func(v any, i int) any { + switch v := v.(*ShareDetail); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[8].Exporter = func(v any, i int) any { + switch v := v.(*SharePrivateRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[9].Exporter = func(v any, i int) any { + switch v := v.(*SharePrivateResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[10].Exporter = func(v any, i int) any { + switch v := v.(*SharePublicRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[11].Exporter = func(v any, i int) any { + switch v := v.(*SharePublicResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[12].Exporter = func(v any, i int) any { + switch v := v.(*ShareReservedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[13].Exporter = func(v any, i int) any { + switch v := v.(*ShareReservedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[14].Exporter = func(v any, i int) any { + switch v := v.(*StatusRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[15].Exporter = func(v any, i int) any { + switch v := v.(*StatusResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[16].Exporter = func(v any, i int) any { + switch v := v.(*VersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_agent_agentGrpc_agent_proto_msgTypes[17].Exporter = func(v any, i int) any { + switch v := v.(*VersionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_agent_agentGrpc_agent_proto_rawDesc, + NumEnums: 0, + NumMessages: 18, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_agent_agentGrpc_agent_proto_goTypes, + DependencyIndexes: file_agent_agentGrpc_agent_proto_depIdxs, + MessageInfos: file_agent_agentGrpc_agent_proto_msgTypes, + }.Build() + File_agent_agentGrpc_agent_proto = out.File + file_agent_agentGrpc_agent_proto_rawDesc = nil + file_agent_agentGrpc_agent_proto_goTypes = nil + file_agent_agentGrpc_agent_proto_depIdxs = nil +} diff --git a/agent/agentGrpc/agent.pb.gw.go b/agent/agentGrpc/agent.pb.gw.go new file mode 100644 index 000000000..b8b234d69 --- /dev/null +++ b/agent/agentGrpc/agent.pb.gw.go @@ -0,0 +1,659 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: agent/agentGrpc/agent.proto + +/* +Package agentGrpc is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package agentGrpc + +import ( + "context" + "io" + "net/http" + + "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" + "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "google.golang.org/protobuf/proto" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = metadata.Join + +var ( + filter_Agent_AccessPrivate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Agent_AccessPrivate_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AccessPrivateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_AccessPrivate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.AccessPrivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_AccessPrivate_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq AccessPrivateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_AccessPrivate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.AccessPrivate(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Agent_ReleaseAccess_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Agent_ReleaseAccess_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ReleaseAccessRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseAccess_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ReleaseAccess(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_ReleaseAccess_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ReleaseAccessRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseAccess_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ReleaseAccess(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Agent_ReleaseShare_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Agent_ReleaseShare_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ReleaseShareRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseShare_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ReleaseShare(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_ReleaseShare_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ReleaseShareRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseShare_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ReleaseShare(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Agent_SharePrivate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Agent_SharePrivate_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SharePrivateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePrivate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SharePrivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_SharePrivate_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SharePrivateRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePrivate_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SharePrivate(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Agent_SharePublic_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Agent_SharePublic_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SharePublicRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePublic_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SharePublic(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_SharePublic_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SharePublicRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePublic_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SharePublic(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Agent_Status_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StatusRequest + var metadata runtime.ServerMetadata + + msg, err := client.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_Status_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StatusRequest + var metadata runtime.ServerMetadata + + msg, err := server.Status(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Agent_Version_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VersionRequest + var metadata runtime.ServerMetadata + + msg, err := client.Version(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Agent_Version_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq VersionRequest + var metadata runtime.ServerMetadata + + msg, err := server.Version(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterAgentHandlerServer registers the http handlers for service Agent to "mux". +// UnaryRPC :call AgentServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAgentHandlerFromEndpoint instead. +func RegisterAgentHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AgentServer) error { + + mux.Handle("POST", pattern_Agent_AccessPrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/AccessPrivate", runtime.WithHTTPPathPattern("/v1/agent/accessPrivate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_AccessPrivate_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_AccessPrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_ReleaseAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/ReleaseAccess", runtime.WithHTTPPathPattern("/v1/agent/releaseAccess")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_ReleaseAccess_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_ReleaseAccess_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_ReleaseShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/ReleaseShare", runtime.WithHTTPPathPattern("/v1/agent/releaseShare")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_ReleaseShare_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_ReleaseShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_SharePrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/SharePrivate", runtime.WithHTTPPathPattern("/v1/agent/sharePrivate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_SharePrivate_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_SharePrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_SharePublic_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/SharePublic", runtime.WithHTTPPathPattern("/v1/agent/sharePublic")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_SharePublic_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_SharePublic_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Agent_Status_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/Status", runtime.WithHTTPPathPattern("/v1/agent/status")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_Status_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_Status_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Agent_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/Version", runtime.WithHTTPPathPattern("/v1/agent/version")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Agent_Version_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_Version_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterAgentHandlerFromEndpoint is same as RegisterAgentHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterAgentHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.DialContext(ctx, endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterAgentHandler(ctx, mux, conn) +} + +// RegisterAgentHandler registers the http handlers for service Agent to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterAgentHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterAgentHandlerClient(ctx, mux, NewAgentClient(conn)) +} + +// RegisterAgentHandlerClient registers the http handlers for service Agent +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AgentClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AgentClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "AgentClient" to call the correct interceptors. +func RegisterAgentHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AgentClient) error { + + mux.Handle("POST", pattern_Agent_AccessPrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/AccessPrivate", runtime.WithHTTPPathPattern("/v1/agent/accessPrivate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_AccessPrivate_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_AccessPrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_ReleaseAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/ReleaseAccess", runtime.WithHTTPPathPattern("/v1/agent/releaseAccess")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_ReleaseAccess_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_ReleaseAccess_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_ReleaseShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/ReleaseShare", runtime.WithHTTPPathPattern("/v1/agent/releaseShare")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_ReleaseShare_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_ReleaseShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_SharePrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/SharePrivate", runtime.WithHTTPPathPattern("/v1/agent/sharePrivate")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_SharePrivate_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_SharePrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_Agent_SharePublic_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/SharePublic", runtime.WithHTTPPathPattern("/v1/agent/sharePublic")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_SharePublic_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_SharePublic_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Agent_Status_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/Status", runtime.WithHTTPPathPattern("/v1/agent/status")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_Status_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_Status_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Agent_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/Version", runtime.WithHTTPPathPattern("/v1/agent/version")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Agent_Version_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_Agent_Version_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Agent_AccessPrivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "accessPrivate"}, "")) + + pattern_Agent_ReleaseAccess_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "releaseAccess"}, "")) + + pattern_Agent_ReleaseShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "releaseShare"}, "")) + + pattern_Agent_SharePrivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "sharePrivate"}, "")) + + pattern_Agent_SharePublic_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "sharePublic"}, "")) + + pattern_Agent_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "status"}, "")) + + pattern_Agent_Version_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "version"}, "")) +) + +var ( + forward_Agent_AccessPrivate_0 = runtime.ForwardResponseMessage + + forward_Agent_ReleaseAccess_0 = runtime.ForwardResponseMessage + + forward_Agent_ReleaseShare_0 = runtime.ForwardResponseMessage + + forward_Agent_SharePrivate_0 = runtime.ForwardResponseMessage + + forward_Agent_SharePublic_0 = runtime.ForwardResponseMessage + + forward_Agent_Status_0 = runtime.ForwardResponseMessage + + forward_Agent_Version_0 = runtime.ForwardResponseMessage +) diff --git a/agent/agentGrpc/agent.proto b/agent/agentGrpc/agent.proto new file mode 100644 index 000000000..aca147fee --- /dev/null +++ b/agent/agentGrpc/agent.proto @@ -0,0 +1,150 @@ +syntax = "proto3"; + +option go_package = "github.com/openziti/zrok/agent/agentGrpc"; + +import "google/api/annotations.proto"; + +service Agent { + rpc AccessPrivate(AccessPrivateRequest) returns (AccessPrivateResponse) { + option(google.api.http) = { + post: "/v1/agent/accessPrivate" + }; + } + rpc ReleaseAccess(ReleaseAccessRequest) returns (ReleaseAccessResponse) { + option(google.api.http) = { + post: "/v1/agent/releaseAccess" + }; + } + rpc ReleaseShare(ReleaseShareRequest) returns (ReleaseShareResponse) { + option(google.api.http) = { + post: "/v1/agent/releaseShare" + }; + } + rpc ShareReserved(ShareReservedRequest) returns (ShareReservedResponse) {} + rpc SharePrivate(SharePrivateRequest) returns (SharePrivateResponse) { + option(google.api.http) = { + post: "/v1/agent/sharePrivate" + }; + } + rpc SharePublic(SharePublicRequest) returns (SharePublicResponse) { + option(google.api.http) = { + post: "/v1/agent/sharePublic" + }; + } + rpc Status(StatusRequest) returns (StatusResponse) { + option(google.api.http) = { + get: "/v1/agent/status" + }; + } + rpc Version(VersionRequest) returns (VersionResponse) { + option(google.api.http) = { + get: "/v1/agent/version" + }; + } +} + +message AccessDetail { + string frontendToken = 1; + string token = 2; + string bindAddress = 3; + repeated string responseHeaders = 4; +} + +message AccessPrivateResponse{ + string frontendToken = 1; +} + +message AccessPrivateRequest{ + string token = 1; + string bindAddress = 2; + bool autoMode = 3; + string autoAddress = 4; + uint32 autoStartPort = 5; + uint32 autoEndPort = 6; + repeated string responseHeaders = 7; +} + +message ReleaseAccessRequest { + string frontendToken = 1; +} + +message ReleaseAccessResponse { +} + +message ReleaseShareRequest { + string token = 1; +} + +message ReleaseShareResponse { +} + +message ShareDetail { + string token = 1; + string shareMode = 2; + string backendMode = 3; + bool reserved = 4; + repeated string frontendEndpoint = 5; + string backendEndpoint = 6; + bool closed = 7; + string status = 8; +} + +message SharePrivateRequest { + string target = 1; + string backendMode = 2; + bool insecure = 3; + bool closed = 4; + repeated string accessGrants = 5; +} + +message SharePrivateResponse { + string token = 1; +} + +message SharePublicRequest { + string target = 1; + repeated string basicAuth = 2; + repeated string frontendSelection = 3; + string backendMode = 4; + bool insecure = 5; + string oauthProvider = 6; + repeated string oauthEmailAddressPatterns = 7; + string oauthCheckInterval = 8; + bool closed = 9; + repeated string accessGrants = 10; +} + +message SharePublicResponse { + string token = 1; + repeated string frontendEndpoints = 2; +} + +message ShareReservedRequest { + string token = 1; + string overrideEndpoint = 2; + bool insecure = 3; +} + +message ShareReservedResponse { + string token = 1; + string backendMode = 2; + string shareMode = 3; + repeated string frontendEndpoints = 4; + string target = 5; +} + +message StatusRequest { +} + +message StatusResponse { + repeated AccessDetail accesses = 1; + repeated ShareDetail shares = 2; +} + +message VersionRequest { +} + +message VersionResponse { + string v = 1; + string consoleEndpoint = 2; +} diff --git a/agent/agentGrpc/agent.swagger.json b/agent/agentGrpc/agent.swagger.json new file mode 100644 index 000000000..541d8967c --- /dev/null +++ b/agent/agentGrpc/agent.swagger.json @@ -0,0 +1,525 @@ +{ + "swagger": "2.0", + "info": { + "title": "agent/agentGrpc/agent.proto", + "version": "version not set" + }, + "tags": [ + { + "name": "Agent" + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/v1/agent/accessPrivate": { + "post": { + "operationId": "Agent_AccessPrivate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/AccessPrivateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "token", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "bindAddress", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "autoMode", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "autoAddress", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "autoStartPort", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "autoEndPort", + "in": "query", + "required": false, + "type": "integer", + "format": "int64" + }, + { + "name": "responseHeaders", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/releaseAccess": { + "post": { + "operationId": "Agent_ReleaseAccess", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ReleaseAccessResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "frontendToken", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/releaseShare": { + "post": { + "operationId": "Agent_ReleaseShare", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/ReleaseShareResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "token", + "in": "query", + "required": false, + "type": "string" + } + ], + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/sharePrivate": { + "post": { + "operationId": "Agent_SharePrivate", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/SharePrivateResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "target", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "backendMode", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "insecure", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "closed", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "accessGrants", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/sharePublic": { + "post": { + "operationId": "Agent_SharePublic", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/SharePublicResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "parameters": [ + { + "name": "target", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "basicAuth", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "frontendSelection", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "backendMode", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "insecure", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "oauthProvider", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "oauthEmailAddressPatterns", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + }, + { + "name": "oauthCheckInterval", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "closed", + "in": "query", + "required": false, + "type": "boolean" + }, + { + "name": "accessGrants", + "in": "query", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi" + } + ], + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/status": { + "get": { + "operationId": "Agent_Status", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/StatusResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "Agent" + ] + } + }, + "/v1/agent/version": { + "get": { + "operationId": "Agent_Version", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/VersionResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/rpcStatus" + } + } + }, + "tags": [ + "Agent" + ] + } + } + }, + "definitions": { + "AccessDetail": { + "type": "object", + "properties": { + "frontendToken": { + "type": "string" + }, + "token": { + "type": "string" + }, + "bindAddress": { + "type": "string" + }, + "responseHeaders": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "AccessPrivateResponse": { + "type": "object", + "properties": { + "frontendToken": { + "type": "string" + } + } + }, + "ReleaseAccessResponse": { + "type": "object" + }, + "ReleaseShareResponse": { + "type": "object" + }, + "ShareDetail": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "shareMode": { + "type": "string" + }, + "backendMode": { + "type": "string" + }, + "reserved": { + "type": "boolean" + }, + "frontendEndpoint": { + "type": "array", + "items": { + "type": "string" + } + }, + "backendEndpoint": { + "type": "string" + }, + "closed": { + "type": "boolean" + }, + "status": { + "type": "string" + } + } + }, + "SharePrivateResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "SharePublicResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "frontendEndpoints": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "ShareReservedResponse": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "backendMode": { + "type": "string" + }, + "shareMode": { + "type": "string" + }, + "frontendEndpoints": { + "type": "array", + "items": { + "type": "string" + } + }, + "target": { + "type": "string" + } + } + }, + "StatusResponse": { + "type": "object", + "properties": { + "accesses": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/AccessDetail" + } + }, + "shares": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/ShareDetail" + } + } + } + }, + "VersionResponse": { + "type": "object", + "properties": { + "v": { + "type": "string" + }, + "consoleEndpoint": { + "type": "string" + } + } + }, + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/protobufAny" + } + } + } + } + } +} diff --git a/agent/agentGrpc/agent_grpc.pb.go b/agent/agentGrpc/agent_grpc.pb.go new file mode 100644 index 000000000..cdae84952 --- /dev/null +++ b/agent/agentGrpc/agent_grpc.pb.go @@ -0,0 +1,387 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.27.3 +// source: agent/agentGrpc/agent.proto + +package agentGrpc + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 + +const ( + Agent_AccessPrivate_FullMethodName = "/Agent/AccessPrivate" + Agent_ReleaseAccess_FullMethodName = "/Agent/ReleaseAccess" + Agent_ReleaseShare_FullMethodName = "/Agent/ReleaseShare" + Agent_ShareReserved_FullMethodName = "/Agent/ShareReserved" + Agent_SharePrivate_FullMethodName = "/Agent/SharePrivate" + Agent_SharePublic_FullMethodName = "/Agent/SharePublic" + Agent_Status_FullMethodName = "/Agent/Status" + Agent_Version_FullMethodName = "/Agent/Version" +) + +// AgentClient is the client API for Agent service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AgentClient interface { + AccessPrivate(ctx context.Context, in *AccessPrivateRequest, opts ...grpc.CallOption) (*AccessPrivateResponse, error) + ReleaseAccess(ctx context.Context, in *ReleaseAccessRequest, opts ...grpc.CallOption) (*ReleaseAccessResponse, error) + ReleaseShare(ctx context.Context, in *ReleaseShareRequest, opts ...grpc.CallOption) (*ReleaseShareResponse, error) + ShareReserved(ctx context.Context, in *ShareReservedRequest, opts ...grpc.CallOption) (*ShareReservedResponse, error) + SharePrivate(ctx context.Context, in *SharePrivateRequest, opts ...grpc.CallOption) (*SharePrivateResponse, error) + SharePublic(ctx context.Context, in *SharePublicRequest, opts ...grpc.CallOption) (*SharePublicResponse, error) + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) + Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) +} + +type agentClient struct { + cc grpc.ClientConnInterface +} + +func NewAgentClient(cc grpc.ClientConnInterface) AgentClient { + return &agentClient{cc} +} + +func (c *agentClient) AccessPrivate(ctx context.Context, in *AccessPrivateRequest, opts ...grpc.CallOption) (*AccessPrivateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(AccessPrivateResponse) + err := c.cc.Invoke(ctx, Agent_AccessPrivate_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) ReleaseAccess(ctx context.Context, in *ReleaseAccessRequest, opts ...grpc.CallOption) (*ReleaseAccessResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ReleaseAccessResponse) + err := c.cc.Invoke(ctx, Agent_ReleaseAccess_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) ReleaseShare(ctx context.Context, in *ReleaseShareRequest, opts ...grpc.CallOption) (*ReleaseShareResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ReleaseShareResponse) + err := c.cc.Invoke(ctx, Agent_ReleaseShare_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) ShareReserved(ctx context.Context, in *ShareReservedRequest, opts ...grpc.CallOption) (*ShareReservedResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ShareReservedResponse) + err := c.cc.Invoke(ctx, Agent_ShareReserved_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) SharePrivate(ctx context.Context, in *SharePrivateRequest, opts ...grpc.CallOption) (*SharePrivateResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SharePrivateResponse) + err := c.cc.Invoke(ctx, Agent_SharePrivate_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) SharePublic(ctx context.Context, in *SharePublicRequest, opts ...grpc.CallOption) (*SharePublicResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(SharePublicResponse) + err := c.cc.Invoke(ctx, Agent_SharePublic_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(StatusResponse) + err := c.cc.Invoke(ctx, Agent_Status_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *agentClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(VersionResponse) + err := c.cc.Invoke(ctx, Agent_Version_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AgentServer is the server API for Agent service. +// All implementations must embed UnimplementedAgentServer +// for forward compatibility. +type AgentServer interface { + AccessPrivate(context.Context, *AccessPrivateRequest) (*AccessPrivateResponse, error) + ReleaseAccess(context.Context, *ReleaseAccessRequest) (*ReleaseAccessResponse, error) + ReleaseShare(context.Context, *ReleaseShareRequest) (*ReleaseShareResponse, error) + ShareReserved(context.Context, *ShareReservedRequest) (*ShareReservedResponse, error) + SharePrivate(context.Context, *SharePrivateRequest) (*SharePrivateResponse, error) + SharePublic(context.Context, *SharePublicRequest) (*SharePublicResponse, error) + Status(context.Context, *StatusRequest) (*StatusResponse, error) + Version(context.Context, *VersionRequest) (*VersionResponse, error) + mustEmbedUnimplementedAgentServer() +} + +// UnimplementedAgentServer must be embedded to have +// forward compatible implementations. +// +// NOTE: this should be embedded by value instead of pointer to avoid a nil +// pointer dereference when methods are called. +type UnimplementedAgentServer struct{} + +func (UnimplementedAgentServer) AccessPrivate(context.Context, *AccessPrivateRequest) (*AccessPrivateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AccessPrivate not implemented") +} +func (UnimplementedAgentServer) ReleaseAccess(context.Context, *ReleaseAccessRequest) (*ReleaseAccessResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReleaseAccess not implemented") +} +func (UnimplementedAgentServer) ReleaseShare(context.Context, *ReleaseShareRequest) (*ReleaseShareResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ReleaseShare not implemented") +} +func (UnimplementedAgentServer) ShareReserved(context.Context, *ShareReservedRequest) (*ShareReservedResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShareReserved not implemented") +} +func (UnimplementedAgentServer) SharePrivate(context.Context, *SharePrivateRequest) (*SharePrivateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SharePrivate not implemented") +} +func (UnimplementedAgentServer) SharePublic(context.Context, *SharePublicRequest) (*SharePublicResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SharePublic not implemented") +} +func (UnimplementedAgentServer) Status(context.Context, *StatusRequest) (*StatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Status not implemented") +} +func (UnimplementedAgentServer) Version(context.Context, *VersionRequest) (*VersionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") +} +func (UnimplementedAgentServer) mustEmbedUnimplementedAgentServer() {} +func (UnimplementedAgentServer) testEmbeddedByValue() {} + +// UnsafeAgentServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AgentServer will +// result in compilation errors. +type UnsafeAgentServer interface { + mustEmbedUnimplementedAgentServer() +} + +func RegisterAgentServer(s grpc.ServiceRegistrar, srv AgentServer) { + // If the following call pancis, it indicates UnimplementedAgentServer was + // embedded by pointer and is nil. This will cause panics if an + // unimplemented method is ever invoked, so we test this at initialization + // time to prevent it from happening at runtime later due to I/O. + if t, ok := srv.(interface{ testEmbeddedByValue() }); ok { + t.testEmbeddedByValue() + } + s.RegisterService(&Agent_ServiceDesc, srv) +} + +func _Agent_AccessPrivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AccessPrivateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).AccessPrivate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_AccessPrivate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).AccessPrivate(ctx, req.(*AccessPrivateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_ReleaseAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReleaseAccessRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).ReleaseAccess(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_ReleaseAccess_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).ReleaseAccess(ctx, req.(*ReleaseAccessRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_ReleaseShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReleaseShareRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).ReleaseShare(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_ReleaseShare_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).ReleaseShare(ctx, req.(*ReleaseShareRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_ShareReserved_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ShareReservedRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).ShareReserved(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_ShareReserved_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).ShareReserved(ctx, req.(*ShareReservedRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_SharePrivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SharePrivateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).SharePrivate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_SharePrivate_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).SharePrivate(ctx, req.(*SharePrivateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_SharePublic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SharePublicRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).SharePublic(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_SharePublic_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).SharePublic(ctx, req.(*SharePublicRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).Status(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_Status_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).Status(ctx, req.(*StatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Agent_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(VersionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServer).Version(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: Agent_Version_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServer).Version(ctx, req.(*VersionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// Agent_ServiceDesc is the grpc.ServiceDesc for Agent service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Agent_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "Agent", + HandlerType: (*AgentServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "AccessPrivate", + Handler: _Agent_AccessPrivate_Handler, + }, + { + MethodName: "ReleaseAccess", + Handler: _Agent_ReleaseAccess_Handler, + }, + { + MethodName: "ReleaseShare", + Handler: _Agent_ReleaseShare_Handler, + }, + { + MethodName: "ShareReserved", + Handler: _Agent_ShareReserved_Handler, + }, + { + MethodName: "SharePrivate", + Handler: _Agent_SharePrivate_Handler, + }, + { + MethodName: "SharePublic", + Handler: _Agent_SharePublic_Handler, + }, + { + MethodName: "Status", + Handler: _Agent_Status_Handler, + }, + { + MethodName: "Version", + Handler: _Agent_Version_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "agent/agentGrpc/agent.proto", +} diff --git a/agent/agentGrpc/tools.go b/agent/agentGrpc/tools.go new file mode 100644 index 000000000..816b30c02 --- /dev/null +++ b/agent/agentGrpc/tools.go @@ -0,0 +1,10 @@ +//go:build tools + +package agentGrpc + +import ( + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2" + _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" + _ "google.golang.org/protobuf/cmd/protoc-gen-go" +) diff --git a/agent/agentUi/.gitignore b/agent/agentUi/.gitignore new file mode 100644 index 000000000..a547bf36d --- /dev/null +++ b/agent/agentUi/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/agent/agentUi/README.md b/agent/agentUi/README.md new file mode 100644 index 000000000..74872fd4a --- /dev/null +++ b/agent/agentUi/README.md @@ -0,0 +1,50 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}) +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from 'eslint-plugin-react' + +export default tseslint.config({ + // Set the react version + settings: { react: { version: '18.3' } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + }, +}) +``` diff --git a/agent/agentUi/embed.go b/agent/agentUi/embed.go new file mode 100644 index 000000000..70b7822fc --- /dev/null +++ b/agent/agentUi/embed.go @@ -0,0 +1,6 @@ +package agentUi + +import "embed" + +//go:embed dist +var FS embed.FS diff --git a/agent/agentUi/eslint.config.js b/agent/agentUi/eslint.config.js new file mode 100644 index 000000000..092408a9f --- /dev/null +++ b/agent/agentUi/eslint.config.js @@ -0,0 +1,28 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' + +export default tseslint.config( + { ignores: ['dist'] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ['**/*.{ts,tsx}'], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, + }, +) diff --git a/agent/agentUi/index.html b/agent/agentUi/index.html new file mode 100644 index 000000000..5deb885b8 --- /dev/null +++ b/agent/agentUi/index.html @@ -0,0 +1,103 @@ + + + + + + + + + + + Vite + React + TS + + +
+ + + + + diff --git a/agent/agentUi/middleware.go b/agent/agentUi/middleware.go new file mode 100644 index 000000000..ab669f06c --- /dev/null +++ b/agent/agentUi/middleware.go @@ -0,0 +1,53 @@ +package agentUi + +import ( + "github.com/sirupsen/logrus" + "io/fs" + "net/http" + "os" + "path/filepath" + "strings" +) + +const staticPath = "dist" + +func Middleware(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, "/v1") { + handler.ServeHTTP(w, r) + return + } + + path := filepath.ToSlash(filepath.Join(staticPath, r.URL.Path)) + logrus.Debugf("path = %v", path) + + f, err := FS.Open(path) + if os.IsNotExist(err) { + // file does not exist, serve index.gohtml + index, err := FS.ReadFile(filepath.ToSlash(filepath.Join(staticPath, "index.html"))) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.WriteHeader(http.StatusAccepted) + _, _ = w.Write(index) + return + + } else if err != nil { + // if we got an error (that wasn't that the file doesn't exist) stating the + // file, return a 500 internal server error and stop + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer func() { _ = f.Close() }() + + // get the subdirectory of the static dir + if statics, err := fs.Sub(FS, staticPath); err == nil { + // otherwise, use http.FileServer to serve the static dir + http.FileServer(http.FS(statics)).ServeHTTP(w, r) + } else { + http.Error(w, err.Error(), http.StatusInternalServerError) + } + }) +} diff --git a/agent/agentUi/package-lock.json b/agent/agentUi/package-lock.json new file mode 100644 index 000000000..42856f818 --- /dev/null +++ b/agent/agentUi/package-lock.json @@ -0,0 +1,3931 @@ +{ + "name": "agentui", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "agentui", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^6.1.7", + "@mui/material": "^6.1.7", + "formik": "^2.4.6", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.3", + "eslint": "^9.13.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.11.0", + "typescript-eslint": "^8.15.0", + "vite": "^5.4.10" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz", + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz", + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.2", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz", + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz", + "integrity": "sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.2.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/cache": { + "version": "11.13.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz", + "integrity": "sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.13.3", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz", + "integrity": "sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/cache": "^11.13.0", + "@emotion/serialize": "^1.3.1", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.2.tgz", + "integrity": "sha512-grVnMvVPK9yUVE6rkKfAJlYZgo0cu3l9iMC77V7DW6E1DUIrU68pSEXRmFZFOFB1QFo57TncmOcvcbMDWsL4yA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz", + "integrity": "sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.12.0", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.1.0", + "@emotion/utils": "^1.4.0" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz", + "integrity": "sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.1.tgz", + "integrity": "sha512-BymCXzCG3r72VKJxaYVwOXATqXIZ85cuvg0YOUDxMGNrKc1DJRZk8MgV5wyXRyEayIMd4FuXJIUgTBXvDNW5cA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", + "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", + "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.7.tgz", + "integrity": "sha512-POuIBi80BZBogQkG4PQKIGwy4QFwB+kOr+OI4k7Znh7LqMAIhwB9OC00l6M+w1GrZJYj3T8R5WX8G6QAIvoVEw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.7.tgz", + "integrity": "sha512-RGzkeHNArIVy5ZQ12bq/8VYNeICEyngngsFskTJ/2hYKhIeIII3iRGtaZaSvLpXh7h3Fg3VKTulT+QU0w5K4XQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^6.1.7", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.7.tgz", + "integrity": "sha512-KsjujQL/A2hLd1PV3QboF+W6SSL5QqH6ZlSuQoeYz9r69+TnyBFIevbYLxdjJcJmGBjigL5pfpn7hTGop+vhSg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/core-downloads-tracker": "^6.1.7", + "@mui/system": "^6.1.7", + "@mui/types": "^7.2.19", + "@mui/utils": "^6.1.7", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.11", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.3.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^6.1.7", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.7.tgz", + "integrity": "sha512-uLbfUSsug5K0LVkv0PI6Flste3le8+6WSL2omdTiYde93P89Qr7pKr8TA6d2yXfr+Bm+SvD8/fGnkaRwFkryuQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/utils": "^6.1.7", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.7.tgz", + "integrity": "sha512-Ou4CxN7MQmwrfG1Pu6EYjPgPChQXxPDJrwgizLXlRPOad5qAq4gYXRuzrGQ2DfGjjwmJhjI8T6A0SeapAZPGig==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@emotion/cache": "^11.13.1", + "@emotion/serialize": "^1.3.2", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.7.tgz", + "integrity": "sha512-qbMGgcC/FodpuRSfjXlEDdbNQaW++eATh0vNBcPUv2/YXSpReoOpoT9FhogxEBNks+aQViDXBRZKh6HX2fVmwg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/private-theming": "^6.1.7", + "@mui/styled-engine": "^6.1.7", + "@mui/types": "^7.2.19", + "@mui/utils": "^6.1.7", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.19", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.19.tgz", + "integrity": "sha512-6XpZEM/Q3epK9RN8ENoXuygnqUQxE+siN/6rGRi2iwJPgBUR25mphYQ9ZI87plGh58YoZ5pp40bFvKYOCDJ3tA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.7.tgz", + "integrity": "sha512-Gr7cRZxBoZ0BIa3Xqf/2YaUrBLyNPJvXPQH3OsD9WMZukI/TutibbQBVqLYpgqJn8pKSjbD50Yq2auG0wI1xOw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mui/types": "^7.2.19", + "@types/prop-types": "^15.7.13", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^18.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "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/@rollup/rollup-android-arm-eabi": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.2.tgz", + "integrity": "sha512-Tj+j7Pyzd15wAdSJswvs5CJzJNV+qqSUcr/aCD+jpQSBtXvGnV0pnrjoc8zFTe9fcKCatkpFpOO7yAzpO998HA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.27.2.tgz", + "integrity": "sha512-xsPeJgh2ThBpUqlLgRfiVYBEf/P1nWlWvReG+aBWfNv3XEBpa6ZCmxSVnxJgLgkNz4IbxpLy64h2gCmAAQLneQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.27.2.tgz", + "integrity": "sha512-KnXU4m9MywuZFedL35Z3PuwiTSn/yqRIhrEA9j+7OSkji39NzVkgxuxTYg5F8ryGysq4iFADaU5osSizMXhU2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.27.2.tgz", + "integrity": "sha512-Hj77A3yTvUeCIx/Vi+4d4IbYhyTwtHj07lVzUgpUq9YpJSEiGJj4vXMKwzJ3w5zp5v3PFvpJNgc/J31smZey6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.27.2.tgz", + "integrity": "sha512-RjgKf5C3xbn8gxvCm5VgKZ4nn0pRAIe90J0/fdHUsgztd3+Zesb2lm2+r6uX4prV2eUByuxJNdt647/1KPRq5g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.27.2.tgz", + "integrity": "sha512-duq21FoXwQtuws+V9H6UZ+eCBc7fxSpMK1GQINKn3fAyd9DFYKPJNcUhdIKOrMFjLEJgQskoMoiuizMt+dl20g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.27.2.tgz", + "integrity": "sha512-6npqOKEPRZkLrMcvyC/32OzJ2srdPzCylJjiTJT2c0bwwSGm7nz2F9mNQ1WrAqCBZROcQn91Fno+khFhVijmFA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.27.2.tgz", + "integrity": "sha512-V9Xg6eXtgBtHq2jnuQwM/jr2mwe2EycnopO8cbOvpzFuySCGtKlPCI3Hj9xup/pJK5Q0388qfZZy2DqV2J8ftw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.27.2.tgz", + "integrity": "sha512-uCFX9gtZJoQl2xDTpRdseYuNqyKkuMDtH6zSrBTA28yTfKyjN9hQ2B04N5ynR8ILCoSDOrG/Eg+J2TtJ1e/CSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.27.2.tgz", + "integrity": "sha512-/PU9P+7Rkz8JFYDHIi+xzHabOu9qEWR07L5nWLIUsvserrxegZExKCi2jhMZRd0ATdboKylu/K5yAXbp7fYFvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.27.2.tgz", + "integrity": "sha512-eCHmol/dT5odMYi/N0R0HC8V8QE40rEpkyje/ZAXJYNNoSfrObOvG/Mn+s1F/FJyB7co7UQZZf6FuWnN6a7f4g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.27.2.tgz", + "integrity": "sha512-DEP3Njr9/ADDln3kNi76PXonLMSSMiCir0VHXxmGSHxCxDfQ70oWjHcJGfiBugzaqmYdTC7Y+8Int6qbnxPBIQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.27.2.tgz", + "integrity": "sha512-NHGo5i6IE/PtEPh5m0yw5OmPMpesFnzMIS/lzvN5vknnC1sXM5Z/id5VgcNPgpD+wHmIcuYYgW+Q53v+9s96lQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.27.2.tgz", + "integrity": "sha512-PaW2DY5Tan+IFvNJGHDmUrORadbe/Ceh8tQxi8cmdQVCCYsLoQo2cuaSj+AU+YRX8M4ivS2vJ9UGaxfuNN7gmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.27.2.tgz", + "integrity": "sha512-dOlWEMg2gI91Qx5I/HYqOD6iqlJspxLcS4Zlg3vjk1srE67z5T2Uz91yg/qA8sY0XcwQrFzWWiZhMNERylLrpQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.27.2.tgz", + "integrity": "sha512-euMIv/4x5Y2/ImlbGl88mwKNXDsvzbWUlT7DFky76z2keajCtcbAsN9LUdmk31hAoVmJJYSThgdA0EsPeTr1+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.27.2.tgz", + "integrity": "sha512-RsnE6LQkUHlkC10RKngtHNLxb7scFykEbEwOFDjr3CeCMG+Rr+cKqlkKc2/wJ1u4u990urRHCbjz31x84PBrSQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.27.2.tgz", + "integrity": "sha512-foJM5vv+z2KQmn7emYdDLyTbkoO5bkHZE1oth2tWbQNGW7mX32d46Hz6T0MqXdWS2vBZhaEtHqdy9WYwGfiliA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.13", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.12", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.12.tgz", + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.11", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.11.tgz", + "integrity": "sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.15.0.tgz", + "integrity": "sha512-+zkm9AR1Ds9uLWN3fkoeXgFppaQ+uEVtfOV62dDmsy9QCNqlRHWNEck4yarvRNrvRcHQLGfqBNui3cimoz8XAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/type-utils": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.15.0.tgz", + "integrity": "sha512-7n59qFpghG4uazrF9qtGKBZXn7Oz4sOMm8dwNWDQY96Xlm2oX67eipqcblDj+oY1lLCbf1oltMZFpUso66Kl1A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.15.0.tgz", + "integrity": "sha512-QRGy8ADi4J7ii95xz4UoiymmmMd/zuy9azCaamnZ3FM8T5fZcex8UfJcjkiEZjJSztKfEBe3dZ5T/5RHAmw2mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.15.0.tgz", + "integrity": "sha512-UU6uwXDoI3JGSXmcdnP5d8Fffa2KayOhUUqr/AiBnG1Gl7+7ut/oyagVeSkh7bxQ0zSXV9ptRh/4N15nkCqnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.15.0", + "@typescript-eslint/utils": "8.15.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.15.0.tgz", + "integrity": "sha512-n3Gt8Y/KyJNe0S3yDCD2RVKrHBC4gTUcLTebVBXacPy091E6tNspFLKRXlk3hwT4G55nfr1n2AdFqi/XMxzmPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.15.0.tgz", + "integrity": "sha512-1eMp2JgNec/niZsR7ioFBlsh/Fk0oJbhaqO0jRyQBMgkz7RrFfkqF9lYYmBoGBaSiLnu8TAPQTwoTUiSTUW9dg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/visitor-keys": "8.15.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.15.0.tgz", + "integrity": "sha512-k82RI9yGhr0QM3Dnq+egEpz9qB6Un+WLYhmoNcvl8ltMEededhh7otBVVIDDsEEttauwdY/hQoSsOv13lxrFzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.15.0", + "@typescript-eslint/types": "8.15.0", + "@typescript-eslint/typescript-estree": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.15.0.tgz", + "integrity": "sha512-h8vYOulWec9LhpwfAdZf2bjr8xIp0KNKnpgqSz0qqYYKAW/QZKw3ktRndbiAtUz4acH4QLQavwZBYCc0wulA/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.15.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz", + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.61", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.61.tgz", + "integrity": "sha512-CcRGSBCBB6L9c3PBJWYYrBo6Bzeoi+GZTKvtuRtooJGWsINk+mOInZWcssU35zDTAwreVcrMimc9aMyPpehRNw==", + "dev": true, + "license": "ISC" + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", + "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.15.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.5", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.14.tgz", + "integrity": "sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "15.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.12.0.tgz", + "integrity": "sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "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" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "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.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "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/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.27.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.27.2.tgz", + "integrity": "sha512-KreA+PzWmk2yaFmZVwe6GB2uBD86nXl86OsDkt1bJS9p3vqWuEQ6HnJJ+j/mZi/q0920P99/MVRlB4L3crpF5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.27.2", + "@rollup/rollup-android-arm64": "4.27.2", + "@rollup/rollup-darwin-arm64": "4.27.2", + "@rollup/rollup-darwin-x64": "4.27.2", + "@rollup/rollup-freebsd-arm64": "4.27.2", + "@rollup/rollup-freebsd-x64": "4.27.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.27.2", + "@rollup/rollup-linux-arm-musleabihf": "4.27.2", + "@rollup/rollup-linux-arm64-gnu": "4.27.2", + "@rollup/rollup-linux-arm64-musl": "4.27.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.27.2", + "@rollup/rollup-linux-riscv64-gnu": "4.27.2", + "@rollup/rollup-linux-s390x-gnu": "4.27.2", + "@rollup/rollup-linux-x64-gnu": "4.27.2", + "@rollup/rollup-linux-x64-musl": "4.27.2", + "@rollup/rollup-win32-arm64-msvc": "4.27.2", + "@rollup/rollup-win32-ia32-msvc": "4.27.2", + "@rollup/rollup-win32-x64-msvc": "4.27.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "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" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.0.tgz", + "integrity": "sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.15.0.tgz", + "integrity": "sha512-wY4FRGl0ZI+ZU4Jo/yjdBu0lVTSML58pu6PgGtJmCufvzfV565pUF6iACQt092uFOd49iLOTX/sEVmHtbSrS+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.15.0", + "@typescript-eslint/parser": "8.15.0", + "@typescript-eslint/utils": "8.15.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "5.4.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/agent/agentUi/package.json b/agent/agentUi/package.json new file mode 100644 index 000000000..606334637 --- /dev/null +++ b/agent/agentUi/package.json @@ -0,0 +1,33 @@ +{ + "name": "agentui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@mui/icons-material": "^6.1.7", + "@mui/material": "^6.1.7", + "formik": "^2.4.6", + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@eslint/js": "^9.13.0", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.3", + "eslint": "^9.13.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "globals": "^15.11.0", + "typescript-eslint": "^8.15.0", + "vite": "^5.4.10" + } +} diff --git a/agent/agentUi/public/zrok.png b/agent/agentUi/public/zrok.png new file mode 100644 index 000000000..b9cef0f26 Binary files /dev/null and b/agent/agentUi/public/zrok.png differ diff --git a/agent/agentUi/src/AccessCard.tsx b/agent/agentUi/src/AccessCard.tsx new file mode 100644 index 000000000..f64095069 --- /dev/null +++ b/agent/agentUi/src/AccessCard.tsx @@ -0,0 +1,53 @@ +import {AgentObject} from "./model/overview.ts"; +import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/material"; +import LanIcon from "@mui/icons-material/Lan"; +import {AccessDetail} from "./api"; +import DeleteIcon from "@mui/icons-material/Delete"; +import {GetAgentApi} from "./model/api.ts"; + +interface AccessCardProps { + accessObject: AgentObject; +} + +const AccessCard = ({ accessObject }: AccessCardProps) => { + let access = (accessObject.v as AccessDetail); + + const releaseAccess = () => { + GetAgentApi().agentReleaseAccess({frontendToken: access.frontendToken}) + .catch(e => { + console.log("error releasing access", e); + }); + } + + return ( + + + + + + + {access.frontendToken} + + + + + + + + + + + + {access.token} → {access.bindAddress} + + + + + + + + + ); +} + +export default AccessCard; \ No newline at end of file diff --git a/agent/agentUi/src/AgentUi.tsx b/agent/agentUi/src/AgentUi.tsx new file mode 100644 index 000000000..51d5624ee --- /dev/null +++ b/agent/agentUi/src/AgentUi.tsx @@ -0,0 +1,69 @@ +import {useEffect, useState} from "react"; +import {GetAgentApi} from "./model/api.ts"; +import NavBar from "./NavBar.tsx"; +import {AgentObject, buildOverview} from "./model/overview.ts"; +import Overview from "./Overview.tsx"; +import NewShareModal from "./NewShareModal.tsx"; +import NewAccessModal from "./NewAccessModal.tsx"; + +const AgentUi = () => { + const [version, setVersion] = useState("unset"); + const [overview, setOverview] = useState(new Array()); + const [newShareOpen, setNewShareOpen] = useState(false); + const [newAccessOpen, setNewAccessOpen] = useState(false); + + const openNewShare = () => { + setNewShareOpen(true); + } + const closeNewShare = () => { + setNewShareOpen(false); + } + + const openNewAccess = () => { + setNewAccessOpen(true); + } + const closeNewAccess = () => { + setNewAccessOpen(false); + } + + useEffect(() => { + GetAgentApi().agentVersion() + .then(r => { + if(r.v) { + setVersion(r.v); + } else { + console.log("unexpected", r); + } + }) + .catch(e => { + console.log(e); + }); + }, []); + + useEffect(() => { + let interval = setInterval(() => { + GetAgentApi().agentStatus() + .then(r => { + setOverview(buildOverview(r)); + }) + .catch(e => { + console.log(e); + }) + }, 1000); + return () => { + clearInterval(interval); + setOverview(new Array()); + } + }, []); + + return ( + <> + + + + + + ); +} + +export default AgentUi; \ No newline at end of file diff --git a/agent/agentUi/src/NavBar.tsx b/agent/agentUi/src/NavBar.tsx new file mode 100644 index 000000000..e9911b327 --- /dev/null +++ b/agent/agentUi/src/NavBar.tsx @@ -0,0 +1,37 @@ +import {AppBar, Box, Button, Grid2, IconButton, Toolbar, Typography} from "@mui/material"; +import MenuIcon from "@mui/icons-material/Menu"; +import LanIcon from "@mui/icons-material/Lan"; +import ShareIcon from "@mui/icons-material/Share"; + +interface NavBarProps { + version: string; + shareClick: () => void; + accessClick: () => void; +} + +const NavBar = ({ version, shareClick, accessClick }: NavBarProps) => { + return ( + + + + + + + + zrok Agent { version !== "" ? " | " + version : ""} + + + + + + + + + + + + + ); +} + +export default NavBar \ No newline at end of file diff --git a/agent/agentUi/src/NewAccessModal.tsx b/agent/agentUi/src/NewAccessModal.tsx new file mode 100644 index 000000000..8a5c55721 --- /dev/null +++ b/agent/agentUi/src/NewAccessModal.tsx @@ -0,0 +1,69 @@ +import {useState} from "react"; +import {useFormik} from "formik"; +import {GetAgentApi} from "./model/api.ts"; +import {Box, Button, Modal, TextField, Typography} from "@mui/material"; +import {modalStyle} from "./model/theme.ts"; +import * as React from "react"; + +interface NewAccessModalProps { + close: () => void; + isOpen: boolean; +} + +const NewAccessModal = ({ close, isOpen }: NewAccessModalProps) => { + const [errorMessage, setErrorMessage] = useState(null as React.JSX.Element); + + const newAccessForm = useFormik({ + initialValues: { + token: "", + bindAddress: "", + }, + onSubmit: v => { + setErrorMessage(null as React.JSX.Element); + GetAgentApi().agentAccessPrivate(v) + .then(r => { + close(); + }) + .catch(e => { + e.response.json().then(ex => { + setErrorMessage({ex.message}); + console.log(ex.message); + }) + }); + } + }); + + return ( + + +

Access...

+

{errorMessage}

+
+ + + + +
+
+ ); +} + +export default NewAccessModal; \ No newline at end of file diff --git a/agent/agentUi/src/NewShareModal.tsx b/agent/agentUi/src/NewShareModal.tsx new file mode 100644 index 000000000..7283f90f9 --- /dev/null +++ b/agent/agentUi/src/NewShareModal.tsx @@ -0,0 +1,146 @@ +import {useFormik} from "formik"; +import {GetAgentApi} from "./model/api.ts"; +import {useState} from "react"; +import {Box, Button, Checkbox, FormControlLabel, MenuItem, Modal, TextField, Typography} from "@mui/material"; +import {modalStyle} from "./model/theme.ts"; +import * as React from "react"; + +interface NewShareModalProps { + close: () => void; + isOpen: boolean; +} + +const NewShareModal = ({ close, isOpen }: NewShareModalProps) => { + const [errorMessage, setErrorMessage] = useState(null as React.JSX.Element); + + const form = useFormik({ + initialValues: { + shareMode: "public", + backendMode: "proxy", + target: "", + insecure: false, + }, + onSubmit: v => { + setErrorMessage(null as React.JSX.Element); + switch(v.shareMode) { + case "public": + GetAgentApi().agentSharePublic(v) + .then(r => { + close(); + }) + .catch(e => { + e.response.json().then(ex => { + setErrorMessage({ex.message}); + console.log(ex.message); + }) + }); + break; + + case "private": + GetAgentApi().agentSharePrivate(v) + .then(r => { + close(); + }) + .catch(e => { + e.response().json().then(ex => { + setErrorMessage({ex.message}); + console.log(ex.message); + }) + }); + break; + } + }, + }); + + return ( + + +

Share...

+

{errorMessage}

+
+ + public + private + + {form.values.shareMode === "public" && ( + + proxy + web + caddy + drive + + )} + {form.values.shareMode === "private" && ( + + proxy + web + tcpTunnel + udpTunnel + caddy + drive + socks + vpn + + )} + + {form.values.backendMode === "proxy" && ( + + } + label="Insecure" + sx={{ mt: 2 }} + /> + + )} + + +
+
+ ); +} + +export default NewShareModal; \ No newline at end of file diff --git a/agent/agentUi/src/Overview.tsx b/agent/agentUi/src/Overview.tsx new file mode 100644 index 000000000..c328482c1 --- /dev/null +++ b/agent/agentUi/src/Overview.tsx @@ -0,0 +1,47 @@ +import {AgentObject} from "./model/overview.ts"; +import {Box, Card, Grid2, Typography} from "@mui/material"; +import ShareIcon from "@mui/icons-material/Share"; +import LanIcon from "@mui/icons-material/Lan"; +import ShareCard from "./ShareCard.tsx"; +import AccessCard from "./AccessCard.tsx"; + +interface OverviewProps { + overview: Array; + shareClick: () => void; + accessClick: () => void; +} + +const Overview = ({ overview, shareClick, accessClick }: OverviewProps) => { + let cards = []; + if(overview.length > 0) { + overview.forEach(row => { + switch(row.type) { + case "access": + cards.push(); + break; + + case "share": + cards.push(); + break; + } + }); + } else { + cards.push( + + + + zrok Agent is empty! Add a share or access share to get started. + + + + ); + } + return ( + + {cards} + + ); +} + +export default Overview; \ No newline at end of file diff --git a/agent/agentUi/src/ShareCard.tsx b/agent/agentUi/src/ShareCard.tsx new file mode 100644 index 000000000..95ddf7624 --- /dev/null +++ b/agent/agentUi/src/ShareCard.tsx @@ -0,0 +1,64 @@ +import * as React from "react"; +import {AgentObject} from "./model/overview.ts"; +import {ShareDetail} from "./api"; +import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/material"; +import ShareIcon from "@mui/icons-material/Share"; +import DeleteIcon from "@mui/icons-material/Delete"; +import {GetAgentApi} from "./model/api.ts"; + +interface ShareCardProps { + shareObject: AgentObject; +} + +const ShareCard = ({ shareObject }: ShareCardProps) => { + let frontends = new Array(); + let share = (shareObject.v as ShareDetail); + share.frontendEndpoint!.map(fe => { + frontends.push({fe}); + }); + + const releaseShare = () => { + GetAgentApi().agentReleaseShare({token: share.token}) + .catch(e => { + console.log(e); + }); + } + + return ( + + + + + + + {share.token} + + + + + {share.shareMode === "public" && ( + + )} + {share.shareMode === "private" && ( + + )} + + + + + + + + {share.backendEndpoint} → {frontends}
+
+
+ + + + + +
+ ); +} + +export default ShareCard; \ No newline at end of file diff --git a/agent/agentUi/src/api/.openapi-generator-ignore b/agent/agentUi/src/api/.openapi-generator-ignore new file mode 100644 index 000000000..7484ee590 --- /dev/null +++ b/agent/agentUi/src/api/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/agent/agentUi/src/api/.openapi-generator/FILES b/agent/agentUi/src/api/.openapi-generator/FILES new file mode 100644 index 000000000..fe7bbe552 --- /dev/null +++ b/agent/agentUi/src/api/.openapi-generator/FILES @@ -0,0 +1,15 @@ +apis/AgentApi.ts +apis/index.ts +index.ts +models/AccessDetail.ts +models/AccessPrivateResponse.ts +models/ProtobufAny.ts +models/RpcStatus.ts +models/ShareDetail.ts +models/SharePrivateResponse.ts +models/SharePublicResponse.ts +models/ShareReservedResponse.ts +models/StatusResponse.ts +models/VersionResponse.ts +models/index.ts +runtime.ts diff --git a/agent/agentUi/src/api/.openapi-generator/VERSION b/agent/agentUi/src/api/.openapi-generator/VERSION new file mode 100644 index 000000000..1985849fb --- /dev/null +++ b/agent/agentUi/src/api/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.7.0 diff --git a/agent/agentUi/src/api/apis/AgentApi.ts b/agent/agentUi/src/api/apis/AgentApi.ts new file mode 100644 index 000000000..0424fd5d1 --- /dev/null +++ b/agent/agentUi/src/api/apis/AgentApi.ts @@ -0,0 +1,348 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import * as runtime from '../runtime'; +import type { + AccessPrivateResponse, + RpcStatus, + SharePrivateResponse, + SharePublicResponse, + StatusResponse, + VersionResponse, +} from '../models/index'; +import { + AccessPrivateResponseFromJSON, + AccessPrivateResponseToJSON, + RpcStatusFromJSON, + RpcStatusToJSON, + SharePrivateResponseFromJSON, + SharePrivateResponseToJSON, + SharePublicResponseFromJSON, + SharePublicResponseToJSON, + StatusResponseFromJSON, + StatusResponseToJSON, + VersionResponseFromJSON, + VersionResponseToJSON, +} from '../models/index'; + +export interface AgentAccessPrivateRequest { + token?: string; + bindAddress?: string; + autoMode?: boolean; + autoAddress?: string; + autoStartPort?: number; + autoEndPort?: number; + responseHeaders?: Array; +} + +export interface AgentReleaseAccessRequest { + frontendToken?: string; +} + +export interface AgentReleaseShareRequest { + token?: string; +} + +export interface AgentSharePrivateRequest { + target?: string; + backendMode?: string; + insecure?: boolean; + closed?: boolean; + accessGrants?: Array; +} + +export interface AgentSharePublicRequest { + target?: string; + basicAuth?: Array; + frontendSelection?: Array; + backendMode?: string; + insecure?: boolean; + oauthProvider?: string; + oauthEmailAddressPatterns?: Array; + oauthCheckInterval?: string; + closed?: boolean; + accessGrants?: Array; +} + +/** + * + */ +export class AgentApi extends runtime.BaseAPI { + + /** + */ + async agentAccessPrivateRaw(requestParameters: AgentAccessPrivateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + if (requestParameters['bindAddress'] != null) { + queryParameters['bindAddress'] = requestParameters['bindAddress']; + } + + if (requestParameters['autoMode'] != null) { + queryParameters['autoMode'] = requestParameters['autoMode']; + } + + if (requestParameters['autoAddress'] != null) { + queryParameters['autoAddress'] = requestParameters['autoAddress']; + } + + if (requestParameters['autoStartPort'] != null) { + queryParameters['autoStartPort'] = requestParameters['autoStartPort']; + } + + if (requestParameters['autoEndPort'] != null) { + queryParameters['autoEndPort'] = requestParameters['autoEndPort']; + } + + if (requestParameters['responseHeaders'] != null) { + queryParameters['responseHeaders'] = requestParameters['responseHeaders']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/accessPrivate`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => AccessPrivateResponseFromJSON(jsonValue)); + } + + /** + */ + async agentAccessPrivate(requestParameters: AgentAccessPrivateRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentAccessPrivateRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async agentReleaseAccessRaw(requestParameters: AgentReleaseAccessRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['frontendToken'] != null) { + queryParameters['frontendToken'] = requestParameters['frontendToken']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/releaseAccess`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + */ + async agentReleaseAccess(requestParameters: AgentReleaseAccessRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentReleaseAccessRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async agentReleaseShareRaw(requestParameters: AgentReleaseShareRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['token'] != null) { + queryParameters['token'] = requestParameters['token']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/releaseShare`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response); + } + + /** + */ + async agentReleaseShare(requestParameters: AgentReleaseShareRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentReleaseShareRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async agentSharePrivateRaw(requestParameters: AgentSharePrivateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['target'] != null) { + queryParameters['target'] = requestParameters['target']; + } + + if (requestParameters['backendMode'] != null) { + queryParameters['backendMode'] = requestParameters['backendMode']; + } + + if (requestParameters['insecure'] != null) { + queryParameters['insecure'] = requestParameters['insecure']; + } + + if (requestParameters['closed'] != null) { + queryParameters['closed'] = requestParameters['closed']; + } + + if (requestParameters['accessGrants'] != null) { + queryParameters['accessGrants'] = requestParameters['accessGrants']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/sharePrivate`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharePrivateResponseFromJSON(jsonValue)); + } + + /** + */ + async agentSharePrivate(requestParameters: AgentSharePrivateRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentSharePrivateRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async agentSharePublicRaw(requestParameters: AgentSharePublicRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + if (requestParameters['target'] != null) { + queryParameters['target'] = requestParameters['target']; + } + + if (requestParameters['basicAuth'] != null) { + queryParameters['basicAuth'] = requestParameters['basicAuth']; + } + + if (requestParameters['frontendSelection'] != null) { + queryParameters['frontendSelection'] = requestParameters['frontendSelection']; + } + + if (requestParameters['backendMode'] != null) { + queryParameters['backendMode'] = requestParameters['backendMode']; + } + + if (requestParameters['insecure'] != null) { + queryParameters['insecure'] = requestParameters['insecure']; + } + + if (requestParameters['oauthProvider'] != null) { + queryParameters['oauthProvider'] = requestParameters['oauthProvider']; + } + + if (requestParameters['oauthEmailAddressPatterns'] != null) { + queryParameters['oauthEmailAddressPatterns'] = requestParameters['oauthEmailAddressPatterns']; + } + + if (requestParameters['oauthCheckInterval'] != null) { + queryParameters['oauthCheckInterval'] = requestParameters['oauthCheckInterval']; + } + + if (requestParameters['closed'] != null) { + queryParameters['closed'] = requestParameters['closed']; + } + + if (requestParameters['accessGrants'] != null) { + queryParameters['accessGrants'] = requestParameters['accessGrants']; + } + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/sharePublic`, + method: 'POST', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => SharePublicResponseFromJSON(jsonValue)); + } + + /** + */ + async agentSharePublic(requestParameters: AgentSharePublicRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentSharePublicRaw(requestParameters, initOverrides); + return await response.value(); + } + + /** + */ + async agentStatusRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/status`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => StatusResponseFromJSON(jsonValue)); + } + + /** + */ + async agentStatus(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentStatusRaw(initOverrides); + return await response.value(); + } + + /** + */ + async agentVersionRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise> { + const queryParameters: any = {}; + + const headerParameters: runtime.HTTPHeaders = {}; + + const response = await this.request({ + path: `/v1/agent/version`, + method: 'GET', + headers: headerParameters, + query: queryParameters, + }, initOverrides); + + return new runtime.JSONApiResponse(response, (jsonValue) => VersionResponseFromJSON(jsonValue)); + } + + /** + */ + async agentVersion(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise { + const response = await this.agentVersionRaw(initOverrides); + return await response.value(); + } + +} diff --git a/agent/agentUi/src/api/apis/index.ts b/agent/agentUi/src/api/apis/index.ts new file mode 100644 index 000000000..5fe2a184b --- /dev/null +++ b/agent/agentUi/src/api/apis/index.ts @@ -0,0 +1,3 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './AgentApi'; diff --git a/agent/agentUi/src/api/index.ts b/agent/agentUi/src/api/index.ts new file mode 100644 index 000000000..bebe8bbbe --- /dev/null +++ b/agent/agentUi/src/api/index.ts @@ -0,0 +1,5 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './runtime'; +export * from './apis/index'; +export * from './models/index'; diff --git a/agent/agentUi/src/api/models/AccessDetail.ts b/agent/agentUi/src/api/models/AccessDetail.ts new file mode 100644 index 000000000..fb2fe7243 --- /dev/null +++ b/agent/agentUi/src/api/models/AccessDetail.ts @@ -0,0 +1,84 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AccessDetail + */ +export interface AccessDetail { + /** + * + * @type {string} + * @memberof AccessDetail + */ + frontendToken?: string; + /** + * + * @type {string} + * @memberof AccessDetail + */ + token?: string; + /** + * + * @type {string} + * @memberof AccessDetail + */ + bindAddress?: string; + /** + * + * @type {Array} + * @memberof AccessDetail + */ + responseHeaders?: Array; +} + +/** + * Check if a given object implements the AccessDetail interface. + */ +export function instanceOfAccessDetail(value: object): value is AccessDetail { + return true; +} + +export function AccessDetailFromJSON(json: any): AccessDetail { + return AccessDetailFromJSONTyped(json, false); +} + +export function AccessDetailFromJSONTyped(json: any, ignoreDiscriminator: boolean): AccessDetail { + if (json == null) { + return json; + } + return { + + 'frontendToken': json['frontendToken'] == null ? undefined : json['frontendToken'], + 'token': json['token'] == null ? undefined : json['token'], + 'bindAddress': json['bindAddress'] == null ? undefined : json['bindAddress'], + 'responseHeaders': json['responseHeaders'] == null ? undefined : json['responseHeaders'], + }; +} + +export function AccessDetailToJSON(value?: AccessDetail | null): any { + if (value == null) { + return value; + } + return { + + 'frontendToken': value['frontendToken'], + 'token': value['token'], + 'bindAddress': value['bindAddress'], + 'responseHeaders': value['responseHeaders'], + }; +} + diff --git a/agent/agentUi/src/api/models/AccessPrivateResponse.ts b/agent/agentUi/src/api/models/AccessPrivateResponse.ts new file mode 100644 index 000000000..42218c75d --- /dev/null +++ b/agent/agentUi/src/api/models/AccessPrivateResponse.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface AccessPrivateResponse + */ +export interface AccessPrivateResponse { + /** + * + * @type {string} + * @memberof AccessPrivateResponse + */ + frontendToken?: string; +} + +/** + * Check if a given object implements the AccessPrivateResponse interface. + */ +export function instanceOfAccessPrivateResponse(value: object): value is AccessPrivateResponse { + return true; +} + +export function AccessPrivateResponseFromJSON(json: any): AccessPrivateResponse { + return AccessPrivateResponseFromJSONTyped(json, false); +} + +export function AccessPrivateResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AccessPrivateResponse { + if (json == null) { + return json; + } + return { + + 'frontendToken': json['frontendToken'] == null ? undefined : json['frontendToken'], + }; +} + +export function AccessPrivateResponseToJSON(value?: AccessPrivateResponse | null): any { + if (value == null) { + return value; + } + return { + + 'frontendToken': value['frontendToken'], + }; +} + diff --git a/agent/agentUi/src/api/models/ProtobufAny.ts b/agent/agentUi/src/api/models/ProtobufAny.ts new file mode 100644 index 000000000..20703e350 --- /dev/null +++ b/agent/agentUi/src/api/models/ProtobufAny.ts @@ -0,0 +1,63 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ProtobufAny + */ +export interface ProtobufAny { + [key: string]: object | any; + /** + * + * @type {string} + * @memberof ProtobufAny + */ + type?: string; +} + +/** + * Check if a given object implements the ProtobufAny interface. + */ +export function instanceOfProtobufAny(value: object): value is ProtobufAny { + return true; +} + +export function ProtobufAnyFromJSON(json: any): ProtobufAny { + return ProtobufAnyFromJSONTyped(json, false); +} + +export function ProtobufAnyFromJSONTyped(json: any, ignoreDiscriminator: boolean): ProtobufAny { + if (json == null) { + return json; + } + return { + + ...json, + 'type': json['@type'] == null ? undefined : json['@type'], + }; +} + +export function ProtobufAnyToJSON(value?: ProtobufAny | null): any { + if (value == null) { + return value; + } + return { + + ...value, + '@type': value['type'], + }; +} + diff --git a/agent/agentUi/src/api/models/RpcStatus.ts b/agent/agentUi/src/api/models/RpcStatus.ts new file mode 100644 index 000000000..f27d807ea --- /dev/null +++ b/agent/agentUi/src/api/models/RpcStatus.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { ProtobufAny } from './ProtobufAny'; +import { + ProtobufAnyFromJSON, + ProtobufAnyFromJSONTyped, + ProtobufAnyToJSON, +} from './ProtobufAny'; + +/** + * + * @export + * @interface RpcStatus + */ +export interface RpcStatus { + /** + * + * @type {number} + * @memberof RpcStatus + */ + code?: number; + /** + * + * @type {string} + * @memberof RpcStatus + */ + message?: string; + /** + * + * @type {Array} + * @memberof RpcStatus + */ + details?: Array; +} + +/** + * Check if a given object implements the RpcStatus interface. + */ +export function instanceOfRpcStatus(value: object): value is RpcStatus { + return true; +} + +export function RpcStatusFromJSON(json: any): RpcStatus { + return RpcStatusFromJSONTyped(json, false); +} + +export function RpcStatusFromJSONTyped(json: any, ignoreDiscriminator: boolean): RpcStatus { + if (json == null) { + return json; + } + return { + + 'code': json['code'] == null ? undefined : json['code'], + 'message': json['message'] == null ? undefined : json['message'], + 'details': json['details'] == null ? undefined : ((json['details'] as Array).map(ProtobufAnyFromJSON)), + }; +} + +export function RpcStatusToJSON(value?: RpcStatus | null): any { + if (value == null) { + return value; + } + return { + + 'code': value['code'], + 'message': value['message'], + 'details': value['details'] == null ? undefined : ((value['details'] as Array).map(ProtobufAnyToJSON)), + }; +} + diff --git a/agent/agentUi/src/api/models/ShareDetail.ts b/agent/agentUi/src/api/models/ShareDetail.ts new file mode 100644 index 000000000..faf0b589d --- /dev/null +++ b/agent/agentUi/src/api/models/ShareDetail.ts @@ -0,0 +1,116 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ShareDetail + */ +export interface ShareDetail { + /** + * + * @type {string} + * @memberof ShareDetail + */ + token?: string; + /** + * + * @type {string} + * @memberof ShareDetail + */ + shareMode?: string; + /** + * + * @type {string} + * @memberof ShareDetail + */ + backendMode?: string; + /** + * + * @type {boolean} + * @memberof ShareDetail + */ + reserved?: boolean; + /** + * + * @type {Array} + * @memberof ShareDetail + */ + frontendEndpoint?: Array; + /** + * + * @type {string} + * @memberof ShareDetail + */ + backendEndpoint?: string; + /** + * + * @type {boolean} + * @memberof ShareDetail + */ + closed?: boolean; + /** + * + * @type {string} + * @memberof ShareDetail + */ + status?: string; +} + +/** + * Check if a given object implements the ShareDetail interface. + */ +export function instanceOfShareDetail(value: object): value is ShareDetail { + return true; +} + +export function ShareDetailFromJSON(json: any): ShareDetail { + return ShareDetailFromJSONTyped(json, false); +} + +export function ShareDetailFromJSONTyped(json: any, ignoreDiscriminator: boolean): ShareDetail { + if (json == null) { + return json; + } + return { + + 'token': json['token'] == null ? undefined : json['token'], + 'shareMode': json['shareMode'] == null ? undefined : json['shareMode'], + 'backendMode': json['backendMode'] == null ? undefined : json['backendMode'], + 'reserved': json['reserved'] == null ? undefined : json['reserved'], + 'frontendEndpoint': json['frontendEndpoint'] == null ? undefined : json['frontendEndpoint'], + 'backendEndpoint': json['backendEndpoint'] == null ? undefined : json['backendEndpoint'], + 'closed': json['closed'] == null ? undefined : json['closed'], + 'status': json['status'] == null ? undefined : json['status'], + }; +} + +export function ShareDetailToJSON(value?: ShareDetail | null): any { + if (value == null) { + return value; + } + return { + + 'token': value['token'], + 'shareMode': value['shareMode'], + 'backendMode': value['backendMode'], + 'reserved': value['reserved'], + 'frontendEndpoint': value['frontendEndpoint'], + 'backendEndpoint': value['backendEndpoint'], + 'closed': value['closed'], + 'status': value['status'], + }; +} + diff --git a/agent/agentUi/src/api/models/SharePrivateResponse.ts b/agent/agentUi/src/api/models/SharePrivateResponse.ts new file mode 100644 index 000000000..c9ea4109b --- /dev/null +++ b/agent/agentUi/src/api/models/SharePrivateResponse.ts @@ -0,0 +1,60 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SharePrivateResponse + */ +export interface SharePrivateResponse { + /** + * + * @type {string} + * @memberof SharePrivateResponse + */ + token?: string; +} + +/** + * Check if a given object implements the SharePrivateResponse interface. + */ +export function instanceOfSharePrivateResponse(value: object): value is SharePrivateResponse { + return true; +} + +export function SharePrivateResponseFromJSON(json: any): SharePrivateResponse { + return SharePrivateResponseFromJSONTyped(json, false); +} + +export function SharePrivateResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharePrivateResponse { + if (json == null) { + return json; + } + return { + + 'token': json['token'] == null ? undefined : json['token'], + }; +} + +export function SharePrivateResponseToJSON(value?: SharePrivateResponse | null): any { + if (value == null) { + return value; + } + return { + + 'token': value['token'], + }; +} + diff --git a/agent/agentUi/src/api/models/SharePublicResponse.ts b/agent/agentUi/src/api/models/SharePublicResponse.ts new file mode 100644 index 000000000..f1c0ae13f --- /dev/null +++ b/agent/agentUi/src/api/models/SharePublicResponse.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface SharePublicResponse + */ +export interface SharePublicResponse { + /** + * + * @type {string} + * @memberof SharePublicResponse + */ + token?: string; + /** + * + * @type {Array} + * @memberof SharePublicResponse + */ + frontendEndpoints?: Array; +} + +/** + * Check if a given object implements the SharePublicResponse interface. + */ +export function instanceOfSharePublicResponse(value: object): value is SharePublicResponse { + return true; +} + +export function SharePublicResponseFromJSON(json: any): SharePublicResponse { + return SharePublicResponseFromJSONTyped(json, false); +} + +export function SharePublicResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharePublicResponse { + if (json == null) { + return json; + } + return { + + 'token': json['token'] == null ? undefined : json['token'], + 'frontendEndpoints': json['frontendEndpoints'] == null ? undefined : json['frontendEndpoints'], + }; +} + +export function SharePublicResponseToJSON(value?: SharePublicResponse | null): any { + if (value == null) { + return value; + } + return { + + 'token': value['token'], + 'frontendEndpoints': value['frontendEndpoints'], + }; +} + diff --git a/agent/agentUi/src/api/models/ShareReservedResponse.ts b/agent/agentUi/src/api/models/ShareReservedResponse.ts new file mode 100644 index 000000000..6c77dea55 --- /dev/null +++ b/agent/agentUi/src/api/models/ShareReservedResponse.ts @@ -0,0 +1,92 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface ShareReservedResponse + */ +export interface ShareReservedResponse { + /** + * + * @type {string} + * @memberof ShareReservedResponse + */ + token?: string; + /** + * + * @type {string} + * @memberof ShareReservedResponse + */ + backendMode?: string; + /** + * + * @type {string} + * @memberof ShareReservedResponse + */ + shareMode?: string; + /** + * + * @type {Array} + * @memberof ShareReservedResponse + */ + frontendEndpoints?: Array; + /** + * + * @type {string} + * @memberof ShareReservedResponse + */ + target?: string; +} + +/** + * Check if a given object implements the ShareReservedResponse interface. + */ +export function instanceOfShareReservedResponse(value: object): value is ShareReservedResponse { + return true; +} + +export function ShareReservedResponseFromJSON(json: any): ShareReservedResponse { + return ShareReservedResponseFromJSONTyped(json, false); +} + +export function ShareReservedResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ShareReservedResponse { + if (json == null) { + return json; + } + return { + + 'token': json['token'] == null ? undefined : json['token'], + 'backendMode': json['backendMode'] == null ? undefined : json['backendMode'], + 'shareMode': json['shareMode'] == null ? undefined : json['shareMode'], + 'frontendEndpoints': json['frontendEndpoints'] == null ? undefined : json['frontendEndpoints'], + 'target': json['target'] == null ? undefined : json['target'], + }; +} + +export function ShareReservedResponseToJSON(value?: ShareReservedResponse | null): any { + if (value == null) { + return value; + } + return { + + 'token': value['token'], + 'backendMode': value['backendMode'], + 'shareMode': value['shareMode'], + 'frontendEndpoints': value['frontendEndpoints'], + 'target': value['target'], + }; +} + diff --git a/agent/agentUi/src/api/models/StatusResponse.ts b/agent/agentUi/src/api/models/StatusResponse.ts new file mode 100644 index 000000000..323c839bb --- /dev/null +++ b/agent/agentUi/src/api/models/StatusResponse.ts @@ -0,0 +1,81 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +import type { AccessDetail } from './AccessDetail'; +import { + AccessDetailFromJSON, + AccessDetailFromJSONTyped, + AccessDetailToJSON, +} from './AccessDetail'; +import type { ShareDetail } from './ShareDetail'; +import { + ShareDetailFromJSON, + ShareDetailFromJSONTyped, + ShareDetailToJSON, +} from './ShareDetail'; + +/** + * + * @export + * @interface StatusResponse + */ +export interface StatusResponse { + /** + * + * @type {Array} + * @memberof StatusResponse + */ + accesses?: Array; + /** + * + * @type {Array} + * @memberof StatusResponse + */ + shares?: Array; +} + +/** + * Check if a given object implements the StatusResponse interface. + */ +export function instanceOfStatusResponse(value: object): value is StatusResponse { + return true; +} + +export function StatusResponseFromJSON(json: any): StatusResponse { + return StatusResponseFromJSONTyped(json, false); +} + +export function StatusResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): StatusResponse { + if (json == null) { + return json; + } + return { + + 'accesses': json['accesses'] == null ? undefined : ((json['accesses'] as Array).map(AccessDetailFromJSON)), + 'shares': json['shares'] == null ? undefined : ((json['shares'] as Array).map(ShareDetailFromJSON)), + }; +} + +export function StatusResponseToJSON(value?: StatusResponse | null): any { + if (value == null) { + return value; + } + return { + + 'accesses': value['accesses'] == null ? undefined : ((value['accesses'] as Array).map(AccessDetailToJSON)), + 'shares': value['shares'] == null ? undefined : ((value['shares'] as Array).map(ShareDetailToJSON)), + }; +} + diff --git a/agent/agentUi/src/api/models/VersionResponse.ts b/agent/agentUi/src/api/models/VersionResponse.ts new file mode 100644 index 000000000..0936ccb02 --- /dev/null +++ b/agent/agentUi/src/api/models/VersionResponse.ts @@ -0,0 +1,68 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import { mapValues } from '../runtime'; +/** + * + * @export + * @interface VersionResponse + */ +export interface VersionResponse { + /** + * + * @type {string} + * @memberof VersionResponse + */ + v?: string; + /** + * + * @type {string} + * @memberof VersionResponse + */ + consoleEndpoint?: string; +} + +/** + * Check if a given object implements the VersionResponse interface. + */ +export function instanceOfVersionResponse(value: object): value is VersionResponse { + return true; +} + +export function VersionResponseFromJSON(json: any): VersionResponse { + return VersionResponseFromJSONTyped(json, false); +} + +export function VersionResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): VersionResponse { + if (json == null) { + return json; + } + return { + + 'v': json['v'] == null ? undefined : json['v'], + 'consoleEndpoint': json['consoleEndpoint'] == null ? undefined : json['consoleEndpoint'], + }; +} + +export function VersionResponseToJSON(value?: VersionResponse | null): any { + if (value == null) { + return value; + } + return { + + 'v': value['v'], + 'consoleEndpoint': value['consoleEndpoint'], + }; +} + diff --git a/agent/agentUi/src/api/models/index.ts b/agent/agentUi/src/api/models/index.ts new file mode 100644 index 000000000..ec0484034 --- /dev/null +++ b/agent/agentUi/src/api/models/index.ts @@ -0,0 +1,12 @@ +/* tslint:disable */ +/* eslint-disable */ +export * from './AccessDetail'; +export * from './AccessPrivateResponse'; +export * from './ProtobufAny'; +export * from './RpcStatus'; +export * from './ShareDetail'; +export * from './SharePrivateResponse'; +export * from './SharePublicResponse'; +export * from './ShareReservedResponse'; +export * from './StatusResponse'; +export * from './VersionResponse'; diff --git a/agent/agentUi/src/api/runtime.ts b/agent/agentUi/src/api/runtime.ts new file mode 100644 index 000000000..cf9f8e01f --- /dev/null +++ b/agent/agentUi/src/api/runtime.ts @@ -0,0 +1,426 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * agent/agentGrpc/agent.proto + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: version not set + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export const BASE_PATH = "http://localhost".replace(/\/+$/, ""); + +export interface ConfigurationParameters { + basePath?: string; // override base path + fetchApi?: FetchAPI; // override for fetch implementation + middleware?: Middleware[]; // middleware to apply before/after fetch requests + queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings + username?: string; // parameter for basic security + password?: string; // parameter for basic security + apiKey?: string | Promise | ((name: string) => string | Promise); // parameter for apiKey security + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string | Promise); // parameter for oauth2 security + headers?: HTTPHeaders; //header params we want to use on every request + credentials?: RequestCredentials; //value for the credentials param we want to use on each request +} + +export class Configuration { + constructor(private configuration: ConfigurationParameters = {}) {} + + set config(configuration: Configuration) { + this.configuration = configuration; + } + + get basePath(): string { + return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH; + } + + get fetchApi(): FetchAPI | undefined { + return this.configuration.fetchApi; + } + + get middleware(): Middleware[] { + return this.configuration.middleware || []; + } + + get queryParamsStringify(): (params: HTTPQuery) => string { + return this.configuration.queryParamsStringify || querystring; + } + + get username(): string | undefined { + return this.configuration.username; + } + + get password(): string | undefined { + return this.configuration.password; + } + + get apiKey(): ((name: string) => string | Promise) | undefined { + const apiKey = this.configuration.apiKey; + if (apiKey) { + return typeof apiKey === 'function' ? apiKey : () => apiKey; + } + return undefined; + } + + get accessToken(): ((name?: string, scopes?: string[]) => string | Promise) | undefined { + const accessToken = this.configuration.accessToken; + if (accessToken) { + return typeof accessToken === 'function' ? accessToken : async () => accessToken; + } + return undefined; + } + + get headers(): HTTPHeaders | undefined { + return this.configuration.headers; + } + + get credentials(): RequestCredentials | undefined { + return this.configuration.credentials; + } +} + +export const DefaultConfig = new Configuration(); + +/** + * This is the base class for all generated API classes. + */ +export class BaseAPI { + + private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i'); + private middleware: Middleware[]; + + constructor(protected configuration = DefaultConfig) { + this.middleware = configuration.middleware; + } + + withMiddleware(this: T, ...middlewares: Middleware[]) { + const next = this.clone(); + next.middleware = next.middleware.concat(...middlewares); + return next; + } + + withPreMiddleware(this: T, ...preMiddlewares: Array) { + const middlewares = preMiddlewares.map((pre) => ({ pre })); + return this.withMiddleware(...middlewares); + } + + withPostMiddleware(this: T, ...postMiddlewares: Array) { + const middlewares = postMiddlewares.map((post) => ({ post })); + return this.withMiddleware(...middlewares); + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + protected isJsonMime(mime: string | null | undefined): boolean { + if (!mime) { + return false; + } + return BaseAPI.jsonRegex.test(mime); + } + + protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise { + const { url, init } = await this.createFetchParams(context, initOverrides); + const response = await this.fetchApi(url, init); + if (response && (response.status >= 200 && response.status < 300)) { + return response; + } + throw new ResponseError(response, 'Response returned an error code'); + } + + private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) { + let url = this.configuration.basePath + context.path; + if (context.query !== undefined && Object.keys(context.query).length !== 0) { + // only add the querystring to the URL if there are query parameters. + // this is done to avoid urls ending with a "?" character which buggy webservers + // do not handle correctly sometimes. + url += '?' + this.configuration.queryParamsStringify(context.query); + } + + const headers = Object.assign({}, this.configuration.headers, context.headers); + Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {}); + + const initOverrideFn = + typeof initOverrides === "function" + ? initOverrides + : async () => initOverrides; + + const initParams = { + method: context.method, + headers, + body: context.body, + credentials: this.configuration.credentials, + }; + + const overriddenInit: RequestInit = { + ...initParams, + ...(await initOverrideFn({ + init: initParams, + context, + })) + }; + + let body: any; + if (isFormData(overriddenInit.body) + || (overriddenInit.body instanceof URLSearchParams) + || isBlob(overriddenInit.body)) { + body = overriddenInit.body; + } else if (this.isJsonMime(headers['Content-Type'])) { + body = JSON.stringify(overriddenInit.body); + } else { + body = overriddenInit.body; + } + + const init: RequestInit = { + ...overriddenInit, + body + }; + + return { url, init }; + } + + private fetchApi = async (url: string, init: RequestInit) => { + let fetchParams = { url, init }; + for (const middleware of this.middleware) { + if (middleware.pre) { + fetchParams = await middleware.pre({ + fetch: this.fetchApi, + ...fetchParams, + }) || fetchParams; + } + } + let response: Response | undefined = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response === undefined) { + if (e instanceof Error) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } else { + throw e; + } + } + } + for (const middleware of this.middleware) { + if (middleware.post) { + response = await middleware.post({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + response: response.clone(), + }) || response; + } + } + return response; + } + + /** + * Create a shallow clone of `this` by constructing a new instance + * and then shallow cloning data members. + */ + private clone(this: T): T { + const constructor = this.constructor as any; + const next = new constructor(this.configuration); + next.middleware = this.middleware.slice(); + return next; + } +}; + +function isBlob(value: any): value is Blob { + return typeof Blob !== 'undefined' && value instanceof Blob; +} + +function isFormData(value: any): value is FormData { + return typeof FormData !== "undefined" && value instanceof FormData; +} + +export class ResponseError extends Error { + override name: "ResponseError" = "ResponseError"; + constructor(public response: Response, msg?: string) { + super(msg); + } +} + +export class FetchError extends Error { + override name: "FetchError" = "FetchError"; + constructor(public cause: Error, msg?: string) { + super(msg); + } +} + +export class RequiredError extends Error { + override name: "RequiredError" = "RequiredError"; + constructor(public field: string, msg?: string) { + super(msg); + } +} + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export type FetchAPI = WindowOrWorkerGlobalScope['fetch']; + +export type Json = any; +export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD'; +export type HTTPHeaders = { [key: string]: string }; +export type HTTPQuery = { [key: string]: string | number | null | boolean | Array | Set | HTTPQuery }; +export type HTTPBody = Json | FormData | URLSearchParams; +export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody }; +export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original'; + +export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise + +export interface FetchParams { + url: string; + init: RequestInit; +} + +export interface RequestOpts { + path: string; + method: HTTPMethod; + headers: HTTPHeaders; + query?: HTTPQuery; + body?: HTTPBody; +} + +export function querystring(params: HTTPQuery, prefix: string = ''): string { + return Object.keys(params) + .map(key => querystringSingleKey(key, params[key], prefix)) + .filter(part => part.length > 0) + .join('&'); +} + +function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array | Set | HTTPQuery, keyPrefix: string = ''): string { + const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key); + if (value instanceof Array) { + const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue))) + .join(`&${encodeURIComponent(fullKey)}=`); + return `${encodeURIComponent(fullKey)}=${multiValue}`; + } + if (value instanceof Set) { + const valueAsArray = Array.from(value); + return querystringSingleKey(key, valueAsArray, keyPrefix); + } + if (value instanceof Date) { + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`; + } + if (value instanceof Object) { + return querystring(value as HTTPQuery, fullKey); + } + return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`; +} + +export function mapValues(data: any, fn: (item: any) => any) { + return Object.keys(data).reduce( + (acc, key) => ({ ...acc, [key]: fn(data[key]) }), + {} + ); +} + +export function canConsumeForm(consumes: Consume[]): boolean { + for (const consume of consumes) { + if ('multipart/form-data' === consume.contentType) { + return true; + } + } + return false; +} + +export interface Consume { + contentType: string; +} + +export interface RequestContext { + fetch: FetchAPI; + url: string; + init: RequestInit; +} + +export interface ResponseContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + response: Response; +} + +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + +export interface Middleware { + pre?(context: RequestContext): Promise; + post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; +} + +export interface ApiResponse { + raw: Response; + value(): Promise; +} + +export interface ResponseTransformer { + (json: any): T; +} + +export class JSONApiResponse { + constructor(public raw: Response, private transformer: ResponseTransformer = (jsonValue: any) => jsonValue) {} + + async value(): Promise { + return this.transformer(await this.raw.json()); + } +} + +export class VoidApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return undefined; + } +} + +export class BlobApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.blob(); + }; +} + +export class TextApiResponse { + constructor(public raw: Response) {} + + async value(): Promise { + return await this.raw.text(); + }; +} diff --git a/agent/agentUi/src/index.css b/agent/agentUi/src/index.css new file mode 100644 index 000000000..0b98df584 --- /dev/null +++ b/agent/agentUi/src/index.css @@ -0,0 +1,55 @@ +body { + margin: 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + padding-bottom: 15px; + min-width: 320px; + min-height: 100vh; +} + +code { + font-family: 'JetBrains Mono', sans-serif; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; +} + +#footer { + text-align: center; +} diff --git a/agent/agentUi/src/main.tsx b/agent/agentUi/src/main.tsx new file mode 100644 index 000000000..5ec0aa201 --- /dev/null +++ b/agent/agentUi/src/main.tsx @@ -0,0 +1,14 @@ +import "./index.css"; +import {StrictMode} from "react"; +import {createRoot} from "react-dom/client"; +import {ThemeProvider} from "@mui/material"; +import {theme} from "./model/theme.ts"; +import AgentUi from "./AgentUi.tsx"; + +createRoot(document.getElementById('root')!).render( + + + + + +) diff --git a/agent/agentUi/src/model/api.ts b/agent/agentUi/src/model/api.ts new file mode 100644 index 000000000..f7f860f52 --- /dev/null +++ b/agent/agentUi/src/model/api.ts @@ -0,0 +1,5 @@ +import {AgentApi, Configuration} from "../api"; + +export const GetAgentApi = () => { + return new AgentApi(new Configuration({basePath: window.location.origin})); +} diff --git a/agent/agentUi/src/model/overview.ts b/agent/agentUi/src/model/overview.ts new file mode 100644 index 000000000..b7b97142d --- /dev/null +++ b/agent/agentUi/src/model/overview.ts @@ -0,0 +1,36 @@ +import {AccessDetail, ShareDetail, StatusResponse} from "../api"; + +export class AgentObject { + type: string; + id: string; + v: (ShareDetail|AccessDetail); +} + +export function buildOverview(status: StatusResponse): Array { + let out = new Array(); + if(status) { + if(status.accesses) { + status.accesses.forEach(acc => { + let accObj = new AgentObject(); + accObj.type = "access"; + accObj.id = acc.frontendToken!; + accObj.v = acc; + out.push(accObj); + }); + } + if(status.shares) { + status.shares.forEach(shr => { + let shrObj = new AgentObject(); + shrObj.type = "share"; + shrObj.id = shr.token!; + shrObj.v = shr; + out.push(shrObj); + }); + } + out.sort((a, b) => { + if(a.id < b.id) return -1; + if(a.id > b.id) return 1; + }); + } + return out; +} \ No newline at end of file diff --git a/agent/agentUi/src/model/theme.ts b/agent/agentUi/src/model/theme.ts new file mode 100644 index 000000000..7d10bc70d --- /dev/null +++ b/agent/agentUi/src/model/theme.ts @@ -0,0 +1,47 @@ +import {createTheme} from "@mui/material"; + +const componentOptions = { + MuiCard: { + styleOverrides: { + root: ({theme}) => theme.unstable_sx({ + mt: 5, + p: 1, + borderRadius: 3, + }), + } + }, + MuiAppBar: { + styleOverrides: { + root : ({theme}) => theme.unstable_sx({ + borderRadius: 3, + }), + } + } +} + +export const theme = createTheme({ + components: componentOptions, + palette: { + mode: 'light', + primary: { + main: '#241775', + }, + secondary: { + main: '#9bf316', + }, + }, + typography: { + fontFamily: 'Poppins', + }, +}) + +export const modalStyle = { + position: 'absolute', + top: '25%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 600, + bgcolor: 'background.paper', + boxShadow: 24, + p: 4, +}; \ No newline at end of file diff --git a/agent/agentUi/src/vite-env.d.ts b/agent/agentUi/src/vite-env.d.ts new file mode 100644 index 000000000..11f02fe2a --- /dev/null +++ b/agent/agentUi/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/agent/agentUi/tsconfig.app.json b/agent/agentUi/tsconfig.app.json new file mode 100644 index 000000000..f867de0dd --- /dev/null +++ b/agent/agentUi/tsconfig.app.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/agent/agentUi/tsconfig.json b/agent/agentUi/tsconfig.json new file mode 100644 index 000000000..1ffef600d --- /dev/null +++ b/agent/agentUi/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/agent/agentUi/tsconfig.node.json b/agent/agentUi/tsconfig.node.json new file mode 100644 index 000000000..abcd7f0da --- /dev/null +++ b/agent/agentUi/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/agent/agentUi/vite.config.ts b/agent/agentUi/vite.config.ts new file mode 100644 index 000000000..f20a1e394 --- /dev/null +++ b/agent/agentUi/vite.config.ts @@ -0,0 +1,15 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + '/v1': { + target: 'http://localhost:8888', + changeOrigin: true, + } + } + } +}) diff --git a/agent/config.go b/agent/config.go new file mode 100644 index 000000000..e44e37a81 --- /dev/null +++ b/agent/config.go @@ -0,0 +1,15 @@ +package agent + +type AgentConfig struct { + ConsoleAddress string + ConsoleStartPort uint16 + ConsoleEndPort uint16 +} + +func DefaultConfig() *AgentConfig { + return &AgentConfig{ + ConsoleAddress: "127.0.0.1", + ConsoleStartPort: 8080, + ConsoleEndPort: 8181, + } +} diff --git a/agent/proctree/impl_posix.go b/agent/proctree/impl_posix.go new file mode 100644 index 000000000..aa8596c56 --- /dev/null +++ b/agent/proctree/impl_posix.go @@ -0,0 +1,59 @@ +//go:build !windows + +package proctree + +import ( + "os/exec" + "sync" +) + +func Init(_ string) error { + return nil +} + +func StartChild(tail TailFunction, args ...string) (*Child, error) { + cmd := exec.Command(args[0], args[1:]...) + + cld := &Child{ + TailFunction: tail, + cmd: cmd, + outStream: make(chan []byte), + errStream: make(chan []byte), + wg: new(sync.WaitGroup), + } + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + if err := cmd.Start(); err != nil { + return nil, err + } + + cld.wg.Add(3) + go reader(stdout, cld.outStream, cld.wg) + go reader(stderr, cld.errStream, cld.wg) + go cld.combiner(cld.wg) + + return cld, nil +} + +func WaitChild(c *Child) error { + c.wg.Wait() + if err := c.cmd.Wait(); err != nil { + return err + } + return nil +} + +func StopChild(c *Child) error { + if err := c.cmd.Process.Kill(); err != nil { + return err + } + return nil +} diff --git a/agent/proctree/impl_windows.go b/agent/proctree/impl_windows.go new file mode 100755 index 000000000..6a446fe8b --- /dev/null +++ b/agent/proctree/impl_windows.go @@ -0,0 +1,79 @@ +//go:build windows + +package proctree + +import ( + "github.com/kolesnikovae/go-winjob" + "golang.org/x/sys/windows" + "os/exec" + "sync" +) + +var job *winjob.JobObject + +func Init(name string) error { + var err error + if job == nil { + job, err = winjob.Create(name, winjob.LimitKillOnJobClose, winjob.LimitBreakawayOK) + if err != nil { + return err + } + } + return nil +} + +func StartChild(tail TailFunction, args ...string) (*Child, error) { + cmd := exec.Command(args[0], args[1:]...) + cmd.SysProcAttr = &windows.SysProcAttr{CreationFlags: windows.CREATE_SUSPENDED} + + cld := &Child{ + TailFunction: tail, + cmd: cmd, + outStream: make(chan []byte), + errStream: make(chan []byte), + wg: new(sync.WaitGroup), + } + + stdout, err := cmd.StdoutPipe() + if err != nil { + return nil, err + } + stderr, err := cmd.StderrPipe() + if err != nil { + return nil, err + } + + if err := cmd.Start(); err != nil { + return nil, err + } + + if err := job.Assign(cmd.Process); err != nil { + return nil, err + } + + if err := winjob.ResumeProcess(cmd.Process.Pid); err != nil { + return nil, err + } + + cld.wg.Add(3) + go reader(stdout, cld.outStream, cld.wg) + go reader(stderr, cld.errStream, cld.wg) + go cld.combiner(cld.wg) + + return cld, nil +} + +func WaitChild(c *Child) error { + c.wg.Wait() + if err := c.cmd.Wait(); err != nil { + return err + } + return nil +} + +func StopChild(c *Child) error { + if err := c.cmd.Process.Kill(); err != nil { + return err + } + return nil +} diff --git a/agent/proctree/proctree.go b/agent/proctree/proctree.go new file mode 100755 index 000000000..506435b0a --- /dev/null +++ b/agent/proctree/proctree.go @@ -0,0 +1,67 @@ +package proctree + +import ( + "fmt" + _ "github.com/kolesnikovae/go-winjob" + "io" + "os/exec" + "sync" +) + +type Child struct { + TailFunction TailFunction + cmd *exec.Cmd + outStream chan []byte + errStream chan []byte + wg *sync.WaitGroup +} + +type TailFunction func(data []byte) + +func (c *Child) combiner(wg *sync.WaitGroup) { + defer wg.Done() + + outDone := false + errDone := false + for { + select { + case data := <-c.outStream: + if data != nil { + if c.TailFunction != nil { + c.TailFunction(data) + } + } else { + outDone = true + } + case data := <-c.errStream: + if data != nil { + if c.TailFunction != nil { + c.TailFunction(data) + } + } else { + errDone = true + } + } + if outDone && errDone { + return + } + } +} + +func reader(r io.ReadCloser, o chan []byte, wg *sync.WaitGroup) { + defer close(o) + defer wg.Done() + + buf := make([]byte, 64*1024) + for { + n, err := r.Read(buf) + if err != nil { + if err == io.EOF { + return + } + fmt.Printf("error reading: %v", err) + return + } + o <- buf[:n] + } +} diff --git a/agent/releaseAccess.go b/agent/releaseAccess.go new file mode 100644 index 000000000..86e2f8d23 --- /dev/null +++ b/agent/releaseAccess.go @@ -0,0 +1,19 @@ +package agent + +import ( + "context" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func (i *agentGrpcImpl) ReleaseAccess(_ context.Context, req *agentGrpc.ReleaseAccessRequest) (*agentGrpc.ReleaseAccessResponse, error) { + if acc, found := i.agent.accesses[req.FrontendToken]; found { + i.agent.rmAccess <- acc + logrus.Infof("released access '%v'", acc.frontendToken) + + } else { + return nil, errors.Errorf("agent has no access with frontend token '%v'", req.FrontendToken) + } + return nil, nil +} diff --git a/agent/releaseShare.go b/agent/releaseShare.go new file mode 100755 index 000000000..0759e1c57 --- /dev/null +++ b/agent/releaseShare.go @@ -0,0 +1,19 @@ +package agent + +import ( + "context" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func (i *agentGrpcImpl) ReleaseShare(_ context.Context, req *agentGrpc.ReleaseShareRequest) (*agentGrpc.ReleaseShareResponse, error) { + if shr, found := i.agent.shares[req.Token]; found { + i.agent.rmShare <- shr + logrus.Infof("released share '%v'", shr.token) + + } else { + return nil, errors.Errorf("agent has no share with token '%v'", req.Token) + } + return nil, nil +} diff --git a/agent/share.go b/agent/share.go new file mode 100644 index 000000000..d90ad0fb1 --- /dev/null +++ b/agent/share.go @@ -0,0 +1,83 @@ +package agent + +import ( + "errors" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" + "github.com/openziti/zrok/sdk/golang/sdk" + "time" +) + +type share struct { + token string + frontendEndpoints []string + target string + basicAuth []string + frontendSelection []string + shareMode sdk.ShareMode + backendMode sdk.BackendMode + reserved bool + insecure bool + oauthProvider string + oauthEmailAddressPatterns []string + oauthCheckInterval time.Duration + closed bool + accessGrants []string + + process *proctree.Child + sub *subordinate.MessageHandler + + agent *Agent +} + +func (s *share) monitor() { + if err := proctree.WaitChild(s.process); err != nil { + pfxlog.ChannelLogger(s.token).Error(err) + } + s.agent.rmShare <- s +} + +func (s *share) bootHandler(msgType string, msg subordinate.Message) error { + switch msgType { + case subordinate.BootMessage: + if v, found := msg["token"]; found { + if str, ok := v.(string); ok { + s.token = str + } + } + if v, found := msg["backend_mode"]; found { + if str, ok := v.(string); ok { + s.backendMode = sdk.BackendMode(str) + } + } + if v, found := msg["share_mode"]; found { + if str, ok := v.(string); ok { + s.shareMode = sdk.ShareMode(str) + } + } + if v, found := msg["frontend_endpoints"]; found { + if vArr, ok := v.([]interface{}); ok { + for _, v := range vArr { + if str, ok := v.(string); ok { + s.frontendEndpoints = append(s.frontendEndpoints, str) + } + } + } + } + if v, found := msg["target"]; found { + if str, ok := v.(string); ok { + s.target = str + } + } + + case subordinate.ErrorMessage: + if v, found := msg[subordinate.ErrorMessage]; found { + if str, ok := v.(string); ok { + return errors.New(str) + } + } + } + + return nil +} diff --git a/agent/sharePrivate.go b/agent/sharePrivate.go new file mode 100644 index 000000000..350ff5aac --- /dev/null +++ b/agent/sharePrivate.go @@ -0,0 +1,82 @@ +package agent + +import ( + "context" + "errors" + "fmt" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/sdk/golang/sdk" + "github.com/sirupsen/logrus" + "os" +) + +func (i *agentGrpcImpl) SharePrivate(_ context.Context, req *agentGrpc.SharePrivateRequest) (*agentGrpc.SharePrivateResponse, error) { + root, err := environment.LoadRoot() + if err != nil { + return nil, err + } + + if !root.IsEnabled() { + return nil, errors.New("unable to load environment; did you 'zrok enable'?") + } + + shrCmd := []string{os.Args[0], "share", "private", "--subordinate", "-b", req.BackendMode} + shr := &share{ + shareMode: sdk.PrivateShareMode, + backendMode: sdk.BackendMode(req.BackendMode), + sub: subordinate.NewMessageHandler(), + agent: i.agent, + } + shr.sub.MessageHandler = func(msg subordinate.Message) { + logrus.Info(msg) + } + var bootErr error + shr.sub.BootHandler = func(msgType string, msg subordinate.Message) { + bootErr = shr.bootHandler(msgType, msg) + } + shr.sub.MalformedHandler = func(msg subordinate.Message) { + logrus.Error(msg) + } + + if req.Insecure { + shrCmd = append(shrCmd, "--insecure") + } + shr.insecure = req.Insecure + + if req.Closed { + shrCmd = append(shrCmd, "--closed") + } + shr.closed = req.Closed + + for _, grant := range req.AccessGrants { + shrCmd = append(shrCmd, "--access-grant", grant) + } + shr.accessGrants = req.AccessGrants + + shrCmd = append(shrCmd, req.Target) + shr.target = req.Target + + logrus.Infof("executing '%v'", shrCmd) + + shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...) + if err != nil { + return nil, err + } + + <-shr.sub.BootComplete + + if bootErr == nil { + go shr.monitor() + i.agent.addShare <- shr + return &agentGrpc.SharePrivateResponse{Token: shr.token}, nil + + } else { + if err := proctree.WaitChild(shr.process); err != nil { + logrus.Errorf("error joining: %v", err) + } + return nil, fmt.Errorf("unable to start share: %v", bootErr) + } +} diff --git a/agent/sharePublic.go b/agent/sharePublic.go new file mode 100644 index 000000000..fb584eda2 --- /dev/null +++ b/agent/sharePublic.go @@ -0,0 +1,109 @@ +package agent + +import ( + "context" + "errors" + "fmt" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/sdk/golang/sdk" + "github.com/sirupsen/logrus" + "os" +) + +func (i *agentGrpcImpl) SharePublic(_ context.Context, req *agentGrpc.SharePublicRequest) (*agentGrpc.SharePublicResponse, error) { + root, err := environment.LoadRoot() + if err != nil { + return nil, err + } + + if !root.IsEnabled() { + return nil, errors.New("unable to load environment; did you 'zrok enable'?") + } + + shrCmd := []string{os.Args[0], "share", "public", "--subordinate", "-b", req.BackendMode} + shr := &share{ + shareMode: sdk.PublicShareMode, + backendMode: sdk.BackendMode(req.BackendMode), + sub: subordinate.NewMessageHandler(), + agent: i.agent, + } + shr.sub.MessageHandler = func(msg subordinate.Message) { + logrus.Info(msg) + } + var bootErr error + shr.sub.BootHandler = func(msgType string, msg subordinate.Message) { + bootErr = shr.bootHandler(msgType, msg) + } + shr.sub.MalformedHandler = func(msg subordinate.Message) { + logrus.Error(msg) + } + + for _, basicAuth := range req.BasicAuth { + shrCmd = append(shrCmd, "--basic-auth", basicAuth) + } + shr.basicAuth = req.BasicAuth + + for _, frontendSelection := range req.FrontendSelection { + shrCmd = append(shrCmd, "--frontend", frontendSelection) + } + shr.frontendSelection = req.FrontendSelection + + if req.Insecure { + shrCmd = append(shrCmd, "--insecure") + } + shr.insecure = req.Insecure + + if req.OauthProvider != "" { + shrCmd = append(shrCmd, "--oauth-provider", req.OauthProvider) + } + shr.oauthProvider = req.OauthProvider + + for _, pattern := range req.OauthEmailAddressPatterns { + shrCmd = append(shrCmd, "--oauth-email-address-patterns", pattern) + } + shr.oauthEmailAddressPatterns = req.OauthEmailAddressPatterns + + if req.OauthCheckInterval != "" { + shrCmd = append(shrCmd, "--oauth-check-interval", req.OauthCheckInterval) + } + + if req.Closed { + shrCmd = append(shrCmd, "--closed") + } + shr.closed = req.Closed + + for _, grant := range req.AccessGrants { + shrCmd = append(shrCmd, "--access-grant", grant) + } + shr.accessGrants = req.AccessGrants + + shrCmd = append(shrCmd, req.Target) + shr.target = req.Target + + logrus.Infof("executing '%v'", shrCmd) + + shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...) + if err != nil { + return nil, err + } + + <-shr.sub.BootComplete + + if bootErr == nil { + go shr.monitor() + i.agent.addShare <- shr + return &agentGrpc.SharePublicResponse{ + Token: shr.token, + FrontendEndpoints: shr.frontendEndpoints, + }, nil + + } else { + if err := proctree.WaitChild(shr.process); err != nil { + logrus.Errorf("error joining: %v", err) + } + return nil, fmt.Errorf("unable to start share: %v", bootErr) + } +} diff --git a/agent/shareReserved.go b/agent/shareReserved.go new file mode 100644 index 000000000..cfa5eebcb --- /dev/null +++ b/agent/shareReserved.go @@ -0,0 +1,78 @@ +package agent + +import ( + "context" + "errors" + "fmt" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/agent/proctree" + "github.com/openziti/zrok/cmd/zrok/subordinate" + "github.com/openziti/zrok/environment" + "github.com/sirupsen/logrus" + "os" +) + +func (i *agentGrpcImpl) ShareReserved(_ context.Context, req *agentGrpc.ShareReservedRequest) (*agentGrpc.ShareReservedResponse, error) { + root, err := environment.LoadRoot() + if err != nil { + return nil, err + } + + if !root.IsEnabled() { + return nil, errors.New("unable to load environment; did you 'zrok enable'?") + } + + shrCmd := []string{os.Args[0], "share", "reserved", "--subordinate"} + shr := &share{ + reserved: true, + sub: subordinate.NewMessageHandler(), + agent: i.agent, + } + shr.sub.MessageHandler = func(msg subordinate.Message) { + logrus.Info(msg) + } + var bootErr error + shr.sub.BootHandler = func(msgType string, msg subordinate.Message) { + bootErr = shr.bootHandler(msgType, msg) + } + shr.sub.MalformedHandler = func(msg subordinate.Message) { + logrus.Error(msg) + } + + if req.OverrideEndpoint != "" { + shrCmd = append(shrCmd, "--override-endpoint", req.OverrideEndpoint) + } + + if req.Insecure { + shrCmd = append(shrCmd, "--insecure") + } + shr.insecure = req.Insecure + + shrCmd = append(shrCmd, req.Token) + shr.token = req.Token + + shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...) + if err != nil { + return nil, err + } + + <-shr.sub.BootComplete + + if bootErr == nil { + go shr.monitor() + i.agent.addShare <- shr + return &agentGrpc.ShareReservedResponse{ + Token: shr.token, + BackendMode: string(shr.backendMode), + ShareMode: string(shr.shareMode), + FrontendEndpoints: shr.frontendEndpoints, + Target: shr.target, + }, nil + + } else { + if err := proctree.WaitChild(shr.process); err != nil { + logrus.Errorf("error joining: %v", err) + } + return nil, fmt.Errorf("unable to start share: %v", bootErr) + } +} diff --git a/agent/status.go b/agent/status.go new file mode 100644 index 000000000..f3dbda592 --- /dev/null +++ b/agent/status.go @@ -0,0 +1,40 @@ +package agent + +import ( + "context" + "github.com/openziti/zrok/agent/agentGrpc" + "sort" +) + +func (i *agentGrpcImpl) Status(_ context.Context, _ *agentGrpc.StatusRequest) (*agentGrpc.StatusResponse, error) { + var accesses []*agentGrpc.AccessDetail + for feToken, acc := range i.agent.accesses { + accesses = append(accesses, &agentGrpc.AccessDetail{ + FrontendToken: feToken, + Token: acc.token, + BindAddress: acc.bindAddress, + ResponseHeaders: acc.responseHeaders, + }) + } + sort.Slice(accesses, func(i, j int) bool { + return accesses[i].FrontendToken < accesses[j].FrontendToken + }) + + var shares []*agentGrpc.ShareDetail + for token, shr := range i.agent.shares { + shares = append(shares, &agentGrpc.ShareDetail{ + Token: token, + ShareMode: string(shr.shareMode), + BackendMode: string(shr.backendMode), + Reserved: shr.reserved, + FrontendEndpoint: shr.frontendEndpoints, + BackendEndpoint: shr.target, + Closed: shr.closed, + }) + } + sort.Slice(shares, func(i, j int) bool { + return shares[i].Token < shares[j].Token + }) + + return &agentGrpc.StatusResponse{Accesses: accesses, Shares: shares}, nil +} diff --git a/agent/version.go b/agent/version.go new file mode 100644 index 000000000..5633b34d3 --- /dev/null +++ b/agent/version.go @@ -0,0 +1,17 @@ +package agent + +import ( + "context" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/build" + "github.com/sirupsen/logrus" +) + +func (i *agentGrpcImpl) Version(_ context.Context, _ *agentGrpc.VersionRequest) (*agentGrpc.VersionResponse, error) { + v := build.String() + logrus.Debugf("responding to version inquiry with '%v'", v) + return &agentGrpc.VersionResponse{ + V: v, + ConsoleEndpoint: i.agent.httpEndpoint, + }, nil +} diff --git a/bin/generate_pb.sh b/bin/generate_pb.sh new file mode 100755 index 000000000..9d8679505 --- /dev/null +++ b/bin/generate_pb.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +go install \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \ + github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \ + google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc + +protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + --grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative \ + --openapiv2_out=. \ + agent/agentGrpc/agent.proto + diff --git a/bin/generate_rest.sh b/bin/generate_rest.sh index 684131d00..93d908309 100755 --- a/bin/generate_rest.sh +++ b/bin/generate_rest.sh @@ -42,13 +42,16 @@ swagger generate server -P rest_model_zrok.Principal -f "$zrokSpec" -s rest_serv echo "...generating zrok client" swagger generate client -P rest_model_zrok.Principal -f "$zrokSpec" -c rest_client_zrok -t "$zrokDir" -m "rest_model_zrok" -echo "...generating js client" +echo "...generating web console js client" openapi -s specs/zrok.yml -o ui/src/api -l js +echo "...generating agent console js client" +openapi-generator-cli generate -i agent/agentGrpc/agent.swagger.json -o agent/agentUi/src/api -g typescript-fetch + echo "...generating ts client" openapi-generator-cli generate -i specs/zrok.yml -o sdk/nodejs/sdk/src/zrok/api -g typescript-node echo "...generating python client" swagger-codegen generate -i specs/zrok.yml -o sdk/python/sdk/zrok -c $pythonConfig -l python -git checkout rest_server_zrok/configure_zrok.go +git checkout rest_server_zrok/configure_zrok.go \ No newline at end of file diff --git a/build/metadata.go b/build/metadata.go index e57f1dddf..0de2ced08 100644 --- a/build/metadata.go +++ b/build/metadata.go @@ -5,7 +5,7 @@ import "fmt" var Version string var Hash string -const Series = "v0.4" +const Series = "v1.0" func String() string { if Version != "" { diff --git a/cmd/zrok/accessPrivate.go b/cmd/zrok/accessPrivate.go index 1bb41be1b..facfe75c2 100644 --- a/cmd/zrok/accessPrivate.go +++ b/cmd/zrok/accessPrivate.go @@ -1,19 +1,28 @@ package main import ( + "context" + "encoding/json" + "errors" + "fmt" tea "github.com/charmbracelet/bubbletea" "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/cmd/zrok/subordinate" "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/endpoints/tcpTunnel" "github.com/openziti/zrok/endpoints/udpTunnel" "github.com/openziti/zrok/endpoints/vpn" "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/rest_client_zrok" "github.com/openziti/zrok/rest_client_zrok/share" "github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/tui" + "github.com/openziti/zrok/util" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "net/url" @@ -29,7 +38,14 @@ func init() { type accessPrivateCommand struct { bindAddress string + autoMode bool + autoAddress string + autoStartPort uint16 + autoEndPort uint16 headless bool + subordinate bool + forceLocal bool + forceAgent bool responseHeaders []string cmd *cobra.Command } @@ -41,47 +57,88 @@ func newAccessPrivateCommand() *accessPrivateCommand { Args: cobra.ExactArgs(1), } command := &accessPrivateCommand{cmd: cmd} - cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") - cmd.Flags().StringVarP(&command.bindAddress, "bind", "b", "127.0.0.1:9191", "The address to bind the private frontend") + headless := false + if root, err := environment.LoadRoot(); err == nil { + headless, _ = root.Headless() + } + cmd.Flags().BoolVar(&command.headless, "headless", headless, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.subordinate, "subordinate", false, "Enable subordinate mode") + cmd.MarkFlagsMutuallyExclusive("headless", "subordinate") + cmd.Flags().BoolVar(&command.forceLocal, "force-local", false, "Skip agent detection and force local mode") + cmd.Flags().BoolVar(&command.forceAgent, "force-agent", false, "Skip agent detection and force agent mode") + cmd.MarkFlagsMutuallyExclusive("force-local", "force-agent") + cmd.Flags().StringVarP(&command.bindAddress, "bind", "b", "127.0.0.1:9191", "The address to bind the private frontend (ignored when using '--auto')") + cmd.Flags().BoolVar(&command.autoMode, "auto", false, "Enable automatic port detection") + cmd.Flags().StringVar(&command.autoAddress, "auto-address", "127.0.0.1", "The address to use for automatic port detection") + cmd.Flags().Uint16Var(&command.autoStartPort, "auto-start-port", 8080, "The starting port to use for automatic port detection") + cmd.Flags().Uint16Var(&command.autoEndPort, "auto-end-port", 8888, "The ending port to use for automatic port detection") cmd.Flags().StringArrayVar(&command.responseHeaders, "response-header", []string{}, "Add a response header ('key:value')") cmd.Run = command.run return command } func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) { - shrToken := args[0] + if cmd.subordinate { + logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano}) + } - env, err := environment.LoadRoot() + root, err := environment.LoadRoot() if err != nil { - tui.Error("error loading environment", err) + cmd.error(err) } - if !env.IsEnabled() { + if !root.IsEnabled() { tui.Error("unable to load environment; did you 'zrok enable'?", nil) } - zrok, err := env.Client() - if err != nil { - if !panicInstead { - tui.Error("unable to create zrok client", err) + if cmd.subordinate || cmd.forceLocal { + cmd.accessLocal(args, root) + } else { + agent := cmd.forceAgent + if !cmd.forceAgent { + agent, err = agentClient.IsAgentRunning(root) + if err != nil { + tui.Error("error checking if agent is running", err) + } + } + if agent { + cmd.accessAgent(args, root) + } else { + cmd.accessLocal(args, root) } - panic(err) } +} + +func (cmd *accessPrivateCommand) accessLocal(args []string, root env_core.Root) { + shrToken := args[0] - auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Environment().Token) + zrok, err := root.Client() + if err != nil { + cmd.error(err) + } + + auth := httptransport.APIKeyAuth("X-TOKEN", "header", root.Environment().Token) req := share.NewAccessParams() req.Body = &rest_model_zrok.AccessRequest{ ShrToken: shrToken, - EnvZID: env.Environment().ZitiIdentity, + EnvZID: root.Environment().ZitiIdentity, } accessResp, err := zrok.Share.Access(req, auth) if err != nil { - if !panicInstead { - tui.Error("unable to access", err) + cmd.error(err) + } + + bindAddress := cmd.bindAddress + if cmd.autoMode { + if accessResp.Payload.BackendMode == "udpTunnel" { + cmd.error(errors.New("auto-addressing is not compatible with the 'udpTunnel' backend mode")) + } + autoAddress, err := util.AutoListenerAddress("tcp", cmd.autoAddress, cmd.autoStartPort, cmd.autoEndPort) + if err != nil { + cmd.error(err) } - panic(err) + bindAddress = autoAddress } - logrus.Infof("allocated frontend '%v'", accessResp.Payload.FrontendToken) protocol := "http://" switch accessResp.Payload.BackendMode { @@ -91,80 +148,59 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) { protocol = "udp://" } - endpointUrl, err := url.Parse(protocol + cmd.bindAddress) + endpointUrl, err := url.Parse(protocol + bindAddress) if err != nil { - if !panicInstead { - tui.Error("invalid endpoint address", err) - } - panic(err) + cmd.error(err) } requests := make(chan *endpoints.Request, 1024) switch accessResp.Payload.BackendMode { case "tcpTunnel": fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{ - BindAddress: cmd.bindAddress, - IdentityName: env.EnvironmentIdentityName(), + BindAddress: bindAddress, + IdentityName: root.EnvironmentIdentityName(), ShrToken: args[0], RequestsChan: requests, }) if err != nil { - if !panicInstead { - tui.Error("unable to create private access", err) - } - panic(err) + cmd.error(err) } go func() { if err := fe.Run(); err != nil { - if !panicInstead { - tui.Error("error starting access", err) - } - panic(err) + cmd.error(err) } }() case "udpTunnel": fe, err := udpTunnel.NewFrontend(&udpTunnel.FrontendConfig{ BindAddress: cmd.bindAddress, - IdentityName: env.EnvironmentIdentityName(), + IdentityName: root.EnvironmentIdentityName(), ShrToken: args[0], RequestsChan: requests, IdleTime: time.Minute, }) if err != nil { - if !panicInstead { - tui.Error("unable to create private frontend", err) - } - panic(err) + cmd.error(err) } go func() { if err := fe.Run(); err != nil { - if !panicInstead { - tui.Error("error starting frontend", err) - } - panic(err) + cmd.error(err) } }() case "socks": fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{ - BindAddress: cmd.bindAddress, - IdentityName: env.EnvironmentIdentityName(), + BindAddress: bindAddress, + IdentityName: root.EnvironmentIdentityName(), ShrToken: args[0], RequestsChan: requests, }) if err != nil { - if !panicInstead { - tui.Error("unable to create private access", err) - } - panic(err) + cmd.error(err) } go func() { if err := fe.Run(); err != nil { - if !panicInstead { - tui.Error("error starting access", err) - } - panic(err) + cmd.error(err) } }() @@ -173,55 +209,56 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) { Scheme: "VPN", } fe, err := vpn.NewFrontend(&vpn.FrontendConfig{ - IdentityName: env.EnvironmentIdentityName(), + IdentityName: root.EnvironmentIdentityName(), ShrToken: args[0], RequestsChan: requests, }) if err != nil { - if !panicInstead { - tui.Error("unable to create private access", err) - } - panic(err) + cmd.error(err) } go func() { if err := fe.Run(); err != nil { - if !panicInstead { - tui.Error("error starting access", err) - } - panic(err) + cmd.error(err) } }() default: - cfg := proxy.DefaultFrontendConfig(env.EnvironmentIdentityName()) + cfg := proxy.DefaultFrontendConfig(root.EnvironmentIdentityName()) cfg.ShrToken = shrToken - cfg.Address = cmd.bindAddress + cfg.Address = bindAddress cfg.ResponseHeaders = cmd.responseHeaders cfg.RequestsChan = requests fe, err := proxy.NewFrontend(cfg) if err != nil { - if !panicInstead { - tui.Error("unable to create private frontend", err) - } - panic(err) + cmd.error(err) } go func() { if err := fe.Run(); err != nil { - if !panicInstead { - tui.Error("unable to run frontend", err) - } + cmd.error(err) } }() } c := make(chan os.Signal) - signal.Notify(c, os.Interrupt, syscall.SIGTERM) + signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT) go func() { <-c - cmd.destroy(accessResp.Payload.FrontendToken, env.Environment().ZitiIdentity, shrToken, zrok, auth) + cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth) os.Exit(0) }() + if cmd.subordinate { + data := make(map[string]interface{}) + data[subordinate.MessageKey] = subordinate.BootMessage + data["frontend_token"] = accessResp.Payload.FrontendToken + data["bind_address"] = bindAddress + jsonData, err := json.Marshal(data) + if err != nil { + subordinateError(err) + } + fmt.Println(string(jsonData)) + } + if cmd.headless { logrus.Infof("access the zrok share at the following endpoint: %v", endpointUrl.String()) for { @@ -230,7 +267,22 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) { logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path) } } - + } else if cmd.subordinate { + for { + select { + case req := <-requests: + data := make(map[string]interface{}) + data[subordinate.MessageKey] = "access" + data["remote-address"] = req.RemoteAddr + data["method"] = req.Method + data["path"] = req.Path + jsonData, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + fmt.Println(string(jsonData)) + } + } } else { mdl := newAccessModel(shrToken, endpointUrl.String()) logrus.SetOutput(mdl) @@ -253,12 +305,22 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) { } close(requests) - cmd.destroy(accessResp.Payload.FrontendToken, env.Environment().ZitiIdentity, shrToken, zrok, auth) + cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth) + } +} + +func (cmd *accessPrivateCommand) error(err error) { + if cmd.subordinate { + subordinateError(err) } + if !panicInstead { + tui.Error("unable to create private access", err) + } + panic(err) } -func (cmd *accessPrivateCommand) destroy(frontendName, envZId, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) { - logrus.Debugf("shutting down '%v'", shrToken) +func (cmd *accessPrivateCommand) shutdown(frontendName, envZId, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) { + logrus.Infof("shutting down '%v'", shrToken) req := share.NewUnaccessParams() req.Body = &rest_model_zrok.UnaccessRequest{ FrontendToken: frontendName, @@ -271,3 +333,30 @@ func (cmd *accessPrivateCommand) destroy(frontendName, envZId, shrToken string, logrus.Errorf("error shutting down: %v", err) } } + +func (cmd *accessPrivateCommand) accessAgent(args []string, root env_core.Root) { + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + req := &agentGrpc.AccessPrivateRequest{ + Token: args[0], + BindAddress: cmd.bindAddress, + ResponseHeaders: cmd.responseHeaders, + } + if cmd.autoMode { + req.AutoMode = true + req.AutoAddress = cmd.autoAddress + req.AutoStartPort = uint32(cmd.autoStartPort) + req.AutoEndPort = uint32(cmd.autoEndPort) + } + + acc, err := client.AccessPrivate(context.Background(), req) + if err != nil { + tui.Error("error creating access", err) + } + + fmt.Println(acc) +} diff --git a/cmd/zrok/agentConsole.go b/cmd/zrok/agentConsole.go new file mode 100644 index 000000000..d60e353bb --- /dev/null +++ b/cmd/zrok/agentConsole.go @@ -0,0 +1,52 @@ +package main + +import ( + "context" + "fmt" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" +) + +func init() { + agentCmd.AddCommand(newAgentConsoleCommand().cmd) +} + +type agentConsoleCommand struct { + cmd *cobra.Command +} + +func newAgentConsoleCommand() *agentConsoleCommand { + cmd := &cobra.Command{ + Use: "console", + Short: "Open the Agent console", + Args: cobra.NoArgs, + } + command := &agentConsoleCommand{cmd} + cmd.Run = command.run + return command +} + +func (cmd *agentConsoleCommand) run(_ *cobra.Command, _ []string) { + root, err := environment.LoadRoot() + if err != nil { + tui.Error("error loading zrokdir", err) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + v, err := client.Version(context.Background(), &agentGrpc.VersionRequest{}) + if err != nil { + tui.Error("error getting agent version", err) + } + + if err := openBrowser("http://" + v.ConsoleEndpoint); err != nil { + tui.Error(fmt.Sprintf("unable to open agent console at 'http://%v'", v.ConsoleEndpoint), err) + } +} diff --git a/cmd/zrok/agentReleaseAccess.go b/cmd/zrok/agentReleaseAccess.go new file mode 100644 index 000000000..5e0cdaa31 --- /dev/null +++ b/cmd/zrok/agentReleaseAccess.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "fmt" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" +) + +func init() { + agentReleaseCmd.AddCommand(newAgentReleaseAccessCommand().cmd) +} + +type agentReleaseAccessCommand struct { + cmd *cobra.Command +} + +func newAgentReleaseAccessCommand() *agentReleaseAccessCommand { + cmd := &cobra.Command{ + Use: "access ", + Short: "Unbind an access from the zrok Agent", + Args: cobra.ExactArgs(1), + } + command := &agentReleaseAccessCommand{cmd: cmd} + cmd.Run = command.run + return command +} + +func (cmd *agentReleaseAccessCommand) run(_ *cobra.Command, args []string) { + root, err := environment.LoadRoot() + if err != nil { + if !panicInstead { + tui.Error("unable to load environment", err) + } + panic(err) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer conn.Close() + + _, err = client.ReleaseAccess(context.Background(), &agentGrpc.ReleaseAccessRequest{ + FrontendToken: args[0], + }) + if err != nil { + tui.Error("error releasing access", err) + } + + fmt.Println("success.") +} diff --git a/cmd/zrok/agentReleaseShare.go b/cmd/zrok/agentReleaseShare.go new file mode 100755 index 000000000..09c0968bd --- /dev/null +++ b/cmd/zrok/agentReleaseShare.go @@ -0,0 +1,55 @@ +package main + +import ( + "context" + "fmt" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" +) + +func init() { + agentReleaseCmd.AddCommand(newAgentReleaseShareCommand().cmd) +} + +type agentReleaseShareCommand struct { + cmd *cobra.Command +} + +func newAgentReleaseShareCommand() *agentReleaseShareCommand { + cmd := &cobra.Command{ + Use: "share ", + Short: "Release a share from the zrok Agent", + Args: cobra.ExactArgs(1), + } + command := &agentReleaseShareCommand{cmd: cmd} + cmd.Run = command.run + return command +} + +func (cmd *agentReleaseShareCommand) run(_ *cobra.Command, args []string) { + root, err := environment.LoadRoot() + if err != nil { + if !panicInstead { + tui.Error("unable to load environment", err) + } + panic(err) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer conn.Close() + + _, err = client.ReleaseShare(context.Background(), &agentGrpc.ReleaseShareRequest{ + Token: args[0], + }) + if err != nil { + tui.Error("error releasing share", err) + } + + fmt.Println("success.") +} diff --git a/cmd/zrok/agentStart.go b/cmd/zrok/agentStart.go new file mode 100644 index 000000000..965199f33 --- /dev/null +++ b/cmd/zrok/agentStart.go @@ -0,0 +1,72 @@ +package main + +import ( + "github.com/openziti/zrok/agent" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" + "os" + "os/signal" + "syscall" +) + +func init() { + agentCmd.AddCommand(newAgentStartCommand().cmd) +} + +type agentStartCommand struct { + cmd *cobra.Command + consoleAddress string + consoleStartPort uint16 + consoleEndPort uint16 +} + +func newAgentStartCommand() *agentStartCommand { + cmd := &cobra.Command{ + Use: "start", + Short: "Start a zrok agent", + Args: cobra.NoArgs, + } + command := &agentStartCommand{cmd: cmd} + cmd.Run = command.run + cmd.Flags().StringVar(&command.consoleAddress, "console-address", "127.0.0.1", "gRPC gateway address") + cmd.Flags().Uint16Var(&command.consoleStartPort, "console-start-port", 8888, "gRPC gateway starting port") + cmd.Flags().Uint16Var(&command.consoleEndPort, "console-end-port", 8988, "gRPC gateway ending port") + return command +} + +func (cmd *agentStartCommand) run(_ *cobra.Command, _ []string) { + root, err := environment.LoadRoot() + if err != nil { + tui.Error("error loading zrokdir", err) + } + + if !root.IsEnabled() { + tui.Error("unable to load environment; did you 'zrok enable'?", nil) + } + + cfg := agent.DefaultConfig() + cfg.ConsoleAddress = cmd.consoleAddress + cfg.ConsoleStartPort = cmd.consoleStartPort + cfg.ConsoleEndPort = cmd.consoleEndPort + a, err := agent.NewAgent(cfg, root) + if err != nil { + tui.Error("error creating agent", err) + } + + c := make(chan os.Signal) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + cmd.shutdown(a) + os.Exit(0) + }() + + if err := a.Run(); err != nil { + tui.Error("agent aborted", err) + } +} + +func (cmd *agentStartCommand) shutdown(a *agent.Agent) { + a.Shutdown() +} diff --git a/cmd/zrok/agentStatus.go b/cmd/zrok/agentStatus.go new file mode 100644 index 000000000..5229a26d5 --- /dev/null +++ b/cmd/zrok/agentStatus.go @@ -0,0 +1,74 @@ +package main + +import ( + "context" + "fmt" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" + "os" +) + +func init() { + agentCmd.AddCommand(newAgentStatusCommand().cmd) +} + +type agentStatusCommand struct { + cmd *cobra.Command +} + +func newAgentStatusCommand() *agentStatusCommand { + cmd := &cobra.Command{ + Use: "status", + Short: "Show the status of the running zrok Agent", + Args: cobra.NoArgs, + } + command := &agentStatusCommand{cmd: cmd} + cmd.Run = command.run + return command +} + +func (cmd *agentStatusCommand) run(_ *cobra.Command, _ []string) { + root, err := environment.LoadRoot() + if err != nil { + tui.Error("error loading zrokdir", err) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer conn.Close() + + status, err := client.Status(context.Background(), &agentGrpc.StatusRequest{}) + if err != nil { + tui.Error("error getting status", err) + } + + fmt.Println() + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.SetStyle(table.StyleColoredDark) + t.AppendHeader(table.Row{"Frontend Token", "Token", "Bind Address"}) + for _, access := range status.GetAccesses() { + t.AppendRow(table.Row{access.FrontendToken, access.Token, access.BindAddress}) + } + t.Render() + fmt.Printf("%d accesses in agent\n", len(status.GetAccesses())) + + fmt.Println() + t = table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.SetStyle(table.StyleColoredDark) + t.AppendHeader(table.Row{"Token", "Reserved", "Share Mode", "Backend Mode", "Target"}) + for _, share := range status.GetShares() { + t.AppendRow(table.Row{share.Token, share.Reserved, share.ShareMode, share.BackendMode, share.BackendEndpoint}) + } + t.Render() + fmt.Printf("%d shares in agent\n", len(status.GetShares())) + + fmt.Println() +} diff --git a/cmd/zrok/agentVersion.go b/cmd/zrok/agentVersion.go new file mode 100644 index 000000000..bb2afd435 --- /dev/null +++ b/cmd/zrok/agentVersion.go @@ -0,0 +1,50 @@ +package main + +import ( + "context" + "fmt" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" +) + +func init() { + agentCmd.AddCommand(newAgentVersionCommand().cmd) +} + +type agentVersionCommand struct { + cmd *cobra.Command +} + +func newAgentVersionCommand() *agentVersionCommand { + cmd := &cobra.Command{ + Use: "version", + Short: "Retrieve the running zrok Agent version", + Args: cobra.NoArgs, + } + command := &agentVersionCommand{cmd: cmd} + cmd.Run = command.run + return command +} + +func (cmd *agentVersionCommand) run(_ *cobra.Command, _ []string) { + root, err := environment.LoadRoot() + if err != nil { + tui.Error("error loading zrokdir", err) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + v, err := client.Version(context.Background(), &agentGrpc.VersionRequest{}) + if err != nil { + tui.Error("error getting agent version", err) + } + + fmt.Printf("%v\n%v\n", v.GetV(), v.GetConsoleEndpoint()) +} diff --git a/cmd/zrok/configGet.go b/cmd/zrok/configGet.go index 6706d2060..3ea408456 100644 --- a/cmd/zrok/configGet.go +++ b/cmd/zrok/configGet.go @@ -47,6 +47,12 @@ func (cmd *configGetCommand) run(_ *cobra.Command, args []string) { } else { fmt.Println("defaultFrontend = ") } + case "headless": + if env.Config() != nil { + fmt.Printf("headless = %v\n", env.Config().Headless) + } else { + fmt.Println("headless = ") + } default: fmt.Printf("unknown config name '%v'\n", configName) } diff --git a/cmd/zrok/configSet.go b/cmd/zrok/configSet.go index 76c9f3d72..e1601a0af 100644 --- a/cmd/zrok/configSet.go +++ b/cmd/zrok/configSet.go @@ -8,6 +8,7 @@ import ( "github.com/spf13/cobra" "net/url" "os" + "strconv" ) func init() { @@ -78,6 +79,24 @@ func (cmd *configSetCommand) run(_ *cobra.Command, args []string) { } fmt.Println("zrok configuration updated") + case "headless": + headless, err := strconv.ParseBool(value) + if err != nil { + tui.Error("unable to parse value for 'headless': %v", err) + } + if env.Config() == nil { + if err := env.SetConfig(&env_core.Config{Headless: headless}); err != nil { + tui.Error("unable to save config", err) + } + } else { + cfg := env.Config() + cfg.Headless = headless + 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 34e5d292f..5fbb817b3 100644 --- a/cmd/zrok/configUnset.go +++ b/cmd/zrok/configUnset.go @@ -47,6 +47,9 @@ func (cmd *configUnsetCommand) run(_ *cobra.Command, args []string) { case "defaultFrontend": cfg.DefaultFrontend = "" + case "headless": + cfg.Headless = false + default: fmt.Printf("unknown config name '%v'\n", configName) os.Exit(1) diff --git a/cmd/zrok/console.go b/cmd/zrok/console.go index 72de2ce4b..77394e549 100644 --- a/cmd/zrok/console.go +++ b/cmd/zrok/console.go @@ -19,7 +19,7 @@ func newConsoleCommand() *consoleCommand { cmd := &cobra.Command{ Use: "console", Short: "Open the web console", - Args: cobra.ExactArgs(0), + Args: cobra.NoArgs, } command := &consoleCommand{cmd} cmd.Run = command.run diff --git a/cmd/zrok/main.go b/cmd/zrok/main.go index 197ef7ca6..3ceffc4d2 100644 --- a/cmd/zrok/main.go +++ b/cmd/zrok/main.go @@ -24,6 +24,10 @@ func init() { adminCmd.AddCommand(adminDeleteCmd) adminCmd.AddCommand(adminListCmd) adminCmd.AddCommand(adminUpdateCmd) + rootCmd.AddCommand(agentCmd) + agentCmd.AddCommand(agentAccessCmd) + agentCmd.AddCommand(agentShareCmd) + agentCmd.AddCommand(agentReleaseCmd) testCmd.AddCommand(loopCmd) rootCmd.AddCommand(adminCmd) rootCmd.AddCommand(configCmd) @@ -79,6 +83,27 @@ var adminUpdateCmd = &cobra.Command{ Short: "Update global resources", } +var agentAccessCmd = &cobra.Command{ + Use: "access", + Short: "zrok Agent access commands", +} + +var agentCmd = &cobra.Command{ + Use: "agent", + Short: "zrok Agent commands", + Aliases: []string{"daemon"}, +} + +var agentShareCmd = &cobra.Command{ + Use: "share", + Short: "zrok Agent sharing commands", +} + +var agentReleaseCmd = &cobra.Command{ + Use: "release", + Short: "zrok Agent release commands", +} + var configCmd = &cobra.Command{ Use: "config", Short: "Configure your zrok environment", diff --git a/cmd/zrok/sharePrivate.go b/cmd/zrok/sharePrivate.go index 304a7a6ff..38a3fd330 100644 --- a/cmd/zrok/sharePrivate.go +++ b/cmd/zrok/sharePrivate.go @@ -1,8 +1,13 @@ package main import ( + "context" + "encoding/json" "fmt" tea "github.com/charmbracelet/bubbletea" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/cmd/zrok/subordinate" "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/proxy" @@ -14,12 +19,15 @@ import ( "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/tui" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "net" "os" "os/signal" + "path/filepath" "syscall" + "time" ) func init() { @@ -29,6 +37,9 @@ func init() { type sharePrivateCommand struct { backendMode string headless bool + subordinate bool + forceLocal bool + forceAgent bool insecure bool closed bool accessGrants []string @@ -42,8 +53,17 @@ func newSharePrivateCommand() *sharePrivateCommand { Args: cobra.RangeArgs(0, 1), } command := &sharePrivateCommand{cmd: cmd} + headless := false + if root, err := environment.LoadRoot(); err == nil { + headless, _ = root.Headless() + } cmd.Flags().StringVarP(&command.backendMode, "backend-mode", "b", "proxy", "The backend mode {proxy, web, tcpTunnel, udpTunnel, caddy, drive, socks, vpn}") - cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.headless, "headless", headless, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.subordinate, "subordinate", false, "Enable agent mode") + cmd.MarkFlagsMutuallyExclusive("headless", "subordinate") + cmd.Flags().BoolVar(&command.forceLocal, "force-local", false, "Skip agent detection and force local mode") + cmd.Flags().BoolVar(&command.forceAgent, "force-agent", false, "Skip agent detection and force agent mode") + cmd.MarkFlagsMutuallyExclusive("force-local", "force-agent") cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for ") cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)") cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)") @@ -52,56 +72,85 @@ func newSharePrivateCommand() *sharePrivateCommand { } func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { + if cmd.subordinate { + logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano}) + } + + root, err := environment.LoadRoot() + if err != nil { + cmd.error("error loading environment", err) + } + + if !root.IsEnabled() { + tui.Error("unable to load environment; did you 'zrok enable'?", nil) + } + + if cmd.subordinate || cmd.forceLocal { + cmd.shareLocal(args, root) + } else { + agent := cmd.forceAgent + if !cmd.forceAgent { + agent, err = agentClient.IsAgentRunning(root) + if err != nil { + tui.Error("error checking if agent is running", err) + } + } + if agent { + cmd.shareAgent(args, root) + } else { + cmd.shareLocal(args, root) + } + } +} + +func (cmd *sharePrivateCommand) shareLocal(args []string, root env_core.Root) { var target string switch cmd.backendMode { case "proxy": if len(args) != 1 { - tui.Error("the 'proxy' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'proxy' backend mode expects a ")) } v, err := parseUrl(args[0]) if err != nil { - if !panicInstead { - tui.Error("invalid target endpoint URL", err) - } - panic(err) + cmd.error("invalid target endpoint URL", err) } target = v case "web": if len(args) != 1 { - tui.Error("the 'web' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'web' backend mode expects a ")) } target = args[0] case "tcpTunnel": if len(args) != 1 { - tui.Error("the 'tcpTunnel' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'tcpTunnel' backend mode expects a ")) } target = args[0] case "udpTunnel": if len(args) != 1 { - tui.Error("the 'udpTunnel' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'udpTunnel' backend mode expects a ")) } target = args[0] case "caddy": if len(args) != 1 { - tui.Error("the 'caddy' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'caddy' backend mode expects a ")) } target = args[0] cmd.headless = true case "drive": if len(args) != 1 { - tui.Error("the 'drive' backend mode expects a ", nil) + cmd.error("unable to create share", errors.New("the 'drive' backend mode expects a ")) } target = args[0] case "socks": if len(args) != 0 { - tui.Error("the 'socks' backend mode does not expect ", nil) + cmd.error("unable to create share", errors.New("the 'socks' backend mode expects a ")) } target = "socks" @@ -109,7 +158,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { if len(args) == 1 { _, _, err := net.ParseCIDR(args[0]) if err != nil { - tui.Error("the 'vpn' backend expect valid CIDR ", err) + cmd.error("unable to create share", errors.New("the 'vpn' backend mode expects a valid CIDR ")) } target = args[0] } else { @@ -117,27 +166,21 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } default: - tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive}", cmd.backendMode), nil) + cmd.error("unable to create share", fmt.Errorf("invalid backend mode '%v'; expected {proxy, web, tcpTunnel, udpTunnel, caddy, drive}", cmd.backendMode)) } root, err := environment.LoadRoot() if err != nil { - if !panicInstead { - tui.Error("unable to load environment", err) - } - panic(err) + cmd.error("unable to load environment", err) } if !root.IsEnabled() { - tui.Error("unable to load environment; did you 'zrok enable'?", nil) + cmd.error("unable to create share", errors.New("unable to load environment; did you 'zrok enable'?")) } zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { - if !panicInstead { - tui.Error("unable to load ziti identity configuration", err) - } - panic(err) + cmd.error("unable to load ziti identity configuration", err) } req := &sdk.ShareRequest{ @@ -151,15 +194,12 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } shr, err := sdk.CreateShare(root, req) if err != nil { - if !panicInstead { - tui.Error("unable to create share", err) - } - panic(err) + cmd.error("unable to create share", err) } shareDescription := fmt.Sprintf("access your share with: %v", tui.Code.Render(fmt.Sprintf("zrok access private %v", shr.Token))) mdl := newShareModel(shr.Token, []string{shareDescription}, sdk.PrivateShareMode, sdk.BackendMode(cmd.backendMode)) - if !cmd.headless { + if !cmd.headless && !cmd.subordinate { proxy.SetCaddyLoggingWriter(mdl) } @@ -185,10 +225,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating proxy backend", err) - } - panic(err) + cmd.error("unable to create 'proxy' backend", err) } go func() { @@ -207,10 +244,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating web backend", err) - } - panic(err) + cmd.error("unable to create 'web' backend", err) } go func() { @@ -229,10 +263,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := tcpTunnel.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating tcpTunnel backend", err) - } - panic(err) + cmd.error("unable to create 'tcpTunnel' backend", err) } go func() { @@ -251,10 +282,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := udpTunnel.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating udpTunnel backend", err) - } - panic(err) + cmd.error("unable to create 'udpTunnel' backend", err) } go func() { @@ -273,10 +301,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyfileBackend(cfg) if err != nil { cmd.shutdown(root, shr) - if !panicInstead { - tui.Error("error creating caddy backend", err) - } - panic(err) + cmd.error("unable to create 'caddy' backend", err) } go func() { @@ -295,10 +320,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := drive.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating drive backend", err) - } - panic(err) + cmd.error("unable to create 'drive' backend", err) } go func() { @@ -316,10 +338,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := socks.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating socks backend", err) - } - panic(err) + cmd.error("unable to create 'socks' backend", err) } go func() { @@ -338,10 +357,7 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { be, err := vpn.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating VPN backend", err) - } - panic(err) + cmd.error("unable to create 'vpn' backend", err) } go func() { @@ -351,10 +367,22 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { }() default: - tui.Error("invalid backend mode", nil) + cmd.error("unable to create share", errors.New("invalid backend mode")) } - if cmd.headless { + if cmd.subordinate { + data := make(map[string]interface{}) + data[subordinate.MessageKey] = subordinate.BootMessage + data["token"] = shr.Token + data["frontend_endpoints"] = shr.FrontendEndpoints + jsonData, err := json.Marshal(data) + if err != nil { + cmd.error("unable to create share", err) + } + fmt.Println(string(jsonData)) + } + + if cmd.headless && !cmd.subordinate { logrus.Infof("allow other to access your share with the following command:\nzrok access private %v", shr.Token) for { select { @@ -363,6 +391,23 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } } + } else if cmd.subordinate { + for { + select { + case req := <-requests: + data := make(map[string]interface{}) + data[subordinate.MessageKey] = "access" + data["remote_address"] = req.RemoteAddr + data["method"] = req.Method + data["path"] = req.Path + jsonData, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + fmt.Println(string(jsonData)) + } + } + } else { logrus.SetOutput(mdl) prg := tea.NewProgram(mdl, tea.WithAltScreen()) @@ -386,6 +431,16 @@ func (cmd *sharePrivateCommand) run(_ *cobra.Command, args []string) { } } +func (cmd *sharePrivateCommand) error(msg string, err error) { + if cmd.subordinate { + subordinateError(errors.Wrap(err, msg)) + } + if !panicInstead { + tui.Error(msg, err) + } + panic(errors.Wrap(err, msg)) +} + func (cmd *sharePrivateCommand) shutdown(root env_core.Root, shr *sdk.Share) { logrus.Debugf("shutting down '%v'", shr.Token) if err := sdk.DeleteShare(root, shr); err != nil { @@ -393,3 +448,112 @@ func (cmd *sharePrivateCommand) shutdown(root env_core.Root, shr *sdk.Share) { } logrus.Debugf("shutdown complete") } + +func (cmd *sharePrivateCommand) shareAgent(args []string, root env_core.Root) { + var target string + + switch cmd.backendMode { + case "proxy": + if len(args) != 1 { + tui.Error("the 'proxy' backend mode expects a ", nil) + } + v, err := parseUrl(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "web": + if len(args) != 1 { + tui.Error("the 'web' backend mode expects a ", nil) + } + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "tcpTunnel": + if len(args) != 1 { + tui.Error("the 'tcpTunnel' backend mode expects a ", nil) + } + target = args[0] + + case "udpTunnel": + if len(args) != 1 { + tui.Error("the 'udpTunnel' backend mode expects a ", nil) + } + target = args[0] + + case "caddy": + if len(args) != 1 { + tui.Error("the 'caddy' backend mode expects a ", nil) + } + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "drive": + if len(args) != 1 { + tui.Error("the 'drive' backend mode expects a ", nil) + } + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "socks": + if len(args) != 0 { + tui.Error("the 'socks' backend mode does not expect ", nil) + } + target = "socks" + + case "vpn": + if len(args) == 1 { + _, _, err := net.ParseCIDR(args[0]) + if err != nil { + tui.Error("the 'vpn' backend expect valid CIDR ", err) + } + target = args[0] + } else { + target = vpn.DefaultTarget() + } + + default: + tui.Error(fmt.Sprintf("invalid backend mode '%v'", cmd.backendMode), nil) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + shr, err := client.SharePrivate(context.Background(), &agentGrpc.SharePrivateRequest{ + Target: target, + BackendMode: cmd.backendMode, + Insecure: cmd.insecure, + Closed: cmd.closed, + AccessGrants: cmd.accessGrants, + }) + if err != nil { + tui.Error("error creating share", err) + } + + fmt.Println(shr) +} diff --git a/cmd/zrok/sharePublic.go b/cmd/zrok/sharePublic.go index d66867df3..91de615df 100644 --- a/cmd/zrok/sharePublic.go +++ b/cmd/zrok/sharePublic.go @@ -1,20 +1,27 @@ package main import ( + "context" + "encoding/json" "fmt" tea "github.com/charmbracelet/bubbletea" "github.com/gobwas/glob" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/cmd/zrok/subordinate" "github.com/openziti/zrok/endpoints" - drive "github.com/openziti/zrok/endpoints/drive" + "github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/proxy" "github.com/openziti/zrok/environment" "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/tui" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "os" "os/signal" + "path/filepath" "strings" "syscall" "time" @@ -29,6 +36,9 @@ type sharePublicCommand struct { frontendSelection []string backendMode string headless bool + subordinate bool + forceLocal bool + forceAgent bool insecure bool oauthProvider string oauthEmailAddressPatterns []string @@ -50,13 +60,21 @@ func newSharePublicCommand() *sharePublicCommand { defaultFrontend, _ := root.DefaultFrontend() defaultFrontends = []string{defaultFrontend} } + headless := false + if root, err := environment.LoadRoot(); err == nil { + headless, _ = root.Headless() + } 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.headless, "headless", headless, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.subordinate, "subordinate", false, "Enable agent mode") + cmd.MarkFlagsMutuallyExclusive("headless", "subordinate") + cmd.Flags().BoolVar(&command.forceLocal, "force-local", false, "Skip agent detection and force local mode") + cmd.Flags().BoolVar(&command.forceAgent, "force-agent", false, "Skip agent detection and force agent mode") + cmd.MarkFlagsMutuallyExclusive("force-local", "force-agent") cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation for ") cmd.Flags().BoolVar(&command.closed, "closed", false, "Enable closed permission mode (see --access-grant)") cmd.Flags().StringArrayVar(&command.accessGrants, "access-grant", []string{}, "zrok accounts that are allowed to access this share (see --closed)") - cmd.Flags().StringArrayVar(&command.basicAuth, "basic-auth", []string{}, "Basic authentication users (,...)") cmd.Flags().StringVar(&command.oauthProvider, "oauth-provider", "", "Enable OAuth provider [google, github]") cmd.Flags().StringArrayVar(&command.oauthEmailAddressPatterns, "oauth-email-address-patterns", []string{}, "Allow only these email domain globs to authenticate via OAuth") @@ -68,16 +86,45 @@ func newSharePublicCommand() *sharePublicCommand { } func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { + if cmd.subordinate { + logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano}) + } + + root, err := environment.LoadRoot() + if err != nil { + cmd.error("error loading environment", err) + } + + if !root.IsEnabled() { + cmd.error("unable to create share", errors.New("unable to load environment; did you 'zrok enable'?")) + } + + if cmd.subordinate || cmd.forceLocal { + cmd.shareLocal(args, root) + } else { + agent := cmd.forceAgent + if !cmd.forceAgent { + agent, err = agentClient.IsAgentRunning(root) + if err != nil { + tui.Error("error checking if agent is running", err) + } + } + if agent { + cmd.shareAgent(args, root) + } else { + cmd.shareLocal(args, root) + } + } +} + +func (cmd *sharePublicCommand) shareLocal(args []string, root env_core.Root) { var target string switch cmd.backendMode { case "proxy": v, err := parseUrl(args[0]) if err != nil { - if !panicInstead { - tui.Error("invalid target endpoint URL", err) - } - panic(err) + cmd.error("invalid target endpoint URL", err) } target = v @@ -92,27 +139,12 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { target = args[0] default: - tui.Error(fmt.Sprintf("invalid backend mode '%v'; expected {proxy, web, caddy, drive}", cmd.backendMode), nil) - } - - root, err := environment.LoadRoot() - if err != nil { - if !panicInstead { - tui.Error("unable to load environment", err) - } - panic(err) - } - - if !root.IsEnabled() { - tui.Error("unable to load environment; did you 'zrok enable'?", nil) + cmd.error("unable to create share", fmt.Errorf("invalid backend mode '%v'; expected {proxy, web, caddy, drive}", cmd.backendMode)) } zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { - if !panicInstead { - tui.Error("unable to access ziti identity file", err) - } - panic(err) + cmd.error("unable to access ziti identity file", err) } req := &sdk.ShareRequest{ @@ -134,23 +166,17 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { for _, g := range cmd.oauthEmailAddressPatterns { _, err := glob.Compile(g) if err != nil { - if !panicInstead { - tui.Error(fmt.Sprintf("unable to create share, invalid oauth email glob (%v)", g), err) - } - panic(err) + cmd.error(fmt.Sprintf("unable to create share, invalid oauth email glob (%v)", g), err) } } } shr, err := sdk.CreateShare(root, req) if err != nil { - if !panicInstead { - tui.Error("unable to create share", err) - } - panic(err) + cmd.error("unable to create share", err) } mdl := newShareModel(shr.Token, shr.FrontendEndpoints, sdk.PublicShareMode, sdk.BackendMode(cmd.backendMode)) - if !cmd.headless { + if !cmd.headless && !cmd.subordinate { proxy.SetCaddyLoggingWriter(mdl) } @@ -176,10 +202,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating proxy backend", err) - } - panic(err) + cmd.error("unable to create proxy backend", err) } go func() { @@ -198,10 +221,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("unable to create web backend", err) - } - panic(err) + cmd.error("unable to create web backend", err) } go func() { @@ -220,10 +240,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyfileBackend(cfg) if err != nil { cmd.shutdown(root, shr) - if !panicInstead { - tui.Error("unable to create caddy backend", err) - } - panic(err) + cmd.error("unable to create caddy backend", err) } go func() { @@ -242,10 +259,7 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { be, err := drive.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating drive backend", err) - } - panic(err) + cmd.error("unable to create drive backend", err) } go func() { @@ -258,7 +272,19 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { tui.Error("invalid backend mode", nil) } - if cmd.headless { + if cmd.subordinate { + data := make(map[string]interface{}) + data[subordinate.MessageKey] = subordinate.BootMessage + data["token"] = shr.Token + data["frontend_endpoints"] = shr.FrontendEndpoints + jsonData, err := json.Marshal(data) + if err != nil { + cmd.error("unable to marshal", err) + } + fmt.Println(string(jsonData)) + } + + if cmd.headless && !cmd.subordinate { logrus.Infof("access your zrok share at the following endpoints:\n %v", strings.Join(shr.FrontendEndpoints, "\n")) for { select { @@ -267,6 +293,23 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { } } + } else if cmd.subordinate { + for { + select { + case req := <-requests: + data := make(map[string]interface{}) + data[subordinate.MessageKey] = "access" + data["remote_address"] = req.RemoteAddr + data["method"] = req.Method + data["path"] = req.Path + jsonData, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + fmt.Println(string(jsonData)) + } + } + } else { logrus.SetOutput(mdl) prg := tea.NewProgram(mdl, tea.WithAltScreen()) @@ -290,6 +333,16 @@ func (cmd *sharePublicCommand) run(_ *cobra.Command, args []string) { } } +func (cmd *sharePublicCommand) error(msg string, err error) { + if cmd.subordinate { + subordinateError(errors.Wrap(err, msg)) + } + if !panicInstead { + tui.Error(msg, err) + } + panic(errors.Wrap(err, msg)) +} + func (cmd *sharePublicCommand) shutdown(root env_core.Root, shr *sdk.Share) { logrus.Debugf("shutting down '%v'", shr.Token) if err := sdk.DeleteShare(root, shr); err != nil { @@ -297,3 +350,76 @@ func (cmd *sharePublicCommand) shutdown(root env_core.Root, shr *sdk.Share) { } logrus.Debugf("shutdown complete") } + +func (cmd *sharePublicCommand) shareAgent(args []string, root env_core.Root) { + var target string + + switch cmd.backendMode { + case "proxy": + v, err := parseUrl(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "web": + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "caddy": + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + case "drive": + v, err := filepath.Abs(args[0]) + if err != nil { + if !panicInstead { + tui.Error("invalid target endpoint URL", err) + } + panic(err) + } + target = v + + default: + tui.Error(fmt.Sprintf("invalid backend mode '%v'", cmd.backendMode), nil) + } + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + shr, err := client.SharePublic(context.Background(), &agentGrpc.SharePublicRequest{ + Target: target, + BasicAuth: cmd.basicAuth, + FrontendSelection: cmd.frontendSelection, + BackendMode: cmd.backendMode, + Insecure: cmd.insecure, + OauthProvider: cmd.oauthProvider, + OauthEmailAddressPatterns: cmd.oauthEmailAddressPatterns, + OauthCheckInterval: cmd.oauthCheckInterval.String(), + Closed: cmd.closed, + AccessGrants: cmd.accessGrants, + }) + if err != nil { + tui.Error("error creating share", err) + } + + fmt.Println(shr) +} diff --git a/cmd/zrok/shareReserved.go b/cmd/zrok/shareReserved.go index 0d5688e46..38a1678a5 100644 --- a/cmd/zrok/shareReserved.go +++ b/cmd/zrok/shareReserved.go @@ -1,9 +1,14 @@ package main import ( + "context" + "encoding/json" "fmt" tea "github.com/charmbracelet/bubbletea" httptransport "github.com/go-openapi/runtime/client" + "github.com/openziti/zrok/agent/agentClient" + "github.com/openziti/zrok/agent/agentGrpc" + "github.com/openziti/zrok/cmd/zrok/subordinate" "github.com/openziti/zrok/endpoints" "github.com/openziti/zrok/endpoints/drive" "github.com/openziti/zrok/endpoints/proxy" @@ -12,13 +17,16 @@ import ( "github.com/openziti/zrok/endpoints/udpTunnel" "github.com/openziti/zrok/endpoints/vpn" "github.com/openziti/zrok/environment" + "github.com/openziti/zrok/environment/env_core" "github.com/openziti/zrok/rest_client_zrok/metadata" "github.com/openziti/zrok/rest_client_zrok/share" "github.com/openziti/zrok/rest_model_zrok" "github.com/openziti/zrok/sdk/golang/sdk" "github.com/openziti/zrok/tui" + "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "time" ) func init() { @@ -28,6 +36,9 @@ func init() { type shareReservedCommand struct { overrideEndpoint string headless bool + subordinate bool + forceLocal bool + forceAgent bool insecure bool cmd *cobra.Command } @@ -39,45 +50,68 @@ func newShareReservedCommand() *shareReservedCommand { Args: cobra.ExactArgs(1), } command := &shareReservedCommand{cmd: cmd} + headless := false + if root, err := environment.LoadRoot(); err == nil { + headless, _ = root.Headless() + } cmd.Flags().StringVar(&command.overrideEndpoint, "override-endpoint", "", "Override the stored target endpoint with a replacement") - cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.headless, "headless", headless, "Disable TUI and run headless") + cmd.Flags().BoolVar(&command.subordinate, "subordinate", false, "Enable agent mode") + cmd.MarkFlagsMutuallyExclusive("headless", "subordinate") + cmd.Flags().BoolVar(&command.forceLocal, "force-local", false, "Skip agent detection and force local mode") + cmd.Flags().BoolVar(&command.forceAgent, "force-agent", false, "Skip agent detection and force agent mode") + cmd.MarkFlagsMutuallyExclusive("force-local", "force-agent") cmd.Flags().BoolVar(&command.insecure, "insecure", false, "Enable insecure TLS certificate validation") cmd.Run = command.run return command } func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { - shrToken := args[0] - var target string + if cmd.subordinate { + logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano}) + } root, err := environment.LoadRoot() if err != nil { - if !panicInstead { - tui.Error("error loading environment", err) - } - panic(err) + cmd.error("error loading environment", err) } if !root.IsEnabled() { - tui.Error("unable to load environment; did you 'zrok enable'?", nil) + cmd.error("unable to create share", errors.New("unable to load environment; did you 'zrok enable'?")) } + if cmd.subordinate || cmd.forceLocal { + cmd.shareLocal(args, root) + } else { + agent := cmd.forceAgent + if !cmd.forceAgent { + agent, err = agentClient.IsAgentRunning(root) + if err != nil { + tui.Error("error checking if agent is running", err) + } + } + if agent { + cmd.shareAgent(args, root) + } else { + cmd.shareLocal(args, root) + } + } +} + +func (cmd *shareReservedCommand) shareLocal(args []string, root env_core.Root) { + shrToken := args[0] + var target string + zrok, err := root.Client() if err != nil { - if !panicInstead { - tui.Error("unable to create zrok client", err) - } - panic(err) + cmd.error("unable to create zrok client", err) } auth := httptransport.APIKeyAuth("X-TOKEN", "header", root.Environment().Token) req := metadata.NewGetShareDetailParams() req.ShrToken = shrToken resp, err := zrok.Metadata.GetShareDetail(req, auth) if err != nil { - if !panicInstead { - tui.Error("unable to retrieve reserved share", err) - } - panic(err) + cmd.error("unable to retrieve reserved share", err) } target = cmd.overrideEndpoint if target == "" { @@ -89,14 +123,13 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { zif, err := root.ZitiIdentityNamed(root.EnvironmentIdentityName()) if err != nil { - if !panicInstead { - tui.Error("unable to load ziti identity configuration", err) - } - panic(err) + cmd.error("unable to load ziti identity configuration", err) } if resp.Payload.BackendMode != "socks" { - logrus.Infof("sharing target: '%v'", target) + if !cmd.subordinate { + logrus.Infof("sharing target: '%v'", target) + } if resp.Payload.BackendProxyEndpoint != target { upReq := share.NewUpdateShareParams() @@ -105,14 +138,15 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { BackendProxyEndpoint: target, } if _, err := zrok.Share.UpdateShare(upReq, auth); err != nil { - if !panicInstead { - tui.Error("unable to update backend target", err) - } - panic(err) + cmd.error("unable to update backend target", err) + } + if !cmd.subordinate { + logrus.Infof("updated backend target to: %v", target) } - logrus.Infof("updated backend target to: %v", target) } else { - logrus.Infof("using existing backend target: %v", target) + if !cmd.subordinate { + logrus.Infof("using existing backend target: %v", target) + } } } @@ -125,7 +159,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { } mdl := newShareModel(shrToken, []string{shareDescription}, sdk.ShareMode(resp.Payload.ShareMode), sdk.BackendMode(resp.Payload.BackendMode)) - if !cmd.headless { + if !cmd.headless && !cmd.subordinate { proxy.SetCaddyLoggingWriter(mdl) } @@ -142,10 +176,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("unable to create proxy backend handler", err) - } - panic(err) + cmd.error("unable to create 'proxy' backend", err) } go func() { @@ -164,10 +195,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyWebBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating web backend", err) - } - panic(err) + cmd.error("unable to create 'web' backend", err) } go func() { @@ -186,10 +214,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := tcpTunnel.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating tcpTunnel backend", err) - } - panic(err) + cmd.error("unable to create 'tcpTunnel' backend", err) } go func() { @@ -208,10 +233,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := udpTunnel.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating udpTunnel backend", err) - } - panic(err) + cmd.error("unable to create 'udpTunnel' backend", err) } go func() { @@ -229,10 +251,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := proxy.NewCaddyfileBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating caddy backend", err) - } - panic(err) + cmd.error("unable to create 'caddy' backend", err) } go func() { @@ -251,10 +270,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := drive.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating drive backend", err) - } - panic(err) + cmd.error("unable to create 'drive' backend", err) } go func() { @@ -272,10 +288,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := socks.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating socks backend", err) - } - panic(err) + cmd.error("unable to create 'socks' backend", err) } go func() { @@ -294,10 +307,7 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { be, err := vpn.NewBackend(cfg) if err != nil { - if !panicInstead { - tui.Error("error creating VPN backend", err) - } - panic(err) + cmd.error("unable to create 'vpn' backend", err) } go func() { @@ -307,10 +317,29 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { }() default: - tui.Error("invalid backend mode", nil) + cmd.error("unable to share", errors.New("invalid backend mode")) + } + + if cmd.subordinate { + data := make(map[string]interface{}) + data[subordinate.MessageKey] = subordinate.BootMessage + data["token"] = resp.Payload.Token + data["backend_mode"] = resp.Payload.BackendMode + data["share_mode"] = resp.Payload.ShareMode + if resp.Payload.FrontendEndpoint != "" { + data["frontend_endpoints"] = resp.Payload.FrontendEndpoint + } + if resp.Payload.BackendProxyEndpoint != "" { + data["target"] = resp.Payload.BackendProxyEndpoint + } + jsonData, err := json.Marshal(data) + if err != nil { + cmd.error("unable to marshal", err) + } + fmt.Println(string(jsonData)) } - if cmd.headless { + if cmd.headless && !cmd.subordinate { switch resp.Payload.ShareMode { case string(sdk.PublicShareMode): logrus.Infof("access your zrok share: %v", resp.Payload.FrontendEndpoint) @@ -324,6 +353,24 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path) } } + + } else if cmd.subordinate { + for { + select { + case req := <-requests: + data := make(map[string]interface{}) + data[subordinate.MessageKey] = "access" + data["remote-address"] = req.RemoteAddr + data["method"] = req.Method + data["path"] = req.Path + jsonData, err := json.Marshal(data) + if err != nil { + fmt.Println(err) + } + fmt.Println(string(jsonData)) + } + } + } else { logrus.SetOutput(mdl) prg := tea.NewProgram(mdl, tea.WithAltScreen()) @@ -345,3 +392,34 @@ func (cmd *shareReservedCommand) run(_ *cobra.Command, args []string) { close(requests) } } + +func (cmd *shareReservedCommand) error(msg string, err error) { + if cmd.subordinate { + subordinateError(errors.Wrap(err, msg)) + } + if !panicInstead { + tui.Error(msg, err) + } + panic(errors.Wrap(err, msg)) +} + +func (cmd *shareReservedCommand) shareAgent(args []string, root env_core.Root) { + logrus.Info("starting") + + client, conn, err := agentClient.NewClient(root) + if err != nil { + tui.Error("error connecting to agent", err) + } + defer func() { _ = conn.Close() }() + + shr, err := client.ShareReserved(context.Background(), &agentGrpc.ShareReservedRequest{ + Token: args[0], + OverrideEndpoint: cmd.overrideEndpoint, + Insecure: cmd.insecure, + }) + if err != nil { + tui.Error("error sharing reserved share", err) + } + + fmt.Println(shr) +} diff --git a/cmd/zrok/status.go b/cmd/zrok/status.go index f54f83cb0..304b7dcac 100644 --- a/cmd/zrok/status.go +++ b/cmd/zrok/status.go @@ -52,6 +52,8 @@ func (cmd *statusCommand) run(_ *cobra.Command, _ []string) { t.AppendRow(table.Row{"apiEndpoint", apiEndpoint, apiEndpointFrom}) defaultFrontend, defaultFrontendFrom := env.DefaultFrontend() t.AppendRow(table.Row{"defaultFrontend", defaultFrontend, defaultFrontendFrom}) + headless, headlessFrom := env.Headless() + t.AppendRow(table.Row{"headless", headless, headlessFrom}) t.Render() _, _ = fmt.Fprintf(os.Stderr, "\n") diff --git a/cmd/zrok/subordinate/message.go b/cmd/zrok/subordinate/message.go new file mode 100644 index 000000000..958909544 --- /dev/null +++ b/cmd/zrok/subordinate/message.go @@ -0,0 +1,86 @@ +package subordinate + +import ( + "bytes" + "encoding/json" + "github.com/sirupsen/logrus" + "strings" +) + +const ( + MessageKey = "msg" + RawMessage = "raw" + BootMessage = "boot" + ErrorMessage = "error" +) + +type Message map[string]interface{} + +type MessageHandler struct { + BootHandler func(string, Message) + MessageHandler func(Message) + MalformedHandler func(Message) + BootComplete chan struct{} + readBuffer bytes.Buffer + booted bool +} + +func NewMessageHandler() *MessageHandler { + return &MessageHandler{ + BootComplete: make(chan struct{}), + } +} + +func (h *MessageHandler) Tail(data []byte) { + defer func() { + if r := recover(); r != nil { + logrus.Errorf("recovered: %v", r) + } + }() + + h.readBuffer.Write(data) + if line, err := h.readBuffer.ReadString('\n'); err == nil { + line = strings.Trim(line, "\n \t") + logrus.Debugf("line: '%v'", line) + msg := make(map[string]interface{}) + if !h.booted { + if line[0] == '{' { + if err := json.Unmarshal([]byte(line), &msg); err == nil { + if v, found := msg[MessageKey]; found { + if vStr, ok := v.(string); ok { + if vStr == BootMessage || vStr == ErrorMessage { + h.BootHandler(vStr, msg) + h.booted = true + close(h.BootComplete) + } else { + h.MessageHandler(msg) + } + } else { + h.MalformedHandler(msg) + } + } else { + h.MalformedHandler(msg) + } + } else { + msg[MessageKey] = RawMessage + msg[RawMessage] = line + h.MessageHandler(msg) + } + } else { + msg[MessageKey] = RawMessage + msg[RawMessage] = line + h.MessageHandler(msg) + } + } else { + if line[0] == '{' { + if err := json.Unmarshal([]byte(line), &msg); err != nil { + logrus.Error(line) + } + } else { + msg[MessageKey] = RawMessage + msg[RawMessage] = line + } + h.MessageHandler(msg) + } + } +} diff --git a/cmd/zrok/util.go b/cmd/zrok/util.go index 6a04d2889..887106b84 100644 --- a/cmd/zrok/util.go +++ b/cmd/zrok/util.go @@ -1,9 +1,11 @@ package main import ( + "encoding/json" "fmt" "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" + "github.com/openziti/zrok/cmd/zrok/subordinate" "github.com/pkg/errors" "math" "net/url" @@ -45,3 +47,15 @@ func parseUrl(in string) (string, error) { return targetEndpoint.String(), nil } + +func subordinateError(err error) { + msg := make(map[string]interface{}) + msg[subordinate.MessageKey] = subordinate.ErrorMessage + msg[subordinate.ErrorMessage] = err.Error() + if data, err := json.Marshal(msg); err == nil { + fmt.Println(string(data)) + } else { + fmt.Println("{\"" + subordinate.MessageKey + "\":\"" + subordinate.ErrorMessage + "\",\"" + subordinate.ErrorMessage + "\":\"internal error\"}") + } + os.Exit(1) +} diff --git a/endpoints/proxy/backend.go b/endpoints/proxy/backend.go index a181b0254..4d3491d32 100644 --- a/endpoints/proxy/backend.go +++ b/endpoints/proxy/backend.go @@ -67,6 +67,10 @@ func (b *Backend) Run() error { return nil } +func (b *Backend) Stop() error { + return b.listener.Close() +} + func newReverseProxy(cfg *BackendConfig) (*httputil.ReverseProxy, error) { targetURL, err := url.Parse(cfg.EndpointAddress) if err != nil { diff --git a/endpoints/proxy/caddyWebBackend.go b/endpoints/proxy/caddyWebBackend.go index ebae913a6..e5d6a663f 100644 --- a/endpoints/proxy/caddyWebBackend.go +++ b/endpoints/proxy/caddyWebBackend.go @@ -81,6 +81,10 @@ func (c *CaddyWebBackend) Run() error { return caddy.Run(c.caddyCfg) } +func (c *CaddyWebBackend) Stop() error { + return caddy.Stop() +} + func (c *CaddyWebBackend) Requests() func() int32 { return func() int32 { return 0 } } diff --git a/environment/env_core/model.go b/environment/env_core/model.go index ebb1df349..396247741 100644 --- a/environment/env_core/model.go +++ b/environment/env_core/model.go @@ -14,6 +14,7 @@ type Root interface { Client() (*rest_client_zrok.Zrok, error) ApiEndpoint() (string, string) DefaultFrontend() (string, string) + Headless() (bool, string) IsEnabled() bool Environment() *Environment @@ -26,6 +27,8 @@ type Root interface { ZitiIdentityNamed(name string) (string, error) SaveZitiIdentityNamed(name, data string) error DeleteZitiIdentityNamed(name string) error + + AgentSocket() (string, error) } type Environment struct { @@ -37,6 +40,7 @@ type Environment struct { type Config struct { ApiEndpoint string DefaultFrontend string + Headless bool } type Metadata struct { diff --git a/environment/env_v0_3/api.go b/environment/env_v0_3/api.go index 61a03296a..e71df04c0 100644 --- a/environment/env_v0_3/api.go +++ b/environment/env_v0_3/api.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" "regexp" + "strconv" ) func (r *Root) Metadata() *env_core.Metadata { @@ -103,6 +104,26 @@ func (r *Root) DefaultFrontend() (string, string) { return defaultFrontend, from } +func (r *Root) Headless() (bool, string) { + headless := false + from := "binary" + + if r.Config() != nil { + headless = r.Config().Headless + from = "config" + } + + env := os.Getenv("ZROK_HEADLESS") + if env != "" { + if v, err := strconv.ParseBool(env); err == nil { + headless = v + from = "ZROK_HEADLESS" + } + } + + return headless, from +} + func (r *Root) Environment() *env_core.Environment { return r.env } @@ -174,6 +195,10 @@ func (r *Root) DeleteZitiIdentityNamed(name string) error { return nil } +func (r *Root) AgentSocket() (string, error) { + return "", errors.Errorf("this environment version does not support agent sockets; please 'zrok update' this environment") +} + func (r *Root) Obliterate() error { zrd, err := rootDir() if err != nil { diff --git a/environment/env_v0_4/api.go b/environment/env_v0_4/api.go index 35db06c50..cfe589c2f 100644 --- a/environment/env_v0_4/api.go +++ b/environment/env_v0_4/api.go @@ -12,6 +12,7 @@ import ( "os" "path/filepath" "regexp" + "strconv" ) func (r *Root) Metadata() *env_core.Metadata { @@ -103,6 +104,26 @@ func (r *Root) DefaultFrontend() (string, string) { return defaultFrontend, from } +func (r *Root) Headless() (bool, string) { + headless := false + from := "binary" + + if r.Config() != nil { + headless = r.Config().Headless + from = "config" + } + + env := os.Getenv("ZROK_HEADLESS") + if env != "" { + if v, err := strconv.ParseBool(env); err == nil { + headless = v + from = "ZROK_HEADLESS" + } + } + + return headless, from +} + func (r *Root) Environment() *env_core.Environment { return r.env } @@ -174,6 +195,10 @@ func (r *Root) DeleteZitiIdentityNamed(name string) error { return nil } +func (r *Root) AgentSocket() (string, error) { + return agentSocket() +} + func (r *Root) Obliterate() error { zrd, err := rootDir() if err != nil { diff --git a/environment/env_v0_4/dirs.go b/environment/env_v0_4/dirs.go index b259fe094..bf18febfe 100644 --- a/environment/env_v0_4/dirs.go +++ b/environment/env_v0_4/dirs.go @@ -53,3 +53,11 @@ func identityFile(name string) (string, error) { } return filepath.Join(idd, fmt.Sprintf("%v.json", name)), nil } + +func agentSocket() (string, error) { + zrd, err := rootDir() + if err != nil { + return "", err + } + return filepath.Join(zrd, "agent.socket"), nil +} diff --git a/environment/env_v0_4/root.go b/environment/env_v0_4/root.go index f085f3f61..329c7fd1a 100644 --- a/environment/env_v0_4/root.go +++ b/environment/env_v0_4/root.go @@ -225,12 +225,17 @@ func loadConfig() (*env_core.Config, error) { out := &env_core.Config{ ApiEndpoint: cfg.ApiEndpoint, DefaultFrontend: cfg.DefaultFrontend, + Headless: cfg.Headless, } return out, nil } func saveConfig(cfg *env_core.Config) error { - in := &config{ApiEndpoint: cfg.ApiEndpoint, DefaultFrontend: cfg.DefaultFrontend} + in := &config{ + ApiEndpoint: cfg.ApiEndpoint, + DefaultFrontend: cfg.DefaultFrontend, + Headless: cfg.Headless, + } data, err := json.MarshalIndent(in, "", " ") if err != nil { return errors.Wrap(err, "error marshaling config") @@ -326,6 +331,7 @@ type metadata struct { type config struct { ApiEndpoint string `json:"api_endpoint"` DefaultFrontend string `json:"default_frontend"` + Headless bool `json:"headless"` } type environment struct { diff --git a/go.mod b/go.mod index 18964fa30..f4de47ed8 100644 --- a/go.mod +++ b/go.mod @@ -23,12 +23,14 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/greenpau/caddy-security v1.1.29 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 github.com/iancoleman/strcase v0.3.0 github.com/influxdata/influxdb-client-go/v2 v2.11.0 github.com/jaevor/go-nanoid v1.3.0 github.com/jedib0t/go-pretty/v6 v6.5.9 github.com/jessevdk/go-flags v1.6.1 github.com/jmoiron/sqlx v1.3.5 + github.com/kolesnikovae/go-winjob v1.0.0 github.com/lib/pq v1.10.9 github.com/mattn/go-sqlite3 v1.14.18 github.com/michaelquigley/cf v0.0.13 @@ -59,12 +61,17 @@ require ( golang.org/x/crypto v0.27.0 golang.org/x/net v0.29.0 golang.org/x/oauth2 v0.23.0 + golang.org/x/sys v0.25.0 golang.org/x/time v0.6.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 + google.golang.org/grpc v1.67.1 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 + google.golang.org/protobuf v1.34.2 nhooyr.io/websocket v1.8.17 ) require ( - cloud.google.com/go/compute/metadata v0.3.0 // indirect + cloud.google.com/go/compute/metadata v0.5.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect @@ -87,7 +94,7 @@ require ( github.com/caddyserver/zerossl v0.1.3 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/containerd/console v1.0.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect @@ -129,7 +136,7 @@ require ( github.com/gobwas/pool v0.2.1 // indirect github.com/gobwas/ws v1.2.1 // indirect github.com/golang-jwt/jwt/v4 v4.5.1 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/cel-go v0.20.1 // indirect @@ -142,7 +149,6 @@ require ( github.com/gorilla/securecookie v1.1.2 // indirect github.com/greenpau/go-authcrunch v1.1.4 // indirect github.com/greenpau/versioned v1.0.30 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -257,17 +263,13 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.19.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect golang.org/x/term v0.24.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.23.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20220703234212-c31a7b1ab478 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect - google.golang.org/grpc v1.63.2 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect diff --git a/go.sum b/go.sum index 2a3bc51ce..cd243e1a0 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= -cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/compute/metadata v0.5.0 h1:Zr0eK8JbFv6+Wi4ilXAR8FJ3wyNdpxHKJNPos6LTZOY= +cloud.google.com/go/compute/metadata v0.5.0/go.mod h1:aHnloV2TPI38yx4s9+wAZhHykWvVCfu7hQbF+9CWoiY= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= @@ -151,8 +151,8 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.14.0 h1:DJfCwnARfWjZLvMglhSQzo76UZ2gucuHPy9jLWX45Og= github.com/charmbracelet/bubbles v0.14.0/go.mod h1:bbeTiXwPww4M031aGi8UK2HT9RDWoiNibae+1yCMtcc= github.com/charmbracelet/bubbletea v0.21.0/go.mod h1:GgmJMec61d08zXsOhqRC/AiOx4K4pmz+VIcRIm1FKr4= @@ -334,8 +334,8 @@ github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -588,6 +588,8 @@ github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ib github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/kolesnikovae/go-winjob v1.0.0 h1:OKEtCHB3sYNAiqNwGDhf08Y6luM7C8mP+42rp1N6SeE= +github.com/kolesnikovae/go-winjob v1.0.0/go.mod h1:k0joOLP3/NBrRmDQjPV2+oN1TPmEWt6arTNtFjVeQuM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -1223,6 +1225,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1440,10 +1443,10 @@ google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaE google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= -google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae h1:AH34z6WAGVNkllnKs5raNq3yRq93VnjBG6rpfub/jYk= -google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142 h1:wKguEg1hsxI2/L3hUYrpo1RVi48K+uTyzKqprwLXsb8= +google.golang.org/genproto/googleapis/api v0.0.0-20240814211410-ddb44dafa142/go.mod h1:d6be+8HhtEtucleCbxpPW9PA9XwISACu8nvpPqF0BVo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= 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= @@ -1464,8 +1467,10 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/google/api/annotations.proto b/google/api/annotations.proto new file mode 100644 index 000000000..84c48164a --- /dev/null +++ b/google/api/annotations.proto @@ -0,0 +1,31 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/google/api/field_behavior.proto b/google/api/field_behavior.proto new file mode 100644 index 000000000..2865ba053 --- /dev/null +++ b/google/api/field_behavior.proto @@ -0,0 +1,104 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/descriptor.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "FieldBehaviorProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.FieldOptions { + // A designation of a specific field behavior (required, output only, etc.) + // in protobuf messages. + // + // Examples: + // + // string name = 1 [(google.api.field_behavior) = REQUIRED]; + // State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY]; + // google.protobuf.Duration ttl = 1 + // [(google.api.field_behavior) = INPUT_ONLY]; + // google.protobuf.Timestamp expire_time = 1 + // [(google.api.field_behavior) = OUTPUT_ONLY, + // (google.api.field_behavior) = IMMUTABLE]; + repeated google.api.FieldBehavior field_behavior = 1052 [packed = false]; +} + +// An indicator of the behavior of a given field (for example, that a field +// is required in requests, or given as output but ignored as input). +// This **does not** change the behavior in protocol buffers itself; it only +// denotes the behavior and may affect how API tooling handles the field. +// +// Note: This enum **may** receive new values in the future. +enum FieldBehavior { + // Conventional default for enums. Do not use this. + FIELD_BEHAVIOR_UNSPECIFIED = 0; + + // Specifically denotes a field as optional. + // While all fields in protocol buffers are optional, this may be specified + // for emphasis if appropriate. + OPTIONAL = 1; + + // Denotes a field as required. + // This indicates that the field **must** be provided as part of the request, + // and failure to do so will cause an error (usually `INVALID_ARGUMENT`). + REQUIRED = 2; + + // Denotes a field as output only. + // This indicates that the field is provided in responses, but including the + // field in a request does nothing (the server *must* ignore it and + // *must not* throw an error as a result of the field's presence). + OUTPUT_ONLY = 3; + + // Denotes a field as input only. + // This indicates that the field is provided in requests, and the + // corresponding field is not included in output. + INPUT_ONLY = 4; + + // Denotes a field as immutable. + // This indicates that the field may be set once in a request to create a + // resource, but may not be changed thereafter. + IMMUTABLE = 5; + + // Denotes that a (repeated) field is an unordered list. + // This indicates that the service may provide the elements of the list + // in any arbitrary order, rather than the order the user originally + // provided. Additionally, the list's order may or may not be stable. + UNORDERED_LIST = 6; + + // Denotes that this field returns a non-empty default value if not set. + // This indicates that if the user provides the empty value in a request, + // a non-empty value will be returned. The user will not be aware of what + // non-empty value to expect. + NON_EMPTY_DEFAULT = 7; + + // Denotes that the field in a resource (a message annotated with + // google.api.resource) is used in the resource name to uniquely identify the + // resource. For AIP-compliant APIs, this should only be applied to the + // `name` field on the resource. + // + // This behavior should not be applied to references to other resources within + // the message. + // + // The identifier field of resources often have different field behavior + // depending on the request it is embedded in (e.g. for Create methods name + // is optional and unused, while for Update methods it is required). Instead + // of method-specific annotations, only `IDENTIFIER` is required. + IDENTIFIER = 8; +} diff --git a/google/api/http.proto b/google/api/http.proto new file mode 100644 index 000000000..e3270371d --- /dev/null +++ b/google/api/http.proto @@ -0,0 +1,371 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// - HTTP: `GET /v1/messages/123456` +// - gRPC: `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// - HTTP: `GET /v1/messages/123456?revision=2&sub.subfield=foo` +// - gRPC: `GetMessage(message_id: "123456" revision: 2 sub: +// SubMessage(subfield: "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` +// - gRPC: `UpdateMessage(message_id: "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// - HTTP: `PATCH /v1/messages/123456 { "text": "Hi!" }` +// - gRPC: `UpdateMessage(message_id: "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// - HTTP: `GET /v1/messages/123456` +// - gRPC: `GetMessage(message_id: "123456")` +// +// - HTTP: `GET /v1/users/me/messages/123456` +// - gRPC: `GetMessage(user_id: "me" message_id: "123456")` +// +// Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They +// are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL +// query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP +// request body, all +// fields are passed via URL path and URL query parameters. +// +// Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// The following example selects a gRPC method and applies an `HttpRule` to it: +// +// http: +// rules: +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax + // details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/google/api/httpbody.proto b/google/api/httpbody.proto new file mode 100644 index 000000000..920612dc7 --- /dev/null +++ b/google/api/httpbody.proto @@ -0,0 +1,81 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; +option java_multiple_files = true; +option java_outer_classname = "HttpBodyProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Message that represents an arbitrary HTTP body. It should only be used for +// payload formats that can't be represented as JSON, such as raw binary or +// an HTML page. +// +// +// This message can be used both in streaming and non-streaming API methods in +// the request as well as the response. +// +// It can be used as a top-level request field, which is convenient if one +// wants to extract parameters from either the URL or HTTP template into the +// request fields and also want access to the raw HTTP body. +// +// Example: +// +// message GetResourceRequest { +// // A unique request id. +// string request_id = 1; +// +// // The raw HTTP body is bound to this field. +// google.api.HttpBody http_body = 2; +// +// } +// +// service ResourceService { +// rpc GetResource(GetResourceRequest) +// returns (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) +// returns (google.protobuf.Empty); +// +// } +// +// Example with streaming methods: +// +// service CaldavService { +// rpc GetCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// rpc UpdateCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// +// } +// +// Use of this type only changes how the request and response bodies are +// handled, all other features will continue to work unchanged. +message HttpBody { + // The HTTP Content-Type header value specifying the content type of the body. + string content_type = 1; + + // The HTTP request/response body as raw binary. + bytes data = 2; + + // Application specific response metadata. Must be set in the first response + // for streaming APIs. + repeated google.protobuf.Any extensions = 3; +} diff --git a/rest_server_zrok/doc.go b/rest_server_zrok/doc.go index 98311f939..aef023ab7 100644 --- a/rest_server_zrok/doc.go +++ b/rest_server_zrok/doc.go @@ -7,7 +7,7 @@ // http // Host: localhost // BasePath: /api/v1 -// Version: 0.3.0 +// Version: 1.0.0 // // Consumes: // - application/zrok.v1+json diff --git a/rest_server_zrok/embedded_spec.go b/rest_server_zrok/embedded_spec.go index 3879712e6..bb4478c32 100644 --- a/rest_server_zrok/embedded_spec.go +++ b/rest_server_zrok/embedded_spec.go @@ -31,7 +31,7 @@ func init() { "info": { "description": "zrok client access", "title": "zrok", - "version": "0.3.0" + "version": "1.0.0" }, "basePath": "/api/v1", "paths": { @@ -2281,7 +2281,7 @@ func init() { "info": { "description": "zrok client access", "title": "zrok", - "version": "0.3.0" + "version": "1.0.0" }, "basePath": "/api/v1", "paths": { diff --git a/sdk/nodejs/sdk/src/zrok/api/api/accountApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/accountApi.ts index bd0b1bb55..1de3b92c8 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/accountApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/accountApi.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts index 20ece673b..6626482a4 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/adminApi.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/api/environmentApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/environmentApi.ts index 9cc5b9103..d8ace5b35 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/environmentApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/environmentApi.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/api/metadataApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/metadataApi.ts index 4348628c4..a2b20f8df 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/metadataApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/metadataApi.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/api/shareApi.ts b/sdk/nodejs/sdk/src/zrok/api/api/shareApi.ts index ad3e6a322..e14454693 100644 --- a/sdk/nodejs/sdk/src/zrok/api/api/shareApi.ts +++ b/sdk/nodejs/sdk/src/zrok/api/api/shareApi.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/accessRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/accessRequest.ts index 438421b03..9c632631b 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/accessRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/accessRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/accessResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/accessResponse.ts index eb4bfa9e8..bc4c5833e 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/accessResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/accessResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/authUser.ts b/sdk/nodejs/sdk/src/zrok/api/model/authUser.ts index 18af66f4e..59d2cb904 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/authUser.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/authUser.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/changePasswordRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/changePasswordRequest.ts index bd32752a7..1ff0696a0 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/changePasswordRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/changePasswordRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/configuration.ts b/sdk/nodejs/sdk/src/zrok/api/model/configuration.ts index 78c489bd9..4b99212d5 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/configuration.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/configuration.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createAccountRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/createAccountRequest.ts index 84845bbad..e3011b336 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createAccountRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createAccountRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts index 35b425ef8..8166454d1 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendResponse.ts index 9484bcc27..e65bc6e47 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createFrontendResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createFrontendResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createIdentity201Response.ts b/sdk/nodejs/sdk/src/zrok/api/model/createIdentity201Response.ts index 8adb56c49..9487c0a02 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createIdentity201Response.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createIdentity201Response.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/createIdentityRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/createIdentityRequest.ts index d8b88a5fa..6d1828fc3 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/createIdentityRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/createIdentityRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/deleteFrontendRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/deleteFrontendRequest.ts index 9bb036079..83ede2e9b 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/deleteFrontendRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/deleteFrontendRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/disableRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/disableRequest.ts index 719e18870..11751b97b 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/disableRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/disableRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/enableRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/enableRequest.ts index f7d579a3a..53a774407 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/enableRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/enableRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/enableResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/enableResponse.ts index ef3e144c3..1e31726a9 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/enableResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/enableResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/environment.ts b/sdk/nodejs/sdk/src/zrok/api/model/environment.ts index 2bd9c3f98..5e13a7acb 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/environment.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/environment.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/environmentAndResources.ts b/sdk/nodejs/sdk/src/zrok/api/model/environmentAndResources.ts index 0d352df48..6bfd34cd5 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/environmentAndResources.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/environmentAndResources.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/frontend.ts b/sdk/nodejs/sdk/src/zrok/api/model/frontend.ts index 1573263d8..6da24ecae 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/frontend.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/frontend.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/grantsRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/grantsRequest.ts index 1018c48f2..f1c221a3a 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/grantsRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/grantsRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/inviteRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/inviteRequest.ts index 9fbb0b3dc..5f3494678 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/inviteRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/inviteRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/inviteTokenGenerateRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/inviteTokenGenerateRequest.ts index 5a39bd9f8..1e54dc8b4 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/inviteTokenGenerateRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/inviteTokenGenerateRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/loginRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/loginRequest.ts index e10a6c374..ed868723d 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/loginRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/loginRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/metrics.ts b/sdk/nodejs/sdk/src/zrok/api/model/metrics.ts index 8a76f49f8..526cc7968 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/metrics.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/metrics.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/metricsSample.ts b/sdk/nodejs/sdk/src/zrok/api/model/metricsSample.ts index 03b059731..a8d52b152 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/metricsSample.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/metricsSample.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/overview.ts b/sdk/nodejs/sdk/src/zrok/api/model/overview.ts index 44a46d766..cadd20f5a 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/overview.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/overview.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/passwordRequirements.ts b/sdk/nodejs/sdk/src/zrok/api/model/passwordRequirements.ts index c082d0a47..3500aa348 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/passwordRequirements.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/passwordRequirements.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/principal.ts b/sdk/nodejs/sdk/src/zrok/api/model/principal.ts index 33038f2b9..1c9c3b155 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/principal.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/principal.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/publicFrontend.ts b/sdk/nodejs/sdk/src/zrok/api/model/publicFrontend.ts index 3046ad131..f01df9f72 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/publicFrontend.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/publicFrontend.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/regenerateToken200Response.ts b/sdk/nodejs/sdk/src/zrok/api/model/regenerateToken200Response.ts index af10ab0c0..355b5ea79 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/regenerateToken200Response.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/regenerateToken200Response.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/regenerateTokenRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/regenerateTokenRequest.ts index 63c881e92..869ab3f96 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/regenerateTokenRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/regenerateTokenRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/registerRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/registerRequest.ts index 379678c32..f29eb8809 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/registerRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/registerRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/registerResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/registerResponse.ts index b8716d719..6fbd56b9c 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/registerResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/registerResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/resetPasswordRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/resetPasswordRequest.ts index 931d71369..fb80f8da4 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/resetPasswordRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/resetPasswordRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/share.ts b/sdk/nodejs/sdk/src/zrok/api/model/share.ts index 41b059d83..4113ea1ff 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/share.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/share.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts index 086ba7d87..13b5071d0 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/shareRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/shareResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/shareResponse.ts index 9b134a098..f099ef230 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/shareResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/shareResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/sparkDataSample.ts b/sdk/nodejs/sdk/src/zrok/api/model/sparkDataSample.ts index b5fb3c075..dc331435f 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/sparkDataSample.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/sparkDataSample.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/unaccessRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/unaccessRequest.ts index dbacc6cb5..11beb921a 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/unaccessRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/unaccessRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/unshareRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/unshareRequest.ts index bab4fae85..16485d21f 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/unshareRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/unshareRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/updateFrontendRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/updateFrontendRequest.ts index 83692f6bd..cbc7deb03 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/updateFrontendRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/updateFrontendRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/updateShareRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/updateShareRequest.ts index d3223d34f..554971b57 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/updateShareRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/updateShareRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/verifyRequest.ts b/sdk/nodejs/sdk/src/zrok/api/model/verifyRequest.ts index b9a015873..ca71ab084 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/verifyRequest.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/verifyRequest.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/nodejs/sdk/src/zrok/api/model/verifyResponse.ts b/sdk/nodejs/sdk/src/zrok/api/model/verifyResponse.ts index a2d01f634..91b97fb56 100644 --- a/sdk/nodejs/sdk/src/zrok/api/model/verifyResponse.ts +++ b/sdk/nodejs/sdk/src/zrok/api/model/verifyResponse.ts @@ -2,7 +2,7 @@ * zrok * zrok client access * - * The version of the OpenAPI document: 0.3.0 + * The version of the OpenAPI document: 1.0.0 * * * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). diff --git a/sdk/python/sdk/zrok/zrok_api/__init__.py b/sdk/python/sdk/zrok/zrok_api/__init__.py index 5028fe657..89ee97d60 100644 --- a/sdk/python/sdk/zrok/zrok_api/__init__.py +++ b/sdk/python/sdk/zrok/zrok_api/__init__.py @@ -7,7 +7,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api/account_api.py b/sdk/python/sdk/zrok/zrok_api/api/account_api.py index c74faed7b..908994ccf 100644 --- a/sdk/python/sdk/zrok/zrok_api/api/account_api.py +++ b/sdk/python/sdk/zrok/zrok_api/api/account_api.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api/admin_api.py b/sdk/python/sdk/zrok/zrok_api/api/admin_api.py index 172d0968f..d243c2102 100644 --- a/sdk/python/sdk/zrok/zrok_api/api/admin_api.py +++ b/sdk/python/sdk/zrok/zrok_api/api/admin_api.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api/environment_api.py b/sdk/python/sdk/zrok/zrok_api/api/environment_api.py index 01eeb922b..5f4f7d1b8 100644 --- a/sdk/python/sdk/zrok/zrok_api/api/environment_api.py +++ b/sdk/python/sdk/zrok/zrok_api/api/environment_api.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api/metadata_api.py b/sdk/python/sdk/zrok/zrok_api/api/metadata_api.py index 59ab45cbc..000ecd22b 100644 --- a/sdk/python/sdk/zrok/zrok_api/api/metadata_api.py +++ b/sdk/python/sdk/zrok/zrok_api/api/metadata_api.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api/share_api.py b/sdk/python/sdk/zrok/zrok_api/api/share_api.py index 647e63692..c9f1550ed 100644 --- a/sdk/python/sdk/zrok/zrok_api/api/share_api.py +++ b/sdk/python/sdk/zrok/zrok_api/api/share_api.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/api_client.py b/sdk/python/sdk/zrok/zrok_api/api_client.py index 763a3bb5d..f917a79bf 100644 --- a/sdk/python/sdk/zrok/zrok_api/api_client.py +++ b/sdk/python/sdk/zrok/zrok_api/api_client.py @@ -4,7 +4,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/configuration.py b/sdk/python/sdk/zrok/zrok_api/configuration.py index 9fd585c44..331c27b72 100644 --- a/sdk/python/sdk/zrok/zrok_api/configuration.py +++ b/sdk/python/sdk/zrok/zrok_api/configuration.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ @@ -246,6 +246,6 @@ def to_debug_report(self): return "Python SDK Debug Report:\n"\ "OS: {env}\n"\ "Python Version: {pyversion}\n"\ - "Version of the API: 0.3.0\n"\ + "Version of the API: 1.0.0\n"\ "SDK Package Version: 1.0.0".\ format(env=sys.platform, pyversion=sys.version) diff --git a/sdk/python/sdk/zrok/zrok_api/models/__init__.py b/sdk/python/sdk/zrok/zrok_api/models/__init__.py index fff66b79a..486bc17b1 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/__init__.py +++ b/sdk/python/sdk/zrok/zrok_api/models/__init__.py @@ -6,7 +6,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/access_request.py b/sdk/python/sdk/zrok/zrok_api/models/access_request.py index e51ea20ac..2fdb2addd 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/access_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/access_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/access_response.py b/sdk/python/sdk/zrok/zrok_api/models/access_response.py index ba02584ff..2ee62cc6f 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/access_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/access_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/account_body.py b/sdk/python/sdk/zrok/zrok_api/models/account_body.py index 2447dea1f..ea261eb00 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/account_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/account_body.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/auth_user.py b/sdk/python/sdk/zrok/zrok_api/models/auth_user.py index a3b6eaf28..0a04dc102 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/auth_user.py +++ b/sdk/python/sdk/zrok/zrok_api/models/auth_user.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/change_password_request.py b/sdk/python/sdk/zrok/zrok_api/models/change_password_request.py index fe3f48626..385283de0 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/change_password_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/change_password_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/configuration.py b/sdk/python/sdk/zrok/zrok_api/models/configuration.py index 20a1f0c59..65ddac05a 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/configuration.py +++ b/sdk/python/sdk/zrok/zrok_api/models/configuration.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ 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 f6a0cf016..804ee1f1f 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 @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/create_frontend_response.py b/sdk/python/sdk/zrok/zrok_api/models/create_frontend_response.py index d93e99ed7..bd8b347aa 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/create_frontend_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/create_frontend_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/delete_frontend_request.py b/sdk/python/sdk/zrok/zrok_api/models/delete_frontend_request.py index c9b92bad8..36f43f1a8 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/delete_frontend_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/delete_frontend_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/disable_request.py b/sdk/python/sdk/zrok/zrok_api/models/disable_request.py index c04502565..df1d4c64b 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/disable_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/disable_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/enable_request.py b/sdk/python/sdk/zrok/zrok_api/models/enable_request.py index 6d35968f2..dc8d2a137 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/enable_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/enable_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/enable_response.py b/sdk/python/sdk/zrok/zrok_api/models/enable_response.py index 66c8af2f7..116197c1b 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/enable_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/enable_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/environment.py b/sdk/python/sdk/zrok/zrok_api/models/environment.py index 79e03aeeb..53c855595 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/environment.py +++ b/sdk/python/sdk/zrok/zrok_api/models/environment.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/environment_and_resources.py b/sdk/python/sdk/zrok/zrok_api/models/environment_and_resources.py index 10275235d..12c466bb2 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/environment_and_resources.py +++ b/sdk/python/sdk/zrok/zrok_api/models/environment_and_resources.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/environments.py b/sdk/python/sdk/zrok/zrok_api/models/environments.py index ccbc297c8..e6d72d56a 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/environments.py +++ b/sdk/python/sdk/zrok/zrok_api/models/environments.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/error_message.py b/sdk/python/sdk/zrok/zrok_api/models/error_message.py index 21e07ea07..193251870 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/error_message.py +++ b/sdk/python/sdk/zrok/zrok_api/models/error_message.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/frontend.py b/sdk/python/sdk/zrok/zrok_api/models/frontend.py index f45b26a37..aa06fa749 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/frontend.py +++ b/sdk/python/sdk/zrok/zrok_api/models/frontend.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/frontends.py b/sdk/python/sdk/zrok/zrok_api/models/frontends.py index 923baa9d0..3c00604a1 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/frontends.py +++ b/sdk/python/sdk/zrok/zrok_api/models/frontends.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/grants_body.py b/sdk/python/sdk/zrok/zrok_api/models/grants_body.py index e61ea02d3..78e7d53aa 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/grants_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/grants_body.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/identity_body.py b/sdk/python/sdk/zrok/zrok_api/models/identity_body.py index 8da98c333..4be3f8e52 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/identity_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/identity_body.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/inline_response200.py b/sdk/python/sdk/zrok/zrok_api/models/inline_response200.py index a972a3fbb..e2b54d34d 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/inline_response200.py +++ b/sdk/python/sdk/zrok/zrok_api/models/inline_response200.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/inline_response201.py b/sdk/python/sdk/zrok/zrok_api/models/inline_response201.py index a5672fe16..25230c117 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/inline_response201.py +++ b/sdk/python/sdk/zrok/zrok_api/models/inline_response201.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/invite_request.py b/sdk/python/sdk/zrok/zrok_api/models/invite_request.py index cd4a2d925..7e3365131 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/invite_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/invite_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/invite_token_generate_request.py b/sdk/python/sdk/zrok/zrok_api/models/invite_token_generate_request.py index 6cc198d96..e0add5eea 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/invite_token_generate_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/invite_token_generate_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/login_request.py b/sdk/python/sdk/zrok/zrok_api/models/login_request.py index c91bcc2bb..9094b6a6c 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/login_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/login_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/login_response.py b/sdk/python/sdk/zrok/zrok_api/models/login_response.py index 65178a79d..857ae4ed1 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/login_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/login_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/metrics.py b/sdk/python/sdk/zrok/zrok_api/models/metrics.py index 6fe13362a..d7dd52f8c 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/metrics.py +++ b/sdk/python/sdk/zrok/zrok_api/models/metrics.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/metrics_sample.py b/sdk/python/sdk/zrok/zrok_api/models/metrics_sample.py index 70db528d2..8e297c435 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/metrics_sample.py +++ b/sdk/python/sdk/zrok/zrok_api/models/metrics_sample.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/overview.py b/sdk/python/sdk/zrok/zrok_api/models/overview.py index d8319858e..7ef8aac48 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/overview.py +++ b/sdk/python/sdk/zrok/zrok_api/models/overview.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/password_requirements.py b/sdk/python/sdk/zrok/zrok_api/models/password_requirements.py index 8589a8b81..b691dd903 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/password_requirements.py +++ b/sdk/python/sdk/zrok/zrok_api/models/password_requirements.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/principal.py b/sdk/python/sdk/zrok/zrok_api/models/principal.py index b93a23f88..0f1c6ff48 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/principal.py +++ b/sdk/python/sdk/zrok/zrok_api/models/principal.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/public_frontend.py b/sdk/python/sdk/zrok/zrok_api/models/public_frontend.py index d28734039..06743e983 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/public_frontend.py +++ b/sdk/python/sdk/zrok/zrok_api/models/public_frontend.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/public_frontend_list.py b/sdk/python/sdk/zrok/zrok_api/models/public_frontend_list.py index abbe9bd3c..ff698b749 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/public_frontend_list.py +++ b/sdk/python/sdk/zrok/zrok_api/models/public_frontend_list.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/regenerate_token_body.py b/sdk/python/sdk/zrok/zrok_api/models/regenerate_token_body.py index 0b1e532c7..8c4184ac3 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/regenerate_token_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/regenerate_token_body.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/register_request.py b/sdk/python/sdk/zrok/zrok_api/models/register_request.py index cfb274a84..dba735737 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/register_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/register_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/register_response.py b/sdk/python/sdk/zrok/zrok_api/models/register_response.py index a0b7ac034..695d11842 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/register_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/register_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/reset_password_request.py b/sdk/python/sdk/zrok/zrok_api/models/reset_password_request.py index cf52cc887..dee32ab03 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/reset_password_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/reset_password_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/reset_password_request_body.py b/sdk/python/sdk/zrok/zrok_api/models/reset_password_request_body.py index 44e975ec3..2d0bd6140 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/reset_password_request_body.py +++ b/sdk/python/sdk/zrok/zrok_api/models/reset_password_request_body.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/share.py b/sdk/python/sdk/zrok/zrok_api/models/share.py index 7399068c8..cb0b8a1f2 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/share.py +++ b/sdk/python/sdk/zrok/zrok_api/models/share.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/share_request.py b/sdk/python/sdk/zrok/zrok_api/models/share_request.py index 32f02f295..ee9a08b18 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/share_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/share_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/share_response.py b/sdk/python/sdk/zrok/zrok_api/models/share_response.py index b8d01c703..5f466321e 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/share_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/share_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/shares.py b/sdk/python/sdk/zrok/zrok_api/models/shares.py index 7fba2e9cd..c1ce3f4de 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/shares.py +++ b/sdk/python/sdk/zrok/zrok_api/models/shares.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/spark_data.py b/sdk/python/sdk/zrok/zrok_api/models/spark_data.py index 8dd2e32be..9ed04dfe4 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/spark_data.py +++ b/sdk/python/sdk/zrok/zrok_api/models/spark_data.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/spark_data_sample.py b/sdk/python/sdk/zrok/zrok_api/models/spark_data_sample.py index ce5f2b090..52a1c1fd3 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/spark_data_sample.py +++ b/sdk/python/sdk/zrok/zrok_api/models/spark_data_sample.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/unaccess_request.py b/sdk/python/sdk/zrok/zrok_api/models/unaccess_request.py index 75158673a..d3a979a0d 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/unaccess_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/unaccess_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/unshare_request.py b/sdk/python/sdk/zrok/zrok_api/models/unshare_request.py index ecfc9e3cf..2181147ea 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/unshare_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/unshare_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/update_frontend_request.py b/sdk/python/sdk/zrok/zrok_api/models/update_frontend_request.py index 415543908..b8f47c1a6 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/update_frontend_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/update_frontend_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/update_share_request.py b/sdk/python/sdk/zrok/zrok_api/models/update_share_request.py index 3548c1017..d53343dcd 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/update_share_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/update_share_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/verify_request.py b/sdk/python/sdk/zrok/zrok_api/models/verify_request.py index 8089bc9bc..72a00aad0 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/verify_request.py +++ b/sdk/python/sdk/zrok/zrok_api/models/verify_request.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/verify_response.py b/sdk/python/sdk/zrok/zrok_api/models/verify_response.py index d6b9a617d..4f2b39685 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/verify_response.py +++ b/sdk/python/sdk/zrok/zrok_api/models/verify_response.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/models/version.py b/sdk/python/sdk/zrok/zrok_api/models/version.py index eba996e27..98e907608 100644 --- a/sdk/python/sdk/zrok/zrok_api/models/version.py +++ b/sdk/python/sdk/zrok/zrok_api/models/version.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/sdk/python/sdk/zrok/zrok_api/rest.py b/sdk/python/sdk/zrok/zrok_api/rest.py index 21bc091ba..a2c54065f 100644 --- a/sdk/python/sdk/zrok/zrok_api/rest.py +++ b/sdk/python/sdk/zrok/zrok_api/rest.py @@ -5,7 +5,7 @@ zrok client access # noqa: E501 - OpenAPI spec version: 0.3.0 + OpenAPI spec version: 1.0.0 Generated by: https://github.com/swagger-api/swagger-codegen.git """ diff --git a/specs/zrok.yml b/specs/zrok.yml index 8a88e0192..6c8bd5640 100644 --- a/specs/zrok.yml +++ b/specs/zrok.yml @@ -1,7 +1,7 @@ info: description: zrok client access title: zrok - version: 0.3.0 + version: 1.0.0 basePath: /api/v1 diff --git a/util/autoListener.go b/util/autoListener.go new file mode 100644 index 000000000..a28783511 --- /dev/null +++ b/util/autoListener.go @@ -0,0 +1,29 @@ +package util + +import ( + "fmt" + "net" +) + +func AutoListener(protocol, address string, startPort, endPort uint16) (net.Listener, error) { + for i := startPort; i <= endPort; i++ { + l, err := net.Listen(protocol, fmt.Sprintf("%s:%d", address, i)) + if err != nil { + continue + } + return l, nil + } + return nil, fmt.Errorf("no listener found in range") +} + +func AutoListenerAddress(protocol, address string, startPort, endPort uint16) (string, error) { + listener, err := AutoListener(protocol, address, startPort, endPort) + if err != nil { + return "", err + } + autoAddress := listener.Addr().String() + if err := listener.Close(); err != nil { + return "", err + } + return autoAddress, nil +} diff --git a/util/cors.go b/util/cors.go new file mode 100644 index 000000000..5d1f21f5b --- /dev/null +++ b/util/cors.go @@ -0,0 +1,15 @@ +package util + +import "net/http" + +func cors(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE") + w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization, ResponseType, User-Agent") + if r.Method == "OPTIONS" { + return + } + h.ServeHTTP(w, r) + }) +}