mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: added option for manually adding token in browser login failure
This commit is contained in:
@@ -5,6 +5,7 @@ go 1.21
|
|||||||
require (
|
require (
|
||||||
github.com/bradleyjkemp/cupaloy/v2 v2.8.0
|
github.com/bradleyjkemp/cupaloy/v2 v2.8.0
|
||||||
github.com/charmbracelet/lipgloss v0.5.0
|
github.com/charmbracelet/lipgloss v0.5.0
|
||||||
|
github.com/chzyer/readline v1.5.1
|
||||||
github.com/creack/pty v1.1.21
|
github.com/creack/pty v1.1.21
|
||||||
github.com/denisbrodbeck/machineid v1.0.1
|
github.com/denisbrodbeck/machineid v1.0.1
|
||||||
github.com/fatih/semgroup v1.2.0
|
github.com/fatih/semgroup v1.2.0
|
||||||
@@ -49,7 +50,6 @@ require (
|
|||||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 // indirect
|
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.5 // indirect
|
||||||
github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 // indirect
|
github.com/aws/aws-sdk-go-v2/service/sts v1.28.12 // indirect
|
||||||
github.com/aws/smithy-go v1.20.2 // indirect
|
github.com/aws/smithy-go v1.20.2 // indirect
|
||||||
github.com/chzyer/readline v1.5.1 // indirect
|
|
||||||
github.com/danieljoos/wincred v1.2.0 // indirect
|
github.com/danieljoos/wincred v1.2.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
|
github.com/dvsekhvalnov/jose2go v1.6.0 // indirect
|
||||||
@@ -94,7 +94,7 @@ require (
|
|||||||
golang.org/x/net v0.25.0 // indirect
|
golang.org/x/net v0.25.0 // indirect
|
||||||
golang.org/x/oauth2 v0.21.0 // indirect
|
golang.org/x/oauth2 v0.21.0 // indirect
|
||||||
golang.org/x/sync v0.7.0 // indirect
|
golang.org/x/sync v0.7.0 // indirect
|
||||||
golang.org/x/sys v0.20.0 // indirect
|
golang.org/x/sys v0.22.0 // indirect
|
||||||
golang.org/x/text v0.15.0 // indirect
|
golang.org/x/text v0.15.0 // indirect
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
google.golang.org/api v0.183.0 // indirect
|
google.golang.org/api v0.183.0 // indirect
|
||||||
|
|||||||
@@ -621,8 +621,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.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.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.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=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/Infisical/infisical-merge/packages/models"
|
"github.com/Infisical/infisical-merge/packages/models"
|
||||||
"github.com/Infisical/infisical-merge/packages/srp"
|
"github.com/Infisical/infisical-merge/packages/srp"
|
||||||
"github.com/Infisical/infisical-merge/packages/util"
|
"github.com/Infisical/infisical-merge/packages/util"
|
||||||
|
"github.com/chzyer/readline"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
"github.com/manifoldco/promptui"
|
"github.com/manifoldco/promptui"
|
||||||
@@ -229,6 +230,7 @@ var loginCmd = &cobra.Command{
|
|||||||
fmt.Println("Logging in via browser... To login via interactive mode run [infisical login -i]")
|
fmt.Println("Logging in via browser... To login via interactive mode run [infisical login -i]")
|
||||||
userCredentialsToBeStored, err = browserCliLogin()
|
userCredentialsToBeStored, err = browserCliLogin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
fmt.Printf("Logging in via browser failed. %s", err.Error())
|
||||||
//default to cli login on error
|
//default to cli login on error
|
||||||
cliDefaultLogin(&userCredentialsToBeStored)
|
cliDefaultLogin(&userCredentialsToBeStored)
|
||||||
}
|
}
|
||||||
@@ -713,10 +715,63 @@ func askForMFACode() string {
|
|||||||
return mfaVerifyCode
|
return mfaVerifyCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func askToPasteJwtToken(stdin *readline.CancelableStdin, success chan models.UserCredentials, failure chan error) {
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
|
||||||
|
prompt := &promptui.Prompt{
|
||||||
|
Label: "Did you see a prompt in your browser asking you to paste a token?",
|
||||||
|
IsConfirm: true,
|
||||||
|
Stdin: stdin,
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, promptui.ErrAbort) {
|
||||||
|
stdin.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
failure <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt = &promptui.Prompt{
|
||||||
|
Label: "Paste your token",
|
||||||
|
Mask: '*',
|
||||||
|
Stdin: stdin,
|
||||||
|
}
|
||||||
|
infisicalPastedToken, err := prompt.Run()
|
||||||
|
if err != nil {
|
||||||
|
failure <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userCredentials, err := decodePastedBase64Token(infisicalPastedToken)
|
||||||
|
if err != nil {
|
||||||
|
failure <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
success <- *userCredentials
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodePastedBase64Token(token string) (*models.UserCredentials, error) {
|
||||||
|
data, err := base64.StdEncoding.DecodeString(token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var loginResponse models.UserCredentials
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &loginResponse)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &loginResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Manages the browser login flow.
|
// Manages the browser login flow.
|
||||||
// Returns a UserCredentials object on success and an error on failure
|
// Returns a UserCredentials object on success and an error on failure
|
||||||
func browserCliLogin() (models.UserCredentials, error) {
|
func browserCliLogin() (models.UserCredentials, error) {
|
||||||
SERVER_TIMEOUT := 60 * 10
|
SERVER_TIMEOUT := 10 * 60
|
||||||
|
|
||||||
//create listener
|
//create listener
|
||||||
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||||||
@@ -738,7 +793,6 @@ func browserCliLogin() (models.UserCredentials, error) {
|
|||||||
success := make(chan models.UserCredentials)
|
success := make(chan models.UserCredentials)
|
||||||
failure := make(chan error)
|
failure := make(chan error)
|
||||||
timeout := time.After(time.Second * time.Duration(SERVER_TIMEOUT))
|
timeout := time.After(time.Second * time.Duration(SERVER_TIMEOUT))
|
||||||
quit := make(chan bool)
|
|
||||||
|
|
||||||
//terminal state
|
//terminal state
|
||||||
oldState, err := term.GetState(int(os.Stdin.Fd()))
|
oldState, err := term.GetState(int(os.Stdin.Fd()))
|
||||||
@@ -760,24 +814,27 @@ func browserCliLogin() (models.UserCredentials, error) {
|
|||||||
|
|
||||||
log.Debug().Msgf("Callback server listening on port %d", callbackPort)
|
log.Debug().Msgf("Callback server listening on port %d", callbackPort)
|
||||||
|
|
||||||
|
stdin := readline.NewCancelableStdin(os.Stdin)
|
||||||
go http.Serve(listener, corsHandler)
|
go http.Serve(listener, corsHandler)
|
||||||
|
go askToPasteJwtToken(stdin, success, failure)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case loginResponse := <-success:
|
case loginResponse := <-success:
|
||||||
_ = closeListener(&listener)
|
_ = closeListener(&listener)
|
||||||
|
_ = stdin.Close()
|
||||||
|
fmt.Println("Browser login successfull")
|
||||||
return loginResponse, nil
|
return loginResponse, nil
|
||||||
|
|
||||||
case <-failure:
|
case err := <-failure:
|
||||||
err = closeListener(&listener)
|
serverErr := closeListener(&listener)
|
||||||
return models.UserCredentials{}, err
|
stdErr := stdin.Close()
|
||||||
|
return models.UserCredentials{}, errors.Join(err, serverErr, stdErr)
|
||||||
|
|
||||||
case <-timeout:
|
case <-timeout:
|
||||||
_ = closeListener(&listener)
|
_ = closeListener(&listener)
|
||||||
|
_ = stdin.Close()
|
||||||
return models.UserCredentials{}, errors.New("server timeout")
|
return models.UserCredentials{}, errors.New("server timeout")
|
||||||
|
|
||||||
case <-quit:
|
|
||||||
return models.UserCredentials{}, errors.New("quitting browser login, defaulting to cli...")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user