From 6f704d6c34bd650c2f8bdcb1cd0c20749ff3b529 Mon Sep 17 00:00:00 2001 From: Stefan Jacobi Date: Thu, 16 May 2024 16:34:19 +0200 Subject: [PATCH] fix(transaction): check identifier before saving * the check now tries to fetch all transactions with a given identifier from a tenant before proceeding Closes: #62 --- server/api/services/transaction_service.go | 14 +++++++++----- .../persisters/transaction_persister.go | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/server/api/services/transaction_service.go b/server/api/services/transaction_service.go index 0950f5a..bf0b1b9 100644 --- a/server/api/services/transaction_service.go +++ b/server/api/services/transaction_service.go @@ -62,11 +62,15 @@ func (ts *transactionService) Initialize(userId string, transaction *models.Tran return nil, echo.NewHTTPError(http.StatusNotFound, "unable to find user") } - for _, storedTransaction := range webauthnUser.Transactions { - if storedTransaction.Identifier == transaction.Identifier { - ts.logger.Error("transaction already exists") - return nil, echo.NewHTTPError(http.StatusConflict, "transaction already exists") - } + foundTransaction, err := ts.transactionPersister.GetByIdentifier(transaction.Identifier, ts.tenant.ID) + if err != nil { + ts.logger.Error(err) + return nil, echo.NewHTTPError(http.StatusInternalServerError, "unable to search for transaction") + } + + if foundTransaction != nil { + ts.logger.Error("transaction already exists") + return nil, echo.NewHTTPError(http.StatusConflict, "transaction already exists") } // check for better error handling as BeginLogin can throw a BadRequestError AND normal errors (but same type) diff --git a/server/persistence/persisters/transaction_persister.go b/server/persistence/persisters/transaction_persister.go index 4fbbb96..3ce14ba 100644 --- a/server/persistence/persisters/transaction_persister.go +++ b/server/persistence/persisters/transaction_persister.go @@ -12,6 +12,7 @@ import ( type TransactionPersister interface { Create(transaction *models.Transaction) error + GetByIdentifier(identifier string, tenantID uuid.UUID) (*models.Transactions, error) ListByUserId(userId uuid.UUID, tenantId uuid.UUID) (*models.Transactions, error) GetByUserId(userId uuid.UUID, tenantId uuid.UUID) (*models.Transaction, error) GetByChallenge(challenge string, tenantId uuid.UUID) (*models.Transaction, error) @@ -65,6 +66,19 @@ func (p *transactionPersister) ListByUserId(userId uuid.UUID, tenantId uuid.UUID return &transactions, nil } +func (p *transactionPersister) GetByIdentifier(identifier string, tenantId uuid.UUID) (*models.Transactions, error) { + transactions := models.Transactions{} + err := p.database.Eager().Where("identifier = ? AND tenant_id = ?", identifier, tenantId).All(&transactions) + if err != nil && errors.Is(err, sql.ErrNoRows) { + return nil, nil + } + if err != nil { + return nil, fmt.Errorf("failed to list transactions by user id: %w", err) + } + + return &transactions, nil +} + func (p *transactionPersister) GetByChallenge(challenge string, tenantId uuid.UUID) (*models.Transaction, error) { transaction := models.Transaction{} err := p.database.Eager().Where("challenge = ? AND tenant_id = ?", challenge, tenantId).First(&transaction)