API Inviting an email from blacklisted domains returns HTTP 402 but no json

Hi folks,

I’m currently writing some simple PHP using CURL to invite users to our discourse forum from another system.

Whenever the /invites endpoint is POSTed the expected data, I get a JSON encoded response of success: OK and the expected HTTP 200 response.

Whenever I submit a email on a blacklisted domain which should get me a HTTP 422 response from the server I get nothing but the HTTP 422 response back. This is both from CURL and testing via postman.

From my testing the /invites endpoint returns 422 when an invite has already been accepted or when you’re trying to invite a user to a domain you’ve blacklisted in the email domains blacklist. I need to let the end-user know which of these it was so they know why it failed.

This is happening on the most recent commit as well as the commit we’ve been running on for a few months - I did a rebuild to be sure it wasn’t something weird.

4 Likes

Every 422 response in the invites controller I can see renders a JSON response. Can you give a small, self-contained example of how to reproduce this behaviour that we can run against a local dev instance of Discourse?

4 Likes

Yeah, I had a look at the code for the controller and saw it should be sending a response also.

Easiest way I’ve found to replicate this is to use Postman or similar and then:

  1. Set the dropdown for HTTP request to POST.
  2. Give it the URL containing your install’s FQDN or url ending in /invites (In my case, this would be https://forum.hsbne.org/invites )
  3. In the body tab, add an email address as ‘email’ that is at mailinator, which I believe is blacklisted by default?
  4. Add api_key the body tab also, containing your API key.
  5. Add api_username to the body tab so that the invite comes from a particular user.
  6. Click send.

Here’s a picture of a successful invite result via postman for me:

And the same setup but with a 422 response because the domain the email was from is blacklisted.

Had to split the post because it seems I haven’t posted here enough to put two in an image :slight_smile:

Our discourse yaml config is the standard standalone except we’ve added a couple of env variables to the docker container so that nginx-proxy and an nginx-proxy letsencrypt helper in other docker containers can work.

Sorry, final addendum but when I POST an email that already exists as a user I get a JSON formatted response correctly. So this appears to be only relating to domains that are blacklisted.

4 Likes

Assume I don’t have this Postman tool you speak of. How can I replicate this using tools that are available in or alongside a Discourse installation (such as curl)? A single curl command sounds like it should be capable of triggering this.

If you have to use curl, this should do it.

`curl -X POST -v --data "email=email@mailinator.com&api_key=apikey&api_username=system" https://forumurl/invites

The second to last line should be the body response from the server, like so.`

The above is a response to an email address that already exists, which is the expected result (json formatted errors object.)

The below is what you get with an email from a blacklisted domain (email@mailinator.com in this case):

2 Likes

OK, I can reproduce this on try using the curl command you gave. The code still doesn’t look like it should ever be flinging back a 422 with a HTML response, but I see @techAPJ is on the case, so I’m sure he’ll figure it out quickly enough.

4 Likes

The error message was getting logged but was not getting passed on as response. Fixed via:

https://github.com/discourse/discourse/commit/34996b4eff623ec874d482a019365f2fd8d2aa00

6 Likes