mutationCustomerCreate.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package graphql
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/Nerzal/gocloak/v12"
  6. "github.com/gshopify/service-wrapper/scalar"
  7. "github.com/gshopify/service-wrapper/server/middleware"
  8. "gshopper.com/gshopify/customer/graphql/generated"
  9. m "gshopper.com/gshopify/customer/model"
  10. "time"
  11. )
  12. var minPasswordEntropy = 42.0
  13. func (r *mutationResolver) CustomerCreate(
  14. ctx context.Context, input generated.CustomerCreateInput) (*generated.CustomerCreatePayload, error) {
  15. var (
  16. response = &generated.CustomerCreatePayload{}
  17. user = gocloak.User{
  18. Enabled: gocloak.BoolP(true),
  19. }
  20. err error
  21. )
  22. if e := input.ValidateEmail(); e != nil {
  23. response.CustomerUserErrors = append(response.CustomerUserErrors, e)
  24. return response, nil
  25. }
  26. if e := input.ValidatePassword(minPasswordEntropy); e != nil {
  27. response.CustomerUserErrors = append(response.CustomerUserErrors, e)
  28. return response, nil
  29. }
  30. admin, err := r.conf.Admin.Token(r.client, ctx)
  31. if err != nil {
  32. response.CustomerUserErrors = append(response.CustomerUserErrors,
  33. CustomerError(generated.CustomerErrorCodeTokenInvalid, err, "adminAccessToken"))
  34. return response, err
  35. }
  36. if count, err := r.client.GetUserCount(ctx, admin.AccessToken, r.conf.Cli.Realm, gocloak.GetUsersParams{
  37. Email: gocloak.StringP(input.Email),
  38. }); err != nil || count > 0 {
  39. if count > 0 {
  40. err = fmt.Errorf("email has been already registered")
  41. }
  42. response.CustomerUserErrors = append(response.CustomerUserErrors,
  43. CustomerError(generated.CustomerErrorCodeTaken, err, "email"))
  44. }
  45. if len(response.CustomerUserErrors) > 0 {
  46. return response, nil
  47. }
  48. now := scalar.Now()
  49. user.Email = gocloak.StringP(input.Email)
  50. user.LastName = input.LastName
  51. user.FirstName = input.FirstName
  52. user.CreatedTimestamp = gocloak.Int64P(time.Now().In(time.UTC).Unix())
  53. user.Attributes = &map[string][]string{
  54. "updated_at": {fmt.Sprintf("%d", now)},
  55. "created_at": {fmt.Sprintf("%d", now)},
  56. }
  57. if input.AcceptsMarketing != nil {
  58. (*user.Attributes)["accepts_marketing"] = []string{fmt.Sprintf("%v", input.AcceptsMarketing)}
  59. }
  60. if input.Phone != nil {
  61. inContext, err := middleware.InContext(ctx)
  62. if err != nil {
  63. response.CustomerUserErrors = append(response.CustomerUserErrors,
  64. CustomerError(generated.CustomerErrorCodeInvalid, err, "inContext"))
  65. return response, nil
  66. }
  67. number, err := m.NewPhoneNumber(*input.Phone, inContext.Country.String(), true)
  68. if err != nil {
  69. response.CustomerUserErrors = append(response.CustomerUserErrors,
  70. CustomerError(generated.CustomerErrorCodeInvalid, err, "phone"))
  71. return response, nil
  72. }
  73. (*user.Attributes)["phone_number"] = []string{number.String()}
  74. (*user.Attributes)["phone_region"] = []string{number.PhoneRegion}
  75. (*user.Attributes)["phone_verified"] = []string{"false"}
  76. }
  77. // Create new user
  78. uid, err := r.client.CreateUser(ctx, admin.AccessToken, r.conf.Cli.Realm, user)
  79. if err != nil {
  80. response.CustomerUserErrors = append(response.CustomerUserErrors,
  81. CustomerError(generated.CustomerErrorCodeBlank, err))
  82. return response, nil
  83. }
  84. // Set user password
  85. if err = r.setPassword(ctx, uid, input.Password, false); err != nil {
  86. response.CustomerUserErrors = append(response.CustomerUserErrors,
  87. CustomerError(generated.CustomerErrorCodeBlank, err))
  88. return response, nil
  89. }
  90. // Email verification
  91. if err = r.client.SendVerifyEmail(ctx, admin.AccessToken, uid, r.conf.Cli.Realm, gocloak.SendVerificationMailParams{
  92. ClientID: gocloak.StringP(r.conf.Cli.ClientId),
  93. RedirectURI: nil,
  94. }); err != nil {
  95. response.CustomerUserErrors = append(response.CustomerUserErrors,
  96. CustomerError(generated.CustomerErrorCodeBlank, err))
  97. return response, nil
  98. }
  99. user.ID = &uid
  100. response.Customer = User2Customer(&user)
  101. return response, nil
  102. }