package graphql import ( "context" "fmt" "github.com/Nerzal/gocloak/v12" "github.com/gshopify/service-wrapper/scalar" "github.com/gshopify/service-wrapper/server/middleware" "gshopper.com/gshopify/customer/graphql/generated" m "gshopper.com/gshopify/customer/model" ) func (r *mutationResolver) CustomerUpdate( ctx context.Context, t string, udata generated.CustomerUpdateInput) (*generated.CustomerUpdatePayload, error) { var ( inContext, err = middleware.InContext(ctx) response = &generated.CustomerUpdatePayload{} claims *m.Claims customer *generated.Customer phone *m.Phone ) if err != nil { return nil, err } if _, claims, err = r.decodeAccessToken(ctx, t); err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeTokenInvalid, err, "customerAccessToken")) return response, nil } customer, err = r.customer(ctx, claims.Sub) if err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeTokenInvalid, err, "customerAccessToken")) return response, nil } // upsert FirstName if udata.FirstName != nil { customer.FirstName = udata.FirstName } // upsert LastName if udata.LastName != nil { customer.LastName = udata.LastName } // upsert AcceptsMarketing if udata.AcceptsMarketing != nil { customer.AcceptsMarketing = *udata.AcceptsMarketing } if udata.Phone != nil { phone, err = m.NewPhoneNumber(*udata.Phone, inContext.Country.String(), false) if err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeInvalid, err, "phone")) return response, nil } customer.Phone = gocloak.StringP(phone.String()) } user := gocloak.User{ ID: gocloak.StringP(customer.ID), FirstName: customer.FirstName, LastName: customer.LastName, Email: customer.Email, Attributes: &map[string][]string{ "accepts_marketing": {fmt.Sprintf("%v", customer.AcceptsMarketing)}, "phone_number": {*customer.Phone}, }, } for _, metafield := range customer.Metafields { (*user.Attributes)[metafield.Key] = []string{metafield.Value} } (*user.Attributes)["updated_at"] = []string{fmt.Sprintf("%d", scalar.Now())} // update user properties & attributes admin, err := r.conf.Admin.Token(r.client, ctx) if err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeTokenInvalid, err, "adminAccessToken")) return response, nil } if err = r.client.UpdateUser(ctx, admin.AccessToken, r.conf.Cli.Realm, user); err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeInvalid, err)) return response, nil } // update user password if udata.Password != nil { var payload *generated.CustomerAccessTokenCreatePayload if err = r.setPassword(ctx, customer.ID, *udata.Password, true); err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeInvalid, err, "password")) return response, nil } _, _ = r.CustomerAccessTokenDelete(ctx, t) payload, err = r.CustomerAccessTokenCreate(ctx, generated.CustomerAccessTokenCreateInput{ Email: *customer.Email, Password: *udata.Password, }) if err != nil { response.CustomerUserErrors = append(response.CustomerUserErrors, CustomerError(generated.CustomerErrorCodeInvalid, err, "password")) return response, nil } response.CustomerAccessToken = payload.CustomerAccessToken } response.Customer = customer return response, nil }