
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>joepie91&#39;s Ramblings</title>
		<description></description>		
		<link>http://cryto.net/~joepie91/blog</link>
		<atom:link href="http://cryto.net/~joepie91/blog/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>CloudFlare, We Have A Problem</title>
				<description>&lt;p&gt;For the past few years, CloudFlare has been steadily gaining popularity - being used by a staggering amount of websites, big and small. One of their frequently repeated claims to fame is that they &amp;quot;make web properties faster and safer&amp;quot;.&lt;/p&gt;

&lt;p&gt;I disagree.&lt;/p&gt;

&lt;p&gt;In reality, CloudFlare has been structurally making the web &lt;em&gt;less&lt;/em&gt; secure during these years. And they are incredibly good at selling that as a feature.&lt;/p&gt;

&lt;h3&gt;The Solution To No Problems&lt;/h3&gt;

&lt;p&gt;Back in 2011, when I ran AnonNews.org, I had to cope with frequent DDoS attacks - not all that surprising, given that it was a very popular news site and community for Anonymous, which was seeing the peak of its media coverage at the time. In 2011, however, it was pretty much impossible to get working DDoS mitigation for less than $100 a month, and that was simply not a budget I had to spend on it.&lt;/p&gt;

&lt;p&gt;I eventually ran across CloudFlare, and - despite it not advertising DDoS mitigation &lt;em&gt;anywhere&lt;/em&gt; at the time - I realized that with it being essentially a reverse proxy on beefy infrastructure, it would make for a useful pincushion against most DDoS attacks. And it did - it got in the way of many attacks, saved me some traffic as a bonus, and was overall a good solution to the problem at the time, even if it wasn&amp;#39;t &amp;quot;real&amp;quot; DDoS mitigation.&lt;/p&gt;

&lt;p&gt;Fast-forward to today, in 2016. It&amp;#39;s not so clear anymore whether CloudFlare really solves any problems. Single-homed bandwidth can be gotten for $0.35/TB, DDoS mitigation services are plentiful and sometimes even provided by default, and the web is generally Fast Enough. Of course this doesn&amp;#39;t stop CloudFlare from marketing to AWS customers - who are still grossly overpaying for bandwidth - or simply to those who are not aware of the changes in the hosting landscape.&lt;/p&gt;

&lt;p&gt;Essentially, there&amp;#39;s not really a reason to use CloudFlare anymore, and the majority of sites won&amp;#39;t see any real benefit from it at all. I&amp;#39;ll go into the alternatives further down the article, but I want to address some of the &lt;em&gt;problems&lt;/em&gt; that CloudFlare introduces first.&lt;/p&gt;

&lt;h3&gt;Encryption? What&amp;#39;s That?&lt;/h3&gt;

&lt;p&gt;A big issue with CloudFlare today is their &lt;a href=&quot;https://blog.cloudflare.com/introducing-universal-ssl/&quot;&gt;&amp;quot;Universal SSL&amp;quot;&lt;/a&gt; feature. Hailed as a way to &amp;quot;support SSL connections to every CloudFlare customer&amp;quot;, it actually does the very thing that SSL/TLS is meant to &lt;em&gt;prevent&lt;/em&gt;. One instance of this occurred today, when visitors of The Pirate Bay suddenly started &lt;a href=&quot;https://medium.com/@karthikb351/airtel-is-sniffing-and-censoring-cloudflares-traffic-in-india-and-they-don-t-even-know-it-90935f7f6d98&quot;&gt;seeing network blocking messages from Airtel&lt;/a&gt;. This wasn&amp;#39;t a compromise of CloudFlare; rather, the connection between CloudFlare and the real TPB servers wasn&amp;#39;t encrypted, and so &lt;em&gt;CloudFlare&amp;#39;s network provider&lt;/em&gt; could intercept and mess with the traffic.&lt;/p&gt;

&lt;p&gt;This is a simplified schematic illustrating what happened:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=&quot;post&quot;&gt;
&lt;img class=&quot;wide&quot; src=&quot;../../../../attachments/cloudflare1.png&quot;&gt;
&lt;/div&gt;&lt;/p&gt;&lt;div class=&quot;site&quot;&gt;&lt;div class=&quot;post&quot;&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The reason this could happen is CloudFlare&amp;#39;s &amp;quot;Flexible SSL&amp;quot; option, which is one of the modes in which &amp;quot;Universal SSL&amp;quot; can operate. In this mode, the TLS connection only runs from the end user to CloudFlare, and is plaintext beyond that point.&lt;/p&gt;

&lt;p&gt;See the problem?&lt;/p&gt;

&lt;p&gt;To the end user, it will look like they are &lt;em&gt;using TLS&lt;/em&gt;, and their connection is secure right up until the site they are trying to reach - after all, that&amp;#39;s how TLS is meant to work, right? In reality, anybody could have still messed with the traffic between CloudFlare and the &amp;quot;origin server&amp;quot;. The user is presented with a false sense of security, suggesting security that simply isn&amp;#39;t there. This breaks the TLS model, and is extremely dangerous; users will behave more carelessly because they believe they are being protected, resulting in a &lt;em&gt;greater&lt;/em&gt; compromise.&lt;/p&gt;

&lt;p&gt;The issue is made even worse by CloudFlare &lt;a href=&quot;http://www.theregister.co.uk/2016/07/14/cloudflare_investigating_mystery_interception_of_site_traffic_across_india/&quot;&gt;claiming&lt;/a&gt; that &amp;quot;there are no security flaws on its side&amp;quot;. Apparently, they don&amp;#39;t consider &amp;quot;complete compromise of the SSL/TLS trust model&amp;quot; a security flaw. Right.&lt;/p&gt;

&lt;p&gt;But let&amp;#39;s pretend that CloudFlare realizes that Flexible SSL was a mistake, and removes the option. They&amp;#39;d then require TLS between CloudFlare servers and the origin server as well. While this solves the specific problem of &lt;em&gt;other&lt;/em&gt; ISPs meddling with the connection, it leaves a bigger problem unsolved: the fact that CloudFlare &lt;em&gt;itself&lt;/em&gt; acts as an MITM (&lt;a href=&quot;https://en.wikipedia.org/wiki/Man-in-the-middle_attack&quot;&gt;man-in-the-middle&lt;/a&gt;). By the very definition of how their system works, they &lt;em&gt;must&lt;/em&gt; decrypt and then re-encrypt all traffic, meaning they will &lt;em&gt;always&lt;/em&gt; be able to see all the traffic on your site, no matter what you do.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=&quot;post&quot;&gt;
&lt;img class=&quot;wide&quot; src=&quot;../../../../attachments/cloudflare2.png&quot;&gt;
&lt;/div&gt;&lt;/p&gt;&lt;div class=&quot;site&quot;&gt;&lt;div class=&quot;post&quot;&gt;&lt;p&gt;&lt;/p&gt;

&lt;p&gt;This may not sound that bad - after all, they&amp;#39;re just a service provider, right? - but let&amp;#39;s put this in context for a moment. Currently, CloudFlare essentially controls 11% of the 10k biggest websites, over 8% of the 100k biggest websites (&lt;a href=&quot;https://trends.builtwith.com/cdn/CloudFlare&quot;&gt;source&lt;/a&gt;), and almost 5% of sites on the &lt;em&gt;entire web&lt;/em&gt; (&lt;a href=&quot;https://w3techs.com/technologies/details/cn-cloudflare/all/all&quot;&gt;source&lt;/a&gt;). According to their own numbers from 2012(!), they had more traffic than several of the most popular sites and services on earth combined, and almost half the traffic of Facebook. It has only grown since. And unlike every other backbone provider and mitigation provider, they can read your traffic &lt;em&gt;in plaintext&lt;/em&gt;, TLS or not.&lt;/p&gt;

&lt;p&gt;Could you claim with a straight face that all this intercepted data isn&amp;#39;t used by intelligence agencies, whether with CloudFlare&amp;#39;s cooperation or not? It would be the &lt;em&gt;perfect&lt;/em&gt; intelligence source, and the only way to have a &lt;em&gt;guarantee&lt;/em&gt; that target sites will never start encrypting the data - after all, that&amp;#39;s what they&amp;#39;re expecting the service to do for them!&lt;/p&gt;

&lt;p&gt;And what if somebody wanted to serve malware? What better place to do that than injected directly into potentially billions of sites, without any cross-domain restrictions whatsoever?&lt;/p&gt;

&lt;p&gt;And all of this is completely inevitable, because &lt;em&gt;CloudFlare&amp;#39;s very business model&lt;/em&gt; is based on the ability to intercept and read HTTP traffic. They can&amp;#39;t offer &lt;em&gt;any&lt;/em&gt; of their services without it.&lt;/p&gt;

&lt;p&gt;Which brings us to...&lt;/p&gt;

&lt;h3&gt;Packets, Please!&lt;/h3&gt;

&lt;p&gt;CloudFlare is frequently hailed as a &amp;quot;free DDoS mitigation provider&amp;quot;, ever since they started marketing themselves as such. The reality is very different; you won&amp;#39;t get any &lt;em&gt;actual&lt;/em&gt; DDoS mitigation, &lt;em&gt;even&lt;/em&gt; if you pay $200/month for their Business plan.&lt;/p&gt;

&lt;p&gt;Traditional DDoS mitigation services work by analyzing the packets coming in, spotting unusual patterns, and (temporarily) blocking the origin of that traffic. They never need to know &lt;em&gt;what&lt;/em&gt; the traffic contains, they only need to care about the patterns in which it is received. This means that you can tunnel TLS-encrypted traffic through a DDoS mitigation service just fine, without the mitigation service ever seeing the plaintext traffic... and you&amp;#39;re still protected.&lt;/p&gt;

&lt;p&gt;In contrast, CloudFlare is just a reverse proxy with a very fast connection. Layer 3/4 attacks (those aimed at the underlying network infrastructure, rather than the application or protocol itself) will only ever reach up to the point where it&amp;#39;s handled by a server rather than just passed through, and in a &amp;quot;reverse proxy&amp;quot;-type setup, that server is CloudFlare. They&amp;#39;re not actually &lt;em&gt;mitigating&lt;/em&gt; anything, it just so happens that they are the other side of the connection and thus &amp;quot;take the hit&amp;quot;!&lt;/p&gt;

&lt;p&gt;This is also why CloudFlare only supports HTTP(S), and not other protocols - they never actually pass through any traffic. Their servers will make a request to your site on the behalf of a visitor, and forward the response, after potentially modifying it first. They would have to write a custom reverse proxy for each protocol to support.&lt;/p&gt;

&lt;p&gt;At this point, you might be wondering &amp;quot;well okay, I get that, but why should I care as long as it protects my site?&amp;quot;, and the answer to that would be: because it doesn&amp;#39;t. You can&amp;#39;t protect the rest of your infrastructure (mailservers, chat servers, gameservers, and so on), and even for your web-based services, CloudFlare will kick you off the Free and Pro plans if you get attacked too much and they can figure out that you are the target.&lt;/p&gt;

&lt;p&gt;In other words: unless you pay them $200/month, they won&amp;#39;t provide any protection that you wouldn&amp;#39;t already have anyway. And if you &lt;em&gt;do&lt;/em&gt; pay them $200/month, you&amp;#39;ll get half-functional protection for a single protocol on a single domain, with all your users being completely exposed to CloudFlare and whatever other organizations might obtain access to their traffic or servers. As you&amp;#39;ll see below, this is a pretty shitty deal, and there are &lt;em&gt;far&lt;/em&gt; better options today.&lt;/p&gt;

&lt;p&gt;Oh, and about that &amp;quot;I&amp;#39;m Under Attack&amp;quot; mode that you get on the Free plan as well? Yeah, well, it doesn&amp;#39;t work. But don&amp;#39;t take my word for it - &lt;a href=&quot;https://gist.github.com/joepie91/c5949279cd52ce5cb646d7bd03c3ea36&quot;&gt;here&amp;#39;s proof&lt;/a&gt;. That code will solve the &amp;#39;challenge&amp;#39; that it presents to your browser, in a matter of milliseconds. Any attacker can trivially do this. And the challenge &lt;em&gt;can&amp;#39;t&lt;/em&gt; be made more difficult, because it would make it prohibitively expensive for mobile and embedded devices to use anything hosted at CloudFlare.&lt;/p&gt;

&lt;p&gt;But while it doesn&amp;#39;t stop attackers, it &lt;em&gt;does&lt;/em&gt; stop legitimate users. Which brings us to...&lt;/p&gt;

&lt;h3&gt;You Shall Not Pass&lt;/h3&gt;

&lt;p&gt;See, the &amp;quot;I&amp;#39;m Under Attack&amp;quot; system imposes some problems. By its very definition, it requires that you have JavaScript enabled to be able to view a site - note that I&amp;#39;m &lt;em&gt;not&lt;/em&gt; talking about the CAPTCHA page here, but about the &lt;em&gt;&amp;quot;Checking your browser...&amp;quot;&lt;/em&gt; page.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s quite frequently claimed that &amp;quot;oh well, everybody has JS anyway&amp;quot;, but this is simply not true. Eevee has written an &lt;a href=&quot;https://eev.ee/blog/2016/03/06/maybe-we-could-tone-down-the-javascript/&quot;&gt;excellent article&lt;/a&gt; about this problem, including many examples where this assumption doesn&amp;#39;t hold true.&lt;/p&gt;

&lt;p&gt;But I want to address an issue that I&amp;#39;ve had &lt;em&gt;specifically&lt;/em&gt; with CloudFlare&amp;#39;s &amp;quot;I&amp;#39;m Under Attack&amp;quot; mode. I&amp;#39;m involved in &lt;a href=&quot;http://archiveteam.org/&quot;&gt;ArchiveTeam&lt;/a&gt;, essentially a loose collective of archivists that try to preserve culture and knowledge on an ever-rotting web - the rotting usually being a result of service providers throwing away user data on 2 weeks notice because it&amp;#39;s no longer profitable to them, not really caring about the consequences for the users.&lt;/p&gt;

&lt;p&gt;One of the services that ArchiveTeam operates is &lt;a href=&quot;http://archiveteam.org/index.php?title=ArchiveBot&quot;&gt;ArchiveBot&lt;/a&gt;, essentially an IRC bot that archives whatever is thrown at it, and adds it to the Internet Archive. You can kind of think of it as an on-demand, public service Wayback machine. To be able to do this, it needs to access websites - not as a browser, but just as a plain HTTP client - and spider their content. Somewhat predictably, ArchiveBot has very limited support for JavaScript.&lt;/p&gt;

&lt;p&gt;Indeed it is essentially impossible to archive something that&amp;#39;s in &amp;quot;I&amp;#39;m Under Attack&amp;quot; mode, despite that usually being the exact moment where archival is &lt;em&gt;necessary&lt;/em&gt;!&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve been told that ArchiveBot can be added to the internal whitelist that CloudFlare has, but this completely misses the point. Why do I or anybody else need to talk to a centralized gatekeeper to be able to access content on the web, especially if there might be any number of such gatekeepers? This kind of approach defeats the very point of the web and how it was designed!&lt;/p&gt;

