woocommerce / woocommerce

A customizable, open-source ecommerce platform built on WordPress. Build any commerce solution you can imagine.
https://woocommerce.com
9.31k stars 10.75k forks source link

Store API: Account creation routes #48580

Closed mikejolley closed 1 week ago

mikejolley commented 2 months ago

Issue Description:

With the planned improvements to the checkout flow, notably to support account creation, it looks like we may require some additional routes within the Store API to facilitate this functionality. Thinking ahead, as well as during checkout we will require the ability to register accounts:

This issue is to plan and document what routes/endpoints may be needed, how they will function, and what protections can be put in place to prevent abuse.

Creating users via the API today

WordPress Rest API has a create user endpoint (wp-json/wp/v2/users) but this requires auth to create new users. We can take inspiration from this but ultimately the Store API needs something more restrictive.

As for Store API, this already includes the capability to create user accounts but this is baked into the checkout route:

https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/src/StoreApi/Routes/V1/Checkout.php#L588-L592

If the request param create_account is set, a user account will be created and associated with the new order.

Depending on the designs, this may suffice for the needs of account creation, however, support needs to be added to set a custom password, and potentially a username, at the same time if auto-generation of these items is not enabled in settings.

Screenshot 2024-06-18 at 16 37 15

Tasks:

Account validation

Before an account is created we need to first check and validate if an address is already taken. The new checkout design includes inline validation notices if an address exists already:

Screenshot 2024-06-18 at 16 46 49

Validation for this exists within the /checkout route already when create_account is true, however, there is a discussion about whether or not we should validate earlier so the customer gets more immediate feedback after filling out the email fields, or indicating that they wish to create an account.

Since we also include an option to custom set the username (if enabled) the same validation would be needed for username to ensure the provided value is unique. Again, this can be done when the checkout is posted, but it may make sense to validate as soon as we can to avoid an error when the customer places their order.

Security considerations

Part of the existing registration forms and checkout designs include the use of password strength meters:

Screenshot 2024-06-18 at 16 44 24

This is not something we need to do at API level, however, we should consider whether or not we want to enforce any type of minimum strength at API level, rejecting requests that are too weak if needed.

Another security item to consider is how these endpoints could be potentially abused to discover if accounts exist on a store. While this is probably not a privacy concern (WordPress core login screen will indicate if an email address exists for example if you enter an existing email and incorrect password), we should ensure the routes are not spammed or abused in other ways.

Routes

GET wc/store/v1/account

Returns data about the currently logged in user.

POST wc/store/v1/account

Accepts email address, optional username, optional password. Creates the account and returns success or an error object. If the user is logged in already, this route should return an error.

I would suggest including some optional parameters control how this endpoint works.

@woocommerce/rubik Any feedback on the above, or notable gaps I may have missed?

mikejolley commented 1 month ago

Account routes will be needed for https://github.com/woocommerce/woocommerce/issues/50597 so we'll need to prioritise this (or something similar). Alternatively we could use a basic form POST. If thats the case, this issue can be closed.

mikejolley commented 1 week ago

I'm closing this. We've gone with a traditional form post in https://github.com/woocommerce/woocommerce/pull/50934 which works without additional routes.