|
@@ -2,9 +2,119 @@ 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"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
-func (r *mutationResolver) CustomerCreate(ctx context.Context, input generated.CustomerCreateInput) (*generated.CustomerCreatePayload, error) {
|
|
|
- panic("not implemented")
|
|
|
+var minPasswordEntropy = 42.0
|
|
|
+
|
|
|
+func (r *mutationResolver) CustomerCreate(
|
|
|
+ ctx context.Context, input generated.CustomerCreateInput) (*generated.CustomerCreatePayload, error) {
|
|
|
+
|
|
|
+ var (
|
|
|
+ response = &generated.CustomerCreatePayload{}
|
|
|
+ user = gocloak.User{
|
|
|
+ Enabled: gocloak.BoolP(true),
|
|
|
+ }
|
|
|
+ err error
|
|
|
+ )
|
|
|
+
|
|
|
+ if e := input.ValidateEmail(); e != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors, e)
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if e := input.ValidatePassword(minPasswordEntropy); e != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors, e)
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ admin, err := r.conf.Admin.Token(r.client, ctx)
|
|
|
+ if err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeTokenInvalid, err, "adminAccessToken"))
|
|
|
+ return response, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if ls, err := r.client.GetUsers(ctx, admin.AccessToken, r.conf.Cli.Realm, gocloak.GetUsersParams{
|
|
|
+ Email: gocloak.StringP(input.Email),
|
|
|
+ }); err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeBlank, err))
|
|
|
+ } else if len(ls) > 0 {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeTaken, fmt.Errorf("email has been already registered"), "email"))
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(response.CustomerUserErrors) > 0 {
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ now := scalar.Now()
|
|
|
+ user.Email = gocloak.StringP(input.Email)
|
|
|
+ user.LastName = input.LastName
|
|
|
+ user.FirstName = input.FirstName
|
|
|
+ user.CreatedTimestamp = gocloak.Int64P(time.Now().In(time.UTC).Unix())
|
|
|
+ user.Attributes = &map[string][]string{
|
|
|
+ "updated_at": {fmt.Sprintf("%d", now)},
|
|
|
+ "created_at": {fmt.Sprintf("%d", now)},
|
|
|
+ }
|
|
|
+
|
|
|
+ if input.AcceptsMarketing != nil {
|
|
|
+ (*user.Attributes)["accepts_marketing"] = []string{fmt.Sprintf("%v", input.AcceptsMarketing)}
|
|
|
+ }
|
|
|
+
|
|
|
+ if input.Phone != nil {
|
|
|
+ inContext, err := middleware.InContext(ctx)
|
|
|
+ if err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeInvalid, err, "inContext"))
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ number, err := m.NewPhoneNumber(*input.Phone, inContext.Country.String(), true)
|
|
|
+ if err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeInvalid, err, "phone"))
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ (*user.Attributes)["phone_number"] = []string{number.String()}
|
|
|
+ (*user.Attributes)["phone_region"] = []string{number.PhoneRegion}
|
|
|
+ (*user.Attributes)["phone_verified"] = []string{"false"}
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create new user
|
|
|
+ uid, err := r.client.CreateUser(ctx, admin.AccessToken, r.conf.Cli.Realm, user)
|
|
|
+ if err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeBlank, err))
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // Set user password
|
|
|
+ if err = r.setPassword(ctx, uid, input.Password, false); err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeBlank, err))
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ // Email verification
|
|
|
+ if err = r.client.SendVerifyEmail(ctx, admin.AccessToken, uid, r.conf.Cli.Realm, gocloak.SendVerificationMailParams{
|
|
|
+ ClientID: gocloak.StringP(r.conf.Cli.ClientId),
|
|
|
+ RedirectURI: nil,
|
|
|
+ }); err != nil {
|
|
|
+ response.CustomerUserErrors = append(response.CustomerUserErrors,
|
|
|
+ CustomerError(generated.CustomerErrorCodeBlank, err))
|
|
|
+ return response, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ user.ID = &uid
|
|
|
+ response.Customer = User2Customer(&user)
|
|
|
+ return response, nil
|
|
|
}
|