diff --git a/server/crypto/common.go b/server/crypto/common.go index 91aed06..9671398 100644 --- a/server/crypto/common.go +++ b/server/crypto/common.go @@ -1,7 +1,9 @@ package crypto import ( + "crypto/sha256" "crypto/x509" + "encoding/hex" "encoding/json" "github.com/authorizerdev/authorizer/server/constants" @@ -125,11 +127,33 @@ func EncryptEnvData(data map[string]interface{}) (string, error) { return EncryptB64(string(encryptedConfig)), nil } +// getSHA256 calculates the SHA-256 hash of a string +func getSHA256(input string) string { + hash := sha256.New() + hash.Write([]byte(input)) + return hex.EncodeToString(hash.Sum(nil)) +} + +// VerifyPassword compares a stored hashed password with a user-provided password +func VerifyPassword(storedHashedPassword, userProvidedPassword string) error { + // CompareHashAndPassword returns nil on success + err := bcrypt.CompareHashAndPassword([]byte(storedHashedPassword), []byte(userProvidedPassword)) + if err != nil { + passwordSHA256 := getSHA256(userProvidedPassword) + err = bcrypt.CompareHashAndPassword([]byte(storedHashedPassword), []byte(passwordSHA256)) + } + return err +} + // EncryptPassword is used for encrypting password func EncryptPassword(password string) (string, error) { pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { - return "", err + password = getSHA256(password) + pw, err = bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) + if err != nil { + return "", err + } } return string(pw), nil diff --git a/server/resolvers/login.go b/server/resolvers/login.go index 2db4209..fa5d409 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -7,13 +7,13 @@ import ( "time" "github.com/google/uuid" - "golang.org/x/crypto/bcrypt" log "github.com/sirupsen/logrus" "github.com/authorizerdev/authorizer/server/authenticators" "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" mailService "github.com/authorizerdev/authorizer/server/email" @@ -104,7 +104,7 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes return res, fmt.Errorf(`phone number is not verified`) } } - err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password)) + err = crypto.VerifyPassword(*user.Password, params.Password) if err != nil { log.Debug("Failed to compare password: ", err) return res, fmt.Errorf(`bad user credentials`) diff --git a/server/resolvers/mobile_login.go b/server/resolvers/mobile_login.go index c3ab934..cbc0f28 100644 --- a/server/resolvers/mobile_login.go +++ b/server/resolvers/mobile_login.go @@ -12,6 +12,7 @@ import ( "github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/cookie" + "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/graph/model" @@ -69,7 +70,7 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m return res, fmt.Errorf(`phone number is not verified`) } - err = bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(params.Password)) + err = crypto.VerifyPassword(*user.Password, params.Password) if err != nil { log.Debug("Failed to compare password: ", err) diff --git a/server/resolvers/update_profile.go b/server/resolvers/update_profile.go index 3b9af37..da83bff 100644 --- a/server/resolvers/update_profile.go +++ b/server/resolvers/update_profile.go @@ -163,7 +163,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput) } if isPasswordChanging && user.Password != nil && params.OldPassword != nil { - if err = bcrypt.CompareHashAndPassword([]byte(refs.StringValue(user.Password)), []byte(refs.StringValue(params.OldPassword))); err != nil { + if err = crypto.VerifyPassword(refs.StringValue(user.Password), refs.StringValue(params.OldPassword)); err != nil { log.Debug("Failed to compare hash and old password: ", err) return res, fmt.Errorf("incorrect old password") } diff --git a/server/token/admin_token.go b/server/token/admin_token.go index 9dcbeb3..6e4bed7 100644 --- a/server/token/admin_token.go +++ b/server/token/admin_token.go @@ -8,7 +8,6 @@ import ( "github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/memorystore" "github.com/gin-gonic/gin" - "golang.org/x/crypto/bcrypt" ) // CreateAdminAuthToken creates the admin token based on secret key @@ -31,7 +30,7 @@ func GetAdminAuthToken(gc *gin.Context) (string, error) { if err != nil { return "", err } - err = bcrypt.CompareHashAndPassword([]byte(token), []byte(adminSecret)) + err = crypto.VerifyPassword(token, adminSecret) if err != nil { return "", fmt.Errorf(`unauthorized`)