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.