&lt;p&gt;And for a volunteer-run organization like ArchiveTeam, it&amp;#39;s far more tricky to implement support for these &amp;quot;challenge schemes&amp;quot; than it is for a botnet operator, who stands to profit from it. That problem only becomes worse as more services start implementing these kind of schemes, and often it takes a while for people to notice that their requests are being blocked - sometimes losing important information in the process.&lt;/p&gt;

&lt;p&gt;Some might argue that these kind of archival bots are precisely what CloudFlare is meant to protect against, but that&amp;#39;s not really true. If that were the case, why would there be an offer to add ArchiveBot to the whitelist to begin with? Why would the Wayback Machine be on that very same whitelist?&lt;/p&gt;

&lt;p&gt;Speaking of which, perhaps you&amp;#39;re using CloudFlare because of their blocking of spambots. Apart from the fact that blacklists for this are freely available and don&amp;#39;t require sending your traffic through a centralized middleman, it&amp;#39;s also a completely misguided approach. It&amp;#39;s based entirely on the premise of &amp;quot;malicious IPs&amp;quot;, but &lt;em&gt;there is no such thing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;IP addresses change hands frequently, can be shared by tens of thousands of people, and can be reassigned to a different household 10 minutes later. In reality, there are only malicious &lt;em&gt;clients&lt;/em&gt; and malicious &lt;em&gt;users&lt;/em&gt;, and trying to identify them by IP will lead to a &lt;em&gt;lot&lt;/em&gt; of false positives, and not just &lt;a href=&quot;https://blog.torproject.org/blog/trouble-cloudflare&quot;&gt;on Tor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;effective&lt;/em&gt; way to deal with malicious clients and users isn&amp;#39;t to block &amp;quot;known-bad IPs&amp;quot; - because again, those do not exist, and there&amp;#39;s no correlation to clients or users. It&amp;#39;s to detect patterns of abusive behaviour, and to encourage the behaviour that you desire. Blocking IPs is akin to banning trucks from the freeway - sure, you&amp;#39;ve reduced the amount of truck-on-car collisions to zero, but was the loss of commercial transport really worth it?&lt;/p&gt;

&lt;p&gt;As somebody who has run various high-risk services over the years, attracting a &lt;em&gt;lot&lt;/em&gt; of targeted abuse, I can confidently say that IP blocking is never necessary and rarely effective.&lt;/p&gt;

&lt;h3&gt;But The Speed! The &lt;em&gt;Speed!&lt;/em&gt;&lt;/h3&gt;

&lt;p&gt;CloudFlare&amp;#39;s original mass-market selling point, performance. Route your traffic through us, and everything will be magically faster! Well, as it turns out, that&amp;#39;s not quite true. Where to start...&lt;/p&gt;

&lt;p&gt;In most of the Western world, connectivity is pretty good. You can go from most places in the US to Europe and back - across the ocean! - in about 140 milliseconds. A commonly used metric in the web development industry is that your page and all your assets should be loaded in under 300 milliseconds.&lt;/p&gt;

&lt;p&gt;Assuming you&amp;#39;re declaring all the assets on your page directly, that would make it two roundtrips totalling about 280 milliseconds, since the assets can be retrieved in parallel. Even if you have to cross the Atlantic, you&amp;#39;re still going to clock in under the guideline, without any CDN or geolocation whatsoever.&lt;/p&gt;

&lt;p&gt;But some people still want to squeeze out more performance - for example, they might have assets referenced a few levels deep, or they consider every millisecond critical because they are in e-commerce. Whether that&amp;#39;s a valid concern is something I&amp;#39;ll leave in the middle, but let&amp;#39;s assume for now that it is. Even in this case, the problem is still &lt;em&gt;static assets&lt;/em&gt; - CloudFlare &lt;em&gt;can&amp;#39;t&lt;/em&gt; cache the actual pageloads locally, because they are dynamic and different for everybody.&lt;/p&gt;

&lt;p&gt;So why not just use a CDN? Using a CDN means you can still optimize your asset loading, but you don&amp;#39;t have to forward all your pageloads through CloudFlare. Static assets are &lt;em&gt;much&lt;/em&gt; less sensitive, from a privacy perspective.&lt;/p&gt;

&lt;p&gt;But perhaps you&amp;#39;re also targeting users in regions with historically poor connectivity, such as large parts of Asia. Well, turns out that it doesn&amp;#39;t really work there &lt;em&gt;either&lt;/em&gt; - CloudFlare customers routinely report performance problems in these regions that are worse than they were before they switched to CloudFlare.&lt;/p&gt;

&lt;p&gt;This is not really surprising, given the mess of peering agreements in Asia; using CloudFlare just means you&amp;#39;re adding an additional hop to go through, which increases the risk of ending up on a strange and slow route.&lt;/p&gt;

&lt;p&gt;And this is the problem with CloudFlare in general - you can&amp;#39;t usually make things faster by routing connections through somewhere, because you&amp;#39;re adding an &lt;em&gt;extra location&lt;/em&gt; for the traffic to travel to, before reaching the origin server. There are some cases where these kind of techniques can make a real difference, but they are so rare that it&amp;#39;s unreasonable to build a business model on it. Yet, that&amp;#39;s precisely what CloudFlare has done.&lt;/p&gt;

&lt;p&gt;But perhaps you&amp;#39;re thinking of the extra features that they offer like bundling assets, minification, cache headers, different loading orders, and so on. However, all of these are things that you can do &lt;em&gt;on your own infrastructure&lt;/em&gt;, and &lt;em&gt;without&lt;/em&gt; compromising the privacy of your users. Sending your traffic through a third party is completely unnecessary for that.&lt;/p&gt;

&lt;p&gt;To top it off, for most cases none of this matters anyway - more and more organizations are (unnecessarily) turning their sites into Single Page Applications, and don&amp;#39;t realize that this adds entire &lt;em&gt;seconds&lt;/em&gt; of rendering time on top of your milliseconds worth of asset retrieval. Why bother with those 50 milliseconds difference, especially at such a cost?&lt;/p&gt;

&lt;h3&gt;What Of My Web?&lt;/h3&gt;

&lt;p&gt;Unfortunately, all of these issues together mean that CloudFlare is essentially breaking the open web. Extreme centralization, breaking the trust model of SSL/TLS, a misguided IP blocking strategy, requiring specific technologies like JavaScript to be able to access sites, and so on. None of this benefits anybody but CloudFlare and its partners.&lt;/p&gt;

&lt;p&gt;For you as a CloudFlare customer, the problem is bigger - by routing your traffic through CloudFlare, you are essentially exposing &lt;em&gt;every single one of your users completely&lt;/em&gt;, to CloudFlare and more than likely to intelligence agencies as well. Browsing behaviour, credit card details, passwords, private conversations, &lt;em&gt;everything&lt;/em&gt;. Even if you just have a small static site like a blog, your users can be tracked as having visited it, without either you or your users having any knowledge of it whatsoever.&lt;/p&gt;

&lt;p&gt;We shouldn&amp;#39;t want this, especially if it&amp;#39;s completely unnecessary.&lt;/p&gt;

&lt;h3&gt;And What Of My Provider?&lt;/h3&gt;

&lt;p&gt;One argument I saw in response to this, was that you are trusting your hosting provider &lt;em&gt;anyway&lt;/em&gt;, and so adding CloudFlare doesn&amp;#39;t really do any harm. This is really not true, though - not only does CloudFlare run at a &lt;em&gt;far&lt;/em&gt; larger scale than any hosting provider, they are also in a much better position to maliciously intercept traffic (or be forced to do so). It&amp;#39;s &lt;em&gt;considerably&lt;/em&gt; easier to do dragnet interception on a reverse proxy, than it is to compromise every single server in a datacenter. And either way, you now have &lt;em&gt;two&lt;/em&gt; providers you need to trust, rather than one.&lt;/p&gt;

&lt;p&gt;Another argument is that CloudFlare just does the same thing that load balancers have been doing for over a decade, and that this isn&amp;#39;t really anything new. But while the &lt;em&gt;functionality&lt;/em&gt; is the same, the &lt;em&gt;context&lt;/em&gt; is not - traditional load balancers run on the same network as the servers they are balancing between, and so the risk of interception is almost non-existent. While there are some newer providers that offer similar services to CloudFlare - and I consider them bad on exactly the same grounds - they run on a much smaller scale, and have much less impact.&lt;/p&gt;

&lt;h3&gt;Whence Shall I Source My Solutions?&lt;/h3&gt;

&lt;p&gt;Of course, it&amp;#39;d be a bit strange for me to claim that CloudFlare has outlived its usefulness, and then not provide any alternatives. Thankfully I&amp;#39;ve had this discussion before &lt;a href=&quot;https://news.ycombinator.com/item?id=11913591&quot;&gt;on Hacker News&lt;/a&gt;, so I have some concrete alternatives handy.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ll reiterate them here for your convenience:&lt;/p&gt;

&lt;h4&gt;DDoS mitigation&lt;/h4&gt;

&lt;p&gt;Use a real (network-level) mitigation provider.&lt;/p&gt;

&lt;p&gt;Some providers include mitigation for free with your hosting service (OVH, Online.net, ServerCrate, ...). Others charge a small fee, typically between $1 and $5 (RamNode, BuyVM, SecureDragon, ...).&lt;/p&gt;

&lt;p&gt;There are also dedicated mitigation providers for more demanding usecases (Akamai, Level3, Voxility, CNServers, Sharktech, ...) and some providers that resell and/or combine these services (eg. X4B.net).&lt;/p&gt;

&lt;p&gt;If you have your own physical infrastructure, you can also pick a mitigation appliance provider. There are quite a few.&lt;/p&gt;

&lt;h4&gt;Easy and free SSL/TLS&lt;/h4&gt;

&lt;p&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&amp;#39;s Encrypt&lt;/a&gt; offers free browser-recognized SSL/TLS certificates. If you don&amp;#39;t want the hassle of setting it up, &lt;a href=&quot;https://caddyserver.com/&quot;&gt;Caddy&lt;/a&gt; is a web server that will automatically set up SSL/TLS using Let&amp;#39;s Encrypt certificates out of the box, no configuration required.&lt;/p&gt;

&lt;h4&gt;Web Application Firewall&lt;/h4&gt;

&lt;p&gt;Run one on your own backend server(s) and/or loadbalancer(s). There&amp;#39;s no benefit to doing this remotely, really. Even something relatively simple like ModSecurity will cover a wide array of problems.&lt;/p&gt;

&lt;h4&gt;Better performance&lt;/h4&gt;

&lt;p&gt;Do server-side optimizations of your code. Don&amp;#39;t build an SPA unless you need it - it will significantly slow things down for your users.&lt;/p&gt;

&lt;p&gt;Use a (real) CDN for your static assets, not a proxy like CloudFlare. If you want to optimize your dynamic pageloads as well, look into Anycast hosting (&lt;a href=&quot;http://buyvm.net/anycast-vps/&quot;&gt;BuyVM&lt;/a&gt;, &lt;a href=&quot;https://www.bhost.net/anycast/&quot;&gt;BHost&lt;/a&gt;, and so on.)&lt;/p&gt;

&lt;h4&gt;Saving bandwidth&lt;/h4&gt;

&lt;p&gt;Don&amp;#39;t bother, beyond the usual performance improvements described above. Use a provider that doesn&amp;#39;t gouge you over it - a typical cost for both VPSes and dedicated servers is $1 to $5 per TB per month, with no additional fee for the connection.&lt;/p&gt;

&lt;h4&gt;Free DNS&lt;/h4&gt;

&lt;p&gt;Many hosting providers offer this for free with your plan. If you&amp;#39;d rather not put all your eggs into one basket, &lt;a href=&quot;http://dns.he.net/&quot;&gt;Hurricane Electric&lt;/a&gt; offers free dual-stack Anycast DNS.&lt;/p&gt;

&lt;h4&gt;Other things&lt;/h4&gt;

&lt;p&gt;If there&amp;#39;s anything you&amp;#39;re using CloudFlare (or similar services) for that isn&amp;#39;t listed here, then please do let me know, and I&amp;#39;ll do my best to find you a less harmful alternative. My contact details are at the bottom of this article.&lt;/p&gt;

&lt;p&gt;You can also leave comments in the &lt;a href=&quot;https://news.ycombinator.com/item?id=12096321&quot;&gt;thread on Hacker News&lt;/a&gt;.&lt;/p&gt;
</description>
				<pubDate>Thu, 14 Jul 2016 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2016/07/14/cloudflare-we-have-a-problem</guid>
			</item>
		
			<item>
				<title>Stop using JWT for sessions, part 2: Why your solution doesn&#39;t work</title>
				<description>&lt;p&gt;Almost a week ago I &lt;a href=&quot;http://cryto.net/%7Ejoepie91/blog/2016/06/13/stop-using-jwt-for-sessions/&quot;&gt;published an article&lt;/a&gt; explaining why you shouldn&amp;#39;t use JSON Web Tokens as a session mechanism.&lt;/p&gt;

&lt;p&gt;Unfortunately, it seems I&amp;#39;ve found the upper limit on article length before people stop reading - &lt;em&gt;many&lt;/em&gt; of the commenters on Reddit and Hacker News kept suggesting the same &amp;quot;solutions&amp;quot; over and over again, completely ignoring that they were already addressed and found impractical in the article itself.&lt;/p&gt;

&lt;p&gt;So, this time, I&amp;#39;m going to illustrate it with a slightly sarcastic flowchart.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=&quot;post&quot;&gt;
&lt;a href=&quot;../../../../attachments/jwt-flowchart.png&quot;&gt;&lt;img class=&quot;wide&quot; src=&quot;../../../../attachments/jwt-flowchart.png&quot;&gt;&lt;/a&gt;
&lt;/div&gt;&lt;/p&gt;&lt;div class=&quot;site&quot;&gt;&lt;div class=&quot;post&quot;&gt;&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;Footnote: microservice architectures&lt;/h3&gt;

&lt;p&gt;Another argument that came up a lot, was that using JWT for sessions is still fine in a microservice architecture. This one is &lt;em&gt;also&lt;/em&gt; wrong, but is a bit too complex to fit into a flowchart.&lt;/p&gt;

&lt;p&gt;In a microservice architecture &lt;em&gt;where the client talks directly to the services&lt;/em&gt;, you will have roughly two types of services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stateful services:&lt;/strong&gt; Something that has a concept of a session or persistence, like a chat service.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stateless services:&lt;/strong&gt; Something that does &lt;em&gt;not&lt;/em&gt; have a concept of a session, but rather performs individual self-contained tasks, like a video transcoding service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don&amp;#39;t need to use JWT token as a session in either case. For a stateless service, there&amp;#39;s no session at all, so you simply have the application server hand out &lt;em&gt;short-lived, single-use&lt;/em&gt; tokens for each individual authorized operation.&lt;/p&gt;

&lt;p&gt;For a stateful service, you hand out a new &lt;em&gt;short-lived, single-use&lt;/em&gt; token for each service - which is then exchanged on the service itself, for a &lt;em&gt;session on that specific service&lt;/em&gt;. You never use the token itself &lt;em&gt;as&lt;/em&gt; the session.&lt;/p&gt;

&lt;p&gt;In a microservice architecture &lt;em&gt;where the client only talks to the application server&lt;/em&gt;, none of this as relevant, as there&amp;#39;s no concept of a &amp;quot;session&amp;quot; between services - it&amp;#39;s all individual, self-contained actions from the same origin(s). It&amp;#39;s probably fine to use JWT tokens there, even if they&amp;#39;re not optimal for this kind of case - you&amp;#39;re just not using them &lt;em&gt;as sessions&lt;/em&gt;.&lt;/p&gt;
</description>
				<pubDate>Sun, 19 Jun 2016 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work</guid>
			</item>
		
			<item>
				<title>Stop using JWT for sessions</title>
				<description>&lt;p&gt;&lt;strong&gt;Update - June 19, 2016:&lt;/strong&gt; A lot of people have been suggesting the same &amp;quot;solutions&amp;quot; to the problems below, but none of them are practical. I&amp;#39;ve &lt;a href=&quot;http://cryto.net/%7Ejoepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/&quot;&gt;published a new post&lt;/a&gt; with a slightly sarcastic flowchart - please have a look at it before suggesting a solution.&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;Unfortunately, lately I&amp;#39;ve seen more and more people recommending to use JWT (&lt;a href=&quot;https://en.wikipedia.org/wiki/JSON_Web_Token&quot;&gt;JSON Web Tokens&lt;/a&gt;) for managing user sessions in their web applications. This is a terrible, &lt;em&gt;terrible&lt;/em&gt; idea, and in this post, I&amp;#39;ll explain why.&lt;/p&gt;

&lt;p&gt;Just to prevent any confusion, I&amp;#39;ll define a few terms first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stateless JWT:&lt;/strong&gt; A JWT token that contains the session data, encoded directly into the token.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stateful JWT:&lt;/strong&gt; A JWT token that contains just a reference or ID for the session. The session data is stored server-side.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session token/cookie:&lt;/strong&gt; A standard (optionally signed) session ID, like web frameworks have been using for a long time. The session data is stored server-side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To be clear: This article does &lt;em&gt;not&lt;/em&gt; argue that you should &lt;em&gt;never&lt;/em&gt; use JWT - just that it isn&amp;#39;t suitable as a session mechanism, and that it is &lt;strong&gt;dangerous&lt;/strong&gt; to use it like that. Valid usecases &lt;em&gt;do&lt;/em&gt; exist for them, in other areas. At the end of this article, I&amp;#39;ll briefly go into those other usecases.&lt;/p&gt;

&lt;h3&gt;A note upfront&lt;/h3&gt;

&lt;p&gt;A lot of people mistakenly try to compare &amp;quot;cookies vs. JWT&amp;quot;. This comparison makes no sense at all, and it&amp;#39;s comparing apples to oranges - cookies are a &lt;em&gt;storage mechanism&lt;/em&gt;, whereas JWT tokens are &lt;em&gt;cryptographically signed tokens&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;They aren&amp;#39;t opposites - rather, they can be used either together or independently. The correct comparisons are &amp;quot;&lt;em&gt;sessions&lt;/em&gt; vs. JWT&amp;quot; and &amp;quot;cookies vs. Local Storage&amp;quot;.&lt;/p&gt;

&lt;p&gt;In this particular article, I will be comparing sessions to JWT tokens, and occasionally go into &amp;quot;cookies vs. Local Storage&amp;quot; as well where it makes sense to do so.&lt;/p&gt;

&lt;h3&gt;Claimed advantages of JWT&lt;/h3&gt;

&lt;p&gt;When people recommend JWT, they usually claim one or more of the following benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easier to (horizontally) scale&lt;/li&gt;
&lt;li&gt;Easier to use&lt;/li&gt;
&lt;li&gt;More flexible&lt;/li&gt;
&lt;li&gt;More secure&lt;/li&gt;
&lt;li&gt;Built-in expiration functionality&lt;/li&gt;
&lt;li&gt;No need to ask users for &amp;#39;cookie consent&amp;#39;&lt;/li&gt;
&lt;li&gt;Prevents CSRF&lt;/li&gt;
&lt;li&gt;Works better on mobile&lt;/li&gt;
&lt;li&gt;Works for users that block cookies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&amp;#39;ll address each of these claims - and why they are wrong or misleading - individually. Some of the explanations below may be a little vague; that&amp;#39;s primarily because &lt;em&gt;the claims themselves&lt;/em&gt; are vague. I&amp;#39;ll happily update it to address more specific claims; you can find my contact details at the bottom of this article.&lt;/p&gt;

&lt;h4&gt;Easier to (horizontally) scale&lt;/h4&gt;

&lt;p&gt;This is the only claim in the list that is &lt;em&gt;technically&lt;/em&gt; somewhat true, but only if you are using &lt;em&gt;stateless&lt;/em&gt; JWT tokens. The reality, however, is that almost nobody actually &lt;em&gt;needs&lt;/em&gt; this kind of scalability - there are many easier ways to scale up, and unless you are operating at the size of Reddit, you will not need &amp;#39;stateless sessions&amp;#39;.&lt;/p&gt;

&lt;p&gt;Some examples of scaling &lt;em&gt;stateful&lt;/em&gt; sessions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Once you run multiple backend processes on a server:&lt;/strong&gt; A Redis daemon (on that server) for session storage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Once you run on multiple servers:&lt;/strong&gt; A dedicated server running Redis just for session storage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Once you run on multiple servers, in multiple clusters:&lt;/strong&gt; Sticky sessions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are all scenarios that are well-supported by existing software. Your application is &lt;em&gt;very&lt;/em&gt; unlikely to ever go beyond the second step.&lt;/p&gt;

&lt;p&gt;Perhaps you&amp;#39;re thinking that you should &amp;quot;future-proof&amp;quot; your application, in case you &lt;em&gt;do&lt;/em&gt; ever scale up beyond that. In practice, however, it&amp;#39;s fairly trivial to replace the session mechanism at a later point, with the only cost being logging out every user &lt;em&gt;once&lt;/em&gt;, when you make the transition. It&amp;#39;s just not worth it to implement JWT upfront, especially considering the downsides that I&amp;#39;ll get to later.&lt;/p&gt;

&lt;h4&gt;Easier to use&lt;/h4&gt;

&lt;p&gt;They really aren&amp;#39;t. You will have to deal with session management yourself, on both the client and the server side, whereas standard session cookies &lt;em&gt;just work&lt;/em&gt;, out of the box. JWT isn&amp;#39;t easier in any way.&lt;/p&gt;

&lt;h4&gt;More flexible&lt;/h4&gt;

&lt;p&gt;I have yet to see somebody actually explain &lt;em&gt;how&lt;/em&gt; JWT is more flexible. Almost every major session implementation lets you store arbitrary data for the session &lt;em&gt;anyway&lt;/em&gt;, and this is no different from how JWT works. As far as I can tell, this is just used as a buzzword. If you disagree, feel free to contact me with examples.&lt;/p&gt;

&lt;h4&gt;More secure&lt;/h4&gt;

&lt;p&gt;A lot of people think that JWT tokens are &amp;quot;more secure&amp;quot; because they use cryptography. While signed cookies &lt;em&gt;are&lt;/em&gt; more secure than unsigned cookies, this is in no way unique to JWT, and good session implementations use signed cookies as well.&lt;/p&gt;

&lt;p&gt;&amp;quot;It uses cryptography&amp;quot; doesn&amp;#39;t magically make something more secure either; it must serve a specific purpose, and be an effective solution for that specific purpose. Incorrectly used cryptography can, in fact, make something &lt;em&gt;less&lt;/em&gt; secure.&lt;/p&gt;

&lt;p&gt;Another explanation of the &amp;quot;more secure&amp;quot; argument that I hear a lot, is that &amp;quot;they are not sent as a cookie&amp;quot;. This makes absolutely no sense - a cookie is just a HTTP header, and there&amp;#39;s nothing insecure about using cookies. In fact, cookies are &lt;em&gt;especially&lt;/em&gt; well-protected against eg. malicious client-side code, something I&amp;#39;ll get into later.&lt;/p&gt;

&lt;p&gt;If you are concerned about somebody intercepting your session cookie, you should just be using &lt;a href=&quot;https://en.wikipedia.org/wiki/Transport_Layer_Security&quot;&gt;TLS&lt;/a&gt; instead - &lt;em&gt;any&lt;/em&gt; kind of session implementation will be interceptable if you don&amp;#39;t use TLS, including JWT.&lt;/p&gt;

&lt;h4&gt;Built-in expiration functionality&lt;/h4&gt;

&lt;p&gt;This is nonsense, and not a useful feature. Expiration can be implemented server-side just as well, and many implementations do. Server-side expiration is preferable, in fact - it allows your application to clean up session data that it doesn&amp;#39;t need anymore, something you can&amp;#39;t do if you use stateful JWT tokens and rely on their expiration mechanism.&lt;/p&gt;

&lt;h4&gt;No need to ask users for &amp;#39;cookie consent&amp;#39;&lt;/h4&gt;

&lt;p&gt;Completely wrong. There&amp;#39;s no such thing as a &amp;quot;cookie law&amp;quot; - the various laws concerning cookies actually cover &lt;em&gt;any&lt;/em&gt; kind of persistent identifier that isn&amp;#39;t strictly necessary for the functioning of the service. Any session mechanism you can think of will be covered by this.&lt;/p&gt;

&lt;p&gt;In a nutshell:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are using a session or token for functional purposes (eg. keeping a user logged in), then you &lt;em&gt;don&amp;#39;t&lt;/em&gt; need to ask for user consent, regardless of how you store that session.&lt;/li&gt;
&lt;li&gt;If you are using a session or token for other purposes (eg. analytics or tracking), then you &lt;em&gt;do&lt;/em&gt; need to ask for user consent, &lt;em&gt;regardless of how you store that session&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Prevents CSRF&lt;/h4&gt;

&lt;p&gt;It doesn&amp;#39;t, really. There are roughly two ways to store a JWT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;In a cookie:&lt;/strong&gt; Now you are still vulnerable to CSRF attacks, and still need protection against it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Elsewhere, eg. Local Storage:&lt;/strong&gt; Now you are not vulnerable to CSRF attacks, but your application or site now requires JavaScript to work, &lt;em&gt;and&lt;/em&gt; you&amp;#39;ve just made yourself vulnerable to an entirely different, potentially &lt;em&gt;worse&lt;/em&gt; class of vulnerabilities. More about this below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;em&gt;only&lt;/em&gt; correct CSRF mitigation is a CSRF token. The session mechanism is not relevant here.&lt;/p&gt;

&lt;h4&gt;Works better on mobile&lt;/h4&gt;

&lt;p&gt;Nonsense. Every mobile browser still in use supports cookies, and thus sessions. The same goes for every major mobile development framework, and any serious HTTP library. This is just not a problem &lt;em&gt;at all&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;Works for users that block cookies&lt;/h4&gt;

&lt;p&gt;Unlikely. Users don&amp;#39;t just block cookies, they typically block &lt;em&gt;all&lt;/em&gt; means of persistence. That includes Local Storage, and any other storage mechanism that would allow you to persist a session (with or without using JWT). Whether you use JWT simply doesn&amp;#39;t matter here, it&amp;#39;s an entirely separate problem - and trying to get authentication to work without cookies is a bit of a lost cause.&lt;/p&gt;

&lt;p&gt;On top of that, users that block &lt;em&gt;all&lt;/em&gt; cookies typically understand that this will break authentication functionality for them, and individually unblock cookies for sites where they care about this. It&amp;#39;s simply not a problem that you, as a web developer, need to be solving; a much better solution is to explain to your users &lt;em&gt;why&lt;/em&gt; your site requires cookies to work.&lt;/p&gt;

&lt;h3&gt;The drawbacks&lt;/h3&gt;

&lt;p&gt;Now that I&amp;#39;ve covered all the common claims and why they&amp;#39;re wrong, you might think &amp;quot;oh, that&amp;#39;s not a big deal, it still doesn&amp;#39;t matter that I use JWT even if it doesn&amp;#39;t &lt;em&gt;help&lt;/em&gt; me&amp;quot;, and you&amp;#39;d be wrong. There are quite a few downsides to using JWT as a session mechanism, several of them being &lt;em&gt;serious&lt;/em&gt; security issues.&lt;/p&gt;

&lt;h4&gt;They take up more space&lt;/h4&gt;

&lt;p&gt;JWT tokens are not exactly small. &lt;em&gt;Especially&lt;/em&gt; when using stateless JWT tokens, where all the data is encoded directly into the token, you will quickly exceed the size limit of a cookie or URL. You might decide to store them in Local Storage instead - however...&lt;/p&gt;

&lt;h4&gt;They are &lt;em&gt;less&lt;/em&gt; secure&lt;/h4&gt;

&lt;p&gt;When storing your JWT in a cookie, it&amp;#39;s no different from any other session identifier. But when you&amp;#39;re storing your JWT &lt;em&gt;elsewhere&lt;/em&gt;, you are now vulnerable to a new class of attacks, described in &lt;a href=&quot;http://blog.prevoty.com/does-jwt-put-your-web-app-at-risk&quot;&gt;this article&lt;/a&gt; (specifically, the &amp;quot;Storing sessions&amp;quot; section):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We pick up where we left off: back at local storage, an awesome HTML5 addition that adds a key/value store to browsers and cookies. So should we store JWTs in local storage? It might make sense given the size that these tokens can reach. Cookies typically top out somewhere around 4k of storage. For a large-sized token, a cookie might be out of the question and local storage would be the obvious solution. However, local storage doesn’t provide any of the same security mechanisms that cookies do.&lt;/p&gt;

&lt;p&gt;Local storage, unlike cookies, doesn’t send the contents of your data store with every single request. The only way to retrieve data out of local storage is by using JavaScript, which means any attacker supplied JavaScript that passes the Content Security Policy can access and exfiltrate it. Not only that, but JavaScript also doesn’t care or track whether or not the data is sent over HTTPS. As far as JavaScript is concerned, it’s just data and the browser will operate on it like it would any other data.&lt;/p&gt;

&lt;p&gt;After all the trouble those engineers went through to make sure nobody is going to make off with our cookie jar, here we are trying to ignore all the fancy tricks they’ve given us. That seems a little backwards to me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simply put, &lt;strong&gt;using cookies is not optional&lt;/strong&gt;, regardless of whether you use JWT or not.&lt;/p&gt;

&lt;h4&gt;You cannot invalidate individual JWT tokens&lt;/h4&gt;

&lt;p&gt;And there are more security problems. Unlike sessions - which can be invalidated by the server whenever it feels like it - individual stateless JWT tokens cannot be invalidated. By design, they will be valid until they expire, no matter what happens. This means that you cannot, for example, invalidate the session of an attacker after detecting a compromise. You also cannot invalidate old sessions when a user changes their password.&lt;/p&gt;

&lt;p&gt;You are essentially powerless, and cannot &amp;#39;kill&amp;#39; a session without building complex (and stateful!) infrastructure to explicitly detect and reject them, defeating the entire point of using stateless JWT tokens to begin with.&lt;/p&gt;

&lt;h4&gt;Data goes stale&lt;/h4&gt;

&lt;p&gt;Somewhat related to this issue, and &lt;em&gt;yet another&lt;/em&gt; potential security issue. Like in a cache, the data in a stateless token will eventually &amp;#39;go stale&amp;#39;, and no longer reflect the latest version of the data in your database.&lt;/p&gt;

&lt;p&gt;This can mean that a token contains some outdated information like an old website URL that somebody changed in their profile - but more seriously, it can &lt;em&gt;also&lt;/em&gt; mean somebody has a token with a role of &lt;code&gt;admin&lt;/code&gt;, even though you&amp;#39;ve just revoked their &lt;code&gt;admin&lt;/code&gt; role. Because you can&amp;#39;t invalidate tokens &lt;em&gt;either&lt;/em&gt;, there&amp;#39;s no way for you to remove their administrator access, short of shutting down the entire system.&lt;/p&gt;

&lt;h4&gt;Implementations are less battle-tested or non-existent&lt;/h4&gt;

&lt;p&gt;You might think that all these issues are just with &lt;em&gt;stateless&lt;/em&gt; JWT tokens, and you&amp;#39;d be mostly right. However, using a &lt;em&gt;stateful&lt;/em&gt; token is basically equivalent to a regular session cookie... but without the battle-tested implementations.&lt;/p&gt;

&lt;p&gt;Existing session implementations (eg. &lt;a href=&quot;https://github.com/expressjs/session&quot;&gt;&lt;code&gt;express-session&lt;/code&gt;&lt;/a&gt; for Express) have been running in production for many, many years, and their security has been improved a lot because of that. You don&amp;#39;t get those benefits when using JWT tokens as makeshift session cookies - you will either have to roll your own implementation (and most likely introduce vulnerabilities in the process), or use a third-party implementation that hasn&amp;#39;t seen much real-world use.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Stateless JWT tokens cannot be invalidated or updated, and will introduce either size issues or security issues depending on where you store them. Stateful JWT tokens are functionally the same as session cookies, but without the battle-tested and well-reviewed implementations or client support.&lt;/p&gt;

&lt;p&gt;Unless you work on a Reddit-scale application, there&amp;#39;s no reason to be using JWT tokens as a session mechanism. &lt;em&gt;Just use sessions.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;So... what is JWT good for, then?&lt;/h3&gt;

&lt;p&gt;At the start of this article, I said that there &lt;em&gt;are&lt;/em&gt; good usecases for JWT, but that they&amp;#39;re just not suitable as a session mechanism. This still holds true; the usecases where JWT is particularly effective are typically usecases where they are used as a &lt;em&gt;single-use authorization token&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;From the &lt;a href=&quot;https://tools.ietf.org/html/rfc7519&quot;&gt;JSON Web Token specification&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. [...] enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this context, &amp;quot;claim&amp;quot; can be something like a &amp;#39;command&amp;#39;, a one-time authorization, or basically any other scenario that you can word as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hello Server B, Server A told me that I could &amp;lt;claim goes here&amp;gt;, and here&amp;#39;s the (cryptographic) proof.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, you might run a file-hosting service where the user has to authenticate to download their files, but the files themselves are served by a separate, stateless &amp;quot;download server&amp;quot;. In this case, you might want to have your &lt;em&gt;application server&lt;/em&gt; (Server A) issue single-use &amp;quot;download tokens&amp;quot;, that the client can then use to download the file from a &lt;em&gt;download server&lt;/em&gt; (Server B).&lt;/p&gt;

&lt;p&gt;When using JWT in this manner, there are a few specific properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The tokens are short-lived.&lt;/strong&gt; They only need to be valid for a few minutes, to allow a client to initiate the download.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The token is only expected to be used once.&lt;/strong&gt; The application server would issue a new token for every download, so any one token is just used to request a file once, and then thrown away. There&amp;#39;s no persistent state, &lt;em&gt;at all&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The application server still uses sessions.&lt;/strong&gt; It&amp;#39;s just the &lt;em&gt;download server&lt;/em&gt; that uses tokens to authorize individual downloads, because it doesn&amp;#39;t need persistent state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can see here, it&amp;#39;s completely reasonable to &lt;em&gt;combine&lt;/em&gt; sessions and JWT tokens - they each have their own purpose, and sometimes you need both. Just don&amp;#39;t use JWT for &lt;em&gt;persistent&lt;/em&gt;, &lt;em&gt;long-lived&lt;/em&gt; data.&lt;/p&gt;
</description>
				<pubDate>Mon, 13 Jun 2016 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions</guid>
			</item>
		
			<item>
				<title>What is Promise.try, and why does it matter?</title>
				<description>&lt;p&gt;A topic that frequently confuses users in the #Node.js channel, is the &lt;a href=&quot;http://bluebirdjs.com/docs/api/promise.try.html&quot;&gt;&lt;code&gt;Promise.try&lt;/code&gt;&lt;/a&gt; method provided by Bluebird. People often struggle to understand what it is, or why they should use it - and this isn&amp;#39;t helped by the fact that &lt;em&gt;almost&lt;/em&gt; all guides to Promises fail to demonstrate its use.&lt;/p&gt;

&lt;p&gt;In this brief article, I hope to provide a better explanation of what &lt;code&gt;Promise.try&lt;/code&gt; is, and why you should always use it, without exceptions. I&amp;#39;ll be assuming that you already have some knowledge of Promises, and specifically about the role of &lt;code&gt;.then&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even if you are using a different Promises implementation (such as ES6 Promises), this article will still be useful to you - at the end of this article, I will explain how to achieve the same functionality without Bluebird.&lt;/p&gt;

&lt;h2&gt;So, what is it?&lt;/h2&gt;

&lt;p&gt;Simply put, &lt;code&gt;Promise.try&lt;/code&gt; is like &lt;code&gt;.then&lt;/code&gt;, without requiring a previous Promise. Now that&amp;#39;s still a little vague, so let&amp;#39;s start out with an example.&lt;/p&gt;

&lt;p&gt;This is what some typical code using Promises might look like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So far, so good. We&amp;#39;ll assume that &lt;code&gt;database.users.get&lt;/code&gt; will return a Promise of some sort, and that that Promise will eventually resolve to an object with a &lt;code&gt;name&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Now, this is the same code, but using &lt;code&gt;Promise.try&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bluebird&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, we&amp;#39;ve added &lt;code&gt;Promise.try&lt;/code&gt; at the very start of the chain. Rather than chaining directly off &lt;code&gt;database.users.get&lt;/code&gt;, we chain off &lt;code&gt;Promise.try&lt;/code&gt; and simply &lt;em&gt;return&lt;/em&gt; the result of &lt;code&gt;database.users.get&lt;/code&gt;, like we would normally do from a &lt;code&gt;.then&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;So... what is all this good for?&lt;/h2&gt;

&lt;p&gt;The above may look like needless extra code. But in practice, there are several advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Better error handling;&lt;/strong&gt; synchronous errors are propagated as rejections, no matter where in the process they occur.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better interoperability;&lt;/strong&gt; no matter what Promises implementation the third-party method uses, you will &lt;em&gt;always&lt;/em&gt; be working with your preferred implementation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easier to &amp;#39;scan&amp;#39;;&lt;/strong&gt; all code is horizontally at the same indentation level, so it&amp;#39;s easier to see what&amp;#39;s going on at a glance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below, I&amp;#39;ll address each of these points individually.&lt;/p&gt;

&lt;h2&gt;1. Better error handling&lt;/h2&gt;

&lt;p&gt;One of the touted benefits of Promises is that we can treat synchronous and asynchronous errors in the same way - synchronous errors are simply caught, and &amp;#39;repropagated&amp;#39; as a rejected Promise. But is this really the case? Let&amp;#39;s have a look at a &lt;em&gt;slightly modified&lt;/em&gt; version of our first example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;uesr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In this modified version, we&amp;#39;ve mistyped &lt;code&gt;user.name&lt;/code&gt;, so that it now says &lt;code&gt;uesr.name&lt;/code&gt;. This would normally fail, as &lt;code&gt;uesr&lt;/code&gt; is undefined, and so can&amp;#39;t have any properties. Indeed, this will be caught within the &lt;code&gt;.then&lt;/code&gt; and turn into a rejected Promise, as we expect.&lt;/p&gt;

&lt;p&gt;But what if &lt;code&gt;database.users.get&lt;/code&gt; throws synchronously? What if there&amp;#39;s a typo or other error in the third-party database code, which we didn&amp;#39;t write? The error-catching feature of Promises works by virtue of all your synchronous code being in a &lt;code&gt;.then&lt;/code&gt;, so that it can wrap it in a giant &lt;code&gt;try&lt;/code&gt;/&lt;code&gt;catch&lt;/code&gt; block.&lt;/p&gt;

&lt;p&gt;But... our &lt;code&gt;database.users.get&lt;/code&gt; isn&amp;#39;t in a &lt;code&gt;.then&lt;/code&gt; block! The Promises implementation thus doesn&amp;#39;t have access to that chunk of code, and can&amp;#39;t wrap it. Our synchronous error will remain a synchronous error, and now we&amp;#39;re back where we started - having to deal with two kinds of errors, synchronous and asynchronous.&lt;/p&gt;

&lt;p&gt;Now, let&amp;#39;s look back at our example using &lt;code&gt;Promise.try&lt;/code&gt; again:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bluebird&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I said before that &lt;code&gt;Promise.try&lt;/code&gt; is like a &lt;code&gt;.then&lt;/code&gt;, but without requiring a previous Promise. That holds true here, as well - it will catch the synchronous error in &lt;code&gt;database.users.get&lt;/code&gt;, just like a &lt;code&gt;.then&lt;/code&gt; would have!&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;Promise.try&lt;/code&gt;, we&amp;#39;ve streamlined our error handling to cover &lt;em&gt;all&lt;/em&gt; of the synchronous errors, not just those after the first asynchronous operation (as that is where our first real &lt;code&gt;.then&lt;/code&gt; callback would otherwise be).&lt;/p&gt;

&lt;h2&gt;Interjection: Promises/A+&lt;/h2&gt;

&lt;p&gt;Before we move on to the next point, let&amp;#39;s cover what Promises/A+ is, and what role it plays in the ecosystem. The &lt;a href=&quot;https://promisesaplus.com/&quot;&gt;Promises/A+ site&lt;/a&gt; summarizes it as follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Put differently, it&amp;#39;s a way to ensure that different Promises implementations (Bluebird, ES6, Q, RSVP, ...) work together flawlessly, out of the box. This Promises/A+ specification is why you can use pretty much &lt;em&gt;any&lt;/em&gt; Promises implementation you prefer, and why you don&amp;#39;t have to care about which implementation a third-party library (like, for example, &lt;a href=&quot;http://knexjs.org/&quot;&gt;Knex&lt;/a&gt;) uses.&lt;/p&gt;

&lt;p&gt;To illustrate what Promises/A+ does for you as a user:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;fill&quot; src=&quot;../../../../attachments/promises-aplus.png&quot; alt=&quot;Visual illustration of Promises/A+&quot;&gt;&lt;/p&gt;

&lt;p&gt;All the functions highlighted in &lt;span style=&quot;color: red; font-weight: bold&quot;&gt;red&lt;/span&gt; return Bluebird Promises, the one in &lt;span style=&quot;color: blue; font-weight: bold&quot;&gt;blue&lt;/span&gt; returns an ES6 Promise, and the one in &lt;span style=&quot;color: green; font-weight: bold&quot;&gt;green&lt;/span&gt; returns a Q Promise.&lt;/p&gt;

&lt;p&gt;Note how even though we are returning an ES6 Promise from the first callback, the &lt;code&gt;.then&lt;/code&gt; that wraps it will &lt;em&gt;still&lt;/em&gt; return a Bluebird Promise. Similarly, even though the second callback returns a Q Promise, our &lt;code&gt;doStuff&lt;/code&gt; method will still return a Bluebird Promise.&lt;/p&gt;

&lt;p&gt;This happens because, aside from catching synchronous errors, &lt;code&gt;.then&lt;/code&gt; will also &lt;strong&gt;wrap the return values&lt;/strong&gt; and ensure that they end up being a Promise from the same implementation that the &lt;code&gt;.then&lt;/code&gt; itself comes from. In practice, this means that the &lt;em&gt;first Promise in the chain&lt;/em&gt; determines what implementation you will be working with.&lt;/p&gt;

&lt;p&gt;This is a practical way to ensure that you are always working with a predictable API. The only Promises implementation you have to care about, is whatever the first function in the chain uses - no matter what comes afterwards.&lt;/p&gt;

&lt;h2&gt;2. Better interoperability&lt;/h2&gt;

&lt;p&gt;The above isn&amp;#39;t always desirable, however - for example, look at this example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bluebird&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getAllUsernames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//     ⬐ This will return an ES6 Promise.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are not familiar with &lt;code&gt;map&lt;/code&gt; and you&amp;#39;d like to know more, you can read &lt;a href=&quot;http://cryto.net/%7Ejoepie91/blog/2015/05/04/functional-programming-in-javascript-map-filter-reduce/&quot;&gt;this article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;.map&lt;/code&gt; feature we are using in this particular example is &lt;a href=&quot;http://bluebirdjs.com/docs/api/map.html&quot;&gt;a Bluebird feature&lt;/a&gt;, and is not available on ES6 Promises. We can&amp;#39;t use it here, &lt;em&gt;even&lt;/em&gt; if we are using Bluebird in our project otherwise - simply because the first function in the chain (&lt;code&gt;database.users.getAll&lt;/code&gt;) returned an ES6 Promise rather than a Bluebird Promise.&lt;/p&gt;

&lt;p&gt;Now, let&amp;#39;s look at the same example again, but this time using &lt;code&gt;Promise.try&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;bluebird&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getAllUsernames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//     ⬐ This will return a Bluebird Promise.&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;//     ⬐ This will return an ES6 Promise.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getAll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we &lt;em&gt;can&lt;/em&gt; use &lt;code&gt;.map&lt;/code&gt;! Because we are starting with &lt;code&gt;Promise.try&lt;/code&gt;, which originates from Bluebird, all our subsequent Promises will also be Bluebird Promises, no matter what happens in the &lt;code&gt;.then&lt;/code&gt; callbacks.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;Promise.try&lt;/code&gt; like this, you can decide for yourself what implementation you want to be working with, by ensuring that the first Promise in the chain comes from your preferred implementation. You can&amp;#39;t do this with &lt;code&gt;.then&lt;/code&gt;, because that&amp;#39;d require you to chain off some other Promise - which would defeat the point.&lt;/p&gt;

&lt;h2&gt;3. Easier to scan&lt;/h2&gt;

&lt;p&gt;The final benefit is one of readability. By starting every chain with &lt;code&gt;Promise.try&lt;/code&gt;, all the actual &amp;#39;business logic&amp;#39; exists within a callback at the same (horizontal) level of indentation. While this might seem like a minor benefit, it actually makes a fairly significant difference, due to how humans scan large amounts of text.&lt;/p&gt;

&lt;p&gt;To illustrate the difference, this is how you would visually scan the code without &lt;code&gt;Promise.try&lt;/code&gt;, using a common indentation style:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;fill&quot; src=&quot;../../../../attachments/promises-scan-1.png&quot; alt=&quot;Visual scanning without Promise.try&quot;&gt;&lt;/p&gt;

&lt;p&gt;... and the same code, but using &lt;code&gt;Promise.try&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;fill&quot; src=&quot;../../../../attachments/promises-scan-2.png&quot; alt=&quot;Visual scanning with Promise.try&quot;&gt;&lt;/p&gt;

&lt;p&gt;Even though the code looks slightly &amp;#39;noisier&amp;#39;, it&amp;#39;s still easier to get a quick impression of the code, simply because your eyes have to &amp;#39;seek&amp;#39; less.&lt;/p&gt;

&lt;h2&gt;What if I&amp;#39;m not using Bluebird?&lt;/h2&gt;

&lt;p&gt;To my knowledge, Bluebird is currently the only Promises implementation that ships with &lt;code&gt;Promise.try&lt;/code&gt; out of the box. However, it&amp;#39;s &lt;a href=&quot;https://git.cryto.net/joepie91/node-es6-promise-try/src/master/src/index.js&quot;&gt;relatively easy&lt;/a&gt; to replicate the functionality in other implementations, as long as their version of &lt;code&gt;new Promise&lt;/code&gt; catches synchronous errors.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href=&quot;https://www.npmjs.com/package/es6-promise-try&quot;&gt;&lt;code&gt;es6-promise-try&lt;/code&gt;&lt;/a&gt; is an implementation that I&amp;#39;ve written for ES6 Promises, and it works in the browser too. I have not gotten around to writing its documentation yet, but it works in essentially the same way as &lt;code&gt;Promise.try&lt;/code&gt; - however, instead you call &lt;code&gt;promiseTry&lt;/code&gt; like below:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;promiseTry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;es6-promise-try&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getUsername&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;promiseTry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;userID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Keep in mind that &lt;code&gt;es6-promise-try&lt;/code&gt; will assume that your environment supports ES6 Promises - if that is not the case, you&amp;#39;ll want to use something like &lt;a href=&quot;https://www.npmjs.com/package/es6-promise&quot;&gt;&lt;code&gt;es6-promise&lt;/code&gt;&lt;/a&gt; as a polyfill.&lt;/p&gt;

&lt;p&gt;I&amp;#39;d seriously recommend looking at Bluebird instead, though, as it has much more robust error handling and debugging features. Usually, ES6 Promises are only the ideal option in constrained environments like old versions of Internet Explorer, or when trying to the reduce bundle size of frontend code.&lt;/p&gt;

&lt;p&gt;If you know of &lt;code&gt;Promise.try&lt;/code&gt; implementations for other Promises implementation, then please let me know, and I&amp;#39;ll add them here! My contact details are at the bottom of this page.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am currently offering &lt;strong&gt;Node.js code review and tutoring&lt;/strong&gt; services, at affordable rates. More details can be found &lt;a href=&quot;http://cryto.net/%7Ejoepie91/code-review.html&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 11 May 2016 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2016/05/11/what-is-promise-try-and-why-does-it-matter</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2016/05/11/what-is-promise-try-and-why-does-it-matter</guid>
			</item>
		
			<item>
				<title>Reflections on NPM-gate, one day later</title>
				<description>&lt;p&gt;Okay, so let&amp;#39;s get these things out of the way first:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I am not a lawyer. However, I have to deal with intellectual property on a regular basis, because of my open-source work. I&amp;#39;m also very strongly opposed to copyright and patents, but have a more nuanced stance on trademarks. If any of this makes you uneasy, you can stop reading here.&lt;/li&gt;
&lt;li&gt;This issue was about &lt;strong&gt;trademarks&lt;/strong&gt;. Trademarks are designed to, in summary, &amp;quot;prevent consumers from getting confused or misled as to the origin or endorsement of a thing&amp;quot;. This means that &lt;strong&gt;trademarks are &lt;em&gt;not&lt;/em&gt; a form of copyright&lt;/strong&gt;, they &lt;em&gt;don&amp;#39;&lt;/em&gt;t mean that you &amp;quot;have copyright on a name&amp;#39;, and most importantly, it &lt;em&gt;doesn&amp;#39;t&lt;/em&gt; mean that you &amp;quot;own&amp;quot; the name. I will get back to this later.&lt;/li&gt;
&lt;li&gt;This article is based on public sources, and it&amp;#39;s &lt;em&gt;possible&lt;/em&gt; that some things are inaccurate, if (for example) any of the parties withheld communications or details.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, for the past day, I&amp;#39;ve been following the fallout around and reasons for Azer&amp;#39;s &lt;a href=&quot;https://medium.com/@azerbike/i-ve-just-liberated-my-modules-9045c06be67c&quot;&gt;decision to remove all of his modules from NPM&lt;/a&gt;. I&amp;#39;ve noticed that many people discussing the matter either don&amp;#39;t understand the issue, don&amp;#39;t understand trademarks, or underestimate the complexity of solving this problem.&lt;/p&gt;

&lt;p&gt;Therefore, I&amp;#39;ve decided to write this post - both as a summary of the events, and as a correction of some particularly common misconceptions.&lt;/p&gt;

&lt;h1&gt;What happened?&lt;/h1&gt;

&lt;p&gt;Kik (the company) &lt;a href=&quot;https://medium.com/@mproberts/a-discussion-about-the-breaking-of-the-internet-3d4d2a83aa4d&quot;&gt;contacted&lt;/a&gt; Azer, asking &amp;#39;politely&amp;#39; whether they could have the &lt;code&gt;kik&lt;/code&gt; package name on NPM. Azer responded:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Sorry, I’m building an open source project with that name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After that, the following message was sent by Kik (the company):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We don’t mean to be a dick about it, but it’s a registered Trademark in most countries around the world and if you actually release an open source project called kik, our trademark lawyers are going to be banging on your door and taking down your accounts and stuff like that — and we’d have no choice but to do all that because you have to enforce trademarks or you lose them.&lt;/p&gt;

&lt;p&gt;Can we not come to some sort of a compromise to get you to change the name without involving lawyers? Is there something we could do for you in compensation to get you to change the name?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point, Azer responded with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;hahah, you’re actually being a dick. so, fuck you. don’t e-mail me back.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kik (the company) contacted NPM Inc., asking them to help out, again alluding to trademarks and lawyers. At this point, NPM Inc. offered to take away the &lt;code&gt;kik&lt;/code&gt; package name from Azer and give it to Kik (the company).&lt;/p&gt;

&lt;p&gt;Azer felt that NPM no longer represented his interests as a user (and open-source developer), decided he did not want to be a part of NPM anymore, and &amp;#39;unpublished&amp;#39; all of his modules from NPM.&lt;/p&gt;

&lt;p&gt;Consequently, builds all around the world broke. One of the removed modules was the &lt;code&gt;left-pad&lt;/code&gt; module, which was used in many, &lt;em&gt;many&lt;/em&gt; popular projects, either directly or indirectly.&lt;/p&gt;

&lt;h1&gt;Azer&amp;#39;s response&lt;/h1&gt;

&lt;p&gt;It&amp;#39;s easy to blame Azer for &amp;#39;being a dick&amp;#39; here. However, Azer initially responded politely, and only became rude &lt;em&gt;after&lt;/em&gt; Kik threatened with lawyers, despite having been told no.&lt;/p&gt;

&lt;p&gt;If your immediate response to a &amp;quot;no&amp;quot; is to threaten with lawyers, then that was your plan all along, and you were simply asking &amp;#39;politely&amp;#39; first for appearances, and to save on legal costs. There was clearly no intention to let Azer make a decision in the first place.&lt;/p&gt;

&lt;h1&gt;Kik&amp;#39;s claim&lt;/h1&gt;

&lt;p&gt;&amp;quot;But,&amp;quot; you might say, &amp;quot;they hold the trademark - Azer didn&amp;#39;t have a choice anyway, and had to comply&amp;quot;. This argument &lt;em&gt;in particular&lt;/em&gt; is one I&amp;#39;ve seen a lot, but it&amp;#39;s most likely false.&lt;/p&gt;

&lt;p&gt;Holding a trademark doesn&amp;#39;t mean you own the name, nor does it work like copyright. It simply means that &lt;em&gt;if&lt;/em&gt; somebody could be confused or misled about the origins of something, you can exercise your trademark to put it to a stop. It&amp;#39;s a way to protect a brand name, and prevent scams.&lt;/p&gt;

&lt;p&gt;That wasn&amp;#39;t the case here at all, however - as far as I can tell, Azer&amp;#39;s package was completely unrelated to Kik (the service), and simply happened to have the same three-letter name. There would be no room for confusion here at all, and that would make this a case of trademark trolling; where Kik (the company) just figured that trademark threats would be the easiest way to get hold of a nice and short package name.&lt;/p&gt;

&lt;p&gt;It&amp;#39;s very, &lt;em&gt;very&lt;/em&gt; unlikely that this would have been a legitimate trademark infringement claim. Indeed, no lawyers were ever involved, and it was never more than a threat.&lt;/p&gt;

&lt;p&gt;I also don&amp;#39;t believe Kik&amp;#39;s claim that it was &amp;quot;nothing more than a polite request&amp;quot; - if that were the case, they wouldn&amp;#39;t have threatened with lawyers three(!) times.&lt;/p&gt;

&lt;p&gt;And finally, I&amp;#39;d like to mention Startup Timelines, who &lt;a href=&quot;https://medium.com/@bakztfuture/why-we-re-removing-kik-messenger-from-startup-timelines-ee18b9ede099&quot;&gt;removed Kik from their site&lt;/a&gt; for this very reason.&lt;/p&gt;

&lt;h1&gt;NPM Inc.&amp;#39;s response&lt;/h1&gt;

&lt;p&gt;NPM Inc. removed Azer&amp;#39;s package without any real infringement claim ever having been sent, purely on the basis of the threat of getting lawyers involved.&lt;/p&gt;

&lt;p&gt;By doing this, NPM Inc. has painted a giant target on their back towards trademark trolls, saying &amp;quot;here&amp;#39;s a cheap target&amp;quot; - it is now known that they will not make an effort to represent the interests of their users, and will fold even &lt;em&gt;without&lt;/em&gt; a legal notice being sent.&lt;/p&gt;

&lt;p&gt;This is &lt;em&gt;disastrous&lt;/em&gt; for the ecosystem, as every developer is now a potential target, and &lt;em&gt;their&lt;/em&gt; package might be pulled out from under their feet as well, for an entirely frivolous claim.&lt;/p&gt;

&lt;h1&gt;Reclaimed packages&lt;/h1&gt;

&lt;p&gt;Then the next disaster struck, once people realized that not only could Kik (the company) push whatever code they wanted as a patch version to existing users of the &lt;code&gt;kik&lt;/code&gt; library... but &lt;em&gt;anybody&lt;/em&gt; could register &lt;em&gt;any&lt;/em&gt; of the other now-removed NPM packages, and do the same thing.&lt;/p&gt;

&lt;p&gt;This is a security issue so significant, that I can&amp;#39;t believe it even happened. Had a malware author scooped up &lt;code&gt;left-pad&lt;/code&gt;, for example, they could have infected potentially thousands to millions of users with a single &lt;code&gt;publish&lt;/code&gt;. In fact, that still might happen - because who &lt;em&gt;is&lt;/em&gt; &lt;a href=&quot;https://www.npmjs.com/%7Enj48&quot;&gt;nj48&lt;/a&gt; anyway?&lt;/p&gt;

&lt;p&gt;This really cannot ever, ever, &lt;em&gt;ever&lt;/em&gt; be allowed. Global namespace or not, once an identifier has been used and removed, it should not &lt;em&gt;ever&lt;/em&gt; be possible to reassign it to anything else.&lt;/p&gt;

&lt;h1&gt;But Azer could have published malware as well.&lt;/h1&gt;

&lt;p&gt;Yes, he could have. But he was the only person who could modify his packages (aside from NPM Inc. itself), and people decided to trust him as a legitimate developer. That trust breaks down when you quietly &amp;#39;reallocate&amp;#39; a package to a different, entirely unrelated person.&lt;/p&gt;

&lt;p&gt;Signed packages would be even better, of course - but even without that, preventing reallocation of package names is the &lt;em&gt;most basic&lt;/em&gt; protection you should really have.&lt;/p&gt;

&lt;h1&gt;NPM Inc.&amp;#39;s history&lt;/h1&gt;

&lt;p&gt;Unfortunately, this wasn&amp;#39;t the first incident with NPM Inc. - in the past, NPM employees have advocated for blocking IPs from the registry, when the users they belong to &amp;#39;misbehave&amp;#39; (in their view) &lt;em&gt;outside&lt;/em&gt; of the NPM registry. It&amp;#39;s completely unacceptable to have a small group of people decide who can use critical infrastructure and who can&amp;#39;t, based on personal dislike of off-site behaviour.&lt;/p&gt;

&lt;p&gt;Returning to security. While I won&amp;#39;t go into this too much, I&amp;#39;ve had poor experiences with NPM staff&amp;#39;s handling of security in the past, as well - specifically, with Isaac, who apparently did not understand the severity of the &lt;a href=&quot;https://github.com/nodejs/node/issues/4660&quot;&gt;Buffer security issue&lt;/a&gt; in Node, yet felt that he could proclaim it on Twitter as &amp;quot;no big deal&amp;quot;. I was blocked after showing him a proof-of-concept of the vulnerability. I have heard similar stories from others.&lt;/p&gt;

&lt;p&gt;Overall, I feel that both Kik and NPM have handled this issue very poorly, and that there is a history of doing so for NPM. Which brings us to the next point...&lt;/p&gt;

&lt;h1&gt;Fixing NPM&lt;/h1&gt;

&lt;p&gt;There have been many ideas, from many people, in many places, on how to &amp;#39;fix&amp;#39; NPM. From &lt;a href=&quot;https://github.com/alexanderGugel/ied&quot;&gt;replacing the client&lt;/a&gt;, to replacing the company, to replacing the registry with a decentralized equivalent.&lt;/p&gt;

&lt;p&gt;Unfortunately, not all of these ideas are thought through or argued well. I&amp;#39;ll address some of the common issues below.&lt;/p&gt;

&lt;h1&gt;Namespacing&lt;/h1&gt;

&lt;p&gt;A common complaint is that there&amp;#39;s a single global namespace in NPM - that is, a single collection of packages, with a first-come-first-serve policy. While a valid concern in and of itself, many people seem to think that this is the reason of package takeovers that occurred today. It&amp;#39;s not.&lt;/p&gt;

&lt;p&gt;The problem with the package takeovers is one of mutability and, more specifically, who has permission to do what. Right now, removed packages can apparently be freely re-registered, but this should not be the case, for the reasons I&amp;#39;ve described before. Imagine for a moment that we had a namespaced NPM, where each package was prefixed with the username of the publisher. Imagine that once somebody removed their account, their username could be re-registered.&lt;/p&gt;

&lt;p&gt;What would happen? Exactly the same thing.&lt;/p&gt;

&lt;p&gt;Namespaces do not solve this, and if you can prevent reuse of usernames, &lt;em&gt;then you can also do so for package names&lt;/em&gt;. While namespaces are worth discussing, it&amp;#39;s completely unrelated to the issues that occurred today.&lt;/p&gt;

&lt;h1&gt;Decentralizing NPM&lt;/h1&gt;

&lt;p&gt;There have been various suggested solutions for decentralizing NPM. This is a very good idea in principle, as it would remove single points of failure, like what we&amp;#39;re seeing now with NPM Inc. Unfortunately, most of these proposals won&amp;#39;t actually work, because the author underestimated the complexities involved.&lt;/p&gt;

&lt;p&gt;For example, you might argue for content-addressable packages on IPFS. But how do you handle semantic versioning? You definitely &lt;em&gt;should&lt;/em&gt; support it like NPM does, as it&amp;#39;s essential to receiving (security) patches. But purely content-addressable packages rule out this possibility &lt;em&gt;by definition&lt;/em&gt;, as they require immutability. And there are many subtle issues like this.&lt;/p&gt;

&lt;p&gt;There has been a discussion ongoing about this for a few months now, and it can be found &lt;a href=&quot;https://github.com/nodejs/NG/issues/29&quot;&gt;here&lt;/a&gt;. If you wish to contribute to building a decentralized package manager, then please &lt;em&gt;read that thread&lt;/em&gt; and those linked from it, because they list many of the issues that a naive decentralized implementation would run into. You can&amp;#39;t replace NPM with a package manager that is missing features.&lt;/p&gt;

&lt;h1&gt;In conclusion...&lt;/h1&gt;

&lt;p&gt;I&amp;#39;m surprised you&amp;#39;ve made it this far through the article. Either way, the conclusion is quite simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We need to replace the central NPM registry, but we need to do so carefully.&lt;/strong&gt; Also, Kik needs to stop pretending that it was a polite request.&lt;/p&gt;

&lt;p&gt;To end on a more amusing note, from the Node.js IRC channel:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[20:34] &amp;lt;TheEmpath&amp;gt; Hey guys, I&amp;#39;ve created a package that converts  characters into yellow/gold N&amp;#39;ko, a modern unifier of the Manding  languages spoken by mansas throughout medieval North Africa.  You can try it out with npm  install goldmansachs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And yep, &lt;a href=&quot;https://www.npmjs.com/package/goldmansachs&quot;&gt;it actually exists&lt;/a&gt;.&lt;/p&gt;
</description>
				<pubDate>Wed, 23 Mar 2016 00:00:00 +0100</pubDate>
				<link>http://cryto.net/~joepie91/blog/2016/03/23/reflections-on-npm-gate-one-day-later</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2016/03/23/reflections-on-npm-gate-one-day-later</guid>
			</item>
		
			<item>
				<title>Why you should never, ever, ever use MongoDB</title>
				<description>&lt;p&gt;MongoDB is evil. It...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;... loses data (sources: &lt;a href=&quot;https://aphyr.com/posts/284-call-me-maybe-mongodb&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://aphyr.com/posts/322-call-me-maybe-mongodb-stale-reads&quot;&gt;2&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... in fact, for a long time, ignored errors by default and assumed every single write succeeded no matter what (which on 32-bits systems led to losing all data silently after some 3GB, due to MongoDB limitations)&lt;/li&gt;
&lt;li&gt;... is slow, &lt;em&gt;even&lt;/em&gt; at its advertised usecases, and claims to the contrary are completely lacking evidence (sources: &lt;a href=&quot;http://blogs.enterprisedb.com/2014/09/24/postgres-outperforms-mongodb-and-ushers-in-new-developer-reality/&quot;&gt;3&lt;/a&gt;, &lt;a href=&quot;http://developer.olery.com/blog/goodbye-mongodb-hello-postgresql/&quot;&gt;4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... forces the poor habit of implicit schemas in nearly all usecases (sources: &lt;a href=&quot;http://developer.olery.com/blog/goodbye-mongodb-hello-postgresql/&quot;&gt;4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... has locking issues (sources: &lt;a href=&quot;http://developer.olery.com/blog/goodbye-mongodb-hello-postgresql/&quot;&gt;4&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... has an atrociously poor response time to security issues - it took them &lt;strong&gt;two years&lt;/strong&gt; to patch an insecure default configuration that would expose &lt;em&gt;all of your data&lt;/em&gt; to anybody who asked, without authentication (sources: &lt;a href=&quot;https://blog.shodan.io/its-the-data-stupid/&quot;&gt;5&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... is not ACID-compliant (sources: &lt;a href=&quot;http://css.dzone.com/articles/how-acid-mongodb&quot;&gt;6&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;... is a nightmare to scale and maintain&lt;/li&gt;
&lt;li&gt;... isn&amp;#39;t even exclusive in its offering of JSON-based storage; PostgreSQL does it too, and other (better) document stores like CouchDB have been around for a long time (sources: &lt;a href=&quot;http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/&quot;&gt;7&lt;/a&gt;, &lt;a href=&quot;http://www.postgresql.org/docs/9.4/static/functions-json.html&quot;&gt;8&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... so realistically, there&amp;#39;s nothing it&amp;#39;s good at, and a bunch of stuff it&amp;#39;s outright bad at. And these bulletpoints are facts, not &amp;#39;just your opinion&amp;#39;. You can go out and verify them yourself.&lt;/p&gt;

&lt;p&gt;For most cases, what you want is actually a relational database. PostgreSQL is a good option for these cases, and you can use a query builder or ORM to make working with it easier. In Node.js, some options are &lt;a href=&quot;http://knexjs.org/&quot;&gt;Knex&lt;/a&gt; (as a query builder), &lt;a href=&quot;http://bookshelfjs.org/&quot;&gt;Bookshelf&lt;/a&gt;, &lt;a href=&quot;http://docs.sequelizejs.com/en/latest/&quot;&gt;Sequelize&lt;/a&gt;, or &lt;a href=&quot;https://github.com/balderdashy/waterline&quot;&gt;Waterline&lt;/a&gt; (as ORMs).&lt;/p&gt;

&lt;p&gt;If your project involves user accounts, or any kind of relationship between two records, then you should use a &lt;em&gt;relational&lt;/em&gt; database, and not a document store - after all, your data &lt;em&gt;is&lt;/em&gt; relational.&lt;/p&gt;

&lt;p&gt;If you find yourself using Mongoose, you should also be using a relational database. Libraries like Mongoose just try to (poorly) emulate schemaful relational databases using a document store, so you might as well just use a relational database directly!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Even&lt;/em&gt; if what you need is a document store (and again, in most cases it isn&amp;#39;t), there are many better options available than MongoDB. &lt;a href=&quot;http://db-engines.com/en/ranking/document+store&quot;&gt;Here&lt;/a&gt; is a list of document store databases. Note that that list is ranked &lt;em&gt;by popularity&lt;/em&gt;, and says nothing about the quality of a database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Never use a database because &amp;#39;everybody else does&amp;#39;, do your own research as to the advantages and drawbacks of a particular database.&lt;/strong&gt; Popularity is largely subject to hype, and with the right marketing team, it&amp;#39;s not hard to popularize an inferior solution.&lt;/p&gt;

&lt;p&gt;And no, it isn&amp;#39;t &amp;quot;good for prototyping&amp;quot; either - you just end up locking yourself into a database that can never reasonably make it into production. If your prototype is considered viable, then you&amp;#39;re still going to have to rewrite &lt;em&gt;everything&lt;/em&gt; using a different database.&lt;/p&gt;

&lt;p&gt;Nearly every development ecosystem has migrations with a rollback mechanism by now, which provide a comparable ease of use for prototyping, and without the drawback of having to rewrite your code for production.&lt;/p&gt;

&lt;p&gt;There are no valid usecases for MongoDB. It is technically inferior to other options, does not offer exclusive features that actually &lt;em&gt;work&lt;/em&gt;, and the developers are failing to ensure data integrity and security - arguably two of the most important aspects of a database.&lt;/p&gt;
</description>
				<pubDate>Sun, 19 Jul 2015 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2015/07/19/why-you-should-never-ever-ever-use-mongodb</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2015/07/19/why-you-should-never-ever-ever-use-mongodb</guid>
			</item>
		
			<item>
				<title>Using Promises (eg. bluebird) with Express</title>
				<description>&lt;p&gt;When using a promises library like &lt;a href=&quot;https://github.com/petkaantonov/bluebird&quot;&gt;bluebird&lt;/a&gt; in &lt;a href=&quot;http://expressjs.com/&quot;&gt;Express&lt;/a&gt;, you might have found it somewhat awkward to use them correctly - it&amp;#39;s easy to forget to tack on a &lt;code&gt;.catch&lt;/code&gt; statement at the end of a chain of promises.&lt;/p&gt;

&lt;p&gt;Fortunately, there&amp;#39;s a solution for that, and it&amp;#39;s called &lt;a href=&quot;https://www.npmjs.com/package/express-promise-router&quot;&gt;&lt;code&gt;express-promise-router&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;h1&gt;Using &lt;code&gt;express-promise-router&lt;/code&gt;&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;express-promise-router&lt;/code&gt; is a slightly modified version of the regular router that ships with Express, that expects a route to return a promise object. It then automatically attaches an error handler to the promise, that will forward any errors to your regular &lt;a href=&quot;http://expressjs.com/guide/error-handling.html&quot;&gt;error handling middleware&lt;/a&gt;, so that you can handle them as if you called &lt;code&gt;next(err)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With the regular Express router, your code might look something like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;express&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doSomeAsyncThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doAnotherAsyncThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;newValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this is what it looks like with &lt;code&gt;express-promise-router&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expressPromiseRouter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;express-promise-router&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;expressPromiseRouter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doSomeAsyncThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doAnotherAsyncThing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;newValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Done!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;router&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We no longer need to define a &lt;code&gt;.catch&lt;/code&gt; handler.&lt;/li&gt;
&lt;li&gt;We now &lt;em&gt;return&lt;/em&gt; the chain of promises from the route.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;#39;s it! All errors in your chain of promises now end up in your regular error handling middleware, where you can log them and send an error page.&lt;/p&gt;

&lt;h1&gt;Does this support the same features as a regular Express router?&lt;/h1&gt;

&lt;p&gt;Yep. The &lt;code&gt;express-promise-router&lt;/code&gt; module really just &lt;a href=&quot;https://github.com/alex-whitney/express-promise-router/blob/master/lib/express-promise-router.js&quot;&gt;wraps the native router&lt;/a&gt;, and adds error handling to the route methods. That&amp;#39;s all it does.&lt;/p&gt;

&lt;h1&gt;Can I also return promises from &lt;code&gt;.param()&lt;/code&gt; calls?&lt;/h1&gt;

&lt;p&gt;Yep, &lt;a href=&quot;https://github.com/alex-whitney/express-promise-router/issues/5&quot;&gt;since 0.0.7&lt;/a&gt;. They&amp;#39;re handled in the same way as the regular route methods. If an error occurs in the &lt;code&gt;.param()&lt;/code&gt; call, the request will be aborted, and the route after it won&amp;#39;t be run - in other words, like it should be :)&lt;/p&gt;

&lt;h1&gt;And how about &lt;code&gt;.use()&lt;/code&gt; and &lt;code&gt;.all()&lt;/code&gt;?&lt;/h1&gt;

&lt;p&gt;Yes, same as for &lt;code&gt;.param()&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;What if I don&amp;#39;t return a chain of promises from my route? Will it break?&lt;/h1&gt;

&lt;p&gt;Nope. The &lt;code&gt;express-promise-router&lt;/code&gt; module only implements special behaviour when a chain of promises is returned. Otherwise, it has the default behaviour of the Express router.&lt;/p&gt;

&lt;h1&gt;Can I still use &lt;code&gt;next()&lt;/code&gt; manually?&lt;/h1&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;h1&gt;My rejections are ending up on my console anyway. What gives?&lt;/h1&gt;

&lt;p&gt;Make sure you&amp;#39;re actually &lt;em&gt;returning&lt;/em&gt; the chain of promises from your route or middleware. It can&amp;#39;t handle promises that you don&amp;#39;t give to it!&lt;/p&gt;

&lt;h1&gt;How do I send different kinds of errors? I want to send different HTTP status codes.&lt;/h1&gt;

&lt;p&gt;Ideally, you&amp;#39;d use a module like &lt;a href=&quot;https://www.npmjs.com/package/errors&quot;&gt;&lt;code&gt;errors&lt;/code&gt;&lt;/a&gt; for this. You can either use the standard HTTP error methods that it provides, or even create your own errors - and then handle &lt;em&gt;all&lt;/em&gt; of them in your error handling middleware, like normal.&lt;/p&gt;

&lt;p&gt;You can just do something along these lines:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;req&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statusCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;statusCode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;nx&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;statusCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;My next Node.js article will be an in-depth guide to promises, and how they can help you escape from callback hell. I know I promised that last time, but this time it&amp;#39;s really going to be the next post :)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am currently offering &lt;strong&gt;Node.js code review and tutoring&lt;/strong&gt; services, at affordable rates. More details can be found &lt;a href=&quot;http://cryto.net/%7Ejoepie91/code-review.html&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 14 May 2015 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2015/05/14/using-promises-bluebird-with-express</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2015/05/14/using-promises-bluebird-with-express</guid>
			</item>
		
			<item>
				<title>Functional programming in Javascript: map, filter and reduce</title>
				<description>&lt;p&gt;This article is meant to be an introduction to functional programming in Javascript - specifically, it will explain the &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt; methods.&lt;/p&gt;

&lt;p&gt;While these are natively available in any recent browser and in Node.js, most articles on them are far too technical to understand, while the concept of these functions is actually really simple, and will benefit &lt;em&gt;any&lt;/em&gt; developer - even those working on simple scripts.&lt;/p&gt;

&lt;p&gt;Note that I&amp;#39;ll be pretty verbose in this article, to make the concept understandable to developers of any skill level. If you&amp;#39;re already familiar with some of the concepts described, you can safely skip over those bits. Similarly, if you&amp;#39;re a more advanced developer, and examples alone are enough for you, just skip over the text entirely.&lt;/p&gt;

&lt;p&gt;I won&amp;#39;t address other aspects of functional programming here - these three functions fit well into most workflows on their own. I might explain other concepts in a later post.&lt;/p&gt;

&lt;p&gt;So let&amp;#39;s start with &lt;code&gt;map&lt;/code&gt;, arguably the most common one in a typical project.&lt;/p&gt;

&lt;h1&gt;So, what is this &lt;code&gt;map&lt;/code&gt; business, then?&lt;/h1&gt;

&lt;p&gt;Think of &lt;code&gt;map&lt;/code&gt; as a &amp;quot;for each&amp;quot; loop, that is specifically for &lt;em&gt;transforming&lt;/em&gt; values - one input value corresponds to one &amp;#39;transformed&amp;#39; output value.&lt;/p&gt;

&lt;p&gt;You may have found yourself writing code that looks something like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The doubled numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2, 4, 6, 8]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While this code &lt;em&gt;works&lt;/em&gt;, it&amp;#39;s not very nice. It takes a lot of work to do a pretty simple task - double all the numbers in an array.&lt;/p&gt;

&lt;p&gt;What if we could simply write our &lt;em&gt;intention&lt;/em&gt; of doubling every number in an array?&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The doubled numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2, 4, 6, 8]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Suddenly, we don&amp;#39;t need a loop anymore, and we don&amp;#39;t have to manually add numbers to an array either! We can simply define our &lt;em&gt;intention&lt;/em&gt;, and let &lt;code&gt;map&lt;/code&gt; do the work. This can also be chained easily:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The doubled and incremented numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [3, 5, 7, 9]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Every number is now doubled, and has 1 added to it. We don&amp;#39;t have to manually manage any arrays - we simply specify functions that do some kind of &lt;em&gt;transformation&lt;/em&gt; on a single value.&lt;/p&gt;

&lt;p&gt;There are a few &amp;#39;rules&amp;#39; for &lt;code&gt;map&lt;/code&gt; functions, though. While these are not always &lt;em&gt;strictly&lt;/em&gt; enforced, you should keep to them regardless - they make it a lot easier to understand what your code is doing. If you think these rules will get in your way, just keep reading - your questions will be answered.&lt;/p&gt;

&lt;h2&gt;The amount of input elements is equal to the amount of output elements&lt;/h2&gt;

&lt;p&gt;You can&amp;#39;t give &lt;code&gt;map&lt;/code&gt; 4 values, and only receive 3 back. If the &amp;#39;source array&amp;#39; has an X amount of elements, then the resulting aray will also have X elements. Every output element corresponds to the input element in the same position - they&amp;#39;re never shuffled around.&lt;/p&gt;

&lt;h2&gt;Your callbacks shouldn&amp;#39;t &amp;#39;mutate&amp;#39; values&lt;/h2&gt;

&lt;p&gt;What this means, is really just that you shouldn&amp;#39;t modify objects or arrays directly from within your callbacks - if the input value is an object or an array, &lt;em&gt;clone&lt;/em&gt; it instead, and modify the copy.&lt;/p&gt;

&lt;p&gt;This way, there&amp;#39;s a guarantee that your callback doesn&amp;#39;t cause &amp;#39;side effects&amp;#39; - that is, no matter what happens in your callback, it will only affect the specific value you&amp;#39;re working with. This makes it much easier to write reliable code.&lt;/p&gt;

&lt;p&gt;You can clone an array in Javascript by doing &lt;code&gt;array.slice(0)&lt;/code&gt;. Note that this is a &amp;#39;shallow clone&amp;#39; - if the values in the array are themselves arrays or objects, they will still be the same values in both arrays.&lt;/p&gt;

&lt;p&gt;Shallow-cloning an object is a little more complex. If you&amp;#39;re using a CommonJS environment (Node.js, Webpack, Browserify, ...), you can simply use the &lt;a href=&quot;https://www.npmjs.com/package/xtend&quot;&gt;&lt;code&gt;xtend&lt;/code&gt;&lt;/a&gt; module. Otherwise, using a function like this should suffice:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cloneObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newObj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;newObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;clonedObject&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;cloneObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;originalObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is an exception to this rule, but we&amp;#39;ll get to that later - just assume that this rule always applies, unless told otherwise.&lt;/p&gt;

&lt;h2&gt;Don&amp;#39;t cause side-effects!&lt;/h2&gt;

&lt;p&gt;You should never do anything in a &lt;code&gt;map&lt;/code&gt; call that modifies &amp;#39;state&amp;#39; elsewhere. For example, while making a HTTP GET request is fine (although not really possible with plain &lt;code&gt;Array.map&lt;/code&gt;), changing another array outside of the callback is not. Your callback can &lt;em&gt;only&lt;/em&gt; modify the new value you&amp;#39;re returning &lt;em&gt;from&lt;/em&gt; that callback.&lt;/p&gt;

&lt;h1&gt;But... isn&amp;#39;t this slow? All those callbacks and the cloning...&lt;/h1&gt;

&lt;p&gt;Don&amp;#39;t worry about it. Such operations are actually rather fast in Javascript, especially in V8-based engines like Node.js, and it&amp;#39;s extremely unlikely that it&amp;#39;ll ever cause performance issues for you.&lt;/p&gt;

&lt;p&gt;Always write code for readability first, and for performance second - it&amp;#39;s much easier to optimize readable code, than it is to make optimized code readable.&lt;/p&gt;

&lt;h1&gt;But what if I only want to transform &lt;em&gt;some&lt;/em&gt; of the values?&lt;/h1&gt;

&lt;p&gt;Perhaps your source array has some values that you want to transform, and some values that you just want to throw away entirely. That&amp;#39;s not possible with &lt;code&gt;map&lt;/code&gt; alone, as the number of input values and the number of output values for a &lt;code&gt;map&lt;/code&gt; call is always equal.&lt;/p&gt;

&lt;p&gt;Say you want to double the odd numbers, but throw away the even numbers. Your code may look something like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The doubled numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is what it&amp;#39;d look like using &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The doubled numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2, 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;filter&lt;/code&gt; callback is subject to the same &amp;quot;don&amp;#39;t mutate&amp;quot; and &amp;quot;don&amp;#39;t cause side-effects&amp;quot; rules as &lt;code&gt;map&lt;/code&gt;, but the mechanics are different.&lt;/p&gt;

&lt;p&gt;The return value from the &lt;code&gt;filter&lt;/code&gt; callback should be a boolean, indicating whether to include the original value in the result (&lt;code&gt;true&lt;/code&gt;) or whether to leave it out (&lt;code&gt;false&lt;/code&gt;). You should &lt;em&gt;not&lt;/em&gt; return the value itself, just a boolean - you can&amp;#39;t modify the value from within the callback. The return value just decides whether the value will be included in the result, nothing else.&lt;/p&gt;

&lt;h1&gt;Chaining&lt;/h1&gt;

&lt;p&gt;As you might have noticed, you can chain &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; calls indefinitely. Each of them just returns an array, and every array has these methods by default, so you can build a jQuery-like chain. There is no limit to how many of these calls you can chain, and it&amp;#39;s usually pretty simple to build complex array transformations from just these functions alone.&lt;/p&gt;

&lt;p&gt;An array goes in, an array comes out, and the callback operates on each value individually.&lt;/p&gt;

&lt;h1&gt;So... what if I just want to combine the values in an array?&lt;/h1&gt;

&lt;p&gt;&amp;#39;Combining&amp;#39; the values can mean a lot of different things. For example, you might want to sum all the numbers, doubled:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;totalNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;totalNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The total number is&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;totalNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But what if we want to do that in a &lt;code&gt;map&lt;/code&gt;/&lt;code&gt;filter&lt;/code&gt; chain? Easy enough, with &lt;code&gt;reduce&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;totalNumber&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;total&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;total&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The total number is&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;totalNumber&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The second argument to the function call is considered to be the &amp;#39;starting value&amp;#39; for the total - this is what you start out with.&lt;/li&gt;
&lt;li&gt;For each item in the array, it calls the callback, with the total value up to that point, and the item itself. For the first item, the &amp;#39;total value&amp;#39; is the starting value.&lt;/li&gt;
&lt;li&gt;You return a new &amp;#39;total value&amp;#39;. In this case, it&amp;#39;s the sum of all previous numbers plus the current number. This return value is used as the &amp;#39;total value&amp;#39; for the &lt;em&gt;next&lt;/em&gt; item.&lt;/li&gt;
&lt;li&gt;After running out of items, the &amp;#39;cumulative&amp;#39; total value is returned.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Again, the &amp;quot;don&amp;#39;t mutate&amp;quot; and &amp;quot;don&amp;#39;t cause side-effects&amp;quot; rules apply. Otherwise, it doesn&amp;#39;t matter what kind of value you&amp;#39;re working with - you could be summing a number, concatenating a string, putting together an object, and so on.&lt;/p&gt;

&lt;p&gt;Just keep in mind that &lt;code&gt;reduce&lt;/code&gt; always returns &lt;em&gt;just&lt;/em&gt; the &amp;#39;total value&amp;#39; - unless you&amp;#39;ve specifically made it an array, it won&amp;#39;t be an array like for &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;. That means that unless you&amp;#39;re explicitly returning an array from it, you can&amp;#39;t chain off it any further. But then again, it wouldn&amp;#39;t really make sense to run &lt;code&gt;map&lt;/code&gt; on a number!&lt;/p&gt;

&lt;h1&gt;But what if I want to &lt;em&gt;add&lt;/em&gt; items? Like &lt;code&gt;filter&lt;/code&gt;, but the opposite.&lt;/h1&gt;

&lt;p&gt;If you use Node.js, you may be familiar with transform streams - these are kind of like a &lt;code&gt;map&lt;/code&gt; callback, but besides letting you &amp;#39;push&amp;#39; (return) 0 or 1 values, they also let you push &lt;em&gt;multiple&lt;/em&gt; values. This can be useful if you are, for example, &amp;#39;flattening&amp;#39; an array of arrays down to a single array with all the values.&lt;/p&gt;

&lt;p&gt;While this can&amp;#39;t be done with &lt;code&gt;map&lt;/code&gt; - after all, one input element means one output element - it &lt;em&gt;can&lt;/em&gt; be done with &lt;code&gt;reduce&lt;/code&gt;, despite what the name implies. It&amp;#39;s a slightly unusual trick, but you&amp;#39;ll occasionally find yourself needing it.&lt;/p&gt;

&lt;p&gt;Let&amp;#39;s say you want to add the even numbers to the resulting array twice, but the odd numbers only once. This is what it could look like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/* Add it a second time. */&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The final numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [1, 2, 2, 3, 4, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is how you&amp;#39;d do it with &lt;code&gt;reduce&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;newArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;newArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;cm&quot;&gt;/* Add it a second time. */&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;newArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* This is important! */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The final numbers are&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNumbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [1, 2, 2, 3, 4, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note how we start out with &lt;code&gt;[]&lt;/code&gt; as initial value, and just add the value to it one or more times. While this &lt;em&gt;does&lt;/em&gt; violate the &amp;quot;no mutation&amp;quot; rule, it&amp;#39;s okay in this particular situation - the array object is created explicitly for this &lt;code&gt;reduce&lt;/code&gt; call, so it can&amp;#39;t cause side-effects anywhere else in the code.&lt;/p&gt;

&lt;p&gt;When you use this trick, &lt;em&gt;don&amp;#39;t forget to return the array!&lt;/em&gt; It&amp;#39;s easy to forget this, and you&amp;#39;ll end up with an unexpected output. The &lt;code&gt;reduce&lt;/code&gt; callback always expects the &lt;em&gt;new&lt;/em&gt; total value to be returned, &lt;em&gt;even&lt;/em&gt; if that value is an array, and &lt;em&gt;even&lt;/em&gt; if it&amp;#39;s the same one as before!&lt;/p&gt;

&lt;p&gt;The same trick also works with objects - however, in that case you&amp;#39;d specify &lt;code&gt;{}&lt;/code&gt; as starting value, and you&amp;#39;d use property assignment rather than &lt;code&gt;.push&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;Bonus: forEach&lt;/h1&gt;

&lt;p&gt;Perhaps you really &lt;em&gt;do&lt;/em&gt; want a &amp;#39;for each&amp;#39; loop - you&amp;#39;re not transforming and returning any values, you just want to cause some kind of side-effect (eg. creating a DOM element). It would be nice if you could chain it at the end of a &lt;code&gt;map&lt;/code&gt;/&lt;code&gt;reduce&lt;/code&gt;/&lt;code&gt;filter&lt;/code&gt; &amp;#39;pipeline&amp;#39;, and indeed you can!&lt;/p&gt;

&lt;p&gt;This is what your &lt;code&gt;for&lt;/code&gt; loop might normally look like:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;doSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And this is what it would look like using &lt;code&gt;forEach&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;doSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can do the same for an object, using &lt;code&gt;Object.keys&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;one&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;two&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;Object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;doSomethingWith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;cm&quot;&gt;/* For example, key == &amp;quot;one&amp;quot; and value == 1 */&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should really always consider using &lt;code&gt;forEach&lt;/code&gt; instead of a &lt;code&gt;for&lt;/code&gt; loop . Because &lt;code&gt;forEach&lt;/code&gt; uses callbacks, it prevents scope problems with asynchronous operations in a loop - that is, you don&amp;#39;t have to worry that the value of the &lt;code&gt;key&lt;/code&gt; variable changes inbetween the start and the completion of your operations.&lt;/p&gt;

&lt;h1&gt;Indexes&lt;/h1&gt;

&lt;p&gt;At some point, you may want to get the index of the current item in the source array - however, I&amp;#39;ve only demonstrated the use of the value so far.&lt;/p&gt;

&lt;p&gt;Getting the index of the current element is trivial: it&amp;#39;s the second argument for &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;forEach&lt;/code&gt;, and the third argument for &lt;code&gt;reduce&lt;/code&gt;. In other words, it comes after the arguments I&amp;#39;ve shown in the examples so far.&lt;/p&gt;

&lt;p&gt;If you need a reference to the original array for some reason, that is the argument after &lt;em&gt;that&lt;/em&gt; - however, needing this usually means that you&amp;#39;re doing something wrong. You should never directly modify the source array from any of these functions, for example.&lt;/p&gt;

&lt;h1&gt;Further reference&lt;/h1&gt;

&lt;p&gt;MDN has further documentation on &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot;&gt;&lt;code&gt;map&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter&quot;&gt;&lt;code&gt;filter&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce&quot;&gt;&lt;code&gt;reduce&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach&quot;&gt;&lt;code&gt;forEach&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;Other libraries&lt;/h1&gt;

&lt;p&gt;Some utility libraries like &lt;code&gt;lodash&lt;/code&gt; and &lt;code&gt;underscore&lt;/code&gt; offer similar methods, but you almost certainly don&amp;#39;t need them. All modern Javascript runtimes and browsers have these functions &lt;a href=&quot;https://kangax.github.io/compat-table/es5/#Array.prototype.map&quot;&gt;available natively&lt;/a&gt; on array objects.&lt;/p&gt;

&lt;p&gt;jQuery offers similar methods, but keep in mind that the jQuery equivalents &lt;strong&gt;switch around the value and the index&lt;/strong&gt; - that is, the order of arguments for the callback is &lt;code&gt;(index, value)&lt;/code&gt;. A more reliable way is to use &lt;code&gt;this&lt;/code&gt; within your callback where possible - it is always set to the value in jQuery.&lt;/p&gt;

&lt;p&gt;My next Javascript and Node.js article will be about how Promises can help you escape callback hell. I will be discussing the bluebird library specifically, including its equivalents of &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt; and &lt;code&gt;forEach&lt;/code&gt; (named &lt;code&gt;each&lt;/code&gt; in bluebird).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I am currently offering &lt;strong&gt;Node.js code review and tutoring&lt;/strong&gt; services, at affordable rates. More details can be found &lt;a href=&quot;http://cryto.net/%7Ejoepie91/code-review.html&quot;&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 04 May 2015 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2015/05/04/functional-programming-in-javascript-map-filter-reduce</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2015/05/04/functional-programming-in-javascript-map-filter-reduce</guid>
			</item>
		
			<item>
				<title>On Mozilla&#39;s forced SSL</title>
				<description>&lt;p&gt;Yesterday, Mozilla &lt;a href=&quot;https://blog.mozilla.org/security/2015/04/30/deprecating-non-secure-http/&quot;&gt;made a blogpost&lt;/a&gt;, stating that they will be &amp;quot;deprecating non-secure HTTP&amp;quot; - in other words, forcing HTTPS. I believe that this decision is harmful to the open web, and this is why.&lt;/p&gt;

&lt;p&gt;First of all, for those who are not familiar with me - I actively encourage people to use SSL/TLS wherever possible. I do &lt;em&gt;not&lt;/em&gt; believe that there is data that is &amp;quot;not important enough to encrypt&amp;quot;.&lt;/p&gt;

&lt;p&gt;I do however believe that there are fundamental problems with the way TLS is currently deployed in practice, problems that absolutely need solving &lt;em&gt;before&lt;/em&gt; a forced global deployment of TLS can happen.&lt;/p&gt;

&lt;h1&gt;TLS is broken&lt;/h1&gt;

&lt;p&gt;Yes, it&amp;#39;s broken. Any certificate authority in the world can sign a certificate for any hostname in the world, regardless of whether that&amp;#39;s the actual CA being used by the real owner of that hostname. This means that anybody with access to the signing infrastructure of &lt;em&gt;any&lt;/em&gt; certificate authority anywhere in the world, can sign fake certificates for everybody else.&lt;/p&gt;

&lt;p&gt;While TLS can still provide data confidentiality against passive attackers, and this problem can be circumvented in custom applications and API libraries by hardcoding a certificate or CA into the client, it is very much broken in the common &amp;quot;TLS on the web&amp;quot; implementation.&lt;/p&gt;

&lt;p&gt;Certificate pinning is suggested as a &amp;#39;solution&amp;#39;, but still requires to trust the certificate on the first connection, and it doesn&amp;#39;t provide an easy migration path for service operators who want to switch their certificates to a different certificate authority. It&amp;#39;s also still not actually implemented by major browsers.&lt;/p&gt;

&lt;h1&gt;SSL certificates are a racket&lt;/h1&gt;

&lt;p&gt;It&amp;#39;s really that simple. You are essentially forced to pay for a certificate if you want to use TLS. If you do not, and try to use a self-signed certificate, a browser will show a scary warning page to your users. You can&amp;#39;t even embed (iframe) pages using self-signed certificates &lt;em&gt;at all&lt;/em&gt;. The browser will simply refuse to load the page, not even showing a warning.&lt;/p&gt;

&lt;p&gt;Domain-validated certificates have a cost of practically zero to generate. It&amp;#39;s all automated. Higher-validation certificates have a non-zero, but still trivial cost to generate - the cost is purely in the validation work, which is generally a repetitive and largely automatable job.&lt;/p&gt;

&lt;p&gt;Higher-validation certificates generally &lt;em&gt;do&lt;/em&gt; come with insurance, but there is no way to &amp;#39;opt out&amp;#39; of this if you don&amp;#39;t need it - as is the case for the majority of non-corporate uses of an SSL certificate.&lt;/p&gt;

&lt;p&gt;In short; the true cost of an SSL certificate is generally several magnitudes lower than what you&amp;#39;re being charged for it. And &lt;em&gt;everyone&lt;/em&gt; charges like that. It&amp;#39;s a racket.&lt;/p&gt;

&lt;h1&gt;Startcom is not actually free&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;But Startcom gives away free certificates!&amp;quot;&lt;/em&gt;, you say. Well, no, not really.&lt;/p&gt;

&lt;p&gt;The domain-validated certificates that Startcom provides are indeed free to &lt;em&gt;generate&lt;/em&gt;. Revocation, however, &lt;em&gt;even&lt;/em&gt; in the situation of a &lt;a href=&quot;https://www.techdirt.com/articles/20140409/11442426859/shameful-security-startcom-charges-people-to-revoke-ssl-certs-vulnerable-to-heartbleed.shtml&quot;&gt;global security issue&lt;/a&gt; that is completely out of your control, will cost you money.&lt;/p&gt;

&lt;p&gt;Revocation is a vital part of a secure TLS cryptosystem. If you don&amp;#39;t pay Startcom, you are unable to revoke, and this breaks the security model of TLS. Your security is broken.&lt;/p&gt;

&lt;p&gt;Startcom is not really free.&lt;/p&gt;

&lt;h1&gt;Let&amp;#39;s Encrypt is not a complete solution either&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;But,&amp;quot;&lt;/em&gt; you say, &lt;em&gt;&amp;quot;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&amp;#39;s Encrypt&lt;/a&gt; is just around the corner!&amp;quot;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is. It will also - at least, initially - only offer basic domain-validated, multi-host certificates. It is apparently &lt;a href=&quot;https://github.com/letsencrypt/acme-spec/issues/64&quot;&gt;undecided as of yet&lt;/a&gt; whether wildcard domains will be supported. Other scenarios may also not be supported.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;But if you need a wildcard certificate, surely you have the money to pay for it?&amp;quot;&lt;/em&gt; Well, no, not necessarily. &lt;em&gt;Right now&lt;/em&gt;, I&amp;#39;m building a free CDN for non-commercial projects. This would ideally let me provide a separate subdomain for every user - something that isn&amp;#39;t feasible without a wildcard certificate, if TLS were to be enforced. I don&amp;#39;t have the money for such a certificate - keep in mind that this is all non-commercial - and it would be ludicrous to expect otherwise.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;But you can just generate a new certificate for every subdomain!&amp;quot;&lt;/em&gt; Yes, you could. In complex setups, however, that quickly becomes a bookkeeping nightmare. You now have to add infrastructure for the specific purpose of propagating TLS certificates across multiple frontend servers. Not to mention that if Let&amp;#39;s Encrypt goes down at any point, &lt;em&gt;your entire registration system is down&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;And on top of that, Let&amp;#39;s Encrypt is only one certificate authority. If they are ever removed from browser trust stores - don&amp;#39;t forget that it is still very experimental - you have exactly zero alternatives, other than to suddenly pay for some other CA.&lt;/p&gt;

&lt;h1&gt;&amp;quot;But you can still use HTTP!&amp;quot;&lt;/h1&gt;

&lt;p&gt;Yes, but you will not be able to use many new features. A quote from the original article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For the first of these steps, the community will need to agree on a date, and a definition for what features are considered “new”.  For example, one definition of “new” could be “features that cannot be polyfilled”.  That would allow things like CSS and other rendering features to still be used by insecure websites, since the page can draw effects on its own (e.g., using &amp;lt;canvas&amp;gt;).  But it would still restrict qualitatively new features, such as access to new hardware capabilities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Those features are not disabled for &amp;#39;security reasons&amp;#39;, as some people in the comments on the Mozilla post have suggested. They are disabled to pressure you into using TLS.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&amp;quot;But you won&amp;#39;t need those features!&amp;quot;&lt;/em&gt; Maybe you do, maybe you don&amp;#39;t. Isn&amp;#39;t the point of an &amp;#39;open web&amp;#39; that the same features are available to everybody, regardless of financial means or other qualifications?  Hell, I personally use many newer features to build non-commercial projects.&lt;/p&gt;

&lt;h1&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In conclusion; no, TLS certificates are not really free. Introducing forced TLS would create an imbalance between those who have the money and means to purchase a certificate (or potentially many certificates), and those who don&amp;#39;t - all the while promoting a cryptosystem as being &amp;#39;secure&amp;#39; when there are known problems with it. This is &lt;em&gt;directly counter&lt;/em&gt; to an open web.&lt;/p&gt;

&lt;p&gt;There are plenty of problems with TLS that need to be fixed before pressuring people to use it. Let&amp;#39;s start with that first.&lt;/p&gt;
</description>
				<pubDate>Fri, 01 May 2015 00:00:00 +0200</pubDate>
				<link>http://cryto.net/~joepie91/blog/2015/05/01/on-mozillas-forced-ssl</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2015/05/01/on-mozillas-forced-ssl</guid>
			</item>
		
			<item>
				<title>The EU may have just banned the anonymous sale of online goods and services</title>
				<description>&lt;p&gt;Well, not exactly a cheerful topic for my first post of 2015, but it has to be said.&lt;/p&gt;

&lt;p&gt;The EU has introduced new &lt;a href=&quot;https://en.wikipedia.org/wiki/Value-added_tax&quot;&gt;VAT (Value Added Tax)&lt;/a&gt; legislation that is supposedly meant to prevent companies like Amazon from &amp;#39;reducing their tax burden&amp;#39;.&lt;/p&gt;

&lt;p&gt;Roughly summarized, the change of legislation means that VAT is now calculated based on the country of residence of the &lt;em&gt;buyer&lt;/em&gt;, rather than that of the &lt;em&gt;seller&lt;/em&gt;. Which sounds like a great idea, until you look at the way it&amp;#39;s implemented.&lt;/p&gt;

&lt;p&gt;I&amp;#39;ve just finished reading the &lt;a href=&quot;http://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:52012PC0763&amp;amp;from=EN&quot;&gt;official proposal for these changes&lt;/a&gt;, and as far as I can tell - the proposal does not actually define &amp;#39;electronic service&amp;#39; anywhere like it claimed it would - these changes basically mean that &lt;strong&gt;it is no longer legally possible to, as a company, sell (online) goods or services to an anonymous customer.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Again, due to the lack of definition for &amp;#39;electronic service&amp;#39; it is unclear whether this also entails &lt;em&gt;physical&lt;/em&gt; goods that are bought over the internet.&lt;/p&gt;

&lt;p&gt;The proposal lists nine options for establishing the country of residence, of which &lt;em&gt;a minimum of two&lt;/em&gt; are required. I have quoted the list below, highlighting the options that are relevant to online sales.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;(a)     customer details such as the billing address of the customer;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(b)     the Internet Protocol (IP) address of the device used by the customer or any method of geolocation;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(c)     bank details such as the place where the bank account used for payment is and the billing address of the customer held by that bank;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(d)     the Mobile Country Code (MCC) of the International Mobile Subscriber Identity (IMSI) stored on the Subscriber Identity Module (SIM) card used by the customer;&lt;/p&gt;

&lt;p&gt;(e)     the location of the residential fixed land line through which the service is supplied to the customer;&lt;/p&gt;

&lt;p&gt;(f)      in relation to a customer who is selling goods via the Internet or similar electronic network, the place where the transport or dispatch of the goods sold by that customer initially begins;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(g)     in relation to a customer who is buying goods via the Internet or similar electronic network, the place where the transport or dispatch of the goods bought by that customer finally ends;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(h)     registration details of the means of transport hired by the customer, if registration of that means of transport is required at the place where it is used, and other similar information;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(i)      other commercially relevant information obtained by the supplier.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, practically every relevant item in the list would expose the identity of the customer, and businesses are &lt;em&gt;required&lt;/em&gt; to collect this information &amp;quot;for VAT purposes&amp;quot;.&lt;/p&gt;

&lt;p&gt;The only thing that could potentially be spoofed is the IP address, and even there it is not unreasonable to assume that the tax office will complain about business who do not block known proxies or Tor relays.&lt;/p&gt;

&lt;p&gt;While other forms of proof may also be admissible, it is very likely that they will be held to a similar standard of identity verification.&lt;/p&gt;

&lt;p&gt;According to a well-known Dutch (IT) lawyer, Arnoud Engelfriet, this information is supposed to be &lt;a href=&quot;http://blog.iusmentis.com/2015/01/13/hoe-rampzalig-zijn-de-nieuwe-btw-regels-voor-online-ondernemers/&quot;&gt;kept for 10 years and accessible to any foreign tax office&lt;/a&gt;. While the proposal &lt;em&gt;does&lt;/em&gt; list individual privacy as a consideration, this is not expanded upon in the rest of the proposal.&lt;/p&gt;

&lt;p&gt;The consequences will be especially dire for businesses (and their customers) that use micropayments or cryptocurrencies like Bitcoin. Effectively, the only way to still serve your anonymous customers, is through tax evasion.&lt;/p&gt;

&lt;p&gt;While I&amp;#39;m not a lawyer, I have read through the proposal a few times now, and I really see no other interpretation of it than the above. Whether this side-effect of banning anonymous sales was an oversight or intentional... I&amp;#39;ll leave that as an exercise to the reader.&lt;/p&gt;
</description>
				<pubDate>Tue, 13 Jan 2015 00:00:00 +0100</pubDate>
				<link>http://cryto.net/~joepie91/blog/2015/01/13/the-eu-may-have-just-banned-anonymous-sale-of-online-goods-and-services</link>
				<guid isPermaLink="true">http://cryto.net/~joepie91/blog/2015/01/13/the-eu-may-have-just-banned-anonymous-sale-of-online-goods-and-services</guid>
			</item>
		
	</channel>
</rss>
