From dacfc5a84463a3ba816014a88556e4e9b95c817d Mon Sep 17 00:00:00 2001 From: Surya Paolo Date: Thu, 8 Feb 2024 01:34:30 +0100 Subject: [PATCH] - aggiornato sistema per inviare le newsletter ! --- src/server/models/mailinglist.js | 82 ++++++++---------------- src/server/models/site.js | 1 + src/server/models/user.js | 86 ++++++++++++++++++++++++++ src/server/router/newsletter_router.js | 34 +++++++++- src/server/router/users_router.js | 10 +++ src/server/sendemail.js | 43 ++++++++----- src/server/server.js | 23 ++++--- src/server/tools/general.js | 29 ++++++++- 8 files changed, 223 insertions(+), 85 deletions(-) diff --git a/src/server/models/mailinglist.js b/src/server/models/mailinglist.js index 27085ae..cba709c 100755 --- a/src/server/models/mailinglist.js +++ b/src/server/models/mailinglist.js @@ -6,6 +6,7 @@ const tools = require('../tools/general'); mongoose.Promise = global.Promise; mongoose.level = "F"; +const { User } = require('./user'); // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { @@ -13,115 +14,84 @@ mongoose.plugin(schema => { }); const MailingListSchema = new Schema({ - idapp: { - type: String, - }, - email: { - type: String, - trim: true, - }, - hash: { - type: String, - }, - name: { - type: String, - trim: true, - }, - surname: { - type: String, - trim: true, - }, - statesub: { - type: Boolean, - default: true - }, - wrongerr: { - type: Boolean, - default: false - }, - lastid_newstosent: { - type: String - } }); -MailingListSchema.statics.getFieldsForSearch = function () { - return [{ field: 'name', type: tools.FieldType.string }, - { field: 'surname', type: tools.FieldType.string }, - { field: 'email', type: tools.FieldType.string }] -}; - MailingListSchema.statics.executeQueryTable = function (idapp, params) { - params.fieldsearch = this.getFieldsForSearch(); + params.fieldsearch = User.getFieldsForSearch(); return tools.executeQueryTable(this, idapp, params); }; MailingListSchema.statics.findAllIdAppSubscribed = function (idapp) { - const MailingList = this; - const myfind = { idapp, statesub: true, wrongerr: { $ne: true } }; + const myfind = { + idapp, + news_on: true, + $or: [ + { deleted: { $exists: false } }, + { deleted: { $exists: true, $eq: false } }], + $or: [ + { email_errata: { $exists: false } }, + { email_errata: { $exists: true, $ne: true } }], + }; // Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit. - return MailingList.find(myfind, (err, arrrec) => { + return User.find(myfind, (err, arrrec) => { return arrrec }); }; -MailingListSchema.statics.getnumSent = async function (idapp, idmailinglist) { - const MailingList = this; +MailingListSchema.statics.getnumSent = async function (idapp, idUser) { - const myfind = { idapp, statesub: true, lastid_newstosent: idmailinglist }; + const myfind = { idapp, news_on: true, lastid_newstosent: idUser }; // Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit. - return await MailingList.countDocuments(myfind); + return await User.countDocuments(myfind); }; -MailingListSchema.statics.isOk = async function (idapp, iduser, idmailinglist) { - const MailingList = this; +MailingListSchema.statics.isOk = async function (idapp, iduser, idUser) { - const myfind = { idapp, _id: iduser, statesub: true, lastid_newstosent: { $ne: idmailinglist } }; + + const myfind = { idapp, _id: iduser, news_on: true, lastid_newstosent: { $ne: idUser } }; // Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit. - return await MailingList.countDocuments(myfind) > 0; + return await User.countDocuments(myfind) > 0; }; MailingListSchema.statics.findAllIdApp = async function (idapp) { - const MailingList = this; + const myfind = { idapp }; - return await MailingList.find(myfind, (err, arrrec) => { + return await User.find(myfind, (err, arrrec) => { return arrrec }); }; MailingListSchema.statics.isUnsubscribed = async function (idapp, hash) { - const MailingList = this; - let myperson = await MailingList.findOne({ idapp, hash }); - console.log('myperson', myperson); + let myperson = await User.findOne({ idapp, hash }); if (!!myperson) { - return (!myperson.statesub) + return (!myperson.news_on) } }; MailingListSchema.statics.findByHash = function (idapp, hash) { - const MailingList = this; const myfind = { idapp, hash }; // Extract only the Teacher where in the users table the field permissions is set 'Teacher' bit. - return MailingList.findOne(myfind, (err, rec) => { + return User.findOne(myfind, (err, rec) => { return rec }); }; const MailingList = mongoose.model('MailingList', MailingListSchema); -MailingList.createIndexes((err) => { +User.createIndexes((err) => { if (err) throw err; }); diff --git a/src/server/models/site.js b/src/server/models/site.js index 80d42b6..208efc3 100755 --- a/src/server/models/site.js +++ b/src/server/models/site.js @@ -189,6 +189,7 @@ const SiteSchema = new Schema({ }, ecomm: { enablePreOrders: { type: Boolean, default: false }, + NoteExtraOnCart: { type: String, default: '' }, } }); diff --git a/src/server/models/user.js b/src/server/models/user.js index d8a2cbe..482f30e 100755 --- a/src/server/models/user.js +++ b/src/server/models/user.js @@ -56,6 +56,9 @@ const UserSchema = new mongoose.Schema({ message: '{VALUE} is not a valid email' }*/ }, + hash: { + type: String, + }, idapp: { type: String, required: true, @@ -164,6 +167,12 @@ const UserSchema = new mongoose.Schema({ news_on: { type: Boolean, }, + email_errata: { + type: Boolean, + }, + lastid_newstosent: { + type: String + }, aportador_solidario: { // da cancellare type: String, }, @@ -1146,6 +1155,70 @@ UserSchema.statics.setaportador_solidario = async function ( return !!myrec; }; +UserSchema.statics.setNewsletter = async function ( + idapp, username, newsletter_on) { + const User = this; + + if (username === undefined) + return false; + + const myquery = { + 'idapp': idapp, + 'username': username, + }; + + const myrec = await User.findOneAndUpdate(myquery, + { $set: { 'news_on': newsletter_on } }, { new: false }); + + return !!myrec; +}; + +UserSchema.statics.setEmailErrata = async function ( + idapp, username, email_errata) { + const User = this; + + if (username === undefined) + return false; + + const myquery = { + 'idapp': idapp, + 'username': username, + }; + + const myrec = await User.findOneAndUpdate(myquery, + { $set: { email_errata } }, { new: false }); + + return !!myrec; +}; + +UserSchema.statics.isEmailErrata = async function (idapp, username) { + const User = this; + + return await User.findOne({ + idapp, username, + $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], + }).then((rec) => { + return ((rec) ? rec.email_errata : false); + }).catch((e) => { + return false; + }); +}; +UserSchema.statics.isNewsletterOn = async function (idapp, username) { + const User = this; + + return await User.findOne({ + idapp, username, + $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], + }).then((rec) => { + return ((rec) ? rec.news_on : false); + }).catch((e) => { + console.error('isNewsletterOn', e); + return false; + }); +}; + + + UserSchema.statics.setVerifiedByAportadorToALL = async function () { return await User.updateMany({}, { $set: { 'verified_by_aportador': true } }, @@ -1549,6 +1622,19 @@ UserSchema.statics.getUsernameById = async function (idapp, id) { }); }; +UserSchema.statics.getUsernameByEmail = async function (idapp, email) { + const User = this; + + return await User.findOne({ + idapp, email, + $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], + }, { username: 1 }).then((myuser) => { + return ((myuser) ? myuser.username : ''); + }).catch((e) => { + + }); +}; + UserSchema.statics.getUserById = function (idapp, id) { const User = this; diff --git a/src/server/router/newsletter_router.js b/src/server/router/newsletter_router.js index dbb562a..f2c5a42 100755 --- a/src/server/router/newsletter_router.js +++ b/src/server/router/newsletter_router.js @@ -235,7 +235,7 @@ async function getDataNewsletter(lang, idapp) { for (const user of arrml) { data.totemail++; - if (user.statesub) + if (user.news_on) data.totsubscribed++; else data.totunsubscribed++; @@ -284,6 +284,38 @@ router.post('/setactivate', authenticate, async (req, res) => { }); +router.post('/unsubscribe_user', async (req, res) => { + hashemail = req.body.em; + email = req.body.email; + idapp = req.body.idapp; + locale = req.body.locale ?? 'it'; + + try { + const myuser = await User.findOne({ idapp, email }).lean(); + + if (myuser) { + const hashcalc = tools.getHash(myuser.email + myuser.username); + + if (hashcalc === hashemail) { + await User.setNewsletter(idapp, myuser.username, false); + + return res.send({ + code: server_constants.RIS_UNSUBSCRIBED_OK, + msg: server_constants.RIS_SUBSCRIBED_MSG[locale] + }); + } + } + + } catch (e) { + console.error('err', e); + } + res.send({ + code: server_constants.RIS_SUBSCRIBED_ERR + }); + + +}); + router.post('/unsubscribe', (req, res) => { console.log('unsubscribe -> ', req.body); diff --git a/src/server/router/users_router.js b/src/server/router/users_router.js index 8f02db2..6fa346e 100755 --- a/src/server/router/users_router.js +++ b/src/server/router/users_router.js @@ -1245,6 +1245,16 @@ async function eseguiDbOp(idapp, mydata, locale, req, res) { } else if (mydata.dbop === 'updateReactionsCounts') { await Reaction.updateReactionsCounts(); + } else if (mydata.dbop === 'AbilitaNewsletterALL') { + await User.updateMany({ + $or: [ + { deleted: { $exists: false } }, + { deleted: { $exists: true, $eq: false } }], + + }, + { $set: { news_on: true } }, + { new: false }); + } else if (mydata.dbop === 'removeRegulations') { await Circuit.updateMany({}, { $set: { regulation: '' } }); diff --git a/src/server/sendemail.js b/src/server/sendemail.js index 395fe89..c7aa58f 100755 --- a/src/server/sendemail.js +++ b/src/server/sendemail.js @@ -540,7 +540,7 @@ module.exports = { // Check if exist to the Mailing List let myperson = await MailingList.findByHash(idapp, hash); - if (!myperson || !myperson.statesub || !myperson.wrongerr) { + if (!myperson || !myperson.news_on || !myperson.email_errata) { if (!myperson) { myperson = new MailingList({ name: mylocalsconf.name, @@ -557,8 +557,8 @@ module.exports = { } myperson.idapp = idapp; - myperson.statesub = true; // subscription - myperson.wrongerr = false; + myperson.news_on = true; // subscription + myperson.email_errata = false; // Add/save new record to the DB MailingList const res = await myperson.save(); @@ -597,9 +597,9 @@ module.exports = { } const fields_to_update = { - statesub: false, + news_on: false, }; - let myperson = await MailingList.findOneAndUpdate({ + let myperson = await User.findOneAndUpdate({ idapp, hash: hashemail, }, { $set: fields_to_update }, { new: false }); @@ -618,16 +618,20 @@ module.exports = { }, fieldsloop: function (mylocalsconf, myvar) { - const baseurl = tools.getHostByIdApp(mylocalsconf.idapp); - const urlunsibscribe = baseurl + '/unsubscribe?em=' + mylocalsconf.hashemail + '&mc=' + mylocalsconf.dataemail.mailchimpactive + - '&email=' + mylocalsconf.emailto; + let out = ''; + try { + out = myvar.replace('{urlunsubscribe}', tools.getUnsubsribeUrl(mylocalsconf)); + out = out.replace('{urlunsubscribe_user}', tools.getUnsubsribeUrl_User({ idapp: mylocalsconf.idapp, email: mylocalsconf.emailto, username: mylocalsconf.username, name: mylocalsconf.name, surname: mylocalsconf.surname })); - let out = myvar.replace('{urlunsubscribe}', urlunsibscribe); - out = out.replace('{email}', mylocalsconf.emailto); - out = out.replace('{username}', mylocalsconf.username); - out = out.replace('{name}', mylocalsconf.name ? mylocalsconf.name : mylocalsconf.username); - out = out.replace('{surname}', mylocalsconf.surname ? mylocalsconf.surname : ''); - out = out.replace('{aportador_solidario}', mylocalsconf.aportador_solidario ? mylocalsconf.aportador_solidario : ''); + out = out.replace('{email}', mylocalsconf.emailto); + out = out.replace('{username}', mylocalsconf.username); + out = out.replace('{name}', mylocalsconf.name ? mylocalsconf.name : mylocalsconf.username); + out = out.replace('{surname}', mylocalsconf.surname ? mylocalsconf.surname : ''); + out = out.replace('{aportador_solidario}', mylocalsconf.aportador_solidario ? mylocalsconf.aportador_solidario : ''); + } catch (e) { + console.error('err fieldsloop', e); + return out; + } return out; }, @@ -641,6 +645,10 @@ module.exports = { if (mylocalsconf.dataemail.templ) mylocalsconf.dataemail.templ.testoheadermail_out = !!mylocalsconf.dataemail.templ.testoheadermail ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.testoheadermail) : ''; + + mylocalsconf.dataemail.templ.content = !!mylocalsconf.dataemail.templ.content ? this.fieldsloop(mylocalsconf, + mylocalsconf.dataemail.templ.content) : ''; + } catch (e) { console.error('Error replacefields: ' + e); } @@ -896,7 +904,7 @@ module.exports = { } //Put the result in the database, to check if is sent or not. - const updateml = await MailingList.findOneAndUpdate({ + const updateml = await User.findOneAndUpdate({ idapp, email: user.email, }, { $set: { lastid_newstosent: ObjectID(id_newstosent) } }, { new: false }); @@ -949,7 +957,7 @@ module.exports = { return await Newstosent.findNewsletter_To_Send(idapp).then((rec) => { if (rec) - this.sendNewsletter(rec); + this.sendNewsletter(rec, idapp); }); } , @@ -993,6 +1001,7 @@ module.exports = { arrevents: myarrevents, name: 'TestNome', surname: 'TestCognome', + username: await User.getUsernameByEmail(idapp, myemail), emailto: myemail, baseurl: tools.getHostByIdApp(idapp), hashemail: tools.getHash(myemail), @@ -1005,7 +1014,7 @@ module.exports = { mylocalsconf.dataemail.subject = mylocalsconf.dataemail && mylocalsconf.dataemail.templ ? mylocalsconf.dataemail.templ.subject : '', - this.replacefields(mylocalsconf); + this.replacefields(mylocalsconf); const smtpTransport = this.getTransport(mylocalsconf); diff --git a/src/server/server.js b/src/server/server.js index 1fc8539..d55e16b 100755 --- a/src/server/server.js +++ b/src/server/server.js @@ -348,6 +348,7 @@ async function mystart() { console.log('decrypted:', decrypt); } + mycron(); if (!process.env.DEBUG) { mycron(); } @@ -394,14 +395,20 @@ function populateDBadmin() { let cfg = new CfgServer(cfgserv[0]).save(); } -function mycron() { +async function mycron() { - const sendemail = require('./sendemail'); + try { + const sendemail = require('./sendemail'); - for (const app of tools.getApps()) { - sendemail.checkifPendingNewsletter(app.idapp); - sendemail.checkifSentNewsletter(app.idapp); + const arr = await tools.getApps(); + for (const app of arr) { + sendemail.checkifPendingNewsletter(app.idapp); + sendemail.checkifSentNewsletter(app.idapp); + + } + } catch (e) { + console.error('Err mycron', e); } } @@ -442,11 +449,11 @@ function testmsgwebpush() { } // Cron every X minutes -cron.schedule('*/2 * * * *', () => { +cron.schedule('*/1 * * * *', () => { // console.log('Running Cron Job'); - if (!process.env.DEBUG) { + // if (!process.env.DEBUG) { mycron(); - } + // } }); // Cron every X minutes diff --git a/src/server/tools/general.js b/src/server/tools/general.js index 66636ac..ff443f0 100755 --- a/src/server/tools/general.js +++ b/src/server/tools/general.js @@ -4044,6 +4044,26 @@ module.exports = { return msg; }, + getUnsubsribeUrl(mylocalsconf) { + + if (mylocalsconf) { + const baseurl = this.getHostByIdApp(mylocalsconf.idapp); + const urlunsibscribe = baseurl + '/unsubscribe?em=' + mylocalsconf.hashemail + '&mc=' + mylocalsconf.dataemail.mailchimpactive + + '&email=' + mylocalsconf.emailto; + return urlunsibscribe; + } + return ''; + }, + + getUnsubsribeUrl_User(user) { + + if (user && user.email) { + const hash = this.getHash(user.email + user.username); + return this.getHostByIdApp(user.idapp) + '/unsubscribe_user?em=' + hash + '&email=' + user.email; + } + return ''; + }, + async convertSpecialTags(user, msg) { try { if (!msg) @@ -4060,6 +4080,9 @@ module.exports = { msg = await this.checkStr(msg, '{time_exp_reg}', user, 1); msg = msg.replace('{name}', user.name ? user.name : user.username); msg = msg.replace('{surname}', user.surname ? user.surname : ''); + + let out = myvar.replace('{urlunsubscribe_user}', this.getUnsubsribeUrl_User(user)); + msg = msg.replace('{aportador_solidario}', user.aportador_solidario ? user.aportador_solidario : ''); if (!!user.profile.link_payment) msg = msg.replace('{link_paypalme}', user.profile.link_payment); @@ -4413,7 +4436,7 @@ module.exports = { getWeightAndUnitByText(text) { const result = []; - + text = text.replace(",", "."); const regex = /^(\d+\.?\d*)\s*(ml|gr|l|kg)\s*$/; // Aggiunto un punto dopo \d+ per accettare anche i numeri con la virgola @@ -4466,13 +4489,13 @@ module.exports = { if (valstr === '' || valstr === undefined) valstr = '0'; - + valstr = valstr + ''; valstr = valstr.replace(',', '.'); return parseFloat(valstr); }, - + convertPriceEurToValue(inputString) { inputString = this.removeescape(this.addslashes(inputString)) if (inputString === '')