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

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

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "Z": () => (/* binding */ getAccountId),
/* harmony export */   "e": () => (/* binding */ getRememberMeHash)
/* 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_hash__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(578772);
/* harmony import */ var _cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(820540);
/* harmony import */ var _cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_cocalc_server_auth_remember_me__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 _cocalc_server_auth_api__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(912203);
/* harmony import */ var _cocalc_server_auth_api__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_cocalc_server_auth_api__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
 */ 




// Return account_id if they are signed in.
// If not, returns undefined.
// This is determined by looking in their cookie and checking
// who it identifies in the database.
async function getAccountId(req, noCache = false) {
    if (req == null) return;
    // caching a bit --  We thus want the query below to happen rarely.  We also
    // get expire field as well (since it is usually there) so that the result isn't empty
    // (hence not cached) when a cookie has expired.
    const hash = getRememberMeHash(req);
    if (!hash) {
        // not signed in via a cookie.
        // What about an api key?
        if (req.header("Authorization")) {
            try {
                return await (0,_cocalc_server_auth_api__WEBPACK_IMPORTED_MODULE_4__.getAccountIdFromApiKey)(req);
            } catch (_err) {
                // non-fatal, at least for now...
                return;
            }
        }
        return;
    }
    const pool = _cocalc_database_pool__WEBPACK_IMPORTED_MODULE_0___default()(noCache ? "short" : undefined);
    // important to use CHAR(127) instead of TEXT for 100x performance gain.
    const result = await pool.query("SELECT account_id, expire FROM remember_me WHERE hash = $1::CHAR(127)", [
        hash
    ]);
    if (result.rows.length == 0) {
        return;
    }
    const { account_id , expire  } = result.rows[0];
    if (expire <= new Date()) {
        // expired
        return;
    }
    return account_id;
};
function getRememberMeHash(req) {
    const cookies = new (cookies__WEBPACK_IMPORTED_MODULE_3___default())(req);
    const rememberMe = cookies.get(_cocalc_server_auth_remember_me__WEBPACK_IMPORTED_MODULE_2__.COOKIE_NAME);
    if (!rememberMe) {
        return;
    }
    const x = rememberMe.split("$");
    if (x.length !== 4) {
        throw Error("badly formatted remember_me cookie");
    }
    return (0,_cocalc_server_auth_hash__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(x[0], x[1], parseInt(x[2]), x[3]).slice(0, 127);
}


/***/ }),

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


/*
User management of the v1 API key associated to an account.
This supports three actions:

- get: get the existing key associated to an account; return undefined if there is no api key set.
- delete: delete the existing key associated to an account
- regenerate: delete the existing key and replace it by a new random key.

If the user has a password, then it must be provided and be correct. If they have no password,
then the provided one is ignored.
*/
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.getAccountWithApiKey = void 0;
var pool_1 = __importDefault(__webpack_require__(541808));
var misc_1 = __webpack_require__(854006);
var is_password_correct_1 = __importDefault(__webpack_require__(956897));
var has_password_1 = __importDefault(__webpack_require__(999591));
var random_key_1 = __webpack_require__(630900);
function manage(_a) {
    var account_id = _a.account_id, password = _a.password, action = _a.action;
    return __awaiter(this, void 0, void 0, function () {
        var pool, _b, rows, api_key;
        return __generator(this, function (_c) {
            switch (_c.label) {
                case 0:
                    if (!misc_1.isValidUUID) {
                        throw Error("account_id is not a valid uuid");
                    }
                    return [4 /*yield*/, (0, has_password_1.default)(account_id)];
                case 1:
                    if (!_c.sent()) return [3 /*break*/, 3];
                    if (!password) {
                        throw Error("password must be provided");
                    }
                    return [4 /*yield*/, (0, is_password_correct_1.default)({ account_id: account_id, password: password })];
                case 2:
                    // verify password is correct
                    if (!(_c.sent())) {
                        throw Error("invalid password");
                    }
                    _c.label = 3;
                case 3:
                    pool = (0, pool_1.default)();
                    _b = action;
                    switch (_b) {
                        case "get": return [3 /*break*/, 4];
                        case "delete": return [3 /*break*/, 6];
                        case "regenerate": return [3 /*break*/, 8];
                    }
                    return [3 /*break*/, 10];
                case 4: return [4 /*yield*/, pool.query("SELECT api_key FROM accounts WHERE account_id=$1::UUID", [account_id])];
                case 5:
                    rows = (_c.sent()).rows;
                    if (rows.length == 0) {
                        throw Error("no such account");
                    }
                    return [2 /*return*/, rows[0].api_key];
                case 6: return [4 /*yield*/, pool.query("UPDATE accounts SET api_key=NULL WHERE account_id=$1::UUID", [account_id])];
                case 7:
                    _c.sent();
                    return [2 /*return*/];
                case 8:
                    api_key = "sk_".concat((0, random_key_1.generate)());
                    return [4 /*yield*/, pool.query("UPDATE accounts SET api_key=$1 WHERE account_id=$2::UUID", [api_key, account_id])];
                case 9:
                    _c.sent();
                    return [2 /*return*/, api_key];
                case 10: throw Error("unknown action=\"".concat(action, "\""));
            }
        });
    });
}
exports["default"] = manage;
/* Get the account that has the given api key, or returns undefined if there
is no such account. */
function getAccountWithApiKey(api_key) {
    var _a;
    return __awaiter(this, void 0, void 0, function () {
        var pool, rows;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    pool = (0, pool_1.default)("medium");
                    return [4 /*yield*/, pool.query("SELECT account_id FROM accounts WHERE api_key = $1::TEXT", [api_key])];
                case 1:
                    rows = (_b.sent()).rows;
                    return [2 /*return*/, (_a = rows[0]) === null || _a === void 0 ? void 0 : _a.account_id];
            }
        });
    });
}
exports.getAccountWithApiKey = getAccountWithApiKey;
//# sourceMappingURL=manage.js.map

