MCPcopy Create free account
hub / github.com/supabase/auth / verifyPhoneFactor

Method verifyPhoneFactor

internal/api/mfa.go:729–867  ·  view source on GitHub ↗
(w http.ResponseWriter, r *http.Request, params *VerifyFactorParams)

Source from the content-addressed store, hash-verified

727}
728
729func (a *API) verifyPhoneFactor(w http.ResponseWriter, r *http.Request, params *VerifyFactorParams) error {
730 ctx := r.Context()
731 config := a.config
732 user := getUser(ctx)
733 factor := getFactor(ctx)
734 db := a.db.WithContext(ctx)
735 currentIP := utilities.GetIPAddress(r)
736
737 challenge, err := a.validateChallenge(r, db, factor, params.ChallengeID)
738 if err != nil {
739 return err
740 }
741
742 if challenge.VerifiedAt != nil || challenge.IPAddress != currentIP {
743 return apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeMFAIPAddressMismatch, "Challenge and verify IP addresses mismatch")
744 }
745
746 if challenge.HasExpired(config.MFA.ChallengeExpiryDuration) {
747 if err := db.Destroy(challenge); err != nil {
748 return apierrors.NewInternalServerError("Database error deleting challenge").WithInternalError(err)
749 }
750 return apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeMFAChallengeExpired, "MFA challenge %v has expired, verify against another challenge or create a new challenge.", challenge.ID)
751 }
752 var valid bool
753 var otpCode string
754 var shouldReEncrypt bool
755 if config.Sms.IsTwilioVerifyProvider() {
756 smsProvider, err := sms_provider.GetSmsProvider(*config)
757 if err != nil {
758 return apierrors.NewInternalServerError("Failed to get SMS provider").WithInternalError(err)
759 }
760 if err := smsProvider.VerifyOTP(factor.Phone.String(), params.Code); err != nil {
761 return apierrors.NewForbiddenError(apierrors.ErrorCodeOTPExpired, "Token has expired or is invalid").WithInternalError(err)
762 }
763 valid = true
764 } else {
765 otpCode, shouldReEncrypt, err = challenge.GetOtpCode(config.Security.DBEncryption.DecryptionKeys, config.Security.DBEncryption.Encrypt, config.Security.DBEncryption.EncryptionKeyID)
766 if err != nil {
767 return apierrors.NewInternalServerError("Database error verifying MFA TOTP secret").WithInternalError(err)
768 }
769 valid = subtle.ConstantTimeCompare([]byte(otpCode), []byte(params.Code)) == 1
770 }
771 if config.Hook.MFAVerificationAttempt.Enabled {
772 input := v0hooks.NewMFAVerificationAttemptInput(
773 r,
774 user.ID,
775 factor.ID,
776 factor.FactorType,
777 valid,
778 )
779
780 output := v0hooks.MFAVerificationAttemptOutput{}
781 err := a.hooksMgr.InvokeHook(nil, r, input, &output)
782 if err != nil {
783 return err
784 }
785
786 if output.Decision == v0hooks.HookRejection {

Callers 1

VerifyFactorMethod · 0.95

Calls 15

validateChallengeMethod · 0.95
GetIPAddressFunction · 0.92
NewInternalServerErrorFunction · 0.92
GetSmsProviderFunction · 0.92
NewForbiddenErrorFunction · 0.92
LogoutFunction · 0.92
NewAuditLogEntryFunction · 0.92
FindUserByIDFunction · 0.92

Tested by

no test coverage detected