Skip to content

Instantly share code, notes, and snippets.

@mford22392
Created February 5, 2020 00:36
Show Gist options
  • Save mford22392/4221c5d4ccb2fe1521f52f542acdb45d to your computer and use it in GitHub Desktop.
Save mford22392/4221c5d4ccb2fe1521f52f542acdb45d to your computer and use it in GitHub Desktop.
disney brainstorm
// eslint-disable-next-line no-unused-vars
function linkAccountsByDisneyIdAndMergeMetadata(user, context, callback) {
var request = require('[email protected]');
var async = require('[email protected]');
// This url is: https://<tenant>.auth0.com/api/v2/users
var userApiUrl = auth0.baseUrl + '/users';
// Only run this for DisneySAML users coming through the flow for the first time
// If merging is successful, identities.length will be 2+ the next time through
if (context.connection === 'DisneySAML' && user.identities.length === 1) {
request(
{
url: userApiUrl,
headers: {
Authorization: 'Bearer ' + auth0.accessToken
},
qs: {
search_engine: 'v3',
q: 'app_metadata.employee_id:"' + user.employee_id + '"'
}
},
function (err, response, body) {
if (err) return callback(err);
if (response.statusCode !== 200) return callback(new Error(body));
var data = JSON.parse(body);
// data here is an array of results from the above query
if (data.length > 0) {
async.each(
data,
function (targetUser, cb) {
// targetUser = original Oauth2 user (oauth2|Disney|abc123)
// user = incoming SAML user (samlp|DisneySAML|abc123)
var aryTmp = targetUser.user_id.split('|');
var provider = aryTmp[0];
var connection = aryTmp[1];
// Because the above query returns *every* user with that employee_id, we must filter to make sure we are only acting on the true original user
if (provider === 'oauth2' && connection === 'Disney') {
// capture existing user's app_ and user_metadata
const appMetadata = targetUser.app_metadata || {};
const userMetadata = targetUser.user_metadata || {};
// Then, update incoming user with the metadata captured above
auth0.users
.updateAppMetadata(user.user_id, appMetadata)
.then(
auth0.users.updateUserMetadata(
user.user_id,
userMetadata
)
)
.then(function () {
request.post(
{
url: userApiUrl + '/' + encodeURIComponent(user.user_id) + '/identities',
headers: {
Authorization: 'Bearer ' + auth0.accessToken
},
json: { provider: provider, user_id: targetUser.user_id }
},
function (err, response) {
if (response && response.statusCode >= 400) {
return cb(
new Error(
'Error linking account: ' + response.statusMessage + response.url
)
);
}
cb(err);
}
);
})
.catch(function (err) {
cb(err);
});
} else {
// You will hit this else when you get to the incoming user while looping over the results from the query
// QUESTION: In this case, do we want to return cb()?
// Also, should we filter the results by provider before looping over them?
cb()
}
},
function (err) {
callback(err, user, context);
}
);
} else {
// You will hit this else when *no* users are returned from the query. I.e. this is a new SAML user without a corresponding Oauth2 account
callback(null, user, context);
}
}
);
} else {
// You will hit this else when the connection is not DisneySAML OR if the incoming user already has attached identities (meaning it is not the first time through this flow)
callback(null, user, context);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment