Auth0 Home Blog Docs

Pre-user registration hook doesn't merge app_metadata

hooks

#1

I believe that I’ve discovered a bug in the Pre-user registration hook. Here are detailed instructions on how to reproduce the bug.

Test case

For testing purposes, I’m using this code with a Pre-user registration hook:

module.exports = function (user, context, cb) {
  var response = {};
  response.user = user || {};
  response.user.user_metadata = user.user_metadata || {};
  response.user.app_metadata  = user.app_metadata  || {};

  response.user.user_metadata["email"] = user.email;
  response.user.app_metadata["email"]  = user.email;

  cb(null, response);
};

Testing using the webtask runner

I created a Pre-user registration hook using the Dashboard. I used the integrated runner to test using this body:

{
  "user": {
    "email": "user1@foo.com",
    "user_metadata": {
      "hobby": "surfing"
    },
    "app_metadata": {
      "plan": "full"
    }
  },
  "context": {
    "connection": {}
  }
}

The response came back looking like this:

{
  "user": {
    "email": "user1@foo.com",
    "user_metadata": {
      "hobby": "surfing",
      "email": "user1@foo.com"
    },
    "app_metadata": {
      "plan": "full",
      "email": "user1@foo.com"
    }
  }
}

As expected, the email field is merged into the user_metadata and app_metadata objects, while the pre-existing hobby and plan fields are preserved.

Testing by posting to Management API

Create a basic user (no metadata specified)

Post to /users with the following data:

{
  "connection": "Username-Password-Authentication",
  "email": "demo1@example.com",
  "password": "xX1234Xx",
}

Here’s the response (abridged to show relevant fields only):

{
  "email": "demo1@example.com",
  "email_verified": false,
  "app_metadata": {
    "email": "demo1@example.com"
  },
  "user_metadata": {
    "email": "demo1@example.com"
  }
}

In this case, it appears as though the Pre-user registration hook is working correctly: The response contains both app_metadata.email and user_metadata.email fields.

Create a user with pre-existing metadata

Post to /users with the following data:

{
  "connection": "Username-Password-Authentication",
  "email": "demo2@example.com",
  "password": "xX1234Xx",
  "user_metadata": {"foo": "bar"},
  "app_metadata": {"foo": "bar"}
}

Here’s the response (abridged to show relevant fields only):

{
  "email": "demo2@example.com",
  "user_metadata": {
    "foo": "bar",
    "email": "demo2@example.com"
  },
  "email_verified": false,
  "app_metadata": {
    "foo": "bar"
  }
}

There’s something odd about this response: the app_metadata object includes the foo property, but the email property is missing. Meanwhile, the user_metadata object contains both the foo and email properties, which suggests that the Pre-user registration hook has actually fired.

I think this is a bug in the Pre-user registration hook.