Skip to content

Instantly share code, notes, and snippets.

@pazel-io
Last active January 23, 2022 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pazel-io/27ba1ab177c14c172f5b2b9f4232a50e to your computer and use it in GitHub Desktop.
Save pazel-io/27ba1ab177c14c172f5b2b9f4232a50e to your computer and use it in GitHub Desktop.
Auth0 & have i been Pwned integration example
const axios = require('axios');
const HIBP_BASE_URL = 'https://haveibeenpwned.com/api/v3';
const findTheLastBreachName = async (email, apiKey) => {
const config = {
method: 'get',
url: `${HIBP_BASE_URL}/breachedaccount/${email}`,
headers: {
'hibp-api-key': apiKey,
}
};
const response = await axios(config);
return response.data[0].Name;
}
const getBreachData = async (siteName, apiKey) => {
const config = {
method: 'get',
url: `${HIBP_BASE_URL}/breach/${siteName}`,
headers: {
'hibp-api-key': apiKey,
}
};
const response = await axios(config);
return response.data;
}
const calculateRiskScore = (breachData, lastPasswordChangeDate) => {
const breachDate = new Date(breachData.BreachDate);
console.log(breachDate, lastPasswordChangeDate);
if(breachDate >= lastPasswordChangeDate){
return 'HIGH';
}
return 'LOW'
}
const sendChangePasswordEmail = async(tenantId, clientId, email) => {
const config = {
method: 'POST',
url: `https://${tenantId}.us.auth0.com/dbconnections/change_password`,
headers: {'content-type': 'application/json'},
data: {
client_id: clientId,
email: email,
connection: 'Username-Password-Authentication'
}
};
const response = await axios(config);
return response.data;
}
/**
* Handler that will be called during the execution of a PostLogin flow.
*
* @param {Event} event - Details about the user and the context in which they are logging in.
* @param {PostLoginAPI} api - Interface whose methods can be used to change the behavior of the login.
*/
exports.onExecutePostLogin = async (event, api) => {
const apiKey = event.secrets.HIBP_API_KEY;
const lastPasswordChange = event.user.last_password_reset ?? event.user.created_at;
const lastPasswordChangeDate = new Date(lastPasswordChange);
const isEnrolledForMFA = !!event.user.multifactor && event.user.multifactor.length > 0;
if(!event.user.email) {
return;
}
if(!event.user.email_verified) {
api.access.deny('Please verify your email before you can login!');
return;
}
try {
const lastBreachName = await findTheLastBreachName(event.user.email, apiKey);
const lastBreachData = await getBreachData(lastBreachName, apiKey);
const riskScore = calculateRiskScore(lastBreachData, lastPasswordChangeDate);
switch (riskScore) {
case 'HIGH':
sendChangePasswordEmail(event.tenant.id, event.client.client_id, event.user.email);
if(isEnrolledForMFA) {
api.multifactor.enable('any');
return;
}
api.access.deny('Data breach found. Change your password and try to login again');
break;
case 'LOW':
console.log('Successful login!')
break;
}
}
catch(error) {
console.log(error);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment