Account linking through Actions

Hi,

lately I’ve been struggling with simple email account linking. I’ve tried the “Account Linking Extension”, but it turned out not to be an option for my use case, because it requires the user to manually confirm the linking though the UI.

Then I tried to use actions (specifically the “Post login” flow) and it indeed links accounts with the same email addresses, but then it returns the original user id.

For example:

  1. I sign in with GitHub (github|...)
  2. I sign out
  3. I sign in again in with username/password (auth0|...)
  4. Action correctly links the profile, but it returns the original username/password identity (auth0|...). I’d expect to receive the primary user id (github|...)

To link accounts I used the /link endpoint in the Management API v2.

Is there a way how to return the primary user id after account linking?

2 Likes

Hello,
It is important to set the event.user object to the primary user after the accounts have been linked in the action. Doing this should return the github user_id as a sub claim in the id_token/access token you receive to your application.

Below is a similar post that could be helpful.

Let us know how it goes!

1 Like

Hi Praveen, thank you for your reply :slight_smile:

I’ve tried this before, but now I tried it again just in case I was doing something wrong. Unfortunately it seems that neither assigning to the event.user or returning it has any effect whatsoever.

I think this was possible before, but now it seems it’s not possible (at least according to your docs):

I’ll share the full code of the action just in case I’m doing something wrong:

Thank you.

Hi there.

This does not seem to be working.

I set event.user=murgedUser however, the access token still contains the original users data :frowning:

I’m not sure if I’'m reading this correctly, but I assume this means, that it is no longer possible to edit the access token without the use of api.command or am I missing something?

Hi Praveen,

I’m having the same problem and have tried set the event.user. But this does not seem to be working.
Is there an official way to link accounts in ‘Post Login’?

Below is my full code of the action
Example

Best regards,

Hey @praveen.addepally!

Would you be able to follow-up on that?

I’ve the same problem. Has someone found a solution for this problem already?

thx

Thanks for sharing very helpful and informative for my Walgreenslistens.

Hi @konrad.sopala, can you follow this? I have been stuck on this problem for a while but no solution yet

I have a similar use case that the one explained in this thread and in this one.

I’ve been struggling to plan a working solution for the automatic linking of accounts matching their emails. I’ve read all across the docs that this isn’t supported by any consolidated auth0 solutions but I still don’t get why.

Our platforms are for internal use so all users will use our enterprise email addresses and I still can’t think of any worst-case scenario where automatically linking accounts by email can be a risk in any way possible. Sadly we can’t easily integrate this because the account linking extension doesn’t support passwordless connections.

We were very excited when we discovered that action flows might be useful, but when reading the docs it seems that Account Linking isn’t supported!

I guess I’ll try to create a serverless function somewhere that hit the management API to link accounts when necessary, triggered by the post-login trigger, as briefly described here.

Anybody know if this would work? Any alternatives?

The fact that you cannot log the user in as his/her actual account after linking it makes it impossible for us to migrate from rules to actions, is fixing this on the roadmap, or are you going to revert the deprecated state of rules?

For anyone else currently panicking about rules being deprecated, hold off on trying to migrate until this is resolved. The implementation below works, except the user is still being logged in as the account linked into the actual account. e.g. setting event.user or returning the new user is not working.

We ended up rolling back to using the old rules system for now.

exports.onExecutePostLogin = async (event, api) => {
  
	const ManagementClient = require("auth0").ManagementClient;
  const DOMAIN = event.secrets.DOMAIN;
	const CLIENT_ID = event.secrets.CLIENT_ID;
	const CLIENT_SECRET = event.secrets.CLIENT_SECRET;

	const management = new ManagementClient({
		domain: DOMAIN,
		clientId: CLIENT_ID,
		clientSecret: CLIENT_SECRET
	});

	let currentAccount = event.user;

  let accounts = await management.getUsersByEmail(currentAccount.email);
  
  if (accounts.length > 2) {
    api.access.deny("[!] Rule: Multiple user profiles already exist - cannot select base profile to link with");
    return;
  } else if (accounts.length === 0) {
    api.access.deny("Unable to login, please contact support if this problem persists");
    return;
  } else if (accounts.length === 2) {
    
    const sorted = accounts.sort((a,b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
    const originalUser = sorted[0];
    const newUser = sorted[1];

    // logging back in with original user, confirm
    if (currentAccount.user_id === originalUser.user_id) {
      return;
    }

    // one profile exists, new one is not yet verified
    if (!originalUser.email_verified || !newUser.email_verified) {
      api.access.deny("Please verify your email before logging in.");
      return;
    }

    const provider = newUser.identities[0].provider;
    const providerUserId = newUser.identities[0].user_id;

    originalUser.identities = await management.linkUsers(originalUser.user_id, {
      provider: provider,
      user_id: providerUserId
    });

    event.user = originalUser;
    
    return {
      user: originalUser
    }
  }
};
1 Like