Pre-Registration Action calls api.access.deny, how to show specific message in Universal Login

Hi Auth0 team,
We have a task to block signups from a certain domain and auth0 clientID so that we can do some manual administration ourselves and invite these users after that’s done.

We achieved this with a Pre-Registration Action that blocks signup in this case.
If the conditions for block are met, we run this to return an error.

api.access.deny(`domain_blocked_except_from_api`, `Your domain required invitation so please wait while an admin invites you`);

I expected this error to be shown as-is in the universal login, but it’s not and instead a generic error is shown.

We’re sorry, something went wrong when attempting to sign up.

We expect this message to say the specific friendly_message we provided:

Your domain required invitation so please wait while an admin invites you

When I investigated our customised Universal Login html, I see that we’re registering for a custom language error message for user_exists like this:

      languageDictionary.error = {
        signUp: {
          user_exists: `The user already exists, please use another email or <a class="text-link" href="${goBackURL}">go back and sign in</a> instead.`
        }
      }

Do I have to somehow add our action error code to that same list to show a good message for this error?

Here is an example of a typical error from auth0 signup internal systems:

{
    "name": "BadRequestError",
    "code": "user_exists",
    "description": "The user already exists.",
    "statusCode": 400
}

And here is the error generated from an Action api.access.deny call:

{
    "name": "InternalExtensibilityError",
    "statusCode": 400,
    "code": "extensibility_error",
    "message": "domain_blocked_except_from_api",
    "friendly_message": "Your domain required invitation so please wait while an admin invites you",
    "description": "domain_blocked_except_from_api",
    "fromSandbox": true
}

How can I turn an api.access.deny() from an Action into a readable error in the Universal Login?

After investigating, it’s not possible right now to send a human readable error from an Action to the Lock or Universal Login.
It’s also not possible to leverage the features of Rules and Actions together, because storing data between the two in the same flow is not possible, you would need to store data in an external api.

I’m surprised by this because why were Actions designed with this function api.access.deny(reason, user_message) when the user_message is never shown to a user when using Lock?

I would love to be proven wrong by someone from Auth0.

This makes it not possible for us to migrate from Rules to Actions.

I tried setting a part of the user.app_metadata in the Action, which could then later be read by a Rule, which can return an UnauthorizedError and a nice message.
This is not possible because the user.app_metadata does not update immediately from actions, so can’t be read from rules in the same flow, read more here

The docs for Actions api.user.setUserMetadata also say this:

Note: This method should not be used in callbacks. Invoking this method won’t update the metadata immediately.

So I have to abandon my use of Actions for now until these features exist:

  • api.access.deny messages shown in Lock/Universal Login or translatable in some way from an error key, like the languageDictionary setup.
  • passing properties or storing parameters for access between actions and rules.

I discovered that if you are using New Universal Login with no custom html/js for the login page, then it will show the message from the Action api.access.deny function.

If you use Universal Login with custom html (where you are likely using Lockjs), then there is no way to access the error message and show it.

Features for Lockjs are no longer being accepted.
So there is no way to fully customise a style for your login/signup html/css, and also use errors from Actions.

Finally I did find a workaround:

If your action reports an error like this:

return api.access.deny(`something_happened`, `Something Specific Happened`);

Then in the old Lock (if you have custom html/css for your login branding), there is no way to see that specific message Something Specific Happened however you can at least detect that any action had an error, which come through as a extensibility_error type.

So in your customized html for the branding login you would have this as the languageDictionary you pass as the options to var lock = new Auth0Lock(

      languageDictionary.error = {
        signUp: {
          user_exists: `The user already exists, please use another email or <a class="text-link" href="${goBackURL}">go back and sign in</a> instead.`,
        	// All action alerts appear as extensibility_error, so if you need different errors in the future, use signup error handler below
          extensibility_error: `Your domain requires invitation so please wait while an admin invites you`
        }
      }

Now all errors in actions are caught as extensibility_error and that message is shown.

If you have more than one specific Action error, then you have to rely on raising alert for example:

    lock.on('signup error', function(error) {
      console.log(`A signup error occurred`, error);
      // In the future if we have more than one Action raising an error, this is the only way to show different errors, we have to use alerts.
      //if (error.code === 'extensibility_error' && 
      //    error.description === 'domain_blocked_except_from_api') {
      //  alert(`Your domain requires invitation so please wait while an admin invites you`);
      //}
    });

You can see all the possible events from lock here.

1 Like

Thank you @jesse2 for sharing your solution with our community! :+1:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.