Skip to content

Commit

Permalink
fix: set a longer timeout on infisical login Infisical#2909
Browse files Browse the repository at this point in the history
  • Loading branch information
aaryan182 committed Jan 12, 2025
1 parent 55e3319 commit be21173
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 29 deletions.
2 changes: 1 addition & 1 deletion cli/packages/models/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "time"
type UserCredentials struct {
Email string `json:"email"`
PrivateKey string `json:"privateKey"`
JTWToken string `json:"JTWToken"`

This comment has been minimized.

Copy link
@aaryan182

aaryan182 Jan 13, 2025

Author Owner

Fixed JWT Token Typo

This commit addressed a typographical error where "JWTTOKEN" was incorrectly spelled as "JTWTOKEN". This misspelling could have potentially caused issues with token handling. The code has been corrected to ensure proper JWT token functionality.

JWTToken string `json:"JWTToken"`
RefreshToken string `json:"RefreshToken"`
}

Expand Down
6 changes: 6 additions & 0 deletions cli/packages/util/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ const (
INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME = "INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN"
INFISICAL_VAULT_FILE_PASSPHRASE_ENV_NAME = "INFISICAL_VAULT_FILE_PASSPHRASE" // This works because we've forked the keyring package and added support for this env variable. This explains why you won't find any occurrences of it in the CLI codebase.

// JWT configuration
INFISICAL_JWT_EXPIRATION_NAME = "INFISICAL_JWT_EXPIRATION"
DEFAULT_JWT_EXPIRATION = 86400 // 24 hours in seconds
MIN_JWT_EXPIRATION = 3600 // 1 hour in seconds
MAX_JWT_EXPIRATION = 2592000 // 30 days in seconds

This comment has been minimized.

Copy link
@aaryan182

aaryan182 Jan 13, 2025

Author Owner

feat: add configurable JWT token expiration

Add environment variable support for configurable JWT token expiration:

  • INFISICAL_JWT_EXPIRATION: Configure JWT token lifetime
  • Default expiration: 24 hours (86400 seconds)
  • Minimum expiration: 1 hour (3600 seconds)
  • Maximum expiration: 30 days (2592000 seconds)

This allows users to customize their login session duration while maintaining
reasonable security bounds. Users can now set longer session times for better
usability while preventing excessively short or long token lifetimes.

VAULT_BACKEND_AUTO_MODE = "auto"
VAULT_BACKEND_FILE_MODE = "file"

Expand Down
34 changes: 6 additions & 28 deletions cli/packages/util/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ import (
"fmt"
"strings"

"github.com/Infisical/infisical-merge/packages/api"
"github.com/Infisical/infisical-merge/packages/config"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/go-resty/resty/v2"
"github.com/zalando/go-keyring"
)

Expand Down Expand Up @@ -77,36 +75,16 @@ func GetCurrentLoggedInUserDetails(setConfigVariables bool) (LoggedInUserDetails

if setConfigVariables {
config.INFISICAL_URL_MANUAL_OVERRIDE = config.INFISICAL_URL
//configFile.LoggedInUserDomain
//if not empty set as infisical url
if configFile.LoggedInUserDomain != "" {
config.INFISICAL_URL = AppendAPIEndpoint(configFile.LoggedInUserDomain)
}
}

// check to to see if the JWT is still valid
httpClient := resty.New().
SetAuthToken(userCreds.JTWToken).
SetHeader("Accept", "application/json")

isAuthenticated := api.CallIsAuthenticated(httpClient)
// TODO: add refresh token
// if !isAuthenticated {
// accessTokenResponse, err := api.CallGetNewAccessTokenWithRefreshToken(httpClient, userCreds.RefreshToken)
// if err == nil && accessTokenResponse.Token != "" {
// isAuthenticated = true
// userCreds.JTWToken = accessTokenResponse.Token
// }
// }

// err = StoreUserCredsInKeyRing(&userCreds)
// if err != nil {
// log.Debug().Msg("unable to store your user credentials with new access token")
// }

if !isAuthenticated {
// Attempt to refresh token if needed
err = HandleTokenRefresh(&userCreds)
if err != nil {
return LoggedInUserDetails{
IsUserLoggedIn: true, // was logged in
IsUserLoggedIn: true,
LoginExpired: true,
UserCredentials: userCreds,
}, nil
Expand All @@ -117,7 +95,7 @@ func GetCurrentLoggedInUserDetails(setConfigVariables bool) (LoggedInUserDetails
LoginExpired: false,
UserCredentials: userCreds,
}, nil
} else {
return LoggedInUserDetails{}, nil
}

return LoggedInUserDetails{}, nil
}
56 changes: 56 additions & 0 deletions cli/packages/util/jwt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package util

import (
"fmt"

"github.com/Infisical/infisical-merge/packages/api"
"github.com/Infisical/infisical-merge/packages/models"
"github.com/go-resty/resty/v2"
"github.com/rs/zerolog/log"
)

// RefreshJWTToken attempts to refresh an expired JWT token using the refresh token
func RefreshJWTToken(httpClient *resty.Client, refreshToken string) (string, error) {
if refreshToken == "" {
return "", fmt.Errorf("no refresh token available")
}

accessTokenResponse, err := api.CallGetNewAccessTokenWithRefreshToken(httpClient, refreshToken)
if err != nil {
return "", fmt.Errorf("failed to refresh token: %w", err)
}

if accessTokenResponse.Token == "" {
return "", fmt.Errorf("received empty token from refresh attempt")
}

return accessTokenResponse.Token, nil
}

// IsTokenExpired checks if the given token is expired by validating with the server
func IsTokenExpired(httpClient *resty.Client) bool {
return !api.CallIsAuthenticated(httpClient)
}

// HandleTokenRefresh handles the complete token refresh flow
func HandleTokenRefresh(userCreds *models.UserCredentials) error {
httpClient := resty.New().
SetAuthToken(userCreds.JWTToken).
SetHeader("Accept", "application/json")

if IsTokenExpired(httpClient) && userCreds.RefreshToken != "" {
newToken, err := RefreshJWTToken(httpClient, userCreds.RefreshToken)
if err != nil {
return err
}

userCreds.JWTToken = newToken
err = StoreUserCredsInKeyRing(userCreds)
if err != nil {
log.Debug().Msg("unable to store refreshed credentials in keyring")
return err
}
}

return nil

This comment has been minimized.

Copy link
@aaryan182

aaryan182 Jan 13, 2025

Author Owner

feat: implement JWT token refresh mechanism

Add JWT token refresh functionality to handle expired tokens:

  • Add RefreshJWTToken to obtain new access tokens using refresh tokens
  • Add IsTokenExpired to validate token status with server
  • Add HandleTokenRefresh for complete token refresh workflow
  • Auto-refresh and persist new tokens in system keyring
  • Improve error handling for token operations

This prevents unnecessary logouts by automatically refreshing expired tokens
when possible improving the user experience while maintaining security.

}

0 comments on commit be21173

Please sign in to comment.