From b7f44d817df9f0769d781dc2e9a7cc3bf24900a2 Mon Sep 17 00:00:00 2001 From: Kang Ming Date: Wed, 7 Feb 2024 18:38:15 +0800 Subject: [PATCH] fix: create & update email identity after verify --- internal/api/user.go | 21 --------------------- internal/api/verify.go | 33 ++++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/internal/api/user.go b/internal/api/user.go index 02fd099b21..50ea3fa4b7 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -195,27 +195,6 @@ func (a *API) UserUpdate(w http.ResponseWriter, r *http.Request) error { var identities []models.Identity if params.Email != "" && params.Email != user.GetEmail() { - identity, terr := models.FindIdentityByIdAndProvider(tx, user.ID.String(), "email") - if terr != nil { - if !models.IsNotFoundError(terr) { - return terr - } - // updating the user's email should create a new email identity since the user doesn't have one - identity, terr = a.createNewIdentity(tx, user, "email", structs.Map(provider.Claims{ - Subject: user.ID.String(), - Email: params.Email, - })) - if terr != nil { - return terr - } - } else { - if terr := identity.UpdateIdentityData(tx, map[string]interface{}{ - "email": params.Email, - }); terr != nil { - return terr - } - } - identities = append(identities, *identity) mailer := a.Mailer(ctx) referrer := utilities.GetReferrer(r, config) flowType := getFlowFromChallenge(params.CodeChallenge) diff --git a/internal/api/verify.go b/internal/api/verify.go index c338064097..590aea5b5a 100644 --- a/internal/api/verify.go +++ b/internal/api/verify.go @@ -10,7 +10,9 @@ import ( "strings" "time" + "github.com/fatih/structs" "github.com/sethvargo/go-password/password" + "github.com/supabase/auth/internal/api/provider" "github.com/supabase/auth/internal/api/sms_provider" "github.com/supabase/auth/internal/crypto" "github.com/supabase/auth/internal/models" @@ -478,17 +480,38 @@ func (a *API) emailChangeVerify(r *http.Request, ctx context.Context, conn *stor // one email is confirmed at this point if GOTRUE_MAILER_SECURE_EMAIL_CHANGE_ENABLED is enabled err := conn.Transaction(func(tx *storage.Connection) error { - var terr error - - if terr = models.NewAuditLogEntry(r, tx, user, models.UserModifiedAction, "", nil); terr != nil { + if terr := models.NewAuditLogEntry(r, tx, user, models.UserModifiedAction, "", nil); terr != nil { return terr } - if terr = triggerEventHooks(ctx, tx, EmailChangeEvent, user, config); terr != nil { + if terr := triggerEventHooks(ctx, tx, EmailChangeEvent, user, config); terr != nil { return terr } - if terr = user.ConfirmEmailChange(tx, zeroConfirmation); terr != nil { + if identity, terr := models.FindIdentityByIdAndProvider(tx, user.ID.String(), "email"); terr != nil { + if !models.IsNotFoundError(terr) { + return terr + } + // confirming the email change should create a new email identity if the user doesn't have one + if _, terr = a.createNewIdentity(tx, user, "email", structs.Map(provider.Claims{ + Subject: user.ID.String(), + Email: params.Email, + EmailVerified: true, + })); terr != nil { + return terr + } + } else { + if terr := identity.UpdateIdentityData(tx, map[string]interface{}{ + "email": params.Email, + "email_verified": true, + }); terr != nil { + return terr + } + } + if terr := tx.Load(user, "Identities"); terr != nil { + return internalServerError("Error refetching identities").WithInternalError(terr) + } + if terr := user.ConfirmEmailChange(tx, zeroConfirmation); terr != nil { return internalServerError("Error confirm email").WithInternalError(terr) }