medusajs / medusa

Building blocks for digital commerce
https://medusajs.com
MIT License
24.57k stars 2.41k forks source link

auth/customer/emailpass always return JWT even customers don't exist #8641

Closed Deroswent closed 2 weeks ago

Deroswent commented 3 weeks ago

Following the instructions of https://docs.medusajs.com/v2/api/store#authentication I send a request for a JWT token. In the body of the request I specify the user's email and password from instruction - "email": "user@example.com", "password": "supersecret".

I ALWAYS get a JWT in response to a request, even though the user “user@example.com” doesn't exist in the application at all. The customers table in the database is empty.

Additional bug: you can send not only POST but also GET request, and still get JWT token in the response. This directly contradicts the instruction.

System information

Medusa version (including plugins): 2.0.4 preview-20240817210439 Node.js version: v20.16.0 Database: Postgresql 16 Operating system: Manjaro Linux

Steps to reproduce the behavior

1) Send a valid POST request by any convenient way to /auth/customer/emailpass In the request, specify email and password data from instruction.
example:

curl -X POST 'http://localhost:9000/auth/customer/emailpass' \
-H 'Content-Type: application/json' \
--data-raw '{
  "email": "user@example.com",
  "password": "supersecret"
}'

2) You will get a JWT token in return, even if your application has no consumers at all, you will still get a JWT token. This is a critical error. It looks like “user@example.com” is some kind of "superuser"

3) Send a GET request any way you like with authorization data from instruction. You will still receive a JWT token. An additional bug is that the API endpoint /auth/customer/emailpass should not accept GET requests according to the documentation.

example:

curl -X GET 'http://localhost:9000/auth/customer/emailpass' \                                                                                                                                                   
-H 'Content-Type: application/json' \
--data-raw '{
  "email": "user@example.com",
  "password": "supersecret"
}'

Expected behavior

It is expected that if we pass incorrect authorization data in the request, we will get an error in the response instead of the JWT token.

Additionally, it is expected that the /auth/customer/emailpass endpoint API will not accept GET requests and will return an error in response to all GET requests.

Screenshots

2024-08-18_00-40

Deroswent commented 3 weeks ago

Another bug with the same auth/customer/emailpass route:

If in a request to auth/customer/emailpass send correct authorization credentials for the administrator, not the consumer - the request will return a JWT token, even though this route is for consumers, not administrators.

The route /auth/user/emailpass is used for authorization of administrators.

Moreover, using this JWT (which you got from auth/customer/emailpass but using admin credentials) - you can successfully create a session by sending a request to /auth/session. But with empty app_metatada value in DB (table auth_identity).

2024-08-19_06-45

Expected behavior: When sending a request with admin credentials to auth/customer/emailpass - get 401 Unauthorized in response.

sradevski commented 3 weeks ago

Hey all, we currently have a bit unexpected behavior, where if an auth identity doesn't exist we try to create it, even if you go through the login page. We will be cleaning the UX around this very soon.

One thing to note, an auth identity (eg. identified through your email) can be both an admin and a customer, which is why you are allowed to call both /customer/ and /user/ routes.

Also, if an auth identity doesn't have any app metadata, it means it is not acting neither as user, nor as a customer, so you can't really perform any authenticated actions. This won't result in unauthorized access, even though it might seem like it at first sight.

olivermrbl commented 2 weeks ago

The auth APIs changed in #8683. See PR description.