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

Method verifyWebAuthnFactor

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

Source from the content-addressed store, hash-verified

867}
868
869func (a *API) verifyWebAuthnFactor(w http.ResponseWriter, r *http.Request, params *VerifyFactorParams) error {
870 ctx := r.Context()
871 config := a.config
872 user := getUser(ctx)
873 factor := getFactor(ctx)
874 db := a.db.WithContext(ctx)
875
876 var webAuthn *webauthn.WebAuthn
877 var credential *webauthn.Credential
878 var err error
879
880 switch {
881 case params.WebAuthn == nil:
882 return apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "WebAuthn config required")
883 case params.WebAuthn.Type != "create" && params.WebAuthn.Type != "request":
884 return apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "WebAuthn type must be create or request")
885 case params.WebAuthn.CredentialResponse == nil:
886 return apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "credential_response required")
887 default:
888 webAuthn, err = a.getWebAuthnMFA()
889 if err != nil {
890 return err
891 }
892 }
893
894 challenge, err := a.validateChallenge(r, db, factor, params.ChallengeID)
895 if err != nil {
896 return err
897 }
898 webAuthnSession := *challenge.WebAuthnSessionData.SessionData
899
900 var parsedResponse interface{}
901 switch params.WebAuthn.Type {
902 case "create":
903 parsedResponse, err = wbnprotocol.ParseCredentialCreationResponseBody(bytes.NewReader(params.WebAuthn.CredentialResponse))
904 if err != nil {
905 return apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "Invalid credential_response")
906 }
907 credential, err = webAuthn.CreateCredential(user, webAuthnSession, parsedResponse.(*wbnprotocol.ParsedCredentialCreationData))
908 if err != nil {
909 return err
910 }
911
912 case "request":
913 parsedResponse, err = wbnprotocol.ParseCredentialRequestResponseBody(bytes.NewReader(params.WebAuthn.CredentialResponse))
914 if err != nil {
915 return apierrors.NewBadRequestError(apierrors.ErrorCodeValidationFailed, "Invalid credential_response")
916 }
917 credential, err = webAuthn.ValidateLogin(user, webAuthnSession, parsedResponse.(*wbnprotocol.ParsedCredentialAssertionData))
918 if err != nil {
919 return apierrors.NewInternalServerError("Failed to validate WebAuthn MFA response").WithInternalError(err)
920 }
921 }
922
923 // Once the challenge is validated, we consume the challenge
924 if err := db.Destroy(challenge); err != nil {
925 return apierrors.NewInternalServerError("Database error deleting challenge").WithInternalError(err)
926 }

Callers 1

VerifyFactorMethod · 0.95

Calls 15

getWebAuthnMFAMethod · 0.95
validateChallengeMethod · 0.95
NewBadRequestErrorFunction · 0.92
NewInternalServerErrorFunction · 0.92
NewAuditLogEntryFunction · 0.92
GetIPAddressFunction · 0.92
FindUserByIDFunction · 0.92
DeleteUnverifiedFactorsFunction · 0.92
RecordLoginFunction · 0.92

Tested by

no test coverage detected