<commit_before>var mandrill = require('mandrill-api/mandrill');
var mandrill_client;
var crypto = require('crypto');
var jxutils = require('jxutils');

exports.forgot = function(link) {

    // get link data
    var data = link.data || {};

    // set params
    link.params = link.params || {};

    // get the Mandrill Api Key
    if (!link.params.mandrillKey) {
        link.send(400, 'ERROR_MISSING_MANDRILL_API_KEY');
        return;
    }
    mandrill_client = new mandrill.Mandrill(link.params.mandrillKey);

    var username = (data.username || '').trim();
    delete data.username;

    // send error message if user not provided
    if (!username) {
        return link.send(400, 'ERROR_MISSING_USERNAME');
    }

    // get user
    getUser(link.params, username, null, function(err, user, usersCol) {

        // handle error
        if (err) {
            link.send(400, err);
            return;
        }

        // generate the token
        var token = generateToken(10);
        var resetLink = 'http://' + link.req.headers.host + '/@/login/reset?username=' + username + '&token=' + token;

        var updateObj = {
            $set : {}
        }

        // add the token to the user
        updateObj.$set[link.params.tokenkey] = token;

        usersCol.update({ _id: user._id }, updateObj, function (err) {

            if (err) { return link.send(400, err); }

            // create the mail data
            var mailData = {
                template: (typeof link.params.template === 'object') ? link.params.template[link.session.locale] : link.params.template,
                sender: link.params.sender,
                mergeVars: [
                    {
                        name: 'recover_link',
                        content: resetLink
                    }
                ]
            }

            // check if a custom code for the reciver exists
            if (link.params.customReceiverHandler) {
                M.emit(link.params.customReceiverHandler, { user: user, link: link }, function (err, receiver) {

                    if (err) { return link.send(500, err); }
                    mailData.receiver = receiver;

                    // send mail
                    sendMail(mailData, function (err) {

                        if (err) { return link.send(500, err); }

                        // operation complete
                        link.send(200);
                    });
                });
            } else {
                mailData.receiver = username;

                // send mail
                sendMail(mailData, function (err) {

                    if (err) { return link.send(500, err); }

                    // operation complete
                    link.send(200);
                });
            }
        });
    }, link);
};

exports.reset = function(link) {

    // the reset form is requested
    if (link.req.method === 'GET') {

        if (!link.query.token || !link.query.username) {
            return link.send(400, 'ERROR_INVALID_RESET_LINK');
        }

        // get the token and username
        var token = link.query.token;   
        var username = link.query.username;

        link.res.setHeader('content-type', 'text/html');
        link.send(200, '<form method="POST"><table><tr><td>New password: </td><td><input name="password" type="password"></td></tr><tr><td>Retype password: </td><td><input name="repassword" type="password"></td></tr><tr><td></td><td><button type="submit">Submit</button></td></tr><input name="token" type="hidden" value="' + token +'"><input name="username" type="hidden" value="' + username +'"></form>');
        return;
    }

    // the reset form is submitted
    if (link.req.method === 'POST') {
        var password = (link.data.password || '').trim();
        var repassword = (link.data.repassword || '').trim();
        var token = (link.data.token || '').trim();
        var username = (link.data.username || '').trim();

        if (!link.data.password) {
            return link.send(400, 'ERROR_MISSING_PASSWORD');
        }
        if (link.data.password !== link.data.repassword) {
            return link.send(400, 'ERROR_PASSWORDS_DO_NOT_MATCH');
        }

        // TODO make some configurable regexp password policy

        // handle hash<commit_msg>added support for jade template<commit_after>var mandrill = require('mandrill-api/mandrill');
var mandrill_client;
var crypto = require('crypto');
var jxutils = require('jxutils');
var jade = require('jade');

exports.forgot = function(link) {

    // get link data
    var data = link.data || {};

    // set params
    link.params = link.params || {};

    // get the Mandrill Api Key
    if (!link.params.mandrillKey) {
        link.send(400, 'ERROR_MISSING_MANDRILL_API_KEY');
        return;
    }
    mandrill_client = new mandrill.Mandrill(link.params.mandrillKey);

    var username = (data.username || '').trim();
    delete data.username;

    // send error message if user not provided
    if (!username) {
        return link.send(400, 'ERROR_MISSING_USERNAME');
    }

    // get user
    getUser(link.params, username, null, function(err, user, usersCol) {

        // handle error
        if (err) {
            link.send(400, err);
            return;
        }

        // generate the token
        var token = generateToken(10);
        var resetLink = 'http://' + link.req.headers.host + '/@/login/reset?username=' + username + '&token=' + token;

        var updateObj = {
            $set : {}
        }

        // add the token to the user
        updateObj.$set[link.params.tokenkey] = token;

        usersCol.update({ _id: user._id }, updateObj, function (err) {

            if (err) { return link.send(400, err); }

            // create the mail data
            var mailData = {
                template: (typeof link.params.template === 'object') ? link.params.template[link.session.locale] : link.params.template,
                sender: link.params.sender,
                mergeVars: [
                    {
                        name: 'recover_link',
                        content: resetLink
                    }
                ]
            }

            // check if a custom code for the reciver exists
            if (link.params.customReceiverHandler) {
                M.emit(link.params.customReceiverHandler, { user: user, link: link }, function (err, receiver) {

                    if (err) { return link.send(500, err); }
                    mailData.receiver = receiver;

                    // send mail
                    sendMail(mailData, function (err) {

                        if (err) { return link.send(500, err); }

                        // operation complete
                        link.send(200);
                    });
                });
            } else {
                mailData.receiver = username;

                // send mail
                sendMail(mailData, function (err) {

                    if (err) { return link.send(500, err); }

                    // operation complete
                    link.send(200);
                });
            }
        });
    }, link);
};

exports.reset = function(link) {

    // the reset form is requested
    if (link.req.method === 'GET') {

        if (!link.query.token || !link.query.username) {
            return link.send(400, 'ERROR_INVALID_RESET_LINK');
        }

        // get the token and username
        var token = link.query.token;   
        var username = link.query.username;

        // check if a jade template file exists
        if (link.params.templateFile) {
            var templatePath = M.app.getPath() + '/' + link.params.templateFile;

            // compile jade file
            try {
                var template = jade.compileFile(templatePath);
            } catch (err) {
                return link.send(500, err);
            }

            var data = {
                token: token,
                username: username
            }

            // set response headers
            link.res.setHeader('content-type', 'text/html');
            link.res.send(200, template(data));
            return;
        } else {
            // set response headers
            link.res.setHeader('content-type', 'text/html');
            link.send(200, '<form method="POST"><table><tr><td>New password: </td><td><input name="password" type="password"></td></tr><tr><td>Retype password: </td><td><input name="repassword" type="password"></td></tr><tr><td></td><td><button type="submit">Submit</button></td></tr><input name="token" type="hidden" value="' + token +'"><input name="username" type="hidden" value="' + username +'"></form>');
            return;
        }
    }

    // the reset form is submitted
    if (link.req.method === 'POST') {
        var password = (link.data.password || '').trim();
        var repassword = (link.data.repassword || '').trim();
        var token = (link.data.token || '').trim();
        var username = (link.data.username || '').trim();

        if (!link.data.password) {
            return link.send(400, 'ERROR_MISSING_PASSWORD');
        }
        if (link.data.password !== link.data.repassword) {
            return link.send(400, 'ERROR_PASSWORDS_DO_NOT_MATCH');
        }

        // TODO make some configurable regexp password policy

        // handle hash
{'fraction_non_alphanumeric': 0.13947031183255018, 'fraction_numerical': 0.009397693293464331, 'mean_word_length': 1.6926394479585969, 'pattern_counts': {'":': 0, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1401006', 'n_tokens_mistral': 2711, 'n_tokens_neox': 2517, 'n_words': 601}