From 68a994fd798f189e6f72ba30e4f8efc5e88cc4a1 Mon Sep 17 00:00:00 2001 From: Mike Landau Date: Fri, 11 Oct 2024 15:46:11 -0700 Subject: [PATCH] [auth] Fix failed session refresh --- internal/boxcli/auth.go | 9 ++++++++- .../devbox/providers/identity/identity.go | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/internal/boxcli/auth.go b/internal/boxcli/auth.go index df99e772498..49414907d02 100644 --- a/internal/boxcli/auth.go +++ b/internal/boxcli/auth.go @@ -96,8 +96,15 @@ func whoAmICmd() *cobra.Command { if err != nil { return err } - return box.UninitializedSecrets(cmd.Context()). + // TODO: WhoAmI should be a function in opensource/pkg/auth that takes in a session. + // That way we don't need to handle failed refresh token errors here. + err = box.UninitializedSecrets(cmd.Context()). WhoAmI(cmd.Context(), cmd.OutOrStdout(), flags.showTokens) + if identity.IsRefreshTokenError(err) { + ux.Fwarningf(cmd.ErrOrStderr(), "Your session is expired. Please login again.\n") + return loginCmd().RunE(cmd, args) + } + return err }, } diff --git a/internal/devbox/providers/identity/identity.go b/internal/devbox/providers/identity/identity.go index f1d3bd7bf02..a811ce33a07 100644 --- a/internal/devbox/providers/identity/identity.go +++ b/internal/devbox/providers/identity/identity.go @@ -5,11 +5,13 @@ import ( "errors" "os" "path" + "strings" "github.com/go-jose/go-jose/v4" "github.com/go-jose/go-jose/v4/jwt" "go.jetify.com/typeid" "go.jetpack.io/devbox/internal/build" + "go.jetpack.io/devbox/internal/ux" "go.jetpack.io/pkg/api" "go.jetpack.io/pkg/auth" "go.jetpack.io/pkg/auth/session" @@ -40,7 +42,12 @@ func GenSession(ctx context.Context) (*session.Token, error) { if err != nil { return nil, err } - return c.GetSession(ctx) + tok, err := c.GetSession(ctx) + if IsRefreshTokenError(err) { + ux.Fwarningf(os.Stderr, "Your session is expired. Please login again.\n") + return c.LoginFlow() + } + return tok, err } func Peek() (*session.Token, error) { @@ -129,3 +136,13 @@ func GetOrgSlug(ctx context.Context) (string, error) { return claims["org_trusted_metadata"].(map[string]any)["slug"].(string), nil } + +// invalid_grant or invalid_request usually means the refresh token is expired, revoked, or +// malformed. this belongs in opensource/pkg/auth +func IsRefreshTokenError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "invalid_grant") || + strings.Contains(err.Error(), "invalid_request") +}