One of the best ways of keeping your website secure is keeping Joomla up to date AND keep your installed extensions / plugins up to date.
To facilitate website maintainers in keeping their installed extensions and plugins up to date, the Joomla One Click updater was introduced.
What is the Joomla! Update System?
Starting with Joomla! 1.6, Joomla! has featured an update system to help keep systems up to date. The Joomla! Update System is mainly driven by the Extensions Manager. It offers notification in the administrator area notifying the user that new versions of extensions are available and offers the functionality to seamlessly install these updates with the click of a mouse (hence we use the name Joomla One Click updater).
How it works
Extension developers (like me) need to host an extension repository where (new) versions of the extensions are uploaded. In the extensions manifest file (a special file with extension information in the installation package) is a link included to an xml file on that server. This xml file has all the information regarding the downloadable versions. So when you have installed version 1.2 of a plugin installed, and the developer releases version 1.3, then the Joomla Update manager will visit and download the updated xml file, and will see that a new version (1.3) is available. it will then prompt you to download this version and install it.
But how does it work for paid extensions?
This works perfectly for free downloads, but how do you handle extensions that are part of a subscription, the so called paid downloads?
For this the Joomla Update manager has the option to store an "extra_query" in the #__update_sites table (the table that holds all the locations of the remote xml files of the installed extensions). This extra_query can be set to hold e.g. the value "key=12345678". When the Joomla! Update Manager downloads the new version, it will add the extra_query to the download URL. It is then up to the web server of the extension developer to check if the download id passed as extra_query is liable for a download or not. if not, it will produce a 403 - forbidden response and the Joomla Update Manager will fail to download the update and report this back to the user with a generic message.
How do you add the download key to the extra query?
Well this is not something that Joomla has an API or standard for: every developer can have it's own mechanism (and therefore extra_query) for deciding if the download is allowed or not. Akeeba Release System for example requires a "dlid=[yourpersonaldownloadid]" extra_query where rd_subscriptions (the extension I am using), requires "key=[yourpersonaldownloadid]"
So for an extension developer the challenge is to enable the user to add a download id in the most simple way.
For my plugins I 'cleverly' used the 'onExtensionAfterSave' event trigger. When you save a plugin, the last thing Joomla does is trigger the 'onExtensionAfterSave' event. My plugin listens for this trigger and when triggered, it will take the download id the user has configured in the plugin's configuration and add that in the correct way to the extra_query column in the #__update_sites table.
Although this worked there where some cases where it didn't work.
- When rebuilding the updates sites in the extension manager, all extra_queries are removed, so although you correctly added the download key, it could be erased in an another area resulting in a failed download.
- When setting the download ID in the configuration and pressing save or save close when the plugin is NOT enabled, the plugin (because it is NOT enabled), will not respond to the 'onExtensionAfterSave' event, resulting in the extra_query not being set in the table.
So the Joomla preferred way to implement the download key (via the extra_query) has its flaws, and I sometimes found my self explaining to users on how to fix this when they ran into one of these issues.
New and improved way of adding the download key
As of Joomla version 3.2 Joomla has an event trigger called 'onInstallerBeforePackageDownload', this will trigger an event and pass the header and url of the file it wants to download.
All of my plugins and extensions are now refactored to utilize this event.
So before downloading the new version, the event is triggered. My plugin will listen to this event and based on the download URL passed, it will 'decide' if it is trying to download this plugin's new version. If so. The config for this plugin will be read and the configured download id will be added directly to the download URL.
But there is more...
Together with Robert, the developer of rd-subscriptions, I have extended the rd-subscription extension to have a method for validating a download ID.
So now, before downloading the new version, first the download ID will be validated. If the download ID is not valid, expired, canceled or refunded. We will display a message to the user.
When a download ID is expired, you would normally get a 403 - forbidden message, when doing a lot of updates in one click, it is not always clear as to what extension was giving this error.
Now you are informed as to what is the reason for failing and for what extension.
it will now even notify you when your download ID is valid for less then 30 days. Giving you a valuable notice that action needs to be taken to renew your subscription.
Is this now fault-proof?
Well, almost... it is still possible that you have a plugin installed, but have it disabled. When a new version for this plugin is available, this plugin, because it is disabled, will not respond to the 'onInstallerBeforePackageDownload' event trigger.
What is Joomla's take on this?
Starting from Joomla !version 4, there will be a completely different way of adding download keys, via a new Joomla core extension (well, if this PR will make it into Joomla 4). until then, nothing will be changed for Joomla 3 I'm afraid.