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.