"use strict";
/*
 *  This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
 *  License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
 */
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 });
/*
Password reset works as follows:

1. Query the database to make sure there is a user with the given email address.
2. If a password reset was already sent within the last XX minutes,
   return an error -- we don't want people to spam other people with
   password resets.
3. Generate password reset token and write to database.
4. Send email.
5. Send response to user that email has been sent (or there was an error).
*/
var is_account_available_1 = __importDefault(require("@cocalc/server/auth/is-account-available"));
var password_reset_1 = require("@cocalc/server/auth/password-reset");
var password_reset_2 = __importDefault(require("@cocalc/server/email/password-reset"));
var is_post_1 = __importDefault(require("lib/api/is-post"));
function passwordReset(req, res) {
    return __awaiter(this, void 0, void 0, function () {
        var email, result;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    if (!(0, is_post_1.default)(req, res))
                        return [2 /*return*/];
                    email = req.body.email;
                    return [4 /*yield*/, handle(email, req.ip)];
                case 1:
                    result = _a.sent();
                    res.json(result);
                    return [2 /*return*/];
            }
        });
    });
}
exports.default = passwordReset;
function handle(email, ip) {
    return __awaiter(this, void 0, void 0, function () {
        var n, id, err_1;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0: return [4 /*yield*/, (0, is_account_available_1.default)(email)];
                case 1:
                    if (_a.sent()) {
                        // Bad -- email is *available*, which means no way to reset
                        // the password for it, since it doesn't exist.
                        return [2 /*return*/, { error: "There is no account with email \"".concat(email, "\".") }];
                    }
                    return [4 /*yield*/, (0, password_reset_1.recentAttempts)(email, ip)];
                case 2:
                    n = _a.sent();
                    if (n > 1) {
                        return [2 /*return*/, {
                                error: "We recently sent multiple password resets for \"".concat(email, "\".  Check your email or wait a while and try later."),
                            }];
                    }
                    return [4 /*yield*/, (0, password_reset_1.createReset)(email, ip, 60 * 60 * 4)];
                case 3:
                    id = _a.sent();
                    _a.label = 4;
                case 4:
                    _a.trys.push([4, 6, , 7]);
                    return [4 /*yield*/, (0, password_reset_2.default)(email, id)];
                case 5:
                    _a.sent();
                    return [3 /*break*/, 7];
                case 6:
                    err_1 = _a.sent();
                    return [2 /*return*/, {
                            error: "Sending password reset email failed -- ".concat(err_1.message),
                        }];
                case 7: return [2 /*return*/, {
                        success: "Password reset email successfully sent to ".concat(email, "."),
                    }];
            }
        });
    });
}
//# sourceMappingURL=password-reset.js.map