How do you convert the legacy rule called “Move user metadata attributes to profile root attributes” into an Action? The only example I could find was this, but it does not set the user profile value.
We unfortunately don’t have a pre-existing example of the same functionality in an Action, but I was able to just test this code in my own environment and it seems to be functioning as expected:
const { ManagementClient } = require('auth0');
exports.onExecutePostLogin = async (event, api) => {
const fieldMapping = {
family_name: 'family_name',
given_name: 'given_name',
name: 'name',
nickname: 'nickname',
picture: 'picture'
};
if (needMigration(event.user)) {
const management = new ManagementClient({
domain: event.secrets.domain,
clientId: event.secrets.clientID,
clientSecret: event.secrets.clientSecret,
});
try {
const updatedUser = await management.updateUser(
{ id: event.user.user_id },
generateUserPayload(event.user)
);
updateActionUser(event.user, updatedUser);
} catch (err) {
console.error(err);
throw new Error('Failed to migrate user attributes.');
}
}
function needMigration(user) {
if (user.user_metadata) {
for (const key in fieldMapping) {
if (typeof user.user_metadata[fieldMapping[key]] === 'string') {
return true;
}
}
}
return false;
}
function generateUserPayload(user) {
const payload = { user_metadata: {} };
const userMetadata = user.user_metadata;
for (const key in fieldMapping) {
generateUserPayloadField(userMetadata, payload, key, fieldMapping[key]);
}
return payload;
}
function updateActionUser(user, updatedUser) {
for (const key in fieldMapping) {
if (typeof user.user_metadata[fieldMapping[key]] === 'string') {
user[key] = updatedUser[key];
delete user.user_metadata[fieldMapping[key]];
}
}
}
function generateUserPayloadField(userMetadata, payload, rootField, metadataField) {
if (typeof userMetadata[metadataField] === 'string') {
payload[rootField] = userMetadata[metadataField];
payload.user_metadata[metadataField] = null;
}
}
};
I attempted to mirror the Rule code as closely as possible - I will note that it might be worth looking into caching the Management API access token as well:
I was unable to get this code to work, so I tried to simplify it and now I get this error message when I run the script in the editor window. What am I doing wrong?
unauthorized_client: {“error”:“unauthorized_client”,“error_description”:“Grant type ‘client_credentials’ not allowed for the client.”,“error_uri”:“Application Grant Types”}
at /data/layers/
This most likely has to do with the application you are using to instantiate the ManagementClient - This should be an M2M app and you should see “Client Credentials” enabled if you go to application settings → advanced settings → grant types.
The application also needs to be authorized by the Management API - You can do this by navigating to applications → APIs → Management API → machine to machine applications.
This is a Mobile Single Page application where I am trying to convert the rule: legacy rule called “Move user metadata attributes to profile root attributes” into an Action before it expires next year and no longer works. What is the best approach for this? I am getting nowhere coding actions.
The code I shared previously works in my own environment, so it should work in yours. Are you able to go into a bit more detail as to why exactly the code wasn’t working for you? The more details you can share the better.
Hi there, Im having a similar issue that OP has. We use the rule “Move user metadata attributes to profile root attributes” but as rules are going to be removed, we need to convert what this does into an Action.
I tried to paste in the code you provided @tyf when creating a new Action, but I got the error as seen in attached image.
How would I go about to fix this?
Would this solution increase our API quota someway?
Edit: Follow up question. Is there a better way to solve this? What I need to achieve is that i need to access custom data in app_metadata upon user login as seen in the attached image.