refactor: use new error struct and error messages
This commit is contained in:
parent
593d8ea381
commit
829852c6c1
|
@ -3,12 +3,13 @@ package account
|
||||||
import (
|
import (
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"errors"
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.lumeweb.com/LumeWeb/portal/db/models"
|
"git.lumeweb.com/LumeWeb/portal/db/models"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -38,7 +39,7 @@ func NewAccountService(params AccountServiceParams) *AccountServiceDefault {
|
||||||
return &AccountServiceDefault{db: params.Db, config: params.Config, identity: params.Identity}
|
return &AccountServiceDefault{db: params.Db, config: params.Config, identity: params.Identity}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccountServiceDefault) EmailExists(email string) (bool, *models.User, error) {
|
func (s *AccountServiceDefault) EmailExists(email string) (bool, *models.User, *AccountError) {
|
||||||
user := &models.User{}
|
user := &models.User{}
|
||||||
exists, model, err := s.exists(user, map[string]interface{}{"email": email})
|
exists, model, err := s.exists(user, map[string]interface{}{"email": email})
|
||||||
if !exists || err != nil {
|
if !exists || err != nil {
|
||||||
|
@ -47,7 +48,7 @@ func (s *AccountServiceDefault) EmailExists(email string) (bool, *models.User, e
|
||||||
return true, model.(*models.User), nil // Type assertion since `exists` returns interface{}
|
return true, model.(*models.User), nil // Type assertion since `exists` returns interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccountServiceDefault) PubkeyExists(pubkey string) (bool, *models.PublicKey, error) {
|
func (s *AccountServiceDefault) PubkeyExists(pubkey string) (bool, *models.PublicKey, *AccountError) {
|
||||||
publicKey := &models.PublicKey{}
|
publicKey := &models.PublicKey{}
|
||||||
exists, model, err := s.exists(publicKey, map[string]interface{}{"key": pubkey})
|
exists, model, err := s.exists(publicKey, map[string]interface{}{"key": pubkey})
|
||||||
if !exists || err != nil {
|
if !exists || err != nil {
|
||||||
|
@ -56,7 +57,7 @@ func (s *AccountServiceDefault) PubkeyExists(pubkey string) (bool, *models.Publi
|
||||||
return true, model.(*models.PublicKey), nil // Type assertion is necessary
|
return true, model.(*models.PublicKey), nil // Type assertion is necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccountServiceDefault) AccountExists(id uint) (bool, *models.User, error) {
|
func (s *AccountServiceDefault) AccountExists(id uint) (bool, *models.User, *AccountError) {
|
||||||
user := &models.User{}
|
user := &models.User{}
|
||||||
exists, model, err := s.exists(user, map[string]interface{}{"id": id})
|
exists, model, err := s.exists(user, map[string]interface{}{"id": id})
|
||||||
if !exists || err != nil {
|
if !exists || err != nil {
|
||||||
|
@ -65,15 +66,15 @@ func (s *AccountServiceDefault) AccountExists(id uint) (bool, *models.User, erro
|
||||||
return true, model.(*models.User), nil // Ensure to assert the type correctly
|
return true, model.(*models.User), nil // Ensure to assert the type correctly
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccountServiceDefault) HashPassword(password string) (string, error) {
|
func (s *AccountServiceDefault) HashPassword(password string) (string, *AccountError) {
|
||||||
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", NewAccountError(ErrKeyHashingFailed, err)
|
||||||
}
|
}
|
||||||
return string(bytes), nil
|
return string(bytes), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AccountServiceDefault) CreateAccount(email string, password string) (*models.User, error) {
|
func (s *AccountServiceDefault) CreateAccount(email string, password string) (*models.User, *AccountError) {
|
||||||
passwordHash, err := s.HashPassword(password)
|
passwordHash, err := s.HashPassword(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -86,7 +87,7 @@ func (s *AccountServiceDefault) CreateAccount(email string, password string) (*m
|
||||||
|
|
||||||
result := s.db.Create(&user)
|
result := s.db.Create(&user)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, NewAccountError(ErrKeyAccountCreationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &user, nil
|
return &user, nil
|
||||||
|
@ -96,7 +97,7 @@ func (s AccountServiceDefault) UpdateAccountName(userId uint, firstName string,
|
||||||
return s.updateAccountInfo(userId, models.User{FirstName: firstName, LastName: lastName})
|
return s.updateAccountInfo(userId, models.User{FirstName: firstName, LastName: lastName})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) AddPubkeyToAccount(user models.User, pubkey string) error {
|
func (s AccountServiceDefault) AddPubkeyToAccount(user models.User, pubkey string) *AccountError {
|
||||||
var model models.PublicKey
|
var model models.PublicKey
|
||||||
|
|
||||||
model.Key = pubkey
|
model.Key = pubkey
|
||||||
|
@ -105,12 +106,16 @@ func (s AccountServiceDefault) AddPubkeyToAccount(user models.User, pubkey strin
|
||||||
result := s.db.Create(&model)
|
result := s.db.Create(&model)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return result.Error
|
if errors.Is(result.Error, gorm.ErrDuplicatedKey) {
|
||||||
|
return NewAccountError(ErrKeyPublicKeyExists, result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (s AccountServiceDefault) LoginPassword(email string, password string, ip string) (string, *models.User, error) {
|
func (s AccountServiceDefault) LoginPassword(email string, password string, ip string) (string, *models.User, *AccountError) {
|
||||||
valid, user, err := s.ValidLoginByEmail(email, password)
|
valid, user, err := s.ValidLoginByEmail(email, password)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -130,7 +135,7 @@ func (s AccountServiceDefault) LoginPassword(email string, password string, ip s
|
||||||
return token, user, nil
|
return token, user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) LoginOTP(userId uint, code string) (string, error) {
|
func (s AccountServiceDefault) LoginOTP(userId uint, code string) (string, *AccountError) {
|
||||||
valid, err := s.OTPVerify(userId, code)
|
valid, err := s.OTPVerify(userId, code)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -138,14 +143,14 @@ func (s AccountServiceDefault) LoginOTP(userId uint, code string) (string, error
|
||||||
}
|
}
|
||||||
|
|
||||||
if !valid {
|
if !valid {
|
||||||
return "", ErrInvalidOTPCode
|
return "", NewAccountError(ErrKeyInvalidOTPCode, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
var user models.User
|
var user models.User
|
||||||
user.ID = userId
|
user.ID = userId
|
||||||
|
|
||||||
token, err := JWTGenerateToken(s.config.GetString("core.domain"), s.identity, user.ID, JWTPurposeLogin)
|
token, tokenErr := JWTGenerateToken(s.config.GetString("core.domain"), s.identity, user.ID, JWTPurposeLogin)
|
||||||
if err != nil {
|
if tokenErr != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,13 +161,17 @@ func (s AccountServiceDefault) ValidLoginByUserObj(user *models.User, password s
|
||||||
return s.validPassword(user, password)
|
return s.validPassword(user, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) ValidLoginByEmail(email string, password string) (bool, *models.User, error) {
|
func (s AccountServiceDefault) ValidLoginByEmail(email string, password string) (bool, *models.User, *AccountError) {
|
||||||
var user models.User
|
var user models.User
|
||||||
|
|
||||||
result := s.db.Model(&models.User{}).Where(&models.User{Email: email}).First(&user)
|
result := s.db.Model(&models.User{}).Where(&models.User{Email: email}).First(&user)
|
||||||
|
|
||||||
if result.RowsAffected == 0 || result.Error != nil {
|
if result.RowsAffected == 0 || result.Error != nil {
|
||||||
return false, nil, result.Error
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
|
return false, nil, NewAccountError(ErrKeyInvalidLogin, result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil, NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := s.ValidLoginByUserObj(&user, password)
|
valid := s.ValidLoginByUserObj(&user, password)
|
||||||
|
@ -174,7 +183,7 @@ func (s AccountServiceDefault) ValidLoginByEmail(email string, password string)
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) ValidLoginByUserID(id uint, password string) (bool, *models.User, error) {
|
func (s AccountServiceDefault) ValidLoginByUserID(id uint, password string) (bool, *models.User, *AccountError) {
|
||||||
var user models.User
|
var user models.User
|
||||||
|
|
||||||
user.ID = id
|
user.ID = id
|
||||||
|
@ -182,7 +191,11 @@ func (s AccountServiceDefault) ValidLoginByUserID(id uint, password string) (boo
|
||||||
result := s.db.Model(&user).Where(&user).First(&user)
|
result := s.db.Model(&user).Where(&user).First(&user)
|
||||||
|
|
||||||
if result.RowsAffected == 0 || result.Error != nil {
|
if result.RowsAffected == 0 || result.Error != nil {
|
||||||
return false, nil, result.Error
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
|
return false, nil, NewAccountError(ErrKeyInvalidLogin, result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil, NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := s.ValidLoginByUserObj(&user, password)
|
valid := s.ValidLoginByUserObj(&user, password)
|
||||||
|
@ -194,13 +207,17 @@ func (s AccountServiceDefault) ValidLoginByUserID(id uint, password string) (boo
|
||||||
return true, &user, nil
|
return true, &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) LoginPubkey(pubkey string) (string, error) {
|
func (s AccountServiceDefault) LoginPubkey(pubkey string) (string, *AccountError) {
|
||||||
var model models.PublicKey
|
var model models.PublicKey
|
||||||
|
|
||||||
result := s.db.Model(&models.PublicKey{}).Preload("User").Where(&models.PublicKey{Key: pubkey}).First(&model)
|
result := s.db.Model(&models.PublicKey{}).Preload("User").Where(&models.PublicKey{Key: pubkey}).First(&model)
|
||||||
|
|
||||||
if result.RowsAffected == 0 || result.Error != nil {
|
if result.RowsAffected == 0 || result.Error != nil {
|
||||||
return "", result.Error
|
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
|
||||||
|
return "", NewAccountError(ErrKeyInvalidLogin, result.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := model.User
|
user := model.User
|
||||||
|
@ -214,7 +231,7 @@ func (s AccountServiceDefault) LoginPubkey(pubkey string) (string, error) {
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) AccountPins(id uint, createdAfter uint64) ([]models.Pin, error) {
|
func (s AccountServiceDefault) AccountPins(id uint, createdAfter uint64) ([]models.Pin, *AccountError) {
|
||||||
var pins []models.Pin
|
var pins []models.Pin
|
||||||
|
|
||||||
result := s.db.Model(&models.Pin{}).
|
result := s.db.Model(&models.Pin{}).
|
||||||
|
@ -225,7 +242,7 @@ func (s AccountServiceDefault) AccountPins(id uint, createdAfter uint64) ([]mode
|
||||||
Find(&pins)
|
Find(&pins)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, NewAccountError(ErrKeyPinsRetrievalFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pins, nil
|
return pins, nil
|
||||||
|
@ -303,23 +320,23 @@ func (s AccountServiceDefault) PinByID(uploadId uint, userId uint) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) OTPGenerate(userId uint) (string, error) {
|
func (s AccountServiceDefault) OTPGenerate(userId uint) (string, *AccountError) {
|
||||||
exists, user, err := s.AccountExists(userId)
|
exists, user, err := s.AccountExists(userId)
|
||||||
|
|
||||||
if !exists || err != nil {
|
if !exists || err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
otp, err := TOTPGenerate(user.Email, s.config.GetString("core.domain"))
|
otp, otpErr := TOTPGenerate(user.Email, s.config.GetString("core.domain"))
|
||||||
if err != nil {
|
if otpErr != nil {
|
||||||
return "", err
|
return "", NewAccountError(ErrKeyOTPGenerationFailed, otpErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.updateAccountInfo(user.ID, models.User{OTPSecret: otp})
|
err = s.updateAccountInfo(user.ID, models.User{OTPSecret: otp})
|
||||||
return otp, nil
|
return otp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) OTPVerify(userId uint, code string) (bool, error) {
|
func (s AccountServiceDefault) OTPVerify(userId uint, code string) (bool, *AccountError) {
|
||||||
exists, user, err := s.AccountExists(userId)
|
exists, user, err := s.AccountExists(userId)
|
||||||
|
|
||||||
if !exists || err != nil {
|
if !exists || err != nil {
|
||||||
|
@ -351,21 +368,21 @@ func (s AccountServiceDefault) OTPDisable(userId uint) error {
|
||||||
return s.updateAccountInfo(userId, models.User{OTPEnabled: false, OTPSecret: ""})
|
return s.updateAccountInfo(userId, models.User{OTPEnabled: false, OTPSecret: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) doLogin(user *models.User, ip string) (string, error) {
|
func (s AccountServiceDefault) doLogin(user *models.User, ip string) (string, *AccountError) {
|
||||||
purpose := JWTPurposeLogin
|
purpose := JWTPurposeLogin
|
||||||
|
|
||||||
if user.OTPEnabled {
|
if user.OTPEnabled {
|
||||||
purpose = JWTPurpose2FA
|
purpose = JWTPurpose2FA
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := JWTGenerateToken(s.config.GetString("core.domain"), s.identity, user.ID, purpose)
|
token, jwtErr := JWTGenerateToken(s.config.GetString("core.domain"), s.identity, user.ID, purpose)
|
||||||
if err != nil {
|
if jwtErr != nil {
|
||||||
return "", err
|
return "", NewAccountError(ErrKeyJWTGenerationFailed, jwtErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
err = s.updateAccountInfo(user.ID, models.User{LastLoginIP: ip, LastLogin: &now})
|
err := s.updateAccountInfo(user.ID, models.User{LastLoginIP: ip, LastLogin: &now})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -373,7 +390,7 @@ func (s AccountServiceDefault) doLogin(user *models.User, ip string) (string, er
|
||||||
return token, nil
|
return token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) updateAccountInfo(userId uint, info interface{}) error {
|
func (s AccountServiceDefault) updateAccountInfo(userId uint, info interface{}) *AccountError {
|
||||||
var user models.User
|
var user models.User
|
||||||
|
|
||||||
user.ID = userId
|
user.ID = userId
|
||||||
|
@ -381,13 +398,13 @@ func (s AccountServiceDefault) updateAccountInfo(userId uint, info interface{})
|
||||||
result := s.db.Model(&models.User{}).Where(&user).Updates(info)
|
result := s.db.Model(&models.User{}).Where(&user).Updates(info)
|
||||||
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return result.Error
|
return NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) exists(model interface{}, conditions map[string]interface{}) (bool, interface{}, error) {
|
func (s AccountServiceDefault) exists(model interface{}, conditions map[string]interface{}) (bool, interface{}, *AccountError) {
|
||||||
// Conduct a query with the provided model and conditions
|
// Conduct a query with the provided model and conditions
|
||||||
result := s.db.Model(model).Where(conditions).First(model)
|
result := s.db.Model(model).Where(conditions).First(model)
|
||||||
|
|
||||||
|
@ -398,7 +415,7 @@ func (s AccountServiceDefault) exists(model interface{}, conditions map[string]i
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return exists, model, result.Error
|
return exists, model, NewAccountError(ErrKeyDatabaseOperationFailed, result.Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s AccountServiceDefault) validPassword(user *models.User, password string) bool {
|
func (s AccountServiceDefault) validPassword(user *models.User, password string) bool {
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
package account
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Account creation errors
|
||||||
|
ErrKeyAccountCreationFailed = "ErrAccountCreationFailed"
|
||||||
|
ErrKeyEmailAlreadyExists = "ErrEmailAlreadyExists"
|
||||||
|
ErrKeyPasswordHashingFailed = "ErrPasswordHashingFailed"
|
||||||
|
|
||||||
|
// Account lookup and existence verification errors
|
||||||
|
ErrKeyUserNotFound = "ErrUserNotFound"
|
||||||
|
ErrKeyPublicKeyNotFound = "ErrPublicKeyNotFound"
|
||||||
|
|
||||||
|
// Authentication and login errors
|
||||||
|
ErrKeyInvalidLogin = "ErrInvalidLogin"
|
||||||
|
ErrKeyInvalidPassword = "ErrInvalidPassword"
|
||||||
|
ErrKeyInvalidOTPCode = "ErrInvalidOTPCode"
|
||||||
|
ErrKeyOTPVerificationFailed = "ErrOTPVerificationFailed"
|
||||||
|
ErrKeyLoginFailed = "ErrLoginFailed"
|
||||||
|
ErrKeyHashingFailed = "ErrHashingFailed"
|
||||||
|
|
||||||
|
// Account update errors
|
||||||
|
ErrKeyAccountUpdateFailed = "ErrAccountUpdateFailed"
|
||||||
|
|
||||||
|
// JWT generation errors
|
||||||
|
ErrKeyJWTGenerationFailed = "ErrJWTGenerationFailed"
|
||||||
|
|
||||||
|
// OTP management errors
|
||||||
|
ErrKeyOTPGenerationFailed = "ErrOTPGenerationFailed"
|
||||||
|
ErrKeyOTPEnableFailed = "ErrOTPEnableFailed"
|
||||||
|
ErrKeyOTPDisableFailed = "ErrOTPDisableFailed"
|
||||||
|
|
||||||
|
// Public key management errors
|
||||||
|
ErrKeyAddPublicKeyFailed = "ErrAddPublicKeyFailed"
|
||||||
|
ErrKeyPublicKeyExists = "ErrPublicKeyExists"
|
||||||
|
|
||||||
|
// Pin management errors
|
||||||
|
ErrKeyPinAddFailed = "ErrPinAddFailed"
|
||||||
|
ErrKeyPinDeleteFailed = "ErrPinDeleteFailed"
|
||||||
|
ErrKeyPinsRetrievalFailed = "ErrPinsRetrievalFailed"
|
||||||
|
|
||||||
|
// General errors
|
||||||
|
ErrKeyDatabaseOperationFailed = "ErrDatabaseOperationFailed"
|
||||||
|
)
|
||||||
|
|
||||||
|
var defaultErrorMessages = map[string]string{
|
||||||
|
// Account creation errors
|
||||||
|
ErrKeyAccountCreationFailed: "Account creation failed due to an internal error.",
|
||||||
|
ErrKeyEmailAlreadyExists: "The email address provided is already in use.",
|
||||||
|
ErrKeyPasswordHashingFailed: "Failed to secure the password, please try again later.",
|
||||||
|
|
||||||
|
// Account lookup and existence verification errors
|
||||||
|
ErrKeyUserNotFound: "The requested user was not found.",
|
||||||
|
ErrKeyPublicKeyNotFound: "The specified public key was not found.",
|
||||||
|
ErrKeyHashingFailed: "Failed to hash the password.",
|
||||||
|
|
||||||
|
// Authentication and login errors
|
||||||
|
ErrKeyInvalidLogin: "The login credentials provided are invalid.",
|
||||||
|
ErrKeyInvalidPassword: "The password provided is incorrect.",
|
||||||
|
ErrKeyInvalidOTPCode: "The OTP code provided is invalid or expired.",
|
||||||
|
ErrKeyOTPVerificationFailed: "OTP verification failed, please try again.",
|
||||||
|
ErrKeyLoginFailed: "Login failed due to an internal error.",
|
||||||
|
|
||||||
|
// Account update errors
|
||||||
|
ErrKeyAccountUpdateFailed: "Failed to update account information.",
|
||||||
|
|
||||||
|
// JWT generation errors
|
||||||
|
ErrKeyJWTGenerationFailed: "Failed to generate a new JWT token.",
|
||||||
|
|
||||||
|
// OTP management errors
|
||||||
|
ErrKeyOTPGenerationFailed: "Failed to generate a new OTP secret.",
|
||||||
|
ErrKeyOTPEnableFailed: "Enabling OTP authentication failed.",
|
||||||
|
ErrKeyOTPDisableFailed: "Disabling OTP authentication failed.",
|
||||||
|
|
||||||
|
// Public key management errors
|
||||||
|
ErrKeyAddPublicKeyFailed: "Adding the public key to the account failed.",
|
||||||
|
ErrKeyPublicKeyExists: "The public key already exists for this account.",
|
||||||
|
|
||||||
|
// Pin management errors
|
||||||
|
ErrKeyPinAddFailed: "Failed to add the pin.",
|
||||||
|
ErrKeyPinDeleteFailed: "Failed to delete the pin.",
|
||||||
|
ErrKeyPinsRetrievalFailed: "Failed to retrieve pins.",
|
||||||
|
|
||||||
|
// General errors
|
||||||
|
ErrKeyDatabaseOperationFailed: "A database operation failed.",
|
||||||
|
}
|
||||||
|
|
||||||
|
type AccountError struct {
|
||||||
|
Key string // A unique identifier for the error type
|
||||||
|
Message string // Human-readable error message
|
||||||
|
Err error // Underlying error, if any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *AccountError) Error() string {
|
||||||
|
if e.Err != nil {
|
||||||
|
return fmt.Sprintf("%s: %v", e.Message, e.Err)
|
||||||
|
}
|
||||||
|
return e.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAccountError(key string, err error, customMessage ...string) *AccountError {
|
||||||
|
message, exists := defaultErrorMessages[key]
|
||||||
|
if !exists {
|
||||||
|
message = "An unknown error occurred"
|
||||||
|
}
|
||||||
|
if len(customMessage) > 0 {
|
||||||
|
message = customMessage[0]
|
||||||
|
}
|
||||||
|
return &AccountError{
|
||||||
|
Key: key,
|
||||||
|
Message: message,
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue