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:
I sign in with GitHub (github|...)
I sign out
I sign in again in with username/password (auth0|...)
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?
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.
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’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’?
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
}
}
};
Same issue encountered in my current test, confirmed with a Auth0 engineer, he replied:
Similarly, I reviewed your post login flow and I see that you tried to change the event.user to target user. I don’t think this would ever work, since Auth0 has already processed the identity that was used to log in. event.user would only persist as long as you are in the Actions webtask (container running the script).
Which means, in this scenario updating event.user won’t work.
The suggestion was to “redirect the user to another page and log them out to let them log in again”:
I double checked with my teammates and I’m not sure there is a way to avoid showing the profile of the user that just logged in. The management API call in Rules happens but Auth0 has already processed the user credentials entered. So you would have to log the user back in somehow in order to force the linked accounts to work.
Typically, our customers redirect a user out of Rules/Actions and present them with a page asking them to link accounts. So that gives the system time to process the link and when the user logs in again, their primary account is used. But I know that you guys are trying to give your users a streamlined experience so you would route the user to another login, at least for the first time their account is linked.
I do not understand how this is a viable solution, it’s literally asking thousands of customers to redo their entire authorization flow. The old rules system should not be deprecated before this is fixed, if not we need an actual warning in due time so we can start migrating to a competitor.