MCPcopy Index your code
hub / github.com/supabase/auth / UserUpdate

Method UserUpdate

internal/api/user.go:82–294  ·  view source on GitHub ↗

UserUpdate updates fields on a user

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

80
81// UserUpdate updates fields on a user
82func (a *API) UserUpdate(w http.ResponseWriter, r *http.Request) error {
83 ctx := r.Context()
84 db := a.db.WithContext(ctx)
85 config := a.config
86 aud := a.requestAud(ctx, r)
87
88 params := &UserUpdateParams{}
89 if err := retrieveRequestParams(r, params); err != nil {
90 return err
91 }
92
93 user := getUser(ctx)
94 session := getSession(ctx)
95
96 if err := a.validateUserUpdateParams(ctx, params); err != nil {
97 return err
98 }
99
100 if params.AppData != nil && !isAdmin(user, config) {
101 if !isAdmin(user, config) {
102 return apierrors.NewForbiddenError(apierrors.ErrorCodeNotAdmin, "Updating app_metadata requires admin privileges")
103 }
104 }
105
106 if user.HasMFAEnabled() && !session.IsAAL2() {
107 if (params.Password != nil && *params.Password != "") || (params.Email != "" && user.GetEmail() != params.Email) || (params.Phone != "" && user.GetPhone() != params.Phone) {
108 return apierrors.NewHTTPError(http.StatusUnauthorized, apierrors.ErrorCodeInsufficientAAL, "AAL2 session is required to update email or password when MFA is enabled.")
109 }
110 }
111
112 if user.IsAnonymous {
113 if params.Password != nil && *params.Password != "" {
114 if params.Email == "" && params.Phone == "" {
115 return apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeValidationFailed, "Updating password of an anonymous user without an email or phone is not allowed")
116 }
117 }
118 }
119
120 // TODO: Check if a user is SSO via rows in identities table, not via this flag.
121 if user.IsSSOUser {
122 updatingForbiddenFields := false
123
124 updatingForbiddenFields = updatingForbiddenFields || (params.Password != nil && *params.Password != "")
125 updatingForbiddenFields = updatingForbiddenFields || (params.Email != "" && params.Email != user.GetEmail())
126 updatingForbiddenFields = updatingForbiddenFields || (params.Phone != "" && params.Phone != user.GetPhone())
127 updatingForbiddenFields = updatingForbiddenFields || (params.Nonce != "")
128
129 if updatingForbiddenFields {
130 return apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeUserSSOManaged, "Updating email, phone, password of a SSO account only possible via SSO")
131 }
132 }
133
134 if params.Email != "" && user.GetEmail() != params.Email {
135 if duplicateUser, err := models.IsDuplicatedEmail(db, params.Email, aud, user, config.Experimental.ProvidersWithOwnLinkingDomain); err != nil {
136 return apierrors.NewInternalServerError("Database error checking email").WithInternalError(err)
137 } else if duplicateUser != nil {
138 return apierrors.NewUnprocessableEntityError(apierrors.ErrorCodeEmailExists, DuplicateEmailMsg)
139 }

Callers

nothing calls this directly

Calls 15

requestAudMethod · 0.95
emailChangeVerifyMethod · 0.95
sendEmailChangeMethod · 0.95
smsVerifyMethod · 0.95
sendPhoneConfirmationMethod · 0.95
NewForbiddenErrorFunction · 0.92
NewHTTPErrorFunction · 0.92
IsDuplicatedEmailFunction · 0.92

Tested by

no test coverage detected