func (h *Handler) NewAccount(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	payload, err := payloadFromContext(ctx)
	if err != nil {
		api.WriteError(w, err)
		return
	}
	var nar NewAccountRequest
	if err := json.Unmarshal(payload.value, &nar); err != nil {
		api.WriteError(w, acme.WrapError(acme.ErrorMalformedType, err,
			"failed to unmarshal new-account request payload"))
		return
	}
	if err := nar.Validate(); err != nil {
		api.WriteError(w, err)
		return
	}
	httpStatus := http.StatusCreated
	acc, err := accountFromContext(r.Context())
	if err != nil {
		acmeErr, ok := err.(*acme.Error)
		if !ok || acmeErr.Status != http.StatusBadRequest {
			api.WriteError(w, err)
			return
		}
		if nar.OnlyReturnExisting {
			api.WriteError(w, acme.NewError(acme.ErrorAccountDoesNotExistType,
				"account does not exist"))
			return
		}
		jwk, err := jwkFromContext(ctx)
		if err != nil {
			api.WriteError(w, err)
			return
		}
		acc = &acme.Account{
			Key:     jwk,
			Contact: nar.Contact,
			Status:  acme.StatusValid,
		}
		if err := h.db.CreateAccount(ctx, acc); err != nil {
			api.WriteError(w, acme.WrapErrorISE(err, "error creating account"))
			return
		}
	} else {
		httpStatus = http.StatusOK
	}
	h.linker.LinkAccount(ctx, acc)
	w.Header().Set("Location", h.linker.GetLink(r.Context(), AccountLinkType, acc.ID))
	api.JSONStatus(w, acc, httpStatus)
}
NewAccount is the handler resource for creating new ACME accounts.
package api
import (
	"encoding/json"
	"net/http"
	"github.com/go-chi/chi"
	"github.com/smallstep/certificates/acme"
	"github.com/smallstep/certificates/api"
	"github.com/smallstep/certificates/logging"
)
type NewAccountRequest struct {
	Contact              []string `json:"contact"`
	OnlyReturnExisting   bool     `json:"onlyReturnExisting"`
	TermsOfServiceAgreed bool     `json:"termsOfServiceAgreed"`
}
func validateContacts(cs []string) error {
	for _, c := range cs {
		if c == "" {
			return acme.NewError(acme.ErrorMalformedType, "contact cannot be empty string")
		}
	}
	return nil
}
func (n *NewAccountRequest) Validate() error {
	if n.OnlyReturnExisting && len(n.Contact) > 0 {
		return acme.NewError(acme.ErrorMalformedType, "incompatible input; onlyReturnExisting must be alone")
	}
	return validateContacts(n.Contact)
}
type UpdateAccountRequest struct {
	Contact []string    `json:"contact"`
	Status  acme.Status `json:"status"`
}
func (u *UpdateAccountRequest) Validate() error {
	switch {
	case len(u.Status) > 0 && len(u.Contact) > 0:
		return acme.NewError(acme.ErrorMalformedType, "incompatible input; contact and "+
			"status updates are mutually exclusive")
	case len(u.Contact) > 0:
		if err := validateContacts(u.Contact); err != nil {
			return err
		}
		return nil
	case len(u.Status) > 0:
		if u.Status != acme.StatusDeactivated {
			return acme.NewError(acme.ErrorMalformedType, "cannot update account "+
				"status to %s, only deactivated", u.Status)
		}
		return nil
	default:
		return nil
	}
}