Updating email_verified from an action, error=change_email script does not exist

Hi,
We use our own email verification process. During an Action I would like to be able to update the auth0 users email_verified flag. I found other topics saying to use ManagementClient. I did this. The way it was coded in the post did not work. I had to added the API “audience” to the call. It now works but gets the error “ManagementApiError: change_email script does not exist”. I have search other posts but they all relate to Custom Database scripts, not actions. How do I update the email verify flag from an Action ?

This is the function within my Action-

attributeName = "email_verified";
attributeValue  = true;

try {
    const ManagementClient = require('auth0').ManagementClient;
        
    let domain = event.request.hostname;
    let client_id = event.secrets.auth0Integration_client_id;
    let client_secret = event.secrets.auth0Integration_client_secret;
    let audience = event.secrets.auth0Integration_audience;

    debugLog("Domain:" + domain);
    debugLog("Client Id:" + client_id);    
    debugLog("Client Secret:" + client_secret);

    const management = new ManagementClient({
                domain: domain,
                clientId: client_id,
                clientSecret: client_secret,
                audience: audience       
    });

    const data = { [attributeName]: attributeValue };
    const params =  { id : event.user.user_id};

    await management.users.update(params, data)

    return true;

  } catch (error) {
    console.error("Error in setUserRootAttribute:" + error);
    return false;
  }

thanks
Dave

Hi there @david.isackson ,

Thank you for sharing - to help find out where the error may come from, I would like to understand the context this function runs in :slight_smile:

The code shared is most likely a snippet of the bigger Action script, but I would like to make sure of that (?) What is the flow this function runs within?

Hi,

Thanks for the reply. Yes, this is indeed a function from within an Post-login action.

Business flow:

  1. User signs up to our external system (via Salesforce)
  2. The external system sends a confirmation email containing a hyperlink with an auth0 login URL containing a verification code.
  3. The user clicks the link in the email. During the auth0 login, we run a Post Login action.
  4. In this action, if the user is not currently email_verified (ie. they are new) and the login URL contains a query string passing a verification code, we check that verification code with an external API call to our external system to validate the code. If the code is validated we activate the user in the external system.
  5. If the user is activated in the external system, we also now want to set the email_verified from “pending” to “verified” in auth0. This is the function posted above. This call fails with the " change_email script does not exist " error. I just want to flag the user as now verified.

thanks
Dave

Hi @david.isackson ,

Thank you very much for sharing the context.

To start debugging, I reduced the complexity of the code to a minimum to see if we could update the user property email_verified = true in a Login Action.

To this end, I wrote an action script that checks if the above property holds a false value (replace with your own condition) and, if so, updates the property to true.

exports.onExecutePostLogin = async (event, api) => {
  const ManagementClient = require('auth0').ManagementClient;
  if(!event.user.email_verified) {

    var management = new ManagementClient({
      domain: event.secrets.domain,
      clientId: event.secrets.clientId,
      clientSecret: event.secrets.clientSecret,
});
  
  await management.users.update({ id: event.user.user_id }, { email_verified: true });
  
  }

};

It successfully updates the property of a new user who logs in for the first time via the Username-Password-Authentication connection.

To figure out why it may have failed in your environment, I further checked the details of the Management API endpoint responsible for updating user profiles, and I found this:

Is the connection you’re testing an Enterprise one?

Thank you Marcelina,

We use a Database connection because when the user is added to auth0 it must have previously been registered in Salesforce. In the Login script of the Custom Database, we call an API to confirm the username and password are correct in SF and then return some information. If valid, when create the user and update some metadata. The following Action called during this flow is the one that is failing.

return callback(null, {
username: username,
user_id: salesforceUserId,
email: email,
name: userFullName,
given_name: firstName,
family_name: lastName,
user_metadata: {
user_language: languageCode,
user_locale: userLocale,
user_timezone: userTimeZone,
user_ui_skin: userUiSkin,
user_country_code: countryCode,
},
app_metadata: {
user_id: userd,
user_type: userType,
is_family: isFamily,
is_terms_consent: isTermsConsent,
is_privacy_consent: isPrivacyConsent,
},

Hi @david.isackson :wave:

From the comments provided on this thread, it sounds like you’re using a Custom Database Connection in Auth0. Correct? If so, then the error you’re seeing is likely due to the fact that - whilst you’ve created the Login script in you’re Custom Database Connection definition - you haven’t created a script for Change Email; the error in the Action context is actually a side-effect as a result of the missing script in the Custom Database Connection definition.

If you don’t need to do anything outside of Auth0, then simply implement the email change script in the Custom Database Connection definition as a no-op, as in:

function (email, newEmail, verified, callback) {
    // Return `true` value in callback to signal operation succeeded
    return callback(null, true);
}

Also, if you haven’t found it already, you may find our documentation on extensibility best practices to be helpful; see here for details.

Hope this helps :sunglasses:

1 Like

Thank you Peter.

Let me try this and if it all works, I’ll mark it as the solution.

thanks
Dave