From 914c173a8223c9027dbcfd364bfbc84f5ad06187 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Sat, 13 Jul 2024 10:34:14 -0600 Subject: [PATCH 01/10] feat(cmd): begin implementing auth subcommand --- cmd/lk/auth.go | 214 +++++++++++++++++++++++++++++++++++++++++++++++++ cmd/lk/main.go | 1 + 2 files changed, 215 insertions(+) create mode 100644 cmd/lk/auth.go diff --git a/cmd/lk/auth.go b/cmd/lk/auth.go new file mode 100644 index 00000000..adcc97e1 --- /dev/null +++ b/cmd/lk/auth.go @@ -0,0 +1,214 @@ +// Copyright 2024 LiveKit, Inc. +// +// 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. + +package main + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/urfave/cli/v3" +) + +const ( + cloudAPIServerURL = "http://cloud-api.livekit.run" + cloudDashboardURL = "https://cloud.livekit.run" + // cloudAPIServerURL = "https://cloud-api.livekit.io" + // cloudDashboardURL = "https://cloud.livekit.io" + createTokenEndpoint = "/cli/auth" + confirmAuthEndpoint = "/cli/confirm-auth" + claimSessionEndpoint = "/cli/claim" +) + +type CreateTokenResponse struct { + Identifier string + Token string + Expires int64 + DeviceName string +} + +type AuthClient struct { + client *http.Client + baseURL string + verificationToken CreateTokenResponse +} + +func (a *AuthClient) GetVerificationToken(subdomain string) (*CreateTokenResponse, error) { + reqURL, err := url.Parse(a.baseURL + createTokenEndpoint) + if err != nil { + return nil, err + } + + params := url.Values{} + params.Add("device_name", "CLI") + params.Add("subdomain", subdomain) + reqURL.RawQuery = params.Encode() + + resp, err := a.client.Post(reqURL.String(), "application/json", nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, errors.New(resp.Status) + } + + err = json.NewDecoder(resp.Body).Decode(&a.verificationToken) + if err != nil { + return nil, err + } + + return &a.verificationToken, nil +} + +func (a *AuthClient) ClaimSession() (*CreateTokenResponse, error) { + if a.verificationToken.Token == "" || time.Now().Unix() > a.verificationToken.Expires { + return nil, errors.New("session expired") + } + + reqURL, err := url.Parse(a.baseURL + claimSessionEndpoint) + if err != nil { + return nil, err + } + + params := url.Values{} + params.Add("t", a.verificationToken.Token) + reqURL.RawQuery = params.Encode() + + resp, err := a.client.Get(reqURL.String()) + if err != nil { + return nil, err + } + + sessionToken := &CreateTokenResponse{} + err = json.NewDecoder(resp.Body).Decode(&sessionToken) + if err != nil { + return nil, err + } + + fmt.Println("SESSIONTOKEN: ", sessionToken.Token, sessionToken.DeviceName) + + return sessionToken, nil +} + +func (a *AuthClient) Deauthenticate() error { + // TODO: revoke any session token + return nil +} + +func NewAuthClient(client *http.Client, baseURL string) *AuthClient { + a := &AuthClient{ + client: client, + baseURL: baseURL, + } + return a +} + +var ( + disconnect bool + authClient AuthClient + AuthCommands = []*cli.Command{ + { + Name: "auth", + Usage: "Add or remove projects and view existing project properties", + Category: "Core", + Before: createAuthClient, + Action: handleAuth, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "d", + Aliases: []string{"disconnect"}, + Destination: &disconnect, + }, + }, + }, + } +) + +func createAuthClient(ctx context.Context, cmd *cli.Command) error { + if err := loadProjectConfig(ctx, cmd); err != nil { + return err + } + authClient = *NewAuthClient(&http.Client{}, cloudAPIServerURL) + return nil +} + +func handleAuth(ctx context.Context, cmd *cli.Command) error { + if disconnect { + return authClient.Deauthenticate() + } + return tryAuthIfNeeded(ctx, cmd) +} + +func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { + _, err := loadProjectDetails(cmd) + if err != nil { + return err + } + + // TODO: if we already have a valid session token, return early + + fmt.Println("Requesting verification token...") + token, err := authClient.GetVerificationToken("bar.foo") // FIXME: subdomain? + if err != nil { + return err + } + + authURL, err := url.Parse(cloudDashboardURL + confirmAuthEndpoint) + if err != nil { + return err + } + params := url.Values{} + params.Add("t", token.Token) + authURL.RawQuery = params.Encode() + + fmt.Println(authURL) + + return pollClaim(ctx, cmd) +} + +func pollClaim(context.Context, *cli.Command) error { + claim := make(chan *CreateTokenResponse) + cancel := make(chan error) + go func() { + for { + fmt.Println("Polling...") + time.Sleep(10 * time.Second) + session, err := authClient.ClaimSession() + if err != nil { + cancel <- err + return + } + fmt.Println(session) + claim <- session + } + }() + + select { + case <-time.After(1 * time.Minute): + return errors.New("session claim timed out") + case err := <-cancel: + return err + case sessionToken := <-claim: + // TODO: write to config file + fmt.Println(sessionToken) + return nil + } +} diff --git a/cmd/lk/main.go b/cmd/lk/main.go index 12e66d92..3571b671 100644 --- a/cmd/lk/main.go +++ b/cmd/lk/main.go @@ -67,6 +67,7 @@ func main() { }, } + app.Commands = append(app.Commands, AuthCommands...) app.Commands = append(app.Commands, TokenCommands...) app.Commands = append(app.Commands, RoomCommands...) app.Commands = append(app.Commands, JoinCommands...) From fe8cae2390c0bfaab4741f708c5d30990a74a9df Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Fri, 19 Jul 2024 11:21:27 -0600 Subject: [PATCH 02/10] feat(cmd): complete poll logic and prettify with a spinner --- cmd/lk/auth.go | 97 +++++++++++++++++++++++++++++++++----------------- go.mod | 1 + go.sum | 2 ++ 3 files changed, 68 insertions(+), 32 deletions(-) diff --git a/cmd/lk/auth.go b/cmd/lk/auth.go index adcc97e1..9f153d7c 100644 --- a/cmd/lk/auth.go +++ b/cmd/lk/auth.go @@ -23,6 +23,7 @@ import ( "net/url" "time" + "github.com/charmbracelet/huh/spinner" "github.com/urfave/cli/v3" ) @@ -36,6 +37,43 @@ const ( claimSessionEndpoint = "/cli/claim" ) +var ( + disconnect bool + timeout int64 + interval int64 + authClient AuthClient + AuthCommands = []*cli.Command{ + { + Name: "auth", + Usage: "Authenticate the CLI via the browser to permit advanced actions", + Category: "Core", + Before: createAuthClient, + Action: handleAuth, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "d", + Aliases: []string{"disconnect"}, + Destination: &disconnect, + }, + &cli.IntFlag{ + Name: "t", + Aliases: []string{"timeout"}, + Usage: "Number of `SECONDS` to attempt authentication before giving up", + Destination: &timeout, + Value: 60, + }, + &cli.IntFlag{ + Name: "i", + Aliases: []string{"poll-interval"}, + Usage: "Number of `SECONDS` between poll requests to verify authentication", + Destination: &interval, + Value: 4, + }, + }, + }, + } +) + type CreateTokenResponse struct { Identifier string Token string @@ -78,7 +116,7 @@ func (a *AuthClient) GetVerificationToken(subdomain string) (*CreateTokenRespons return &a.verificationToken, nil } -func (a *AuthClient) ClaimSession() (*CreateTokenResponse, error) { +func (a *AuthClient) ClaimSession(ctx context.Context) (*CreateTokenResponse, error) { if a.verificationToken.Token == "" || time.Now().Unix() > a.verificationToken.Expires { return nil, errors.New("session expired") } @@ -92,11 +130,20 @@ func (a *AuthClient) ClaimSession() (*CreateTokenResponse, error) { params.Add("t", a.verificationToken.Token) reqURL.RawQuery = params.Encode() - resp, err := a.client.Get(reqURL.String()) + req, err := http.NewRequestWithContext(ctx, "GET", reqURL.String(), nil) + if err != nil { + return nil, err + } + resp, err := a.client.Do(req) if err != nil { return nil, err } + if resp.StatusCode == http.StatusUnauthorized { + // Not yet approved + return nil, nil + } + sessionToken := &CreateTokenResponse{} err = json.NewDecoder(resp.Body).Decode(&sessionToken) if err != nil { @@ -121,27 +168,6 @@ func NewAuthClient(client *http.Client, baseURL string) *AuthClient { return a } -var ( - disconnect bool - authClient AuthClient - AuthCommands = []*cli.Command{ - { - Name: "auth", - Usage: "Add or remove projects and view existing project properties", - Category: "Core", - Before: createAuthClient, - Action: handleAuth, - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "d", - Aliases: []string{"disconnect"}, - Destination: &disconnect, - }, - }, - }, - } -) - func createAuthClient(ctx context.Context, cmd *cli.Command) error { if err := loadProjectConfig(ctx, cmd); err != nil { return err @@ -179,30 +205,37 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { params.Add("t", token.Token) authURL.RawQuery = params.Encode() - fmt.Println(authURL) + fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) + + if err := spinner.New(). + Title("Awaiting confirmation..."). + Action(func() { err = pollClaim(ctx, cmd) }). + Run(); err != nil { + return err + } - return pollClaim(ctx, cmd) + return err } -func pollClaim(context.Context, *cli.Command) error { +func pollClaim(ctx context.Context, _ *cli.Command) error { claim := make(chan *CreateTokenResponse) cancel := make(chan error) go func() { for { - fmt.Println("Polling...") - time.Sleep(10 * time.Second) - session, err := authClient.ClaimSession() + time.Sleep(time.Duration(interval) * time.Second) + session, err := authClient.ClaimSession(ctx) if err != nil { cancel <- err return } - fmt.Println(session) - claim <- session + if session != nil { + claim <- session + } } }() select { - case <-time.After(1 * time.Minute): + case <-time.After(time.Duration(timeout) * time.Second): return errors.New("session claim timed out") case err := <-cancel: return err diff --git a/go.mod b/go.mod index b6d23a22..e3394df4 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ toolchain go1.22.2 require ( github.com/charmbracelet/huh v0.5.2 + github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6 github.com/charmbracelet/lipgloss v0.12.1 github.com/frostbyte73/core v0.0.12 github.com/go-logr/logr v1.4.2 diff --git a/go.sum b/go.sum index 5bb2b601..c55b089f 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqp github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/huh v0.5.2 h1:ofeNkJ4iaFnzv46Njhx896DzLUe/j0L2QAf8znwzX4c= github.com/charmbracelet/huh v0.5.2/go.mod h1:Sf7dY0oAn6N/e3sXJFtFX9hdQLrUdO3z7AYollG9bAM= +github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6 h1:Wey8Un1qEEHI18y0HOs3K2HBBb9aEssoDmQo1+Idpuo= +github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6/go.mod h1:CrXBZnOWs3zpyppOZZS7lu2CpLq2jx6U5chL/frRG/E= github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= From dd87ec321bea32512d8d8b6f87c92cea4a6e86c9 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Tue, 6 Aug 2024 22:02:14 -0600 Subject: [PATCH 03/10] chore(auth): move auth subcommand under cloud command --- cmd/lk/auth.go | 247 --------------------------------- cmd/lk/cloud.go | 319 +++++++++++++++++++++++++++++++++++++++++++ pkg/config/config.go | 13 ++ 3 files changed, 332 insertions(+), 247 deletions(-) delete mode 100644 cmd/lk/auth.go create mode 100644 cmd/lk/cloud.go diff --git a/cmd/lk/auth.go b/cmd/lk/auth.go deleted file mode 100644 index 9f153d7c..00000000 --- a/cmd/lk/auth.go +++ /dev/null @@ -1,247 +0,0 @@ -// Copyright 2024 LiveKit, Inc. -// -// 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. - -package main - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - "time" - - "github.com/charmbracelet/huh/spinner" - "github.com/urfave/cli/v3" -) - -const ( - cloudAPIServerURL = "http://cloud-api.livekit.run" - cloudDashboardURL = "https://cloud.livekit.run" - // cloudAPIServerURL = "https://cloud-api.livekit.io" - // cloudDashboardURL = "https://cloud.livekit.io" - createTokenEndpoint = "/cli/auth" - confirmAuthEndpoint = "/cli/confirm-auth" - claimSessionEndpoint = "/cli/claim" -) - -var ( - disconnect bool - timeout int64 - interval int64 - authClient AuthClient - AuthCommands = []*cli.Command{ - { - Name: "auth", - Usage: "Authenticate the CLI via the browser to permit advanced actions", - Category: "Core", - Before: createAuthClient, - Action: handleAuth, - Flags: []cli.Flag{ - &cli.BoolFlag{ - Name: "d", - Aliases: []string{"disconnect"}, - Destination: &disconnect, - }, - &cli.IntFlag{ - Name: "t", - Aliases: []string{"timeout"}, - Usage: "Number of `SECONDS` to attempt authentication before giving up", - Destination: &timeout, - Value: 60, - }, - &cli.IntFlag{ - Name: "i", - Aliases: []string{"poll-interval"}, - Usage: "Number of `SECONDS` between poll requests to verify authentication", - Destination: &interval, - Value: 4, - }, - }, - }, - } -) - -type CreateTokenResponse struct { - Identifier string - Token string - Expires int64 - DeviceName string -} - -type AuthClient struct { - client *http.Client - baseURL string - verificationToken CreateTokenResponse -} - -func (a *AuthClient) GetVerificationToken(subdomain string) (*CreateTokenResponse, error) { - reqURL, err := url.Parse(a.baseURL + createTokenEndpoint) - if err != nil { - return nil, err - } - - params := url.Values{} - params.Add("device_name", "CLI") - params.Add("subdomain", subdomain) - reqURL.RawQuery = params.Encode() - - resp, err := a.client.Post(reqURL.String(), "application/json", nil) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, errors.New(resp.Status) - } - - err = json.NewDecoder(resp.Body).Decode(&a.verificationToken) - if err != nil { - return nil, err - } - - return &a.verificationToken, nil -} - -func (a *AuthClient) ClaimSession(ctx context.Context) (*CreateTokenResponse, error) { - if a.verificationToken.Token == "" || time.Now().Unix() > a.verificationToken.Expires { - return nil, errors.New("session expired") - } - - reqURL, err := url.Parse(a.baseURL + claimSessionEndpoint) - if err != nil { - return nil, err - } - - params := url.Values{} - params.Add("t", a.verificationToken.Token) - reqURL.RawQuery = params.Encode() - - req, err := http.NewRequestWithContext(ctx, "GET", reqURL.String(), nil) - if err != nil { - return nil, err - } - resp, err := a.client.Do(req) - if err != nil { - return nil, err - } - - if resp.StatusCode == http.StatusUnauthorized { - // Not yet approved - return nil, nil - } - - sessionToken := &CreateTokenResponse{} - err = json.NewDecoder(resp.Body).Decode(&sessionToken) - if err != nil { - return nil, err - } - - fmt.Println("SESSIONTOKEN: ", sessionToken.Token, sessionToken.DeviceName) - - return sessionToken, nil -} - -func (a *AuthClient) Deauthenticate() error { - // TODO: revoke any session token - return nil -} - -func NewAuthClient(client *http.Client, baseURL string) *AuthClient { - a := &AuthClient{ - client: client, - baseURL: baseURL, - } - return a -} - -func createAuthClient(ctx context.Context, cmd *cli.Command) error { - if err := loadProjectConfig(ctx, cmd); err != nil { - return err - } - authClient = *NewAuthClient(&http.Client{}, cloudAPIServerURL) - return nil -} - -func handleAuth(ctx context.Context, cmd *cli.Command) error { - if disconnect { - return authClient.Deauthenticate() - } - return tryAuthIfNeeded(ctx, cmd) -} - -func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { - _, err := loadProjectDetails(cmd) - if err != nil { - return err - } - - // TODO: if we already have a valid session token, return early - - fmt.Println("Requesting verification token...") - token, err := authClient.GetVerificationToken("bar.foo") // FIXME: subdomain? - if err != nil { - return err - } - - authURL, err := url.Parse(cloudDashboardURL + confirmAuthEndpoint) - if err != nil { - return err - } - params := url.Values{} - params.Add("t", token.Token) - authURL.RawQuery = params.Encode() - - fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) - - if err := spinner.New(). - Title("Awaiting confirmation..."). - Action(func() { err = pollClaim(ctx, cmd) }). - Run(); err != nil { - return err - } - - return err -} - -func pollClaim(ctx context.Context, _ *cli.Command) error { - claim := make(chan *CreateTokenResponse) - cancel := make(chan error) - go func() { - for { - time.Sleep(time.Duration(interval) * time.Second) - session, err := authClient.ClaimSession(ctx) - if err != nil { - cancel <- err - return - } - if session != nil { - claim <- session - } - } - }() - - select { - case <-time.After(time.Duration(timeout) * time.Second): - return errors.New("session claim timed out") - case err := <-cancel: - return err - case sessionToken := <-claim: - // TODO: write to config file - fmt.Println(sessionToken) - return nil - } -} diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go new file mode 100644 index 00000000..4e155241 --- /dev/null +++ b/cmd/lk/cloud.go @@ -0,0 +1,319 @@ +// Copyright 2024 LiveKit, Inc. +// +// 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. + +package main + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/charmbracelet/huh" + "github.com/charmbracelet/huh/spinner" + "github.com/urfave/cli/v3" + + "github.com/livekit/livekit-cli/pkg/config" +) + +const ( + cloudAPIServerURL = "https://cloud-api.livekit.io" + cloudDashboardURL = "https://cloud.livekit.io" + createTokenEndpoint = "/cli/auth" + confirmAuthEndpoint = "/cli/confirm-auth" + claimSessionEndpoint = "/cli/claim" +) + +var ( + disconnect bool + timeout int64 + interval int64 + serverURL string + dashboardURL string + authClient AuthClient + AuthCommands = []*cli.Command{ + { + Name: "cloud", + Usage: "Manage hosted services and authentication", + Category: "Core", + Commands: []*cli.Command{ + { + Name: "auth", + Usage: "Authenticate the CLI via the browser to permit advanced actions", + Before: initAuth, + Action: handleAuth, + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "R", + Aliases: []string{"revoke"}, + Destination: &disconnect, + }, + &cli.IntFlag{ + Name: "t", + Aliases: []string{"timeout"}, + Usage: "Number of `SECONDS` to attempt authentication before giving up", + Destination: &timeout, + Value: 60 * 15, + }, + &cli.IntFlag{ + Name: "i", + Aliases: []string{"poll-interval"}, + Usage: "Number of `SECONDS` between poll requests to verify authentication", + Destination: &interval, + Value: 4, + }, + &cli.StringFlag{ + // Use "http://cloud-api.livekit.run" in local dev + Name: "server-url", + Value: cloudAPIServerURL, + Destination: &serverURL, + Hidden: true, + }, + &cli.StringFlag{ + // Use "https://cloud.livekit.run" in local dev + Name: "dashboard-url", + Value: cloudDashboardURL, + Destination: &dashboardURL, + Hidden: true, + }, + }, + }, + }, + }, + } +) + +type VerificationToken struct { + Identifier string + Token string + Expires int64 + DeviceName string +} + +type AuthClient struct { + client *http.Client + baseURL string + verificationToken VerificationToken +} + +func (a *AuthClient) GetVerificationToken(deviceName string) (*VerificationToken, error) { + reqURL, err := url.Parse(a.baseURL + createTokenEndpoint) + if err != nil { + return nil, err + } + + params := url.Values{} + params.Add("device_name", deviceName) + reqURL.RawQuery = params.Encode() + + resp, err := a.client.Post(reqURL.String(), "application/json", nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, errors.New(resp.Status) + } + + err = json.NewDecoder(resp.Body).Decode(&a.verificationToken) + if err != nil { + return nil, err + } + + return &a.verificationToken, nil +} + +func (a *AuthClient) ClaimCliKey(ctx context.Context) (*config.AccessKey, error) { + if a.verificationToken.Token == "" || time.Now().Unix() > a.verificationToken.Expires { + return nil, errors.New("session expired") + } + + reqURL, err := url.Parse(a.baseURL + claimSessionEndpoint) + if err != nil { + return nil, err + } + + params := url.Values{} + params.Add("t", a.verificationToken.Token) + reqURL.RawQuery = params.Encode() + + req, err := http.NewRequestWithContext(ctx, "POST", reqURL.String(), nil) + if err != nil { + return nil, err + } + resp, err := a.client.Do(req) + if resp != nil && resp.StatusCode == 404 { + return nil, errors.New("access denied") + } + if err != nil { + return nil, err + } + + if resp.StatusCode == http.StatusUnauthorized { + // Not yet approved + return nil, nil + } + + ak := &config.AccessKey{} + err = json.NewDecoder(resp.Body).Decode(&ak) + if err != nil { + return nil, err + } + + return ak, nil +} + +func (a *AuthClient) Deauthenticate() error { + // TODO: revoke any session token + return nil +} + +func NewAuthClient(client *http.Client, baseURL string) *AuthClient { + a := &AuthClient{ + client: client, + baseURL: baseURL, + } + return a +} + +func initAuth(ctx context.Context, cmd *cli.Command) error { + if err := loadProjectConfig(ctx, cmd); err != nil { + return err + } + authClient = *NewAuthClient(&http.Client{}, serverURL) + return nil +} + +func handleAuth(ctx context.Context, cmd *cli.Command) error { + if disconnect { + return authClient.Deauthenticate() + } + return tryAuthIfNeeded(ctx, cmd) +} + +func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { + _, err := loadProjectDetails(cmd) + if err != nil { + return err + } + + // name + var deviceName string + if err := huh.NewInput(). + Title("What is the name of this device?"). + Value(&deviceName). + WithTheme(theme). + Run(); err != nil { + return err + } + fmt.Println("Device:", deviceName) + + // request token + fmt.Println("Requesting verification token...") + token, err := authClient.GetVerificationToken(deviceName) + if err != nil { + return err + } + + authURL, err := generateConfirmURL(token.Token) + if err != nil { + return err + } + + // poll for keys + fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) + var key *config.AccessKey + var pollErr error + if err := spinner.New(). + Title("Awaiting confirmation..."). + Action(func() { + key, pollErr = pollClaim(ctx, cmd) + }). + Run(); err != nil { + return err + } + if pollErr != nil { + return pollErr + } + + var isDefault bool + if err := huh.NewConfirm(). + Title("Make this project default?"). + Value(&isDefault). + WithTheme(theme). + Run(); err != nil { + return err + } + + // persist to config file + cliConfig.Projects = append(cliConfig.Projects, config.ProjectConfig{ + Name: key.Description, + APIKey: key.Key, + APISecret: key.Secret, + URL: "ws://" + key.Project.Subdomain + ".livekit:7800", + }) + if isDefault { + cliConfig.DefaultProject = key.Description + } + if err = cliConfig.PersistIfNeeded(); err != nil { + return err + } + + return err +} + +func generateConfirmURL(token string) (*url.URL, error) { + base, err := url.Parse(dashboardURL + confirmAuthEndpoint) + if err != nil { + return nil, err + } + + params := url.Values{} + params.Add("t", token) + base.RawQuery = params.Encode() + return base, nil +} + +func pollClaim(ctx context.Context, _ *cli.Command) (*config.AccessKey, error) { + claim := make(chan *config.AccessKey) + cancel := make(chan error) + + // every seconds, poll + go func() { + for { + time.Sleep(time.Duration(interval) * time.Second) + session, err := authClient.ClaimCliKey(ctx) + if err != nil { + cancel <- err + return + } + if session != nil { + claim <- session + } + } + }() + + select { + case <-time.After(time.Duration(timeout) * time.Second): + return nil, errors.New("session claim timed out") + case err := <-cancel: + return nil, err + case accessKey := <-claim: + return accessKey, nil + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go index eb4b2e9e..d1f37aa3 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -37,6 +37,19 @@ type ProjectConfig struct { APISecret string `yaml:"api_secret"` } +type Project struct { + Subdomain string +} + +type AccessKey struct { + Key string + Secret string + ProjectId string + Project Project + OwnerId string + Description string +} + func LoadDefaultProject() (*ProjectConfig, error) { conf, err := LoadOrCreate() if err != nil { From 8d2d61d2138c24d21a9d985398f482bc5ba3a7ed Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Tue, 6 Aug 2024 22:48:16 -0600 Subject: [PATCH 04/10] chore(deps): update deps --- cmd/lk/cloud.go | 2 +- go.mod | 18 +++++++++--------- go.sum | 41 +++++++++++++++++++++++------------------ 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index 4e155241..cdc7fc75 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -48,7 +48,7 @@ var ( AuthCommands = []*cli.Command{ { Name: "cloud", - Usage: "Manage hosted services and authentication", + Usage: "Interacting with LiveKit Cloud", Category: "Core", Commands: []*cli.Command{ { diff --git a/go.mod b/go.mod index e3394df4..79069d93 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/charmbracelet/lipgloss v0.12.1 github.com/frostbyte73/core v0.0.12 github.com/go-logr/logr v1.4.2 - github.com/livekit/protocol v1.19.2-0.20240710171229-73ece66d30e0 + github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff github.com/livekit/server-sdk-go/v2 v2.2.0 github.com/pion/rtcp v1.2.14 github.com/pion/rtp v1.8.9 @@ -54,7 +54,7 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gammazero/deque v0.2.1 // indirect - github.com/go-jose/go-jose/v4 v4.0.3 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/cel-go v0.20.1 // indirect github.com/google/uuid v1.6.0 // indirect @@ -65,7 +65,7 @@ require ( github.com/lithammer/shortuuid/v4 v4.0.0 // indirect github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 // indirect github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75 // indirect - github.com/livekit/psrpc v0.5.3-0.20240526192918-fbdaf10e6aa5 // indirect + github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magefile/mage v1.15.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -97,7 +97,7 @@ require ( github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/puzpuzpuz/xsync/v3 v3.1.0 // indirect - github.com/redis/go-redis/v9 v9.5.3 // indirect + github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/wlynxg/anet v0.0.3 // indirect @@ -108,11 +108,11 @@ require ( go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect - golang.org/x/net v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect + google.golang.org/grpc v1.65.0 // indirect ) diff --git a/go.sum b/go.sum index c55b089f..2c217193 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gammazero/deque v0.2.1 h1:qSdsbG6pgp6nL7A0+K/B7s12mcCY/5l5SIUpMOl+dC0= github.com/gammazero/deque v0.2.1/go.mod h1:LFroj8x4cMYCukHJDbxFCkT+r9AndaJnFMuZDV34tuU= -github.com/go-jose/go-jose/v4 v4.0.3 h1:o8aphO8Hv6RPmH+GfzVuyf7YXSBibp+8YyHdOoDESGo= -github.com/go-jose/go-jose/v4 v4.0.3/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -78,6 +78,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -105,10 +106,10 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75 h1:p60OjeixzXnhGFQL8wmdUwWPxijEDe9ZJFMosq+byec= github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75/go.mod h1:jwKUCmObuiEDH0iiuJHaGMXwRs3RjrB4G6qqgkr/5oE= -github.com/livekit/protocol v1.19.2-0.20240710171229-73ece66d30e0 h1:UpYjV4MoNLD2SgQef31drYDwHyHcfRirJIGo+S2pLgI= -github.com/livekit/protocol v1.19.2-0.20240710171229-73ece66d30e0/go.mod h1:Ca0jA/Tk9sHIIFRQhwIjOPMOM0Foh0psYmDBjgIQa4g= -github.com/livekit/psrpc v0.5.3-0.20240526192918-fbdaf10e6aa5 h1:mTZyrjk5WEWMsvaYtJ42pG7DuxysKj21DKPINpGSIto= -github.com/livekit/psrpc v0.5.3-0.20240526192918-fbdaf10e6aa5/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0= +github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff h1:MltAQO6Le7Gkyed1VbMSJZc1/HwqKYUrdRDLVn/opQM= +github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff/go.mod h1:oU5XbEaQlywdgXcSQDzrI5CPnwuGn/HuRXuQaDxVryQ= +github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a h1:EQAHmcYEGlc6V517cQ3Iy0+jHgP6+tM/B4l2vGuLpQo= +github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0= github.com/livekit/server-sdk-go/v2 v2.2.0 h1:E0Yp45v6Yjhzt0ixGltuQQuBk7ToJkyxIe0931Y7aU4= github.com/livekit/server-sdk-go/v2 v2.2.0/go.mod h1:nYjTi34qkgUvvS9T83KtkQEHTXPEsKoNZ0MQIskVD48= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -193,8 +194,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4= github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/redis/go-redis/v9 v9.5.3 h1:fOAp1/uJG+ZtcITgZOfYFmTKPE7n4Vclj1wZFgRciUU= -github.com/redis/go-redis/v9 v9.5.3/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -206,6 +207,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -243,10 +245,11 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= -golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -257,8 +260,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -278,6 +281,7 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -287,6 +291,7 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -304,12 +309,12 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda h1:b6F6WIV4xHHD0FA4oIyzU6mHWg2WI2X1RBehwa5QN38= -google.golang.org/genproto/googleapis/api v0.0.0-20240401170217-c3f982113cda/go.mod h1:AHcE/gZH76Bk/ROZhQphlRoWo5xKDEtz3eVEO1LfA8c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4 h1:Di6ANFilr+S60a4S61ZM00vLdw0IrQOSMS2/6mrnOU0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240617180043-68d350f18fd4/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= From 33b2541d409656f9959a0e1427e8b9fb41887c21 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Thu, 8 Aug 2024 00:35:57 -0600 Subject: [PATCH 05/10] chore(auth): auto-open browser window for auth --- cmd/lk/cloud.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index cdc7fc75..097350b8 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -28,6 +28,7 @@ import ( "github.com/urfave/cli/v3" "github.com/livekit/livekit-cli/pkg/config" + "github.com/pkg/browser" ) const ( @@ -237,6 +238,11 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { // poll for keys fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) + + if err := browser.OpenURL(authURL.String()); err != nil { + return err + } + var key *config.AccessKey var pollErr error if err := spinner.New(). @@ -244,9 +250,11 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { Action(func() { key, pollErr = pollClaim(ctx, cmd) }). + Context(ctx). Run(); err != nil { return err } + if pollErr != nil { return pollErr } From 2142e8a847f023bddc3e99d8f930ca0501a2e5e5 Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Thu, 8 Aug 2024 18:11:28 -0600 Subject: [PATCH 06/10] fix(auth): handle cancellation of auth polling --- cmd/lk/cloud.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index 097350b8..6ff21766 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -238,7 +238,6 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { // poll for keys fmt.Printf("Please confirm access by visiting:\n\n %s\n\n", authURL.String()) - if err := browser.OpenURL(authURL.String()); err != nil { return err } @@ -254,10 +253,12 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { Run(); err != nil { return err } - if pollErr != nil { return pollErr } + if key == nil { + return errors.New("operation cancelled") + } var isDefault bool if err := huh.NewConfirm(). From cefed2c7c09677990d36229570ed194a843651ee Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Fri, 9 Aug 2024 19:08:12 -0600 Subject: [PATCH 07/10] feat(auth): add revocation of keys --- cmd/lk/cloud.go | 96 ++++++++++++++++++++++++++++++++------------ cmd/lk/project.go | 22 +--------- pkg/config/config.go | 35 ++++++++++------ 3 files changed, 94 insertions(+), 59 deletions(-) diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index 6ff21766..be822917 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -28,19 +28,30 @@ import ( "github.com/urfave/cli/v3" "github.com/livekit/livekit-cli/pkg/config" + "github.com/livekit/protocol/auth" "github.com/pkg/browser" ) +type ClaimAccessKeyResponse struct { + Key string + Secret string + ProjectId string + OwnerId string + Description string + URL string +} + const ( - cloudAPIServerURL = "https://cloud-api.livekit.io" - cloudDashboardURL = "https://cloud.livekit.io" - createTokenEndpoint = "/cli/auth" - confirmAuthEndpoint = "/cli/confirm-auth" - claimSessionEndpoint = "/cli/claim" + cloudAPIServerURL = "https://cloud-api.livekit.io" + cloudDashboardURL = "https://cloud.livekit.io" + createTokenEndpoint = "/cli/auth" + claimKeyEndpoint = "/cli/claim" + confirmAuthEndpoint = "/cli/confirm-auth" + revokeKeyEndpoint = "/cli/revoke" ) var ( - disconnect bool + revoke bool timeout int64 interval int64 serverURL string @@ -61,7 +72,7 @@ var ( &cli.BoolFlag{ Name: "R", Aliases: []string{"revoke"}, - Destination: &disconnect, + Destination: &revoke, }, &cli.IntFlag{ Name: "t", @@ -139,12 +150,12 @@ func (a *AuthClient) GetVerificationToken(deviceName string) (*VerificationToken return &a.verificationToken, nil } -func (a *AuthClient) ClaimCliKey(ctx context.Context) (*config.AccessKey, error) { +func (a *AuthClient) ClaimCliKey(ctx context.Context) (*ClaimAccessKeyResponse, error) { if a.verificationToken.Token == "" || time.Now().Unix() > a.verificationToken.Expires { return nil, errors.New("session expired") } - reqURL, err := url.Parse(a.baseURL + claimSessionEndpoint) + reqURL, err := url.Parse(a.baseURL + claimKeyEndpoint) if err != nil { return nil, err } @@ -170,7 +181,7 @@ func (a *AuthClient) ClaimCliKey(ctx context.Context) (*config.AccessKey, error) return nil, nil } - ak := &config.AccessKey{} + ak := &ClaimAccessKeyResponse{} err = json.NewDecoder(resp.Body).Decode(&ak) if err != nil { return nil, err @@ -179,9 +190,26 @@ func (a *AuthClient) ClaimCliKey(ctx context.Context) (*config.AccessKey, error) return ak, nil } -func (a *AuthClient) Deauthenticate() error { - // TODO: revoke any session token - return nil +func (a *AuthClient) Deauthenticate(ctx context.Context, projectName, token string) error { + reqURL, err := url.Parse(a.baseURL + revokeKeyEndpoint) + if err != nil { + return err + } + + req, err := http.NewRequestWithContext(ctx, "DELETE", reqURL.String(), nil) + req.Header = newHeaderWithToken(token) + if err != nil { + return err + } + + resp, err := a.client.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return errors.New("access denied") + } + return cliConfig.RemoveProject(projectName) } func NewAuthClient(client *http.Client, baseURL string) *AuthClient { @@ -193,23 +221,41 @@ func NewAuthClient(client *http.Client, baseURL string) *AuthClient { } func initAuth(ctx context.Context, cmd *cli.Command) error { - if err := loadProjectConfig(ctx, cmd); err != nil { - return err - } authClient = *NewAuthClient(&http.Client{}, serverURL) return nil } func handleAuth(ctx context.Context, cmd *cli.Command) error { - if disconnect { - return authClient.Deauthenticate() + if revoke { + if err := loadProjectConfig(ctx, cmd); err != nil { + return err + } + cfg, token, err := requireToken(ctx, cmd) + if err != nil { + return err + } + return authClient.Deauthenticate(ctx, cfg.Name, token) } return tryAuthIfNeeded(ctx, cmd) } -func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { - _, err := loadProjectDetails(cmd) +func requireToken(_ context.Context, cmd *cli.Command) (*config.ProjectConfig, string, error) { + cfg, err := loadProjectDetails(cmd) + if err != nil { + return nil, "", err + } + + at := auth.NewAccessToken(cfg.APIKey, cfg.APISecret) + token, err := at.ToJWT() if err != nil { + return nil, "", err + } + + return cfg, token, nil +} + +func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { + if err := loadProjectConfig(ctx, cmd); err != nil { return err } @@ -242,14 +288,13 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { return err } - var key *config.AccessKey + var key *ClaimAccessKeyResponse var pollErr error if err := spinner.New(). Title("Awaiting confirmation..."). Action(func() { key, pollErr = pollClaim(ctx, cmd) }). - Context(ctx). Run(); err != nil { return err } @@ -274,8 +319,9 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { Name: key.Description, APIKey: key.Key, APISecret: key.Secret, - URL: "ws://" + key.Project.Subdomain + ".livekit:7800", + URL: key.URL, }) + if isDefault { cliConfig.DefaultProject = key.Description } @@ -298,8 +344,8 @@ func generateConfirmURL(token string) (*url.URL, error) { return base, nil } -func pollClaim(ctx context.Context, _ *cli.Command) (*config.AccessKey, error) { - claim := make(chan *config.AccessKey) +func pollClaim(ctx context.Context, _ *cli.Command) (*ClaimAccessKeyResponse, error) { + claim := make(chan *ClaimAccessKeyResponse) cancel := make(chan error) // every seconds, poll diff --git a/cmd/lk/project.go b/cmd/lk/project.go index fcffff4a..19c9cdfc 100644 --- a/cmd/lk/project.go +++ b/cmd/lk/project.go @@ -273,27 +273,7 @@ func removeProject(ctx context.Context, cmd *cli.Command) error { return errors.New("project name is required") } name := cmd.Args().First() - - var newProjects []config.ProjectConfig - for _, p := range cliConfig.Projects { - if p.Name == name { - continue - } - newProjects = append(newProjects, p) - } - cliConfig.Projects = newProjects - - if cliConfig.DefaultProject == name { - cliConfig.DefaultProject = "" - } - - if err := cliConfig.PersistIfNeeded(); err != nil { - return err - } - - fmt.Println("Removed project", name) - - return nil + return cliConfig.RemoveProject(name) } func setDefaultProject(ctx context.Context, cmd *cli.Command) error { diff --git a/pkg/config/config.go b/pkg/config/config.go index d1f37aa3..519a9d6d 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -37,19 +37,6 @@ type ProjectConfig struct { APISecret string `yaml:"api_secret"` } -type Project struct { - Subdomain string -} - -type AccessKey struct { - Key string - Secret string - ProjectId string - Project Project - OwnerId string - Description string -} - func LoadDefaultProject() (*ProjectConfig, error) { conf, err := LoadOrCreate() if err != nil { @@ -114,6 +101,28 @@ func LoadOrCreate() (*CLIConfig, error) { return c, nil } +func (c *CLIConfig) RemoveProject(name string) error { + var newProjects []ProjectConfig + for _, p := range c.Projects { + if p.Name == name { + continue + } + newProjects = append(newProjects, p) + } + c.Projects = newProjects + + if c.DefaultProject == name { + c.DefaultProject = "" + } + + if err := c.PersistIfNeeded(); err != nil { + return err + } + + fmt.Println("Removed project", name) + return nil +} + func (c *CLIConfig) PersistIfNeeded() error { if len(c.Projects) == 0 && !c.hasPersisted { // doesn't need to be persisted From 95b41fe373793cd4336579723426d740c73b01cd Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Fri, 9 Aug 2024 23:46:12 -0600 Subject: [PATCH 08/10] chore(deps): updates --- go.mod | 58 ++++++++++++++++++++++++++++--------------------------- go.sum | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 79069d93..99f47d79 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,11 @@ toolchain go1.22.2 require ( github.com/charmbracelet/huh v0.5.2 - github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6 + github.com/charmbracelet/huh/spinner v0.0.0-20240809225911-cadaa638c7fa github.com/charmbracelet/lipgloss v0.12.1 github.com/frostbyte73/core v0.0.12 github.com/go-logr/logr v1.4.2 - github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff + github.com/livekit/protocol v1.19.3 github.com/livekit/server-sdk-go/v2 v2.2.0 github.com/pion/rtcp v1.2.14 github.com/pion/rtp v1.8.9 @@ -21,28 +21,28 @@ require ( github.com/twitchtv/twirp v8.1.3+incompatible github.com/urfave/cli/v3 v3.0.0-alpha9 go.uber.org/atomic v1.11.0 - golang.org/x/sync v0.7.0 - golang.org/x/time v0.5.0 + golang.org/x/sync v0.8.0 + golang.org/x/time v0.6.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 ) require ( - buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1 // indirect - github.com/antlr4-go/antlr/v4 v4.13.0 // indirect + buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240717164558-a6c49f84cc0f.2 // indirect + github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bep/debounce v1.2.1 // indirect - github.com/bufbuild/protovalidate-go v0.6.1 // indirect - github.com/bufbuild/protoyaml-go v0.1.9 // indirect + github.com/bufbuild/protovalidate-go v0.6.3 // indirect + github.com/bufbuild/protoyaml-go v0.1.10 // indirect github.com/catppuccin/go v0.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/bubbles v0.18.0 // indirect github.com/charmbracelet/bubbletea v0.26.6 // indirect github.com/charmbracelet/x/ansi v0.1.4 // indirect - github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 // indirect + github.com/charmbracelet/x/exp/strings v0.0.0-20240809174237-9ab0ca04ce0c // indirect github.com/charmbracelet/x/input v0.1.3 // indirect github.com/charmbracelet/x/term v0.1.1 // indirect github.com/charmbracelet/x/windows v0.1.2 // indirect @@ -56,15 +56,15 @@ require ( github.com/gammazero/deque v0.2.1 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/cel-go v0.20.1 // indirect + github.com/google/cel-go v0.21.0 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.2 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/jxskiss/base62 v1.1.0 // indirect github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/lithammer/shortuuid/v4 v4.0.0 // indirect github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 // indirect - github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75 // indirect + github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598 // indirect github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magefile/mage v1.15.0 // indirect @@ -75,44 +75,46 @@ require ( github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.15.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nats-io/nats.go v1.36.0 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.34 // indirect - github.com/pion/interceptor v0.1.29 // indirect + github.com/pion/interceptor v0.1.30 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/sctp v1.8.19 // indirect + github.com/pion/sctp v1.8.20 // indirect github.com/pion/sdp/v3 v3.0.9 // indirect github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect github.com/pion/transport/v2 v2.2.10 // indirect github.com/pion/turn/v2 v2.1.6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.19.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect - github.com/puzpuzpuz/xsync/v3 v3.1.0 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/puzpuzpuz/xsync/v3 v3.4.0 // indirect github.com/redis/go-redis/v9 v9.6.1 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/wlynxg/anet v0.0.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/zeebo/xxh3 v1.0.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go.uber.org/zap/exp v0.2.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect + golang.org/x/mod v0.20.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sys v0.24.0 // indirect + golang.org/x/text v0.17.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240808171019-573a1156607a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a // indirect google.golang.org/grpc v1.65.0 // indirect ) diff --git a/go.sum b/go.sum index 2c217193..23fe9ba3 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,11 @@ buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1 h1:2IGhRovxlsOIQgx2ekZWo4wTPAYpck41+18ICxs37is= buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.33.0-20240401165935-b983156c5e99.1/go.mod h1:Tgn5bgL220vkFOI0KPStlcClPeOJzAv4uT+V8JXGUnw= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240717164558-a6c49f84cc0f.2 h1:SZRVx928rbYZ6hEKUIN+vtGDkl7uotABRWGY4OAg5gM= +buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.34.2-20240717164558-a6c49f84cc0f.2/go.mod h1:ylS4c28ACSI59oJrOdW4pHS4n0Hw4TgSPHn8rpHl4Yw= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= +github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= +github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -18,8 +22,12 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bufbuild/protovalidate-go v0.6.1 h1:uzW8r0CDvqApUChNj87VzZVoQSKhcVdw5UWOE605UIw= github.com/bufbuild/protovalidate-go v0.6.1/go.mod h1:4BR3rKEJiUiTy+sqsusFn2ladOf0kYmA2Reo6BHSBgQ= +github.com/bufbuild/protovalidate-go v0.6.3 h1:wxQyzW035zM16Binbaz/nWAzS12dRIXhZdSUWRY7Fv0= +github.com/bufbuild/protovalidate-go v0.6.3/go.mod h1:J4PtwP9Z2YAGgB0+o+tTWEDtLtXvz/gfhFZD8pbzM/U= github.com/bufbuild/protoyaml-go v0.1.9 h1:anV5UtF1Mlvkkgp4NWA6U/zOnJFng8Orq4Vf3ZUQHBU= github.com/bufbuild/protoyaml-go v0.1.9/go.mod h1:KCBItkvZOK/zwGueLdH1Wx1RLyFn5rCH7YjQrdty2Wc= +github.com/bufbuild/protoyaml-go v0.1.10 h1:gMwDSHNoInt0D6vvTUxAJSWvp87MJraTN7dxsR7C2z4= +github.com/bufbuild/protoyaml-go v0.1.10/go.mod h1:KCBItkvZOK/zwGueLdH1Wx1RLyFn5rCH7YjQrdty2Wc= github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA= github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -32,12 +40,16 @@ github.com/charmbracelet/huh v0.5.2 h1:ofeNkJ4iaFnzv46Njhx896DzLUe/j0L2QAf8znwzX github.com/charmbracelet/huh v0.5.2/go.mod h1:Sf7dY0oAn6N/e3sXJFtFX9hdQLrUdO3z7AYollG9bAM= github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6 h1:Wey8Un1qEEHI18y0HOs3K2HBBb9aEssoDmQo1+Idpuo= github.com/charmbracelet/huh/spinner v0.0.0-20240714135825-43e9eb5aeab6/go.mod h1:CrXBZnOWs3zpyppOZZS7lu2CpLq2jx6U5chL/frRG/E= +github.com/charmbracelet/huh/spinner v0.0.0-20240809225911-cadaa638c7fa h1:R+xMd+iJiGojXspxELx3oxtA+aKaXAo2Azq+71JMFIQ= +github.com/charmbracelet/huh/spinner v0.0.0-20240809225911-cadaa638c7fa/go.mod h1:9VssyY5pUozMRmDYlLYV20QMMcA2sHg3qnaB6PvdIm8= github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4= github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= +github.com/charmbracelet/x/exp/strings v0.0.0-20240809174237-9ab0ca04ce0c h1:6IUwt5Pfsv8ugjei3FKMzKIEJMZJt5QN8nU2VN/IOPw= +github.com/charmbracelet/x/exp/strings v0.0.0-20240809174237-9ab0ca04ce0c/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ= github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a h1:k/s6UoOSVynWiw7PlclyGO2VdVs5ZLbMIHiGp4shFZE= github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a/go.mod h1:YBotIGhfoWhHDlnUpJMkjebGV2pdGRCn1Y4/Nk/vVcU= github.com/charmbracelet/x/input v0.1.3 h1:oy4TMhyGQsYs/WWJwu1ELUMFnjiUAXwtDf048fHbCkg= @@ -77,6 +89,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/cel-go v0.20.1 h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84= github.com/google/cel-go v0.20.1/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= +github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= +github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -87,12 +101,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw= github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw= github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= 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/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -106,8 +124,12 @@ github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1 h1:jm09419p0lqTkD github.com/livekit/mageutil v0.0.0-20230125210925-54e8a70427c1/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75 h1:p60OjeixzXnhGFQL8wmdUwWPxijEDe9ZJFMosq+byec= github.com/livekit/mediatransportutil v0.0.0-20240613015318-84b69facfb75/go.mod h1:jwKUCmObuiEDH0iiuJHaGMXwRs3RjrB4G6qqgkr/5oE= +github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598 h1:yLlkHk2feSLHstD9n4VKg7YEBR4rLODTI4WE8gNBEnQ= +github.com/livekit/mediatransportutil v0.0.0-20240730083616-559fa5ece598/go.mod h1:jwKUCmObuiEDH0iiuJHaGMXwRs3RjrB4G6qqgkr/5oE= github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff h1:MltAQO6Le7Gkyed1VbMSJZc1/HwqKYUrdRDLVn/opQM= github.com/livekit/protocol v1.19.2-0.20240730185318-ffccf573cdff/go.mod h1:oU5XbEaQlywdgXcSQDzrI5CPnwuGn/HuRXuQaDxVryQ= +github.com/livekit/protocol v1.19.3 h1:VOoQV21xm4nWVnGPdvCKUZAy08Q+njD167Pzo24uzBI= +github.com/livekit/protocol v1.19.3/go.mod h1:oU5XbEaQlywdgXcSQDzrI5CPnwuGn/HuRXuQaDxVryQ= github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a h1:EQAHmcYEGlc6V517cQ3Iy0+jHgP6+tM/B4l2vGuLpQo= github.com/livekit/psrpc v0.5.3-0.20240616012458-ac39c8549a0a/go.mod h1:CQUBSPfYYAaevg1TNCc6/aYsa8DJH4jSRFdCeSZk5u0= github.com/livekit/server-sdk-go/v2 v2.2.0 h1:E0Yp45v6Yjhzt0ixGltuQQuBk7ToJkyxIe0931Y7aU4= @@ -130,6 +152,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nats-io/nats.go v1.36.0 h1:suEUPuWzTSse/XhESwqLxXGuj8vGRuPRoG7MoRN/qyU= github.com/nats-io/nats.go v1.36.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8= github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI= @@ -145,6 +169,8 @@ github.com/pion/ice/v2 v2.3.34 h1:Ic1ppYCj4tUOcPAp76U6F3fVrlSw8A9JtRXLqw6BbUM= github.com/pion/ice/v2 v2.3.34/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= github.com/pion/interceptor v0.1.29 h1:39fsnlP1U8gw2JzOFWdfCU82vHvhW9o0rZnZF56wF+M= github.com/pion/interceptor v0.1.29/go.mod h1:ri+LGNjRUc5xUNtDEPzfdkmSqISixVTBF/z/Zms/6T4= +github.com/pion/interceptor v0.1.30 h1:au5rlVHsgmxNi+v/mjOPazbW1SHzfx7/hYOEYQnUcxA= +github.com/pion/interceptor v0.1.30/go.mod h1:RQuKT5HTdkP2Fi0cuOS5G5WNymTjzXaGF75J4k7z2nc= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= @@ -159,6 +185,8 @@ github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= github.com/pion/sctp v1.8.19 h1:2CYuw+SQ5vkQ9t0HdOPccsCz1GQMDuVy5PglLgKVBW8= github.com/pion/sctp v1.8.19/go.mod h1:P6PbDVA++OJMrVNg2AL3XtYHV4uD6dvfyOovCgMs0PE= +github.com/pion/sctp v1.8.20 h1:sOc3lkV/tQaP57ZUEXIMdM2V92IIB2ia5v/ygnBxaEg= +github.com/pion/sctp v1.8.20/go.mod h1:oTxw8i5m+WbDHZJL/xUpe6CPIn1Y0GIKKwTLF4h53H8= github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= @@ -186,14 +214,24 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4= github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/puzpuzpuz/xsync/v3 v3.4.0 h1:DuVBAdXuGFHv8adVXjWWZ63pJq+NRXOWVXlKDBZ+mJ4= +github.com/puzpuzpuz/xsync/v3 v3.4.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -225,6 +263,8 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw= github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= @@ -248,10 +288,17 @@ golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1m golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -262,11 +309,15 @@ golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -284,6 +335,8 @@ golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -301,8 +354,12 @@ golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -311,8 +368,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/api v0.0.0-20240808171019-573a1156607a h1:KyUe15n7B1YCu+kMmPtlXxgkLQbp+Dw0tCRZf9Sd+CE= +google.golang.org/genproto/googleapis/api v0.0.0-20240808171019-573a1156607a/go.mod h1:4+X6GvPs+25wZKbQq9qyAXrwIRExv7w0Ea6MgZLZiDM= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf h1:liao9UHurZLtiEwBgT9LMOnKYsHze6eA6w1KQCMVN2Q= google.golang.org/genproto/googleapis/rpc v0.0.0-20240730163845-b1a4ccb954bf/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a h1:EKiZZXueP9/T68B8Nl0GAx9cjbQnCId0yP3qPMgaaHs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240808171019-573a1156607a/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= From a70fae7f4032294c9978c1524d06666f6894d5ee Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Fri, 9 Aug 2024 23:58:31 -0600 Subject: [PATCH 09/10] chore(cloud): hide cloud commands until dogfooded --- cmd/lk/cloud.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index be822917..0a98773f 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -59,6 +59,7 @@ var ( authClient AuthClient AuthCommands = []*cli.Command{ { + Hidden: true, Name: "cloud", Usage: "Interacting with LiveKit Cloud", Category: "Core", From 2359da4e897609f5bd99b2e731d2ea7151f0d76b Mon Sep 17 00:00:00 2001 From: rektdeckard Date: Sat, 10 Aug 2024 00:49:24 -0600 Subject: [PATCH 10/10] chore(ci): update go and staticcheck versions --- .github/workflows/build.yaml | 4 ++-- .github/workflows/release.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fc6571f3..1a4adf0f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -36,7 +36,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - name: Download Go modules run: go mod download @@ -44,5 +44,5 @@ jobs: - name: Static Check uses: dominikh/staticcheck-action@v1.3.1 with: - version: "2023.1.3" + version: "2023.1.7" install-go: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index a0965ebc..53cf6271 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -50,7 +50,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.21" + go-version: "1.22" - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6