"use strict";
(() => {
var exports = {};
exports.id = 6291;
exports.ids = [6291];
exports.modules = {

/***/ 439491:
/***/ ((module) => {

module.exports = require("assert");

/***/ }),

/***/ 714300:
/***/ ((module) => {

module.exports = require("buffer");

/***/ }),

/***/ 706113:
/***/ ((module) => {

module.exports = require("crypto");

/***/ }),

/***/ 809523:
/***/ ((module) => {

module.exports = require("dns");

/***/ }),

/***/ 582361:
/***/ ((module) => {

module.exports = require("events");

/***/ }),

/***/ 657147:
/***/ ((module) => {

module.exports = require("fs");

/***/ }),

/***/ 241808:
/***/ ((module) => {

module.exports = require("net");

/***/ }),

/***/ 822037:
/***/ ((module) => {

module.exports = require("os");

/***/ }),

/***/ 371017:
/***/ ((module) => {

module.exports = require("path");

/***/ }),

/***/ 677282:
/***/ ((module) => {

module.exports = require("process");

/***/ }),

/***/ 12781:
/***/ ((module) => {

module.exports = require("stream");

/***/ }),

/***/ 371576:
/***/ ((module) => {

module.exports = require("string_decoder");

/***/ }),

/***/ 924404:
/***/ ((module) => {

module.exports = require("tls");

/***/ }),

/***/ 76224:
/***/ ((module) => {

module.exports = require("tty");

/***/ }),

/***/ 257310:
/***/ ((module) => {

module.exports = require("url");

/***/ }),

/***/ 473837:
/***/ ((module) => {

module.exports = require("util");

/***/ }),

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

/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "Z": () => (/* binding */ getParams)
/* harmony export */ });
function getParams(req) {
    if ((req === null || req === void 0 ? void 0 : req.method) == "POST") {
        return new Proxy({}, {
            get (_, key) {
                var ref;
                return (ref = req.body) === null || ref === void 0 ? void 0 : ref[key];
            }
        });
    /*
    // Disabled, since this could lead to a sneaky click on a link attack.
    // Should only be enabled for dev purposes.
    } else if (req?.method == "GET") {
    return new Proxy(
      {},
      {
        get(_, key) {
          if (typeof key != "string") {
            return undefined;
          }
          return req.query?.[key];
        },
      }
    );
*/ } else {
        // only support params for POST requests.
        return {};
    }
};


/***/ }),

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

__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ handle)
/* harmony export */ });
/* harmony import */ var _cocalc_server_accounts_search__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(766266);
/* harmony import */ var _cocalc_server_accounts_search__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_cocalc_server_accounts_search__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var lib_api_get_params__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(426006);
/*
Search for accounts matching a given query.

If user is signed in, then their account_id is used to prioritize the search.
*/ 

async function handle(req, res) {
    try {
        return res.json(await doUserSearch(req));
    } catch (err) {
        res.json({
            error: err.message
        });
    }
};
async function doUserSearch(req) {
    const { query  } = (0,lib_api_get_params__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z)(req);
    return await _cocalc_server_accounts_search__WEBPACK_IMPORTED_MODULE_0___default()({
        query
    });
}


/***/ }),

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


