in packages/fxa-auth-server/lib/routes/utils/signin.js [124:232]
async checkCustomsAndLoadAccount(request, email, checkAuthenticatedUid) {
let accountRecord, originalError;
let didSigninUnblock = false;
try {
try {
// For testing purposes, some email addresses are forced
// to go through signin unblock on every login attempt.
const forced =
config.signinUnblock && config.signinUnblock.forcedEmailAddresses;
if (forced && forced.test(email)) {
throw error.requestBlocked(true);
}
if (checkAuthenticatedUid) {
await customs.checkAuthenticated(
request,
checkAuthenticatedUid,
'accountLogin'
);
} else {
await customs.check(request, email, 'accountLogin');
}
} catch (e) {
originalError = e;
// Non-customs-related errors get thrown straight back to the caller.
if (
e.errno !== error.ERRNO.REQUEST_BLOCKED &&
e.errno !== error.ERRNO.THROTTLED
) {
throw e;
}
await request.emitMetricsEvent('account.login.blocked');
// If this customs error cannot be bypassed with email confirmation,
// throw it straight back to the caller.
const verificationMethod = e.output.payload.verificationMethod;
if (
verificationMethod !== 'email-captcha' ||
!request.payload.unblockCode
) {
throw e;
}
// Check for a valid unblockCode, to allow the request to proceed.
// This requires that we load the accountRecord to learn the uid.
const unblockCode = request.payload.unblockCode.toUpperCase();
accountRecord = await db.accountRecord(email);
try {
const code = await db.consumeUnblockCode(
accountRecord.uid,
unblockCode
);
if (Date.now() - code.createdAt > unblockCodeLifetime) {
log.info('Account.login.unblockCode.expired', {
uid: accountRecord.uid,
});
throw error.invalidUnblockCode();
}
didSigninUnblock = true;
await request.emitMetricsEvent(
'account.login.confirmedUnblockCode'
);
} catch (e) {
if (e.errno !== error.ERRNO.INVALID_UNBLOCK_CODE) {
throw e;
}
await request.emitMetricsEvent('account.login.invalidUnblockCode');
throw e;
}
}
// If we didn't load it above while checking unblock codes,
// it's now safe to load the account record from the db.
if (!accountRecord) {
// If `originalLoginEmail` is specified, we need to fetch the account record tied
// to that email. In the case where a user has changed their primary email, the `email`
// value here is really the value used to hash the password and has no guarantee to
// belong to the user.
if (request.payload.originalLoginEmail) {
accountRecord = await db.accountRecord(
request.payload.originalLoginEmail
);
} else {
accountRecord = await db.accountRecord(email);
}
}
return { accountRecord, didSigninUnblock };
} catch (e) {
// Some errors need to be flagged with customs.
if (
e.errno === error.ERRNO.INVALID_UNBLOCK_CODE ||
e.errno === error.ERRNO.ACCOUNT_UNKNOWN
) {
customs.flag(request.app.clientAddress, {
email: email,
errno: e.errno,
});
}
// For any error other than INVALID_UNBLOCK_CODE, hide it behind the original customs error.
// This prevents us from accidentally leaking additional info to a caller that's been
// blocked, including e.g. whether or not the target account exists.
if (originalError && e.errno !== error.ERRNO.INVALID_UNBLOCK_CODE) {
throw originalError;
}
throw e;
}
},