diff --git a/cmd/lk/cloud.go b/cmd/lk/cloud.go index 0571e9e6..c14024a8 100644 --- a/cmd/lk/cloud.go +++ b/cmd/lk/cloud.go @@ -36,6 +36,7 @@ type ClaimAccessKeyResponse struct { Key string Secret string ProjectId string + ProjectName string OwnerId string Description string URL string @@ -59,14 +60,13 @@ var ( authClient AuthClient AuthCommands = []*cli.Command{ { - Hidden: true, Name: "cloud", Usage: "Interacting with LiveKit Cloud", Category: "Core", Commands: []*cli.Command{ { Name: "auth", - Usage: "Authenticate the CLI via the browser to permit advanced actions", + Usage: "Authenticate LiveKit Cloud account to link your projects", Before: initAuth, Action: handleAuth, Flags: []cli.Flag{ @@ -296,12 +296,12 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { return err } - var key *ClaimAccessKeyResponse + var ak *ClaimAccessKeyResponse var pollErr error if err := spinner.New(). Title("Awaiting confirmation..."). Action(func() { - key, pollErr = pollClaim(ctx, cmd) + ak, pollErr = pollClaim(ctx, cmd) }). Run(); err != nil { return err @@ -309,7 +309,7 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { if pollErr != nil { return pollErr } - if key == nil { + if ak == nil { return errors.New("operation cancelled") } @@ -322,16 +322,34 @@ func tryAuthIfNeeded(ctx context.Context, cmd *cli.Command) error { return err } + // make sure name is unique + var name = ak.ProjectName + if cliConfig.ProjectExists(name) { + if err := huh.NewInput(). + Title("Project name already exists, please choose a different name"). + Value(&name). + Validate(func(s string) error { + if cliConfig.ProjectExists(s) { + return errors.New("project name already exists") + } + return nil + }). + 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: key.URL, + Name: name, + APIKey: ak.Key, + APISecret: ak.Secret, + URL: ak.URL, }) if isDefault { - cliConfig.DefaultProject = key.Description + cliConfig.DefaultProject = ak.Description } if err = cliConfig.PersistIfNeeded(); err != nil { return err @@ -360,13 +378,13 @@ func pollClaim(ctx context.Context, _ *cli.Command) (*ClaimAccessKeyResponse, er go func() { for { time.Sleep(time.Duration(interval) * time.Second) - session, err := authClient.ClaimCliKey(ctx) + ak, err := authClient.ClaimCliKey(ctx) if err != nil { cancel <- err return } - if session != nil { - claim <- session + if ak != nil { + claim <- ak } } }() diff --git a/pkg/config/config.go b/pkg/config/config.go index 74b11494..f098af33 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -19,6 +19,7 @@ import ( "fmt" "os" "path" + "strings" "gopkg.in/yaml.v3" ) @@ -103,6 +104,15 @@ func LoadOrCreate() (*CLIConfig, error) { return c, nil } +func (c *CLIConfig) ProjectExists(name string) bool { + for _, p := range c.Projects { + if strings.EqualFold(p.Name, name) { + return true + } + } + return false +} + func (c *CLIConfig) RemoveProject(name string) error { var newProjects []ProjectConfig for _, p := range c.Projects {