/*
Search for users.

- by exact account_id
- by exact email_address
- by partial match on first_name and last_name
- by @username
*/
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
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 __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
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 misc_1 = __webpack_require__(854006);
var util_1 = __webpack_require__(863563);
var logger_1 = __webpack_require__(227554);
var logger = (0, logger_1.getLogger)("accounts/search");
function search(_a) {
    var 
    /* account_id,*/
    query = _a.query, limit = _a.limit, admin = _a.admin;
    return __awaiter(this, void 0, void 0, function () {
        var user, _b, user, _c, _d, string_queries, email_queries, email_queries_1, email_queries_1_1, email_address, results, matches, matches_1, matches_1_1, user, x, matches_2, matches_2_1, user, x;
        var e_1, _e, e_2, _f, e_3, _g;
        return __generator(this, function (_h) {
            switch (_h.label) {
                case 0:
                    limit = limit !== null && limit !== void 0 ? limit : 20;
                    admin = !!admin;
                    logger.debug("search for ", query);
                    if (!(0, misc_1.isValidUUID)(query)) return [3 /*break*/, 2];
                    logger.debug("get user by account_id");
                    _b = process;
                    return [4 /*yield*/, getUserByAccountId(query)];
                case 1:
                    user = _b.apply(void 0, [_h.sent(), admin, false]);
                    return [2 /*return*/, user ? [user] : []];
                case 2:
                    if (!(0, misc_1.is_valid_email_address)(query)) return [3 /*break*/, 4];
                    logger.debug("get user by email address");
                    _c = process;
                    return [4 /*yield*/, getUserByEmailAddress(query)];
                case 3:
                    user = _c.apply(void 0, [_h.sent(), admin, true]);
                    return [2 /*return*/, user ? [user] : []];
                case 4:
                    _d = (0, misc_1.parse_user_search)(query), string_queries = _d.string_queries, email_queries = _d.email_queries;
                    if (admin) {
                        try {
                            // For admin we just do substring queries anyways.
                            for (email_queries_1 = __values(email_queries), email_queries_1_1 = email_queries_1.next(); !email_queries_1_1.done; email_queries_1_1 = email_queries_1.next()) {
                                email_address = email_queries_1_1.value;
                                string_queries.push([email_address]);
                            }
                        }
                        catch (e_1_1) { e_1 = { error: e_1_1 }; }
                        finally {
                            try {
                                if (email_queries_1_1 && !email_queries_1_1.done && (_e = email_queries_1.return)) _e.call(email_queries_1);
                            }
                            finally { if (e_1) throw e_1.error; }
                        }
                        email_queries.splice(0, email_queries.length); // empty array
                    }
                    results = [];
                    return [4 /*yield*/, getUsersByEmailAddresses(email_queries, limit)];
                case 5:
                    matches = _h.sent();
                    try {
                        for (matches_1 = __values(matches), matches_1_1 = matches_1.next(); !matches_1_1.done; matches_1_1 = matches_1.next()) {
                            user = matches_1_1.value;
                            x = process(user, admin, true);
                            if (x) {
                                results.push(x);
                            }
                        }
                    }
                    catch (e_2_1) { e_2 = { error: e_2_1 }; }
                    finally {
                        try {
                            if (matches_1_1 && !matches_1_1.done && (_f = matches_1.return)) _f.call(matches_1);
                        }
                        finally { if (e_2) throw e_2.error; }
                    }
                    return [4 /*yield*/, getUsersByStringQueries(string_queries, admin, limit - matches.length)];
                case 6:
                    matches = _h.sent();
                    try {
                        for (matches_2 = __values(matches), matches_2_1 = matches_2.next(); !matches_2_1.done; matches_2_1 = matches_2.next()) {
                            user = matches_2_1.value;
                            x = process(user, admin, false);
                            if (x) {
                                results.push(x);
                            }
                        }
                    }
                    catch (e_3_1) { e_3 = { error: e_3_1 }; }
                    finally {
                        try {
                            if (matches_2_1 && !matches_2_1.done && (_g = matches_2.return)) _g.call(matches_2);
                        }
                        finally { if (e_3) throw e_3.error; }
                    }
                    results.sort(function (a, b) {
                        var _a, _b, _c, _d;
                        return -(0, misc_1.cmp)(Math.max((_a = a.last_active) !== null && _a !== void 0 ? _a : 0, (_b = a.created) !== null && _b !== void 0 ? _b : 0), Math.max((_c = b.last_active) !== null && _c !== void 0 ? _c : 0, (_d = b.created) !== null && _d !== void 0 ? _d : 0));
                    });
                    return [2 /*return*/, results];
            }
        });
    });
}
exports["default"] = search;
function process(user, admin, isEmailSearch) {
    if (admin === void 0) { admin = false; }
    if (user == null)
        return undefined;
    var x = __assign({}, user);
    if (x.email_address && x.email_address_verified) {
        x.email_address_verified =
            x.email_address_verified[x.email_address] != null;
    }
    if (!admin) {
        if (!isEmailSearch) {
            delete x.email_address;
        }
        delete x.banned;
    }
    (0, util_1.toEpoch)(x, ["last_active", "created"]);
    return x;
}
var FIELDS = " account_id, first_name, last_name, name, email_address, last_active, created, banned, email_address_verified ";
function getUserByEmailAddress(email_address) {
    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)("medium");
                    return [4 /*yield*/, pool.query("SELECT ".concat(FIELDS, " FROM accounts WHERE email_address=$1"), [email_address.toLowerCase()])];
                case 1:
                    rows = (_a.sent()).rows;
                    return [2 /*return*/, rows[0]];
            }
        });
    });
}
function getUserByAccountId(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)("medium");
                    return [4 /*yield*/, pool.query("SELECT ".concat(FIELDS, " FROM accounts WHERE account_id=$1"), [account_id.toLowerCase()])];
                case 1:
                    rows = (_a.sent()).rows;
                    return [2 /*return*/, rows[0]];
            }
        });
    });
}
function getUsersByEmailAddresses(email_queries, limit) {
    return __awaiter(this, void 0, void 0, function () {
        var pool, rows;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    logger.debug("getUsersByEmailAddresses", email_queries);
                    if (email_queries.length == 0 || limit <= 0)
                        return [2 /*return*/, []];
                    pool = (0, pool_1.default)("medium");
                    return [4 /*yield*/, pool.query("SELECT ".concat(FIELDS, " FROM accounts WHERE email_address = ANY($1::TEXT[]) AND deleted IS NULL"), [email_queries])];
                case 1:
                    rows = (_a.sent()).rows;
                    return [2 /*return*/, rows];
            }
        });
    });
}
function getUsersByStringQueries(string_queries, admin, limit) {
    return __awaiter(this, void 0, void 0, function () {
        var params, where, i, string_queries_1, string_queries_1_1, terms, v, terms_1, terms_1_1, s, query, pool, rows;
        var e_4, _a, e_5, _b;
        return __generator(this, function (_c) {
            switch (_c.label) {
                case 0:
                    logger.debug("getUsersByStringQueries", string_queries);
                    if (limit <= 0 || string_queries.length <= 0) {
                        return [2 /*return*/, []];
                    }
                    params = [];
                    where = [];
                    i = 1;
                    try {
                        for (string_queries_1 = __values(string_queries), string_queries_1_1 = string_queries_1.next(); !string_queries_1_1.done; string_queries_1_1 = string_queries_1.next()) {
                            terms = string_queries_1_1.value;
                            v = [];
                            try {
                                for (terms_1 = (e_5 = void 0, __values(terms)), terms_1_1 = terms_1.next(); !terms_1_1.done; terms_1_1 = terms_1.next()) {
                                    s = terms_1_1.value;
                                    v.push("(lower(first_name) LIKE $".concat(i, "::TEXT OR lower(last_name) LIKE $").concat(i, "::TEXT OR '@' || lower(name) LIKE $").concat(i, "::TEXT ").concat(admin ? "OR lower(email_address) LIKE $".concat(i, "::TEXT") : "", ")"));
                                    params.push("%".concat(s, "%"));
                                    i += 1;
                                }
                            }
                            catch (e_5_1) { e_5 = { error: e_5_1 }; }
                            finally {
                                try {
                                    if (terms_1_1 && !terms_1_1.done && (_b = terms_1.return)) _b.call(terms_1);
                                }
                                finally { if (e_5) throw e_5.error; }
                            }
                            where.push("(".concat(v.join(" AND "), ")"));
                        }
                    }
                    catch (e_4_1) { e_4 = { error: e_4_1 }; }
                    finally {
                        try {
                            if (string_queries_1_1 && !string_queries_1_1.done && (_a = string_queries_1.return)) _a.call(string_queries_1);
                        }
                        finally { if (e_4) throw e_4.error; }
                    }
                    query = "SELECT ".concat(FIELDS, " FROM accounts WHERE deleted IS NOT TRUE AND (").concat(where.join(" OR "), ")");
                    if (!admin) {
                        // Exclude unlisted users from search results
                        query += " AND unlisted IS NOT true ";
                    }
                    // recently active users are much more relevant than old ones -- #2991
                    query += " ORDER BY COALESCE(last_active, created) DESC NULLS LAST";
                    query += " LIMIT $".concat(i, "::INTEGER ");
                    i += 1;
                    params.push(limit);
                    pool = (0, pool_1.default)("medium");
                    return [4 /*yield*/, pool.query(query, params)];
                case 1:
                    rows = (_c.sent()).rows;
                    return [2 /*return*/, rows];
            }
        });
    });
}
//# sourceMappingURL=search.js.map

/***/ })

};
;

// load runtime
var __webpack_require__ = require("../../../../webpack-api-runtime.js");
__webpack_require__.C(exports);
var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
var __webpack_exports__ = __webpack_require__.X(0, [8180,2921,1808,9738,3563], () => (__webpack_exec__(407284)));
module.exports = __webpack_exports__;

})();