It's been 4 months since we've had a CommandBox release, but we've actually been quite busy on a number of large improvements that took a while to settle down. Today we are pleased to announce a Release Candidate 5.2.0-RC.1 for you to help test. There's not usually a release candidate for "minor" CommandBox releases, but we've updated a lot of libraries and introduced some pretty big new features so we wanted to have a round of testing and feedback before we cut the final release. There are 46 completed tickets for the 5.2.0 release.
Before we get into the new juicy features, everything has been documented already in the CommandBox docs here:
https://commandbox.ortusbooks.com/
And the RC.1 builds can be downloaded from our artifact repository here:
https://downloads.ortussolutions.com/#/ortussolutions/commandbox/5.2.0-rc.1/
New Stuff!Ok, where to begin. There are a number of pretty exciting new features and a pile of bug fixes. And as usual, input from the community via Pull Requests. Huge thanks to Pete Freitag, Kai Koenig, Matthew Clemente, Bobby Hartsfield, Scott Steinbeck, Daniel Mejia, and Miguel Mathus! Here's an overview of the new stuff in 5.2.0
Library UpdatesWe know library updates are boring, but they are important and we want you to know we take them seriously. Keeping up-to-date ensure you have the latest fixes and security updates from all the third-party libs we bundle in CommandBox.
Here's an overview of what we updated in CommandBox 5.2.0.
The Undertow bump is a minor update, but a pretty big deal. Ortus sent three pull requests to the core Undertow project fixing bugs and adding predicate logging. All of our pulls were accepted and merged into the core Undertow project and released in the 2.2 release.
Read more about library updates here:
https://ortussolutions.atlassian.net/browse/COMMANDBOX-1064
Server Security ProfilesThis is a feature that we expect to grow in the future. We've started it out simple, yet powerful but left a lot of room to build on it. The two main goals here are
CommandBox now has profiles you can assign to a server when you start it to configure the default settings. This is to provide easy secure-by-default setups for your production servers, and to make it easier to switch between a development mode and production mode.
There are 3 currently supported profiles. Custom profiles will be added as a future feature.
In production mode, CommandBox will block access to your CF admin to all external traffic, will block all common config files such as box.json or .env and will block, the "TRACK" and "TRACE" HTTP verbs
You can set the profile for your server in your server.json
server set profile=productionOr you can specify it when starting the server like so:
server start profile=productionIf a profile is not set, CommandBox looks for an environment variable called "environment" or it checks to see if the site is bound on localhost to try and guess the correct profile for you.
We've also added some new flags in your server.json to fully customize how your profile behaves.
server set web.blockCFAdmin=true server set web.blockCFAdmin=false server set web.blockCFAdmin=external server set web.blockConfigPaths=true server set web.blockConfigPaths=falseRead more about Server Profiles here:
https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-profiles
Server RulesThis is huge-- probably the biggest chunk of work, and it's actually what makes the server profiles above even possible! It's always been possible to perform basic lock downs with a custom rewrite file, but we've exposed an amazing built-in functionality of Undertow called the Predicate language. It allows you to create ad-hoc rules that apply to your server to provide any of the following:
An example of a server rule using Undertow's predicate language to block access to any box.json files looks like this:
path-suffix(/box.json) -> set-error(404)One of the best things about these rules, is they don't have to be in a single monolithic XML file. Instead they can come from
Here's some examples of what can be in your server.json
{ "web" : { "rules" : [ "path-suffix(/box.json) -> set-error(404)", "path-suffix(hidden.js) -> set-error(404)", "path-prefix(/admin/) -> ip-access-control(192.168.0.* allow)", "path(/sitemap.xml) -> rewrite(/sitemap.cfm)", "disallowed-methods(trace)" ], "rulesFile" : "../secure-rules.json" // Or... "rulesFile" : ["../security.json","../rewrites.txt","../app-headers.json"] // Or... "rulesFile" : "../rules/*.json" } }There are TON of built in predicates and handlers your rules can use. We've documented some of them here:
CommandBox also registers some custom rules in Undertow you can use for your CF apps:
// Block all CF admin access cf-admin() -> set-error( 404 ); // Shortcut for the previous rule block-cf-admin() // Block external CF admin access cf-admin() -> block-external()There are lots of new docs on this. Read more about Server Rules here:
https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/server-rules
Task Runner Lifecyle eventsThe more we use Task Runners for builds, scheduled tasks, and utilities, we've seen the need to have lifecyle events in the same manner as the preHandler and postHandler sort of stuff in ColdBox MVC. Now if a task runner has methods of this name, they will be executed automatically.
The lifecycle methods are very powerful and can be controlled via whitelist and blacklists to control what targets they execute for. "Around" events are very easy to use thanks to the use of closure. There's a lot more details in the docs.
Read more about Task Runner Lifecyle events here:
https://commandbox.ortusbooks.com/task-runners/lifecycle-events
System Setting ${} NamespacesThe default namespace when using the $ {foo} system setting expansion syntax is box environment variable, Java system properties, and OS environment variables.
It is also possible to leverage built-in namespaces to allow expansions that reference:
This gives you a lot more power now to be able to create dynamic configuration in your JSON files and even from the command line. Here are some examples:
// Reference box.json file in this directory $ {boxjson.slug} // Reference server.json file in this directory $ serverjson.web.http.port:80} // Reference local server details $ {serverinfo.serverHomeDirectory} // Reference arbitrary JSON file $ {json.my...@file.json} // Reference CLI's config settings $ {configsetting.endpoints.forgebox.apitoken} // Local reference to a JSON property in the same file { "appFileGlobs" : "models/**/*.cfc,tests/specs/**/*.cfc", "scripts":{ "format":"cfformat run $ {@appFileGlobs} --overwrite", "format:check":"cfformat check $ {@appFileGlobs} --verbose" } }And one of the coolest things is this implementation is driven by a new onSystemSettingExpansion interception point and completely extendable! That means you can write a module that powers something hypothetical like this:
$ {AWSSecretStore.mySecretKey}Read more about System Setting namespaces here:
https://commandbox.ortusbooks.com/usage/system-setting-expansion-namespaces
GZip Compression Control
CommandBox has had the ability to enable/disable GZip compression in Undertow for a while. Now you can fully control when it activates based on the type or size of file, etc. This feature utilizes the same Undertow predicate language that we introduced above.
server set web.gzipEnable=true server set web.gzipPredicate="not path-prefix( admin ) and regex( '(.*).css' ) and request-larger-than(500)"Read more about GZip Compression Control here:
https://commandbox.ortusbooks.com/embedded-server/configuring-your-server/gzip-compression
Generic Watch CommandThis is a fun one. There are some specific commands that make use of the Watcher library in CommandBox such as testbox watch and coldbox watch-reinit. However, there is also now a generic watch command that will run any arbitrary command of your choosing when a path matching your file globbing pattern is added/updated/deleted. Use this to build custom watchers on-the-fly without needing to touch any CFML code to write a Task Runner.
watch *.json "echo 'config file updated!'"That command will echo out "config files updated!" every time a JSON file gets changed in the current directory. Here's a more complex one:
set command = "echo 'You added \$ {item}!'" watch command="foreach '\$ {watcher_added}' \$ {command}" --verboseThat one will list every new file that's added in this directory and all sub directories.
Read more about the generic watch command here:
https://commandbox.ortusbooks.com/usage/watch-command
Control Default BrowserThere are a handful of features in CommandBox that will open URLs for you in your default browser. We've had requests to allow the browser in use to be customized, so we've reworked all of that logic, consolidating it in some places and now you can control what browser CommandBox uses. To change the default browser for all URL opening functions use this:
// use Chrome config set preferredBrowser=chrome // use FireFox config set preferredBrowser=frefox // Just kidding, no one is going to use this!! config set preferredBrowser=ieSupported browsers are:
And you can even dial in a browser on demand for the browse and server open commands.
server open browser=operaRead more about setting the default browser here:
https://commandbox.ortusbooks.com/config-settings/misc-settings#preferredbrowser
MiscellaneousHere are some honorable mentions.
.htaccess rewrite flagsThe CommandBox Tuckey rewrites allow an .htaccess file that uses the mod_rewrite style syntax of rewrites. Previously, use of flags such as these didn't work:L
RewriteRule ^/login.cfm$ /condworks.html [R=301]https://ortussolutions.atlassian.net/browse/COMMANDBOX-1221
Server restart from tray iconWe've added a "restart" option to the tray icon that does exactly what you think it does.
Trick for "cd"ing up directoriesThere's a new trick supported in CommandBox's shell that we've borrowed that allows you to change directories and go "up" more than one directory with less typing:
// current directory cd . -> ./ // back 1 directory cd .. -> ../ // back 2 directories cd ... -> cd ../../ // back 3 directories cd .... -> cd ../../../https://ortussolutions.atlassian.net/browse/COMMANDBOX-1209
Pipe into standard input of native binariesYou can now pipe the output of a previous command in CommandBox directly to a native binary like so:
#createguid | !clip or #createguid | run clipIn this case, clip is a Windows binary that will read the standard input and place that text on the clipboard.