<commit_before>const {Schema} = require('mongoose');
const crypto = require('crypto');

var userSchema = new Schema({
    firstname: {
        type: String, 
        match: [/^[a-zA-Z][a-zA-Z -]+$/, "Invalid first name provided."],
        lowercase: true, 
        trim: true, 
        required: [true, "A first name is required."]
    },
    lastname: {
        type: String, 
        match: [/^[a-zA-Z][a-zA-Z -]+$/, "Invalid last name provided."], 
        lowercase: true, 
        trim: true, 
        required: [true, "A first name is required."]
    },
    email: {
        type: String, 
        match: [ //regex taken from the HTML5 standard
            /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/,
            "Invalid email address provided."
        ],
        lowercase: true, 
        trim: true, 
        required: [true, "An email address is required."], 
        unique: true
    },
    validated: {type: Boolean, default: false, required: true},
    tokens: [{
        token: {type: String, required: true},
        purpose: {type: String, required: true, enum: ["sockauth", "emailvalid"]},
        used: {type: Boolean, default: false, required: true},
        expires: {type: Date, default: ()=>{return new Date(Date.now()+24*60*60*1000);}, required: true}
    }],
    password: {
        salt: {type: String, required: true},
        hash: {type: String, required: true},
    }
}, {timestamps: {}});

class Users {
    constructor(mongoose){
        this.mon = mongoose;
        this.user = mongoose.model('User', userSchema);
    }
    
    register(firstname, lastname, email, password){
        let self = this;
        return new Promise((resolve, reject) => {
            self.get(email).then((dupe)=>{
                if(dupe) return reject(["The email address provided has already been registered."]);
                if(typeof password !== 'string' || password.trim() === "" || password.trim().length < 8){
                    return reject(["Password is required, with a length of at least 8 characters"]);
                }
                password = password.trim();
                let salt = crypto.randomBytes(256).toString('hex');
                crypto.pbkdf2(password, salt, 100000, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 3872"]);
                    }
                    let newuser = new self.user({firstname, lastname, email, password: {salt, hash}, validated: false, tokens: []});
                    let valerr = newuser.validateSync();
                    if(valerr){
                        var msgs = [];
                        for(var i in valerr.errors) msgs.push(valerr.errors[i].message);
                        return reject(msgs);
                    }
                    newuser.save((err)=>{
                        if(err){
                            console.error(err);
                            return reject(["An Unknown issue occured, please contact an admin. 5687"]);
                        }
                        resolve(newuser);
                    });
                });
            }).catch((err)=>{
                console.error(err);
                reject(["An Unknown issue occured, please contact an admin. 5932"]);
            });
        });
    }
    
    login(email, password){
        let self = this;
        return new Promise((resolve, reject) => {
            if(typeof password !== 'string' || password.trim() === "") return reject(["Password is required"]);
            password = password.trim();
            self.user.find({email}, null, {limit: 1}, (err, users)=>{
                if(err){
                    console.error(err);
                    return reject(["An Unknown issue occured, please contact an admin. 5478"]);
                }
                if(users.length < 1) return reject(["Invalid Email/Password."]);
                crypto.pbkdf2(password, users[0].password.salt, 100000, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 4872"]);
                    }
                    if(hash !== users[0].password.hash) return reject(["Invalid Email/Password."]);
                    if(!users[0].validated) return reject(["The email address for this account is not yet validated, please check your email for the validation link."]);
                    resolve(users[0]);
                });
            });
        });
    }
    
    remove(id, password){
        let self = this;
        return new Promise((resolve, reject) => {
            if(typeof password !== 'string' || password.trim() === "") return reject(["Password is required"]);
            password = password.trim();
            self.user.findById(id, null, {limit: 1}, (err, users)=>{
                if(err){
                    console.error(err);
                    return reject(["An Unknown issue occured, please contact an admin. 6478"]);
                }
                if(users.length < 1) return reject(["Account does not exist, try refreshing the page or contacting an admin."]);
                crypto.pbkdf2(password, users[0].password.salt, 100000, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 5872"]);
                    }
                    if(hash !== users[0].password.hash) return reject(["Invalid Password Provided."]);
                    self.user.findByIdAndRemove(id, (err)=>{<commit_msg>iterations too high, causing timeout in testing?<commit_after>const {Schema} = require('mongoose');
const crypto = require('crypto');
var iterations = 10000;

var userSchema = new Schema({
    firstname: {
        type: String, 
        match: [/^[a-zA-Z][a-zA-Z -]+$/, "Invalid first name provided."],
        lowercase: true, 
        trim: true, 
        required: [true, "A first name is required."]
    },
    lastname: {
        type: String, 
        match: [/^[a-zA-Z][a-zA-Z -]+$/, "Invalid last name provided."], 
        lowercase: true, 
        trim: true, 
        required: [true, "A first name is required."]
    },
    email: {
        type: String, 
        match: [ //regex taken from the HTML5 standard
            /^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/,
            "Invalid email address provided."
        ],
        lowercase: true, 
        trim: true, 
        required: [true, "An email address is required."], 
        unique: true
    },
    validated: {type: Boolean, default: false, required: true},
    tokens: [{
        token: {type: String, required: true},
        purpose: {type: String, required: true, enum: ["sockauth", "emailvalid"]},
        used: {type: Boolean, default: false, required: true},
        expires: {type: Date, default: ()=>{return new Date(Date.now()+24*60*60*1000);}, required: true}
    }],
    password: {
        salt: {type: String, required: true},
        hash: {type: String, required: true},
    }
}, {timestamps: {}});

class Users {
    constructor(mongoose){
        this.mon = mongoose;
        this.user = mongoose.model('User', userSchema);
    }
    
    register(firstname, lastname, email, password){
        let self = this;
        return new Promise((resolve, reject) => {
            self.get(email).then((dupe)=>{
                if(dupe) return reject(["The email address provided has already been registered."]);
                if(typeof password !== 'string' || password.trim() === "" || password.trim().length < 8){
                    return reject(["Password is required, with a length of at least 8 characters"]);
                }
                password = <PASSWORD>();
                let salt = crypto.randomBytes(256).toString('hex');
                crypto.pbkdf2(password, salt, iterations, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 3872"]);
                    }
                    let newuser = new self.user({firstname, lastname, email, password: {salt, hash}, validated: false, tokens: []});
                    let valerr = newuser.validateSync();
                    if(valerr){
                        var msgs = [];
                        for(var i in valerr.errors) msgs.push(valerr.errors[i].message);
                        return reject(msgs);
                    }
                    newuser.save((err)=>{
                        if(err){
                            console.error(err);
                            return reject(["An Unknown issue occured, please contact an admin. 5687"]);
                        }
                        resolve(newuser);
                    });
                });
            }).catch((err)=>{
                console.error(err);
                reject(["An Unknown issue occured, please contact an admin. 5932"]);
            });
        });
    }
    
    login(email, password){
        let self = this;
        return new Promise((resolve, reject) => {
            if(typeof password !== 'string' || password.trim() === "") return reject(["Password is required"]);
            password = password.trim();
            self.user.find({email}, null, {limit: 1}, (err, users)=>{
                if(err){
                    console.error(err);
                    return reject(["An Unknown issue occured, please contact an admin. 5478"]);
                }
                if(users.length < 1) return reject(["Invalid Email/Password."]);
                crypto.pbkdf2(password, users[0].password.salt, iterations, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 4872"]);
                    }
                    if(hash !== users[0].password.hash) return reject(["Invalid Email/Password."]);
                    if(!users[0].validated) return reject(["The email address for this account is not yet validated, please check your email for the validation link."]);
                    resolve(users[0]);
                });
            });
        });
    }
    
    remove(id, password){
        let self = this;
        return new Promise((resolve, reject) => {
            if(typeof password !== 'string' || password.trim() === "") return reject(["Password is required"]);
            password = password.trim();
            self.user.findById(id, null, {limit: 1}, (err, users)=>{
                if(err){
                    console.error(err);
                    return reject(["An Unknown issue occured, please contact an admin. 6478"]);
                }
                if(users.length < 1) return reject(["Account does not exist, try refreshing the page or contacting an admin."]);
                crypto.pbkdf2(password, users[0].password.salt, iterations, 512, 'sha512', (err, hash) => {
                    if(err){
                        console.error(err);
                        return reject(["An Unknown issue occured, please contact an admin. 5872"]);
                    }
                    if(hash !== users[0].password.hash) return reject(["Invalid Password Provided."]);
                    self.user.findByIdAndRemove(id, (err)=>{
{'fraction_non_alphanumeric': 0.1441992759868988, 'fraction_numerical': 0.01594552663333908, 'mean_word_length': 1.656364468864469, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 30, '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': '3248901', 'n_tokens_mistral': 3283, 'n_tokens_neox': 2981, 'n_words': 838}