Custom DB login script, setting an array in the user metadata

Ready to post? :mag: First, try searching for your answer.
Hi all,
I’m trying to set an array of strings on the user metadata in the custom database login script but for some reason, it throws a validation error.

I simplified the code to the following:

let profile = {
    name: profileData.name,
    username: profileData.preferred_username,
    email: profileData.email,
    email_verified: true,
    user_id: `onelogin|${profileData.sub}`,
    user_metadata: {
        oneLoginGroups: ['1','2' ],
    },
};
callback(null, profile);

But I get:

DB Custom script (login): invalid fields. Errors: The field “oneLoginGroups” contains an invalid type, expected any of string, int, float, boolean, array, object.

Using an array of numbers instead of strings, seems to work but it’s not useful for me.

Any idea what the problem is?

Thanks!

1 Like

:wave: @andrei.tatar; welcome to the community :sunglasses:

As user_metadata is essentially a JSON object, have you tried using " instead of ' as the string delimiters in the array? :smiley:

Hope this helps

1 Like

@peter.fernandez I did. But the script is just javascript so single quote and double quote should be the same.
In fact in my original code, it’s just:

user_metadata: {
    oneLoginGroups: profileData.groups,
},

since the profileData.groups is already an array of strings.

But I tried explicitly creating an array of strings and it still fails.

Thanks for the update @andrei.tatar :sunglasses:

@peter.fernandez I did. But the script is just javascript so single quote and double quote should be the same.

Whilst the Custom DB Login Script is javascript, user_metadata is interpreted by Auth0 as a JSON object. For example, if I go into the Auth0 Dashboard and manually update the user_metadata for a user, I could enter something like the following which will work:

  "followup_contact": [
    "Yes, I am happy for you to contact me",
    "No, please do not contact me"
  ]

But if I replace the " delimiters in the array with ' it fails.

But I tried explicitly creating an array of strings and it still fails.

So, just to confirm, if you explicitly create an array of strings using " as the string delimiters, it still fails? Correct?

Yes, it still fails. Unfortunately I can’t paste the screenshot, but this:

function login(email, password, callback) {

    // load the profile data here

    const profile = {
        name: profileData.name,
        username: profileData.preferred_username,
        email: profileData.email,
        email_verified: true,
        user_id: `onelogin|${profileData.sub}`,
        app_metadata: {
            oneloginGroups: [
                "group-1",
                "group-2",
            ]
        },
    };

    callback(null, profile);
}

results in:

DB Custom script (login): invalid fields. Errors: The field “oneloginGroups” contains an invalid type, expected any of string, int, float, boolean, array, object.

:thinking: And when using "oneloginGroups" - i.e. putting the declarator in "'s as well - that fails too?

By the way, I noticed you swapped between user_metadata and app_metadata. FYI if the information you’re going to store in the user profile should not be editable by the user themselves then prefer to user app_metadata rather that user_metadata :sunglasses:

Haha, great observation. Indeed why I also switched to app_metadata :sunglasses:

1 Like

same error:

DB Custom script (login): invalid fields. Errors: The field “oneloginGroups” contains an invalid type, expected any of string, int, float, boolean, array, object.

for

"oneloginGroups": [
  "group-1",
  "group-2",
],

:thinking: Puzzling! I just tried the following in my login script , and it works fine for me (using your original user_metadata):

            return callback(null, {
              username: user.name,
              user_id: 'Hipster|' + user.identifier.toString(),
              email_verified: (user.verified) ? true : false,
              email: user.email,
              user_metadata: {
                "test":["a", "b", "c"]
              }
            });

One thing I did spot in your implementation is the trailing , in your array. With user_metadata and app_metadata being JSON objects, a trailing , would cause an error as that is not a syntax supported by the JSON protocol.

I simplified and hardcoded the entire function to:

function login(email, password, callback) {
    callback(null, {
        user_id: 'Hipster|' + email,
        email_verified: true,
        email: email,
        app_metadata: {
          "test": ["a", "b", "c"]
      }
    });
}

and I get the exact same error:

DB Custom script (login): invalid fields. Errors: The field “test” contains an invalid type, expected any of string, int, float, boolean, array, object.

I don’t think it should matter, as the script is javascript. In fact, the end goal is to specify the property from a different object. Eg:

callback(null, {
  ...
  app_metadata: {
    groups: profileData.groups
  }
});

:thinking: Where do you see that error message exactly?

    user_id: 'Hipster|' + email,

For testing. I’d avoid using the email address here as it contains characters that will be problematic as part of the user identifier. Perhaps just go with something like Hipster|1 for the moment.

Ok, I switched to the following, but same error.

function login(email, password, callback) {
    callback(null, {
        user_id: 'Hipster|1',
        email_verified: true,
        email: email,
        app_metadata: {
          "test": ["a", "b", "c"]
      }
    });
}

I get the error when I do Save and Try, enter email/pass and I get a popup with the error message:

DB Custom script (login): invalid fields. Errors: The field “test” contains an invalid type, expected any of string, int, float, boolean, array, object.

I can also see it if I click try connection, enter email/pass, click login, the go to Auth0 dashboard/monitoring/logs and I can see an entry with these raw details:

{
  "client_id": "fGoGdscpXYLojpSWzPBYVA2JCUaletQ0",
  "client_name": "All Applications",
  "connection": "ad-migration",
  "connection_id": "con_sUmslxDzRGbHYnwg",
  "date": "2024-07-05T12:33:33.019Z",
  "description": "DB Custom script (login): invalid fields. Errors: The field \"test\" contains an invalid type, expected any of string, int, float, boolean, array, object.",
  "details": {
    "error": {
      "message": "DB Custom script (login): invalid fields. Errors: The field \"test\" contains an invalid type, expected any of string, int, float, boolean, array, object."
    }
  },
  "ip": "-",
  "strategy": "auth0",
  "strategy_type": "database",
  "type": "f",
  "user_agent": "Edge 126.0.0 / Windows 10.0.0",
  "user_id": "",
  "user_name": "asd@asd.com",
  "log_id": "90020240705123333201480000000000000001223372041951576689",
  "tenant_name": "-",
  "_id": "90020240705123333201480000000000000001223372041951576689",
  "isMobile": false,
  "id": "90020240705123333201480000000000000001223372041951576689"
}

and the same error in context data:

{
  "error": {
    "message": "DB Custom script (login): invalid fields. Errors: The field \"test\" contains an invalid type, expected any of string, int, float, boolean, array, object."
  }
}

:thinking: That’s really strange. Attached is a screenshot of the exact same script being executed using Save And Try in an Auth0 environment that I have. When did you create your Auth0 Tenant?

Unfortunately, I am not be able to answer this. It wasn’t created by me.
Would the date make a difference?

Would the date make a difference?

It shouldn’t, but I’m just trying to work out what might be different here.

Unfortunately, I am not be able to answer this. It wasn’t created by me.

:thinking: Do you have another tenant you can try with?

Alternatively, I would suggest opening a ticket with Auth0 support. If you do, provide as much information as you can, and also link to the conversation in this thread. It sounds like there is definitely something unusual going on here :thinking:

Tried on a different tenant as well. I’ll try contacting support.

1 Like

Good luck @andrei.tatar, and if you get the chance to post your findings back here I’d be very interested in hearing what they discover :sunglasses:

1 Like

For anyone interested, got the following response from the Support team. I can confirm the workaround works for me.

Hello Andrei,

Our Engineering team has confirmed that there is an issue with newer database connections that cause this error, they have created a backlog item to address this.

In the meantime, there is a workaround you can use:

  1. Make a GET request to the connection

https://<tenant_domain>api/v2/connections/<connection_id>

  1. Cope the options object retrieved and remove the property called attributes
  2. Make a PATCH to the same connection using the new options object
  3. Refresh the dashboard and test again

Let me know how that goes,

Thank you!

2 Likes