in packages/fxa-customs-server/lib/server.js [255:367]
async function checkRecords({
ipRecord,
reputation,
emailRecord,
ipEmailRecord,
smsRecord,
}) {
if (ipRecord.isBlocked() || ipRecord.isDisabled()) {
// a blocked ip should just be ignored completely
// it's malicious, it shouldn't penalize emails or allow
// (most) escape hatches. just abort!
return {
block: true,
retryAfter: ipRecord.retryAfter(),
};
}
// Check each record type to see if a retryAfter has been set
const wantsUnblock = payload.unblockCode;
const blockEmail = emailRecord.update(action, !!wantsUnblock);
let blockIpEmail = ipEmailRecord.update(action);
const blockIp = ipRecord.update(action, email);
let blockSMS = 0;
if (smsRecord) {
blockSMS = smsRecord.update(action);
}
if (blockIpEmail && ipEmailRecord.unblockIfReset(emailRecord.pr)) {
blockIpEmail = 0;
}
let retryAfter = [blockEmail, blockIpEmail, blockIp, blockSMS].reduce(
max
);
let block = retryAfter > 0;
let suspect = false;
let blockReason = null;
if (block) {
blockReason = blockReasons.OTHER;
}
if (
requestChecks.treatEveryoneWithSuspicion ||
reputationService.isSuspectBelow(reputation) ||
ipRecord.isSuspected() ||
emailRecord.isSuspected()
) {
suspect = true;
}
if (!block && action === 'accountLogin') {
// All login requests should include a valid flowId.
if (!payload.metricsContext || !payload.metricsContext.flowId) {
// Unless they're legacy user-agents that we know will not include it.
var isExemptUA = false;
var userAgent = headers['user-agent'];
isExemptUA = requestChecks.flowIdExemptUserAgentCompiledREs.some(
function (re) {
return re.test(userAgent);
}
);
// Or unless it's for non-signin-related reasons, e.g. changing password.
// We know these requests will not include it.
var isExemptRequest = false;
if (payload.reason && payload.reason !== 'signin') {
isExemptRequest = true;
}
if (!isExemptUA && !isExemptRequest) {
// By default we just treat a missing flowId as suspicious,
// but config can change this to a hard block.
suspect = true;
if (requestChecks.flowIdRequiredOnLogin) {
block = true;
}
}
}
}
const canUnblock = emailRecord.canUnblock();
// IP's that are in blocklist should be blocked
// and not return a retryAfter because it is not known
// when they would be removed from blocklist
if (config.ipBlocklist.enable && blockListManager.contains(ip)) {
block = true;
blockReason = blockReasons.IP_IN_BLOCKLIST;
retryAfter = 0;
}
if (reputationService.isBlockBelow(reputation)) {
block = true;
retryAfter = ipRecord.retryAfter();
blockReason = blockReasons.IP_BAD_REPUTATION;
}
// smsRecord is optional, trying to save an undefined record results in an error
const recordsToSave = [
ipRecord,
emailRecord,
ipEmailRecord,
smsRecord,
].filter((record) => !!record);
await setRecords(...recordsToSave);
return {
block,
blockReason,
retryAfter,
unblock: canUnblock,
suspect,
};
}