@cocalc/server
Version:
CoCalc server functionality: functions used by either the hub and the next.js server
68 lines • 3.15 kB
JavaScript
;
/*
Some simple sign in throttling to reduce the impact of brute force
attacks. This is in memory per-backend server, and doesn't touch
the database.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.recordFail = exports.signInCheck = void 0;
const get_strategies_1 = __importDefault(require("@cocalc/server/auth/sso/get-strategies"));
const lru_cache_1 = __importDefault(require("lru-cache"));
const check_required_sso_1 = require("./sso/check-required-sso");
const emailShortCache = new lru_cache_1.default({
max: 10000,
maxAge: 1000 * 60,
});
const emailLongCache = new lru_cache_1.default({
max: 20000,
maxAge: 1000 * 60 * 60,
});
const ipShortCache = new lru_cache_1.default({ max: 10000, maxAge: 1000 * 60 });
const ipLongCache = new lru_cache_1.default({
max: 20000,
maxAge: 1000 * 60 * 60,
});
async function isExclusiveEmail(email) {
const strategies = await (0, get_strategies_1.default)();
return (0, check_required_sso_1.checkRequiredSSO)({ email, strategies });
}
async function signInCheck(email, ip, auth_token = false) {
if ((emailShortCache.get(email) ?? 0) > 5) {
// A given email address is allowed at most 5 failed login attempts per minute
return `Too many attempts per minute to sign in as "${email}". Wait one minute, then try again.`;
}
if ((emailLongCache.get(email) ?? 0) > 50) {
// A given email address is allowed at most 50 failed login attempts per hour.
return `Too many attempts per hour to sign in as "${email}". Wait about an hour, then try again.`;
}
if (ip != null && (ipShortCache.get(ip) ?? 0) > 30) {
// A given ip address is allowed at most 30 failed login attempts per minute.
return `Too many attempts per minute to sign in from your computer. Wait one minute, then try again.`;
}
if (ip != null && (ipLongCache.get(ip) ?? 0) > 200) {
// A given ip address is allowed at most 200 failed login attempts per hour.
return `Too many attempts per hour to sign in from your computer. Wait about an hour, then try again.`;
}
// unless user has an auth token, we check if the email address is part of an exclusive SSO mechanism (and block password sign ins)
if (!auth_token) {
const exclusiveSSO = await isExclusiveEmail(email);
if (exclusiveSSO != null) {
const name = exclusiveSSO.display ?? exclusiveSSO.name;
return `You have to sign in using the Single-Sign-On mechanism "${name}" of your institution.`;
}
}
}
exports.signInCheck = signInCheck;
function recordFail(email, ip) {
emailShortCache.set(email, (emailShortCache.get(email) ?? 0) + 1);
emailLongCache.set(email, (emailLongCache.get(email) ?? 0) + 1);
if (ip != null) {
ipShortCache.set(ip, (ipShortCache.get(ip) ?? 0) + 1);
ipLongCache.set(ip, (ipLongCache.get(ip) ?? 0) + 1);
}
}
exports.recordFail = recordFail;
//# sourceMappingURL=throttle.js.map