Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
There are two kinds of events:
Reusable events which may happen many times, like a mouse click or a keypress. When subscribing to such an event, one normally does not care if an event has already been triggered in the past. One just needs to react to the event each time it happens in the future.
One-off events which only happen once, for instance a page load event, an ajax-request responce, a complete of a calculation delegated to a worker, or an asynchronous function callback. For this kind of events it matters if an event has already been triggered at the moment of subscription (which means there should be additional check). In latter case the listener should likely be performed immediately.
Whenable is a design pattern targeted to simplify dealing with the second kind of events by providing a special kind of listener subscriber. When using that subscriber, one does not need to worry about if an event has already been triggered, in this case the listener is invoked immediately. Additionally, the subscriber may be used several times to store additional listeners.
A good example of what could be simplified by using the Whenable solution is the page onload event. Here is how one can listen to the onload event in the traditional style:
if (document.readyState == "complete") {
// page has already been loaded
doWhatWeNeed();
} else {
// preserving any existing listener
var origOnload = window.onload || function(){};
window.onload = function(){
origOnload();
doWhatWeNeed();
}
}
The code should be performed each time a new listener should react to the onload event. Using a whenable subscriber everything above is simplified to:
window.whenLoaded(doWhatWeNeed);
The code says: call the given function doWhatWeNeed()
if the page
is loaded, otherwise wait until the page is loaded, and then call the
function.
Listener subscribers which behave like explained above are
conventionally named starting with the when..
prefix and followed by
a past participle describing an event: whenLoaded()
,
whenCompleted()
, whenFailedToLoad()
and so on. The Whenable term
is also used to refer to a one-off event supporting this kind of
subscription.
Whenable pattern was inspired by Promises, and it is similar to Promises in that it also allows not to care about when an event actually fires. But unlike Promises, Whenable is much easier to use and understand, produces simplier code, and is more general solution thus covering a wider range of use-cases.
This wl
library implements the Whenable
object, which represents
such an event and can be used to easily produce a whenable-style
subscriber.
For the web-browser environment — download the
distribution,
unpack it and load the wl.js
in a preferrable way. That is an
UMD module, thus for instance it may simply be loaded as a plain
JavaScript file using the <script>
tag:
<script src="wl/wl.js"></script>
For Node.js — install wl
with npm:
$ npm install wl
and then in your code:
var wl = require('wl');
Optionally you may load the script from the distribution:
var wl = require('path/to/wl.js');
After the module is loaded, the wl.Whenable()
constructor is
available.
Constructing a Whenable event is simple:
var myWhenable = new wl.Whenable;
The object has the two methods. The emit()
method fires the event
and invokes the subscribed listeners:
myWhenable.emit();
The getSubscriber()
method returns a whenable-style subscriber
function:
var whenEventTriggered = myWhenable.getSubscriber();
The subscriber may later be reused to subscribe a listener to the event:
whenEventTriggered(myListener);
The myListener()
will be invoked after the event is triggered. If
the event has already been triggered at the moment of subscription,
the listener is called immediately (yet asynchronously in order to
keep the flow consistent).
The methods of the Whenable
object (along with the Whenable
instance itself) are not supposed to be exposed to the event
user. Normally the Whenable
event is stored private and is emitted
by internal means. Instead the whenable subscriber function (returned
by the getSubscriber()
method) is to be provided to the user so that
he can attach listeners to the event.
When subscribing a listener, the context may be provided as a second argument:
whenEventTriggered(myObject.someMethod, myObject);
Upon the event is triggered, the subscribed listeners are executed in their respective contexts (if provided upon subscription).
Additionally, the emit()
method may take any set of arguments which
are simply forwarded as the arguments provided to the subscribed
listeners. This allows to supply the listeners with some details about
the event:
myWhenable.emit(result);
Here is an ordinary asynchronous function which executes a callback after some time:
var doSomething = function(cb) {
setTimeout(cb, 1000);
}
Let us create a Whenable event representing the function completion:
var somethingWhenable = new wl.Whenable;
var initiateSomething = function() {
doSomething(function() {
somethingWhenable.emit();
});
}
var whenSomethingDone = somethingWhenable.getSubscriber();
Now there are the two functions:
initiateSomething()
starts the process which should lead to the
event emission in the future, and
whenSomethingDone()
, the whenable-style subscriber which may
subscribe as many listeners as needed, before or after the event
is emitted.
Those two functions may now be used separately.
Similarly, if there is an asynchronous routine with two outcomes, one may prepare the two whenable events:
var doSomething = function(successCb, failureCb) {
var cb = function() {
try {
// do something that may fail
...
} catch(e) {
return failureCb();
}
successCb();
}
setTimeout(cb, 1000);
}
var success = new wl.Whenable;
var failure = new wl.Whenable;
var initiateSomething = function() {
doSomething(
function(){success.emit();},
function(){failure.emit();}
);
}
var whenSomethingSucceded = success.getSubscriber();
var whenSomethingFailed = failure.getSubscriber();
The code above provides the similar initiator function
initiateSomething()
, and the two whenable subscribers,
whenSomethingSucceeded()
and whenSomethingFailed()
which subscribe
a provided listener to the success or failure outcomes respectively.
Another example: here is the implementation of the magic
window.whenLoaded()
subscriber given in the beginning of this
text. The subscriber is used to react to the page load event:
var onloadWhenable = new wl.Whenable;
if (document.readyState == "complete") {
// already loaded
onloadWhenable.emit();
} else {
// preserving existing listener
var origOnload = window.onload || function(){};
window.onload = function(){
origOnload();
onloadWhenable.emit();
}
}
window.whenLoaded = onloadWhenable.getSubscriber();
FAQs
Whenable events implementation
We found that wl demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.