const bcrypt = require('bcryptjs'); const mongoose = require('mongoose'); const validator = require('validator'); const jwt = require('jsonwebtoken'); const _ = require('lodash'); const tools = require('../tools/general'); const { Settings } = require('../models/settings'); const { ExtraList } = require('../models/extralist'); const shared_consts = require('../tools/shared_nodejs'); const queryclass = require('../classes/queryclass'); mongoose.Promise = global.Promise; mongoose.level = "F"; // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true }); mongoose.set('debug', process.env.DEBUG); const UserSchema = new mongoose.Schema({ userId: { type: String, }, email: { type: String, required: true, trim: true, minlength: 1, unique: false, /*validate: { validator: validator.isEmail, message: '{VALUE} is not a valid email' }*/ }, idapp: { type: String, required: true, }, ind_order: { type: Number }, username: { type: String, required: true, trim: true, minlength: 6, unique: false, }, name: { type: String, trim: true, }, surname: { type: String, trim: true, }, password: { type: String, require: true, minlength: 6, }, lang: { type: String, require: true, }, linkreg: { type: String, required: false }, verified_email: { type: Boolean, }, made_gift: { type: Boolean, }, tokens: [{ access: { type: String, required: true }, browser: { type: String, required: true }, token: { type: String, required: true }, date_login: { type: Date }, }], perm: { type: Number }, ipaddr: { type: String, }, date_reg: { type: Date, }, date_temp_reg: { type: Date, }, date_tokenforgot: { type: Date }, tokenforgot: { type: String, }, lasttimeonline: { type: Date }, news_on: { type: Boolean }, aportador_solidario: { type: String, }, aportador_solidario_nome_completo: { type: String, }, aportador_solidario_ind_order: { type: Number, }, note: { type: String, }, profile: { img: { type: String }, nationality: { type: String }, intcode_cell: { type: String }, iso2_cell: { type: String }, cell: { type: String }, country_pay: { type: String }, email_paypal: { type: String }, paymenttypes: [], username_telegram: { type: String }, teleg_id: { type: Number }, teleg_checkcode: { type: Number }, manage_telegram: { type: Boolean }, dateofbirth: { type: Date, }, my_dream: { type: String, }, saw_zoom_presentation: { type: Boolean }, sex: { type: Number, }, }, }); UserSchema.methods.toJSON = function () { const user = this; const userObject = user.toObject(); return _.pick(userObject, ['_id', ...shared_consts.fieldsUserToChange()]); }; UserSchema.methods.generateAuthToken = function (req) { // console.log("GENERA TOKEN : "); const user = this; const useragent = req.get('User-Agent'); // tools.mylog("GENERATE USER-AGENT = ", useragent); const access = 'auth'; const browser = useragent; const token = jwt.sign({ _id: user._id.toHexString(), access }, process.env.SIGNCODE).toString(); const date_login = new Date(); // CANCELLA IL PRECEDENTE ! user.tokens = user.tokens.filter(function (tok) { return (tok.access !== access) || ((tok.access === access) && (tok.browser !== browser)); }); user.tokens.push({ access, browser, token, date_login }); user.lasttimeonline = new Date(); return user.save() .then(() => { // console.log("TOKEN CREATO IN LOGIN : " + token); return token; }) .catch(err => { console.log("Error", err.message); }); }; UserSchema.statics.setPermissionsById = function (id, perm) { const user = this; return user.findByIdAndUpdate(id, { $set: { perm } }).then((user) => { if (user) return res.send({ code: server_constants.RIS_CODE_OK, msg: '' }); else return res.send({ code: server_constants.RIS_CODE_ERR, msg: '' }); }); }; UserSchema.statics.isAdmin = function (perm) { try { return ((perm & shared_consts.Permissions.Admin) === shared_consts.Permissions.Admin); } catch (e) { return false } }; UserSchema.statics.isManager = function (perm) { try { return ((perm & shared_consts.Permissions.Manager) === shared_consts.Permissions.Manager); } catch (e) { return false } }; UserSchema.statics.findByToken = function (token, typeaccess) { const User = this; let decoded; try { decoded = jwt.verify(token, process.env.SIGNCODE); } catch (e) { return Promise.resolve(null); } return User.findOne({ '_id': decoded._id, 'tokens.token': token, 'tokens.access': typeaccess, }); }; UserSchema.statics.findByTokenAnyAccess = function (token) { const User = this; let decoded; try { decoded = jwt.verify(token, process.env.SIGNCODE); } catch (e) { return Promise.resolve(null); } return User.findOne({ '_id': decoded._id, 'tokens.token': token, }); }; UserSchema.statics.findByCredentials = function (idapp, username, password) { const User = this; let pwd = ""; return User.findOne({ idapp, username: username }).then((user) => { if (!user) { // Check if with email: return User.findOne({ idapp, email: username.toLowerCase() }) } else { return user } }).then(user => { if (!user) return null; pwd = user.password; return new Promise((resolve, reject) => { // Use bcrypt.compare to compare password and user.password // console.log("pwd1 " + password); // console.log("pwd2 " + pwd); bcrypt.compare(password, pwd, (err, res) => { if (res) { resolve(user); } else { return resolve(null); } }); }); }); }; UserSchema.statics.findByUsername = function (idapp, username) { const User = this; return User.findOne({ 'idapp': idapp, 'username': username, }); }; UserSchema.statics.getUserShortDataByUsername = function (idapp, username) { const User = this; return User.findOne({ 'idapp': idapp, 'username': username, }, { ind_order: 1, username: 1, name: 1, surname: 1, verified_email: 1, 'profile.teleg_id': 1, 'profile.saw_zoom_presentation': 1, made_gift: 1, email: 1, date_reg: 1, img: 1 }).then((ris) => { if (!!ris) { // console.log('ris', ris); if (!!ris._doc) return ris._doc; else return null; } }); }; UserSchema.statics.getDownlineByUsername = function (idapp, username) { const User = this; return User.find({ 'idapp': idapp, 'aportador_solidario': username, }, { aportador_solidario: 1, ind_order: 1, username: 1, name: 1, surname: 1, verified_email: 1, 'profile.teleg_id': 1, 'profile.saw_zoom_presentation': 1, made_gift: 1, email: 1, date_reg: 1, img: 1 }, (err, arrrec) => { return arrrec }); }; UserSchema.statics.getnumInvitatiAttivi = function (idapp, username) { const User = this; return User.count({ idapp, aportador_solidario: username, 'profile.teleg_id': { $gt: 1 }, 'profile.saw_zoom_presentation': true, }); }; UserSchema.statics.getUsersNationalityQuery = function (idapp) { const query = [ { $match: { idapp } }, { $group: { _id: "$profile.nationality", count: { $sum: 1 } } }, { $sort: { count: -1 } } ]; return query }; UserSchema.statics.getindOrderDuplicate = function (idapp) { const User = this; return User.aggregate(User.getUsersNationalityQuery(idapp)) .then(ris => { // console.table(ris); return JSON.stringify(ris); }); }; UserSchema.statics.getnumInvitati = function (idapp, username) { const User = this; return User.count({ idapp, aportador_solidario: username, }); }; UserSchema.statics.findByLinkreg = function (idapp, linkreg) { const User = this; return User.findOne({ 'linkreg': linkreg, 'idapp': idapp, }); }; UserSchema.statics.findByLinkTokenforgot = function (idapp, email, tokenforgot) { const User = this; return User.findOne({ 'email': email, 'tokenforgot': tokenforgot, 'date_tokenforgot': { $gte: tools.IncDateNow(-1000 * 60 * 60 * 4) }, // 4 ore fa! 'idapp': idapp, }); }; UserSchema.statics.findByEmail = function (idapp, email) { const User = this; return User.findOne({ 'idapp': idapp, 'email': email, }); }; UserSchema.statics.getLastUser = function (idapp) { const User = this; return User.findOne({ idapp }).sort({ ind_order: -1 }) }; UserSchema.pre('save', function (next) { const user = this; /* if (user.isModified('password')) { bcrypt.genSalt(10, (err, salt) => { bcrypt.hash(user.password, salt, (err, hash) => { user.password = hash; next(); }); }); } else { next(); } */ next(); }); UserSchema.methods.removeToken = function (token) { const user = this; return user.updateOne({ $pull: { tokens: { token } } }); }; UserSchema.statics.getEmailByUsername = async function (idapp, username) { const User = this; return await User.findOne({ idapp, username }) .then((arrrec) => { return ((arrrec) ? arrrec.email : ''); }).catch((e) => { console.error('getEmailByUsername', e); }); }; UserSchema.statics.getAportadorSolidarioByUsername = async function (idapp, username) { const User = this; return await User.findOne({ idapp, username }) .then((rec) => { return ((rec) ? rec.aportador_solidario : ''); }).catch((e) => { console.error('getAportadorSolidarioByUsername', e); }); }; UserSchema.statics.UserByIdTelegram = async function (idapp, teleg_id) { const User = this; return await User.findOne({ idapp, 'profile.teleg_id': teleg_id }) .then((rec) => { return (!!rec) ? rec._doc : null; }).catch((e) => { console.error('UserExistByIdTelegram', e); }); }; UserSchema.statics.TelegIdByUsername = async function (idapp, username) { const User = this; return await User.findOne({ idapp, username }, { 'profile.teleg_id': 1 }) .then((rec) => { return (!!rec) ? rec.profile.teleg_id : null; }).catch((e) => { console.error('TelegIdByUsername', e); }); }; UserSchema.statics.SetTelegramCheckCode = async function (idapp, username, teleg_checkcode) { const User = this; const fields_to_update = { 'profile.teleg_checkcode': teleg_checkcode }; return await User.findOneAndUpdate({ idapp, username }, { $set: fields_to_update }, { new: false }).then((record) => { return !!record; }); }; UserSchema.statics.SetTelegramIdSuccess = async function (idapp, username, teleg_id) { const User = this; const fields_to_update = { 'profile.teleg_id': teleg_id, 'profile.teleg_checkcode': 0 }; return await User.findOneAndUpdate({ idapp, username }, { $set: fields_to_update }, { new: false }).then((record) => { return record; }); }; UserSchema.statics.getNameSurnameByUsername = async function (idapp, username) { const User = this; return await User.findOne({ idapp, username }, { name: 1, surname: 1 }) .then((rec) => { return (!!rec) ? `${rec.name} ${rec.surname}` : ''; }).catch((e) => { console.error('getNameSurnameByUsername', e); }); }; UserSchema.statics.getusersManagers = async function (idapp) { const User = this; return await User.find({ idapp, 'profile.manage_telegram': true }, { 'profile.teleg_id': 1 }) .then((arrrec) => { return (!!arrrec) ? arrrec : null; }).catch((e) => { console.error('getusersManagers', e); }); }; UserSchema.statics.getUsersTelegALL = async function (idapp) { const User = this; return await User.find({ idapp, 'profile.teleg_id': { $gt: 0 } }, { 'profile.teleg_id': 1 }) .then((arrrec) => { return (!!arrrec) ? arrrec : null; }).catch((e) => { console.error('getusersManagers', e); }); }; UserSchema.statics.isManagerByIdTeleg = async function (idapp, idtelegram) { const User = this; return await User.findOne({ idapp, 'profile.manage_telegram': true, 'profile.teleg_id': idtelegram }, { 'profile.teleg_id': 1 }) .then((rec) => { return (!!rec && rec.profile.teleg_id === idtelegram); }).catch((e) => { console.error('getusersManagers', e); return false }); }; UserSchema.statics.isAdminByIdTeleg = async function (idapp, idtelegram) { const User = this; return await User.findOne({ idapp, 'username': 'paoloar77', 'profile.manage_telegram': true, 'profile.teleg_id': idtelegram }, { 'profile.teleg_id': 1 }) .then((rec) => { return (!!rec && rec.profile.teleg_id === idtelegram); }).catch((e) => { console.error('getusersManagers', e); return false }); }; UserSchema.statics.getUsersList = function (idapp) { const User = this; return User.find({ 'idapp': idapp }, { username: 1, name: 1, surname: 1, verified_email: 1, made_gift: 1, perm: 1, email: 1, date_reg: 1, img: 1 }) }; UserSchema.statics.getUsersListByParams = function (params) { const User = this; myclParamQuery = new queryclass.CParamsQuery(params); const filterMatchBefore = `${ myclParamQuery.filter }`; return User.find( { $match: filterMatchBefore }, { 'idapp': idapp }, { username: 1, name: 1, surname: 1, verified_email: 1, made_gift: 1, perm: 1, email: 1, date_reg: 1, img: 1, lasttimeonline: 1, news_on: 1 }) }; /** * Query blog posts by user -> paginated results and a total count. * @returns {Object} Object -> `{ rows, count }` */ UserSchema.statics.getFieldsForSearch = function () { return ['username', 'name', 'surname', 'email', 'profile.cell', 'profile.email_paypal', 'profile.username_telegram', 'aportador_solidario'] }; UserSchema.statics.executeQueryTable = function (idapp, params) { params.fieldsearch = this.getFieldsForSearch(); return tools.executeQueryTable(this, idapp, params); }; UserSchema.statics.findAllIdApp = function (idapp) { const User = this; const myfind = { idapp }; return User.find(myfind, (err, arrrec) => { return arrrec }); }; UserSchema.statics.DuplicateAllRecords = async function (idapporig, idappdest) { return tools.DuplicateAllRecords(this, idapporig, idappdest); }; UserSchema.statics.getDashboard = async function (idapp, aportador_solidario, username, aportador_solidario_nome_completo) { try { // DATA: username, name, surname, email, intcode_cell, cell const dashboard = { aportador: {}, downline: [] }; dashboard.myself = await User.getUserShortDataByUsername(idapp, username); // Data of my Aportador dashboard.aportador = await User.getUserShortDataByUsername(idapp, aportador_solidario); if (dashboard.aportador === undefined ) { dashboard.aportador = await ExtraList.getUserNotRegisteredByNameSurname(idapp, aportador_solidario_nome_completo); } // Data of my Downline const arrap = await User.getDownlineByUsername(idapp, aportador_solidario); dashboard.numpeople_aportador = arrap.length; dashboard.downline = await User.getDownlineByUsername(idapp, username); dashboard.downnotreg = await ExtraList.getDownlineNotRegisteredByNameSurname(idapp, dashboard.myself.name + ' ' + dashboard.myself.surname); dashboard.downbyuser = {}; for (const down of dashboard.downline) { dashboard.downbyuser[down.username] = await User.getDownlineByUsername(idapp, down.username); for (const down2 of dashboard.downbyuser[down.username]) { dashboard.downbyuser[down2.username] = await User.getDownlineByUsername(idapp, down2.username); } } return dashboard; } catch (e) { console.error(e); return false; } }; UserSchema.statics.fixUsername = async function (idapp, aportador_solidario_ind_order, username) { const User = this; // Check if somewhere there is my username return User.find({ idapp, aportador_solidario_ind_order }, async (err, arrrec) => { if (arrrec) { for (const myuser of arrrec) { if (!myuser.aportador_solidario || myuser.aportador_solidario === tools.APORTADOR_NONE) { myuser.aportador_solidario = username; await myuser.save() } } } }); }; UserSchema.statics.findByCellAndNameSurname = function (idapp, cell, name, surname) { const User = this; return User.findOne({ 'idapp': idapp, 'profile.cell': cell, 'name': name, 'surname': surname, }); }; UserSchema.statics.getUsersRegistered = async function (idapp) { const User = this; const myfind = { idapp }; return await User.count(myfind); }; UserSchema.statics.getEmailNotVerified = async function (idapp) { const User = this; const myfind = { idapp, verified_email: false }; return await User.count(myfind); }; UserSchema.statics.getUsersTelegramAttivo = async function (idapp) { const User = this; const myfind = { idapp, 'profile.teleg_id': { $gt: 0 } }; return await User.count(myfind); }; UserSchema.statics.getUsersTelegramPending = async function (idapp) { const User = this; const myfind = { idapp, 'profile.teleg_checkcode': { $gt: 0 } }; return await User.count(myfind); }; UserSchema.statics.getUsersZoom = async function (idapp) { const User = this; const myfind = { idapp, 'profile.saw_zoom_presentation': true }; return await User.count(myfind); }; UserSchema.statics.getUsersDreams = async function (idapp) { const User = this; const myfind = { idapp, 'profile.my_dream': { $exists: true }, "$expr": { "$gt": [{ "$strLenCP": "$profile.my_dream" }, 10] } }; return await User.count(myfind); }; UserSchema.statics.getLastUsers = async function (idapp) { const User = this; const lastn = await Settings.getValDbSettings(idapp, 'SHOW_LAST_N_USERS', 5); return await User.find({ idapp }).sort({ date_temp_reg: -1 }).limit(lastn).then((arr) => { //return JSON.stringify(arr) return arr }); }; UserSchema.statics.checkUser = async function (idapp, username) { const User = this; return await User.findOne({ idapp, username }, { verified_email: 1, 'profile.teleg_id': 1, 'profile.teleg_checkcode': 1, }).then((rec) => { return JSON.stringify(rec) }); }; UserSchema.statics.calculateStat = async function (idapp, username) { const User = this; return calcstat = { numinvitati: await User.getnumInvitati(idapp, username), numinvitati_attivi: await User.getnumInvitatiAttivi(idapp, username), }; }; UserSchema.statics.getDistinctNationalityQuery = function (idapp) { const query = [ { $match: { idapp } }, { $group: { _id: "$profile.nationality", count: { $sum: 1 } } }, { $sort: { count: -1 } } ]; return query }; UserSchema.statics.findAllDistinctNationality = async function (idapp) { const User = this; return User.aggregate(User.getDistinctNationalityQuery(idapp)) .then(ris => { // console.table(ris); return JSON.stringify(ris); }); }; UserSchema.statics.getUsersRegDaily = function (idapp, nrec) { const query = [ { $match: { idapp } }, { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date_temp_reg" } }, count: { $sum: 1 } } }, { $sort: { _id: 1 } }, { $limit: nrec } ]; return query }; UserSchema.statics.calcRegDaily = async function (idapp) { const User = this; return User.aggregate(User.getUsersRegDaily(idapp, 30)) .then(ris => { // console.table(ris); return JSON.stringify(ris); }); }; if (tools.INITDB_FIRSTIME) { console.log(' createIndex User Index...'); // UserSchema.index({ username: 'text', name: 'text', surname: 'text', email: 'text' }); // UserSchema.index({ name: 'name' }); // UserSchema.index({ name: 1 }); // UserSchema.index({ surname: 1 }); } UserSchema.statics.DbOp = async function (idapp, mydata) { const User = this; try { if (mydata.dbop === 'changeCellInt') { arrusers = await User.find({ 'idapp': idapp }); let num = 0; for (const rec of arrusers) { let mycell = tools.removespaces(rec.profile.intcode_cell + rec.profile.cell); await User.findOneAndUpdate({ _id: rec._id }, { $set: { 'profile.cell': mycell } }) num++; } return { num }; // return await User.updateMany({ idapp }, { $set: { 'profile.cell': { $concat: ["$profile.intcode_cell", "$profile.cell"] } } }) } } catch (e) { console.error(e); } }; const User = mongoose.model('User', UserSchema); class Hero { constructor(name, level) { this.name = name; this.level = level; } // Adding a method to the constructor greet() { return `${this.name} says hello.`; } } module.exports = { User, Hero };