(r *http.Request, db *storage.Connection, factor *models.Factor, challengeID uuid.UUID)
| 538 | } |
| 539 | |
| 540 | func (a *API) validateChallenge(r *http.Request, db *storage.Connection, factor *models.Factor, challengeID uuid.UUID) (*models.Challenge, error) { |
| 541 | config := a.config |
| 542 | currentIP := utilities.GetIPAddress(r) |
| 543 | |
| 544 | challenge, err := factor.FindChallengeByID(db, challengeID) |
| 545 | if err != nil { |
| 546 | if models.IsNotFoundError(err) { |
| 547 | return nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeMFAFactorNotFound, "MFA factor with the provided challenge ID not found") |
| 548 | } |
| 549 | return nil, apierrors.NewInternalServerError("Database error finding Challenge").WithInternalError(err) |
| 550 | } |
| 551 | |
| 552 | if challenge.VerifiedAt != nil || challenge.IPAddress != currentIP { |
| 553 | return nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeMFAIPAddressMismatch, "Challenge and verify IP addresses mismatch.") |
| 554 | } |
| 555 | |
| 556 | if challenge.HasExpired(config.MFA.ChallengeExpiryDuration) { |
| 557 | if err := db.Destroy(challenge); err != nil { |
| 558 | return nil, apierrors.NewInternalServerError("Database error deleting challenge").WithInternalError(err) |
| 559 | } |
| 560 | return nil, apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeMFAChallengeExpired, "MFA challenge %v has expired, verify against another challenge or create a new challenge.", challenge.ID) |
| 561 | } |
| 562 | |
| 563 | return challenge, nil |
| 564 | } |
| 565 | |
| 566 | func (a *API) ChallengeFactor(w http.ResponseWriter, r *http.Request) error { |
| 567 | ctx := r.Context() |
no test coverage detected