"use strict";
exports.id = 3408;
exports.ids = [3408];
exports.modules = {

/***/ 403408:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ signIn),
/* harmony export */   "getAccount": () => (/* binding */ getAccount),
/* harmony export */   "signUserIn": () => (/* binding */ signUserIn)
/* harmony export */ });
/* harmony import */ var _cocalc_database_pool__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(541808);
/* harmony import */ var _cocalc_database_pool__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_cocalc_database_pool__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(820540);
/* harmony import */ var _cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _cocalc_server_auth_throttle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(796016);
/* harmony import */ var _cocalc_server_auth_throttle__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_cocalc_server_auth_throttle__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var cookies__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(770640);
/* harmony import */ var cookies__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(cookies__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var lib_api_get_params__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26438);
/* harmony import */ var password_hash__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(922687);
/* harmony import */ var password_hash__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(password_hash__WEBPACK_IMPORTED_MODULE_4__);
/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */ /*
Sign in works as follows:

1. Query the database for the account_id and password_hash
   with the given username.

2. Use the password-hash library to determine whether or
   not the given password hashes properly.  If so, create and
   set a secure remember_me http cookie confirming that the
   client is that user and tell user they are now authenticated.
   If not, send an error back.
*/ 





// import reCaptcha from "@cocalc/server/auth/recaptcha";
async function signIn(req, res) {
    let { email , password  } = (0,lib_api_get_params__WEBPACK_IMPORTED_MODULE_5__/* ["default"] */ .Z)(req);
    email = email.toLowerCase().trim();
    const check = await (0,_cocalc_server_auth_throttle__WEBPACK_IMPORTED_MODULE_2__.signInCheck)(email, req.ip);
    if (check) {
        res.json({
            error: check
        });
        return;
    }
    let account_id;
    try {
        // Don't bother checking reCaptcha for *sign in* for now, since it causes trouble
        // when large classes all sign in from one point.  Also, it's much less important
        // for sign in, than for sign up and payment.
        // await reCaptcha(req);
        account_id = await getAccount(email, password);
    } catch (err) {
        res.json({
            error: `Problem signing into account -- ${err.message}.`
        });
        (0,_cocalc_server_auth_throttle__WEBPACK_IMPORTED_MODULE_2__.recordFail)(email, req.ip);
        return;
    }
    await signUserIn(req, res, account_id);
};
async function getAccount(email_address, password) {
    const pool = _cocalc_database_pool__WEBPACK_IMPORTED_MODULE_0___default()();
    const { rows  } = await pool.query("SELECT account_id, password_hash FROM accounts WHERE email_address=$1", [
        email_address
    ]);
    if (rows.length == 0) {
        throw Error(`no account with email address '${email_address}'`);
    }
    const { account_id , password_hash  } = rows[0];
    if (!(0,password_hash__WEBPACK_IMPORTED_MODULE_4__.verify)(password, password_hash)) {
        throw Error(`password for '${email_address}' is incorrect`);
    }
    return account_id;
}
async function signUserIn(req, res, account_id) {
    let value, ttl_s;
    try {
        ({ value , ttl_s  } = await (0,_cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_1__.createRememberMeCookie)(account_id));
    } catch (err) {
        res.json({
            error: `Problem creating session cookie -- ${err.message}.`
        });
        return;
    }
    try {
        const cookies = new (cookies__WEBPACK_IMPORTED_MODULE_3___default())(req, res, {
            maxAge: ttl_s * 1000
        });
        cookies.set(_cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_1__.COOKIE_NAME, value);
    } catch (err1) {
        res.json({
            error: `Problem setting cookie -- ${err1.message}.`
        });
        return;
    }
    res.json({
        account_id
    });
}


/***/ }),

/***/ 796016:
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {


/*
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
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;
var get_strategies_1 = __importDefault(__webpack_require__(728351));
var lru_cache_1 = __importDefault(__webpack_require__(336942));
var check_required_sso_1 = __webpack_require__(234894);
var emailShortCache = new lru_cache_1.default({
    max: 10000,
    maxAge: 1000 * 60,
});
var emailLongCache = new lru_cache_1.default({
    max: 20000,
    maxAge: 1000 * 60 * 60,
});
var ipShortCache = new lru_cache_1.default({ max: 10000, maxAge: 1000 * 60 });
var ipLongCache = new lru_cache_1.default({
    max: 20000,
    maxAge: 1000 * 60 * 60,
});
function isExclusiveEmail(email) {
    return __awaiter(this, void 0, void 0, function () {
        var strategies;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, (0, get_strategies_1.default)()];
                case 1:
                    strategies = _a.sent();
                    return [2 /*return*/, (0, check_required_sso_1.checkRequiredSSO)({ email: email, strategies: strategies })];
            }
        });
    });
}
function signInCheck(email, ip, auth_token) {
    var _a, _b, _c, _d, _e;
    if (auth_token === void 0) { auth_token = false; }
    return __awaiter(this, void 0, void 0, function () {
        var exclusiveSSO, name;
        return __generator(this, function (_f) {
            switch (_f.label) {
                case 0:
                    if (((_a = emailShortCache.get(email)) !== null && _a !== void 0 ? _a : 0) > 5) {
                        // A given email address is allowed at most 5 failed login attempts per minute
                        return [2 /*return*/, "Too many attempts per minute to sign in as \"".concat(email, "\". Wait one minute, then try again.")];
                    }
                    if (((_b = emailLongCache.get(email)) !== null && _b !== void 0 ? _b : 0) > 50) {
                        // A given email address is allowed at most 50 failed login attempts per hour.
                        return [2 /*return*/, "Too many attempts per hour to sign in as \"".concat(email, "\". Wait about an hour, then try again.")];
                    }
                    if (ip != null && ((_c = ipShortCache.get(ip)) !== null && _c !== void 0 ? _c : 0) > 30) {
                        // A given ip address is allowed at most 30 failed login attempts per minute.
                        return [2 /*return*/, "Too many attempts per minute to sign in from your computer. Wait one minute, then try again."];
                    }
                    if (ip != null && ((_d = ipLongCache.get(ip)) !== null && _d !== void 0 ? _d : 0) > 200) {
                        // A given ip address is allowed at most 200 failed login attempts per hour.
                        return [2 /*return*/, "Too many attempts per hour to sign in from your computer. Wait about an hour, then try again."];
                    }
                    if (!!auth_token) return [3 /*break*/, 2];
                    return [4 /*yield*/, isExclusiveEmail(email)];
                case 1:
                    exclusiveSSO = _f.sent();
                    if (exclusiveSSO != null) {
                        name = (_e = exclusiveSSO.display) !== null && _e !== void 0 ? _e : exclusiveSSO.name;
                        return [2 /*return*/, "You have to sign in using the Single-Sign-On mechanism \"".concat(name, "\" of your institution.")];
                    }
                    _f.label = 2;
                case 2: return [2 /*return*/];
            }
        });
    });
}
exports.signInCheck = signInCheck;
function recordFail(email, ip) {
    var _a, _b, _c, _d;
    emailShortCache.set(email, ((_a = emailShortCache.get(email)) !== null && _a !== void 0 ? _a : 0) + 1);
    emailLongCache.set(email, ((_b = emailLongCache.get(email)) !== null && _b !== void 0 ? _b : 0) + 1);
    if (ip != null) {
        ipShortCache.set(ip, ((_c = ipShortCache.get(ip)) !== null && _c !== void 0 ? _c : 0) + 1);
        ipLongCache.set(ip, ((_d = ipLongCache.get(ip)) !== null && _d !== void 0 ? _d : 0) + 1);
    }
}
exports.recordFail = recordFail;
//# sourceMappingURL=throttle.js.map

/***/ })

};
;