Skip to content

Instantly share code, notes, and snippets.

@sandeepneerarambham
Created August 27, 2019 02:07
Show Gist options
  • Save sandeepneerarambham/8f8eee88dd9cf5a614a41ef367637f38 to your computer and use it in GitHub Desktop.
Save sandeepneerarambham/8f8eee88dd9cf5a614a41ef367637f38 to your computer and use it in GitHub Desktop.
// eslint-disable-next-line no-unused-vars
'use strict';
const async = require('async');
const request = require('request-promise');
const uuid = require('uuid');
const generateAuth0AccessToken = async (auth0ClientId, auth0ClientSecret) => {
//Generate Auth0 access token via Authentication API
let accessToken;
const payload = {
client_id: auth0ClientId,
client_secret: auth0ClientSecret,
audience: `https://${auth0Tenant}.au.auth0.com/api/v2/`,
grant_type: 'client_credentials'
};
const options = {
method: 'POST',
url: `https://${auth0Tenant}.au.auth0.com/oauth/token`,
headers: {'content-type': 'application/json'},
body: JSON.stringify(payload)
};
try {
await request(options, function (err, response, body) {
if (!err) {
if (response.statusCode == '200') {
const json = JSON.parse(body);
accessToken = json.access_token;
} else {
exitWithError(currentRunNumber, `Error generating Auth0 access token: ${response.statusCode} - ${response.statusMessage}`);
}
}
});
} catch(err) {
exitWithError(currentRunNumber, `Error generating Auth0 access token: ${err}`);
}
return accessToken;
};
async function createPasswordlessSMSProfileInAuth0(callback) {
createPayload = {
//user_id: uuid(), - this is optional
phone_number: user.phone_number,
phone_verified: true,
connection: sms,
};
createUserOptions = {
method: 'POST',
url: `https://${auth0Tenant}.au.auth0.com/api/v2/users`,
headers: {'Authorization': `Bearer ${auth0AccessToken}`, 'content-type': 'application/json'},
body: JSON.stringify(createPayload),
simple: true,
resolveWithFullResponse: true,
timeout: 20000
};
try {
await request(createUserOptions, function (err, response) {
if (!err) {
if (response.statusCode === 201) {
// Auth0 user profile creation is successful
auth0Profile = JSON.parse(response.body);
createSuccessful = true;
} else if (response.statusCode === 409) {
// Auth0 user profile creation failed because phone number already exists
existingAuth0Profile = true;
} else if (response.statusCode === 429) {
// Auth0 user profile creation failed because rate limit reached
rateLimitReached = true;
sleepTime = response.headers['x-ratelimit-reset'];
} else {
errorMessage = `Error creating Auth0 user profile for phone '${user.email}': ${response.body}`;
}
}
});
} catch (err) {
if (!errorMessage && !createSuccessful && !existingAuth0Profile && !rateLimitReached) {
errorMessage = `Error creating Auth0 user profile for phone '${user.phone_number}': ${err}`;
}
}
}
async function createProfileRetry(callback) {
// If rate limit was reached creating the user profile, try again otherwise skip processing
if (rateLimitReached) {
rateLimitReached = false;
const currentTimeInSeconds = Math.round((new Date()).getTime() / 1000);
await sleep((sleepTime - currentTimeInSeconds) * 1000);
try {
await request(createUserOptions, function (err, response) {
if (!err) {
if (response.statusCode === 201) {
// Auth0 user profile creation is successful upon retry
auth0Profile = JSON.parse(response.body);
createSuccessfulAfterRetry = true;
} else if (response.statusCode === 409) {
// Auth0 user profile creation failed upon retry because email address already exists
existingAuth0Profile = true;
} else {
errorMessage = `Error creating Auth0 user profile after retry for email '${user}': ${response.body}`;
}
}
});
} catch(err) {
if (!errorMessage && !existingAuth0Profile) {
errorMessage = `Error creating Auth0 user profile after retry for email '${user}': ${err}`;
}
}
}
}
async function createPasswordlessEmailProfileInAuth0(callback) {
createPayload = {
//user_id: uuid(), - this is optional
email: user.email,
email_verified: true,
connection: email,
};
createUserOptions = {
method: 'POST',
url: `https://${auth0Tenant}.au.auth0.com/api/v2/users`,
headers: {'Authorization': `Bearer ${auth0AccessToken}`, 'content-type': 'application/json'},
body: JSON.stringify(createPayload),
simple: true,
resolveWithFullResponse: true,
timeout: 20000
};
try {
await request(createUserOptions, function (err, response) {
if (!err) {
if (response.statusCode === 201) {
// Auth0 user profile creation is successful
auth0Profile = JSON.parse(response.body);
createSuccessful = true;
} else if (response.statusCode === 409) {
// Auth0 user profile creation failed because phone number already exists
existingAuth0Profile = true;
} else if (response.statusCode === 429) {
// Auth0 user profile creation failed because rate limit reached
rateLimitReached = true;
sleepTime = response.headers['x-ratelimit-reset'];
} else {
errorMessage = `Error creating Auth0 user profile for phone '${user.email}': ${response.body}`;
}
}
});
} catch (err) {
if (!errorMessage && !createSuccessful && !existingAuth0Profile && !rateLimitReached) {
errorMessage = `Error creating Auth0 user profile for phone '${user.phone_number}': ${err}`;
}
}
}
async function linkIdentitiesToAuth0(callback) {
// If creating profile in Auth0 was successful, link identities
// otherwise skip processing
if (createSuccessful || createSuccessfulAfterRetry) {
try {
const linkOptions = {
url: `https://${auth0Tenant}.au.auth0.com/api/v2/users/${auth0SMSProfile.user_id}/identities`,
headers: { Authorization: `Bearer ${auth0AccessToken}` },
json: {
provider: 'email',
user_id: auth0EmailProfile.user_id
},
simple: true,
resolveWithFullResponse: true,
timeout: 20000
};
const link = await linkIdentity(linkOptions, true);
} catch(err) {
result = `${result.trim()}|Error linking identity to Auth0 user profile '${user.email}' - ${err}`;
}
}
}
const linkIdentity = async (options, retry) => {
return request.post(options).then(response => {
return true;
}).catch(async function(err) {
if (err.statusCode === 429 && retry) {
// Auth0 link identity failed because rate limit reached so try again
const sleepTime = err.response.headers['x-ratelimit-reset'];
const currentTimeInSeconds = Math.round((new Date()).getTime() / 1000);
await sleep((sleepTime - currentTimeInSeconds) * 1000);
return await linkIdentity(options, false);
} else {
result = `${result.trim()}|Error linking identity to Auth0 user profile '${user.email}': '${options.json.provider}|${options.json.user_id}' - ${response.body}`;
return true;
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment