Skip to content

Instantly share code, notes, and snippets.

@zamd
Created May 24, 2017 13:28
Show Gist options
  • Save zamd/4015552cdbed187d1bd6b111e8b8c316 to your computer and use it in GitHub Desktop.
Save zamd/4015552cdbed187d1bd6b111e8b8c316 to your computer and use it in GitHub Desktop.
verify-linked-account
function (user, context, callback) {
var rp = require('request-promise');
var ManagementClient = require('auth0@2.0.0').ManagementClient;
var management;
var ACCOUNT_LINKING_ENABLED_CLIENTS =
[
'Wy1MwWNQlnqy9o24q6cWnl6iFnJBgSfs', //self-care mobile
'if9yMTsPw5s4jQVvbbVa1hYuMnNcFgIu' // identity registration website
];
if (ACCOUNT_LINKING_ENABLED_CLIENTS.indexOf(context.clientID) === -1 ||
user.app_metadata.linkedAccounts.filter(acc=>!acc.verified).length === 0) {
return callback(null,user,context);
}
console.log("starting rule verify-linked-accounts...");
function OwnershipValidationError(){}
function getToken() {
//console.log("context.clientMetadata.clientSecret", context.clientMetadata.clientSecret);
var clientSecret = context.clientMetadata.clientSecret;
var domain = auth0.domain;
//console.log("context.clientID", context.clientID);
return new Promise((resolve,reject)=>{
console.log(`getting token...`);
rp.post({
uri: `https://${domain}/oauth/token`,
json: {
client_id: 'if9yMTsPw5s4jQVvbbVa1hYuMnNcFgIu',
client_secret: 'iUHtN0kg0BG4XN7UenYpPvLaXCoduJTK4Vzu-1qGcIwz4FcSIgPAoUNK4xEY6kSe',
grant_type: 'client_credentials',
audience: `https://${domain}/api/v2/`,
scope: 'update:users'
}
})
.then(r=>resolve(r.access_token))
.catch(err=>reject(err));
});
}
function createManagementClient(token) {
console.log(`token`, token);
return new Promise((resolve,reject)=>{
management = new ManagementClient({
token: token,
domain: auth0.domain
});
resolve(management);
});
}
function ensurePasswordlessFormat(phone_number) {
return phone_number.startsWith("+") ? phone_number : "+" + phone_number;
}
function getPhoneNummber() {
const phone_number = context.connection==='sms' ? user.username : user.app_metadata.phone_number;
return ensurePasswordlessFormat(phone_number);
}
function findUser() {
var clientSecret = context.clientMetadata.clientSecret,
domain = auth0.domain
return new Promise((resolve,reject)=>{
var query = {
q:`app_metadata.phone_number:"${getPhoneNummber()}"`
};
console.log('finding user..');
console.log(query);
management.getUsers(query)
.then(arr=>arr.shift())
.then(user=>resolve(user))
.catch(err=>reject(err));
});
}
function updateMetadata(id, patch) {
return new Promise((resolve,reject)=>{
console.log(`updating app_metadata for ${id}...`);
console.log(patch);
management.updateUser( {id},{app_metadata:patch} )
.then(user=>resolve(user))
.catch(err=>reject(err));
});
}
function getAccountByBan(ban) {
var uri = `http://crm-rest-765300373.ap-southeast-2.elb.amazonaws.com/crm/api/v1.0/account/byban/${ban}`;
return new Promise((resolve,reject)=>{
console.log(`retrieving customer from CRM... ${uri}`);
rp(uri)
.then(json=>JSON.parse(json))
.then(account=>resolve(account.shift()))
.catch(err=>reject(err));
});
}
function validateOwnership(user, account) {
console.log(`validating ownership...`);
return new Promise((resolve,reject) => {
const metadata = user.app_metadata;
if (!user || !account || !metadata) {
console.log(`user & account are required for validation`);
return reject(new OwnershipValidationError());
}
console.log(`account`, account);
console.log(`user`, user);
if ( account.ContactFirstName === user.given_name &&
account.ContactLastName === user.family_name &&
account.ContactHomeMobile === metadata.phone_number) {
const linkedAccounts = metadata.linkedAccounts.concat([]);
linkedAccounts.find(la=>la.billingAccountNumber===account.BillingAccountNumber).verified = true;
console.log(linkedAccounts);
// return updated metadata...
resolve({userId: user.user_id, patch: {linkedAccounts} } );
}
else {
console.log('ownership validation failed...');
reject(new OwnershipValidationError());
}
});
}
/*** </HELPERS> ***/
/** RULE **/
//TODO: handle race-condition
user.app_metadata.linkedAccounts
.filter(acc=>!acc.verified)
.map(acc=>
getAccountByBan(acc.billingAccountNumber)
.then(account=> {
getToken()
.then(token=>createManagementClient(token))
.then(mgmt=>management=mgmt)
.then( _ => findUser())
.then(user=>validateOwnership(user,account))
.then(res => updateMetadata(res.userId, res.patch))
.then(updatedUser=> callback(null,updatedUser,context))
.catch(err=>{
if (err instanceof OwnershipValidationError)
callback(null,user,context);
else callback(err);
})
})
.catch(err=>callback(err))
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment