Posting this as a separate topic as the comment did not get any response.
I marked this one as critical because this will screw over a significant portion of your existing customers if you go live. This is completely necessary functionality for a authentication provider.
If this goes live, our system will break, and so will countless others. Especially those with databases that rely on emails being unique.
The problem is that it is not currently possible to replicate the behaviour of the old account linking rule with the new action system, this is because it is not possible to seamlessly switch the user to the primary account after linking has happened.
The code below should work, but it does not. It links the accounts, but the user starts his/her session with the secondary account, which at this point does not even exist. This leads to all sorts of wacky behaviour.
The extension can not replicate the necessary behaviour either, as there is no way to disable the option that lets the user proceed without linking.
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
}
}
};
I see three potential solutions:
- Don’t deprecate the rules system, at the very least push it back until this is resolved, and everyone has had enough time to migrate away after it is possible to do so (Currently there is no way out).
- Allow the account linking extension to force the users to either link accounts or abandon the signup.
- Fix the Action system so that it can replicate the behaviour of the rule system.