During External Provider login we need to override sub claim with our internal guid from Custom Database. So currently we are doing this logic inside Rule.
- Rule notices that the user that logs by SSO first time.
- Rule creates new user according in CustomDatabase to mapping from incoming user
- The two users are linked
- context.primaryUser is set to the user_id of the new primary user. This is
important because it updates the session created to reflect the new linking
structure.
Rules and Hooks will be depreciated in November 2024 so base on Auth0 recommendation we should use Actions for this.
The problem is that inside Action we don’t have a possibility to update session created with new primaryUser context.primaryUser.
Could you please provide alternative to that Rule which we have. I will only add that we don’t want to redirect to different application/client inside that Action and do some account linking there as we don’t have control over it. We would need to have alternative to this Rule code.
function callback(user, context, callback) {
const ManagementClient = require('auth0@2.35.0').ManagementClient;
const management = new ManagementClient({
domain: auth0domain,
clientId: clientId,
clientSecret: clientSecret,
scope: 'read:users create:users',
audience: `https://${auth0domain}/api/v2/`
});
let shouldCreateLinkUserResult = shouldCreateTokenUser(context, user);
if (shouldCreateLinkUserResult) {
createLinkUser(context, user, callback);
} else {
callback(null, user, context);
}
function shouldCreateTokenUser(context, user) {
return !user.identities.some(x => x.connection === "Token") &&
context.connection !== 'Token' &&
(!user.user_metadata || !user.user_metadata.has_linked_token_user);
}
function linkUser(primaryUserId, secondaryUserId, secondaryConnectionId, provider) {
return management.linkUsers(primaryUserId, { user_id: secondaryUserId, connection_id: secondaryConnectionId, provider: provider });
}
function createAuth0User(userCreateParams) {
return management.createUser(userCreateParams);
}
function generateGUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
function createLinkUser(context, user, callback) {
console.log('Creating link user: ' + identitySearchQueryResult);
var tokenUserId = generateGUID();
var tokenProfile = {
email: user.upn,
name: user.name,
connection: 'CustomDatabase',
password: '8gzR79Kj%fdsa',
user_metadata: {
has_linked_token_user: true
}
};
tokenProfile.user_id = tokenUserId;
createAuth0User(tokenProfile).then(
function (createdProfile) {
return linkUser(createdProfile.user_id, user.user_id, context.connectionID, context.connectionStrategy).then(function () {
context.primaryUser = createdProfile.user_id;
user.identities.unshift(createdProfile);
callback(null, user, context);
}, function (err) {
console.log('Error: ' + JSON.stringify(err));
callback(err);
});
}, function (err) {
console.log('Error: ' + JSON.stringify(err));
return callback(err);
});
}
}