<commit_before>'use strict';

let Response = require('../../tools/response');
let mongoose = require('mongoose');
let async = require('async');
let PassTools = require('../../tools/passTools');
let Mail = require('../../config/mail');

const editableFields = {
    lastName: true,
    firstName: true,
    email: true,
    biography: true,
    birthday: true,
    school: {
        institution: true,
        studyYear: true,
        pathway: true
    },
    material: {
        hasMaterial: true,
        isDesktop: true,
        hasWifi: true
    },
    mailForRecruitment: true,
    cremiAccount: {
        needed: true,
        studentNumber: true,
        studentMail: true
    }
};

module.exports = function (userSchema) {

    /* Tool methods */

    userSchema.statics.computeLogin = function (firstName, lastName, callback) {
        let login = firstName.substr(0, 1).toLowerCase() + '.' +
            lastName.substr(0, 9).toLocaleLowerCase();
        let lastLogin = login;
        let initialLogin = login;
        let currentNumber = 1;

        let user = '';

        async.whilst(
            // Check if a user exist with this login
            () => user !== null,
            // Search a login and compute a new one
            (checkTest) => {
                this.findOne({login: login}, (err, userFound) => {
                    if (err) {
                        return checkTest(err);
                    }

                    // Keep found user in memory for the test
                    user = userFound;

                    // Keep the login in memory
                    lastLogin = login;

                    // Create a new login
                    login = initialLogin + currentNumber;
                    currentNumber++;

                    // Call whilst callback
                    checkTest(null);
                });
            },
            (err) => {
                if (err) {
                    return callback(err);
                }

                callback(null, lastLogin);
            }
        );
    };

    function recursiveEdit(parametersObject, newParams, user) {
        for (let key in parametersObject) {
            if (!parametersObject.hasOwnProperty(key)) {
                continue;
            }

            if (parametersObject[key] instanceof Object && newParams[key]) {
                recursiveEdit(parametersObject[key], newParams[key], user[key]);
            } else if (newParams[key]) {
                user[key] = newParams[key];
            }
        }
    }

    function editUserParameters(params, user) {
        recursiveEdit(editableFields, params, user);
    }

    /* Controllers methods */

    userSchema.statics.create = function (params, callback) {
        let Self = this;

        params.team = undefined;
        params.paswordRecoveryToken = undefined;
        params.data = undefined;

        async.waterfall([
            (next) => PassTools.hashPassword(params.password, next),
            (pass, next) => {
                params.password = <PASSWORD>;

                let user = new Self(params);

                user.save(next);
            },
            (user, requests, next) => {
                Mail.sendSubscribeMail({
                    to: user.email
                }, (err) => next(err, user));
            }
        ], callback);
    };

    userSchema.statics.edit = function (params, callback) {
        async.waterfall([
            (next) => mongoose.model('User').findById(params.user, next),
            (user, next) => {
                if (!user) {
                    callback('User not found');
                }

                editUserParameters(params, user);

                user.save(next);
            }
        ], callback);
    };

    userSchema.statics.changeTeam = function (params, callback) {
        mongoose.model('User').update(
            {_id: params.user._id},
            {team: params.team._id},
            (err) => {
                if (err) {
                    return callback(err);
                }

                callback();
            });
    };

    userSchema.statics.getById = function (params, callback) {
        mongoose.model('User')
            .findById(params.id)
            .select('firstName lastName school team biography')
            .populate('team')
            .exec(callback);
    };

    userSchema.statics.getAll = function (params, callback) {
        mongoose.model('User')
            .find()
            .select('firstName lastName school team biography')
            .populate('team institution')
            .exec(callback);
    };

    /* Express methods verifications */

    function checkParametersExistsForCreate(req, res, callback) {
        let parametersAreGood = false;

        if (!req.body || !req.body.firstName) {
            return Response.missing(res, 'firstName', -11);
        } else if (!req.body.lastName) {
            return Response.missing(res, 'lastName', -12);
        } else if (!req.body.email) {
            return Response.missing(res, 'email', -13);
        } else if (!req.body.password) {
            return Response.missing(res, 'password', -14);
        } else {
            parametersAreGood = true;<commit_msg>fix(server): Fix bad populate field<commit_after>'use strict';

let Response = require('../../tools/response');
let mongoose = require('mongoose');
let async = require('async');
let PassTools = require('../../tools/passTools');
let Mail = require('../../config/mail');

const editableFields = {
    lastName: true,
    firstName: true,
    email: true,
    biography: true,
    birthday: true,
    school: {
        institution: true,
        studyYear: true,
        pathway: true
    },
    material: {
        hasMaterial: true,
        isDesktop: true,
        hasWifi: true
    },
    mailForRecruitment: true,
    cremiAccount: {
        needed: true,
        studentNumber: true,
        studentMail: true
    }
};

module.exports = function (userSchema) {

    /* Tool methods */

    userSchema.statics.computeLogin = function (firstName, lastName, callback) {
        let login = firstName.substr(0, 1).toLowerCase() + '.' +
            lastName.substr(0, 9).toLocaleLowerCase();
        let lastLogin = login;
        let initialLogin = login;
        let currentNumber = 1;

        let user = '';

        async.whilst(
            // Check if a user exist with this login
            () => user !== null,
            // Search a login and compute a new one
            (checkTest) => {
                this.findOne({login: login}, (err, userFound) => {
                    if (err) {
                        return checkTest(err);
                    }

                    // Keep found user in memory for the test
                    user = userFound;

                    // Keep the login in memory
                    lastLogin = login;

                    // Create a new login
                    login = initialLogin + currentNumber;
                    currentNumber++;

                    // Call whilst callback
                    checkTest(null);
                });
            },
            (err) => {
                if (err) {
                    return callback(err);
                }

                callback(null, lastLogin);
            }
        );
    };

    function recursiveEdit(parametersObject, newParams, user) {
        for (let key in parametersObject) {
            if (!parametersObject.hasOwnProperty(key)) {
                continue;
            }

            if (parametersObject[key] instanceof Object && newParams[key]) {
                recursiveEdit(parametersObject[key], newParams[key], user[key]);
            } else if (newParams[key]) {
                user[key] = newParams[key];
            }
        }
    }

    function editUserParameters(params, user) {
        recursiveEdit(editableFields, params, user);
    }

    /* Controllers methods */

    userSchema.statics.create = function (params, callback) {
        let Self = this;

        params.team = undefined;
        params.paswordRecoveryToken = undefined;
        params.data = undefined;

        async.waterfall([
            (next) => PassTools.hashPassword(params.password, next),
            (pass, next) => {
                params.password = <PASSWORD>;

                let user = new Self(params);

                user.save(next);
            },
            (user, requests, next) => {
                Mail.sendSubscribeMail({
                    to: user.email
                }, (err) => next(err, user));
            }
        ], callback);
    };

    userSchema.statics.edit = function (params, callback) {
        async.waterfall([
            (next) => mongoose.model('User').findById(params.user, next),
            (user, next) => {
                if (!user) {
                    callback('User not found');
                }

                editUserParameters(params, user);

                user.save(next);
            }
        ], callback);
    };

    userSchema.statics.changeTeam = function (params, callback) {
        mongoose.model('User').update(
            {_id: params.user._id},
            {team: params.team._id},
            (err) => {
                if (err) {
                    return callback(err);
                }

                callback();
            });
    };

    userSchema.statics.getById = function (params, callback) {
        mongoose.model('User')
            .findById(params.id)
            .select('firstName lastName school team biography')
            .populate('team')
            .exec(callback);
    };

    userSchema.statics.getAll = function (params, callback) {
        mongoose.model('User')
            .find()
            .select('firstName lastName school team biography')
            .populate('team school.institution')
            .exec(callback);
    };

    /* Express methods verifications */

    function checkParametersExistsForCreate(req, res, callback) {
        let parametersAreGood = false;

        if (!req.body || !req.body.firstName) {
            return Response.missing(res, 'firstName', -11);
        } else if (!req.body.lastName) {
            return Response.missing(res, 'lastName', -12);
        } else if (!req.body.email) {
            return Response.missing(res, 'email', -13);
        } else if (!req.body.password) {
            return Response.missing(res, 'password', -14);
        } else {
            parametersAreGood = true;
{'fraction_non_alphanumeric': 0.11963861150737043, 'fraction_numerical': 0.0024726581074655256, 'mean_word_length': 1.5002377555872564, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 27, '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': '5203038', 'n_tokens_mistral': 2786, 'n_tokens_neox': 2655, 'n_words': 631}