/***/ }),

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


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 __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getAccountIdFromApiKey = exports.getApiKey = void 0;
var misc_1 = __webpack_require__(854006);
var manage_1 = __webpack_require__(259972);
function getApiKey(req) {
    var h = req.header("Authorization");
    if (h == null) {
        throw Error("You must provide authentication via an API key.");
    }
    var _a = __read((0, misc_1.split)(h), 2), type = _a[0], user = _a[1];
    switch (type) {
        case "Bearer":
            return user;
        case "Basic":
            return Buffer.from(user, "base64").toString().split(":")[0];
    }
    throw Error("Unknown authorization type '".concat(type, "'"));
}
exports.getApiKey = getApiKey;
function getAccountIdFromApiKey(req) {
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, (0, manage_1.getAccountWithApiKey)(getApiKey(req))];
                case 1: return [2 /*return*/, _a.sent()];
            }
        });
    });
}
exports.getAccountIdFromApiKey = getAccountIdFromApiKey;
//# sourceMappingURL=api.js.map

/***/ }),

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


/*
If the account with given id does not exist, throw an error.

Return true if the account with given id exists and has a password set.

Otherwise, return false... since auth is only doing via a passport.
*/
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 }));
var pool_1 = __importDefault(__webpack_require__(541808));
function hasPassword(account_id) {
    return __awaiter(this, void 0, void 0, function () {
        var pool, rows;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    pool = (0, pool_1.default)("short");
                    return [4 /*yield*/, pool.query("SELECT password_hash FROM accounts WHERE account_id=$1::UUID", [account_id])];
                case 1:
                    rows = (_a.sent()).rows;
                    if (rows.length == 0) {
                        throw Error("no such account");
                    }
                    return [2 /*return*/, !!rows[0].password_hash];
            }
        });
    });
}
exports["default"] = hasPassword;
//# sourceMappingURL=has-password.js.map

/***/ }),

/***/ 578772:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

var __webpack_unused_export__;

__webpack_unused_export__ = ({ value: true });
var crypto_1 = __webpack_require__(706113);
// This function is private and burried inside the password-hash
// library.  To avoid having to fork/modify that library, we've just
// copied it here.  We need it for remember_me cookies.
function hash(algorithm, salt, iterations, password) {
    // there are cases where createHmac throws an error, because "salt" is undefined
    if (algorithm == null || salt == null) {
        throw new Error("undefined arguments: algorithm='".concat(algorithm, "' salt='").concat(salt, "'"));
    }
    iterations = iterations || 1;
    if (!isFinite(iterations) || iterations > 10000) {
        // If somebody could make their own cookie, they might set the number of iterations
        // to be very large and hang the server.
        throw Error("number of iterations invalid or too large");
    }
    var hash = password;
    for (var i = 1, end = iterations, asc = 1 <= end; asc ? i <= end : i >= end; asc ? i++ : i--) {
        hash = (0, crypto_1.createHmac)(algorithm, salt).update(hash).digest("hex");
    }
    return algorithm + "$" + salt + "$" + iterations + "$" + hash;
}
exports.Z = hash;
//# sourceMappingURL=hash.js.map

/***/ }),

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


/*
Returns true if the account with given id exists and the password
is correct for the account.  Returns false in all other cases.

NOTE: Of course some accounts don't even have a password, in which
case this will always return false.
*/
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 }));
var pool_1 = __importDefault(__webpack_require__(541808));
var password_hash_1 = __webpack_require__(987909);
function isPasswordCorrect(_a) {
    var account_id = _a.account_id, password = _a.password;
    return __awaiter(this, void 0, void 0, function () {
        var pool, rows, password_hash;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    pool = (0, pool_1.default)();
                    return [4 /*yield*/, pool.query("SELECT password_hash FROM accounts WHERE account_id=$1", [account_id])];
                case 1:
                    rows = (_b.sent()).rows;
                    if (rows.length == 0)
                        return [2 /*return*/, false];
                    password_hash = rows[0].password_hash;
                    if (!password_hash)
                        return [2 /*return*/, false];
                    return [2 /*return*/, (0, password_hash_1.verifyPassword)(password, password_hash)];
            }
        });
    });
}
exports["default"] = isPasswordCorrect;
//# sourceMappingURL=is-password-correct.js.map

/***/ })

};
;