Actionhero is a realtime multi-transport nodejs API Server with integrated cluster capabilities and delayed tasks
APACHE-2.0 License
Bot releases are hidden (Show)
Published by evantahler over 7 years ago
api.cache.lock
The old implementation of the api.cache.lock
method did not check the result of the setnx
function, which could have lead to multiple nodes acquiring the same lock multiple times.
The latest version of Standard.js checks for deprecated methods from node's core. We were using a few of these older methods and they have been removed.
Published by evantahler over 7 years ago
actionhero
github team.This repo is now actionhero/actionhero
(rather than the old evantahler/actionhero
). We are a grown up organization now! All links in the project and docs should be updated.
Add schema input type for actions which allow validator, required, default, and formatter for actions with inputs having nested properties.
exports.addUser = {
name: 'api/addUser',
description: 'I add user',
firstName: { required: true },
lastName: { required: false },
username: { required: true },
address: {
required: false,
schema: {
country: {
required: true,
default: 'USA'
},
state: { required: false },
city: {
required: true,
formatter: (val) => `City:${val}`,
validator: (val) => val.length > 10,
}
}
}
run: () => {},
}
standard.js
and pass lintNew Actionhero projects (created with actionhero generate
) will now include standard as a devDependency and pretest
with the linter. New package.json will also include the necessary standard global ignores so that everything passes. This is all also now tested
We now properly supply connection.rawConnection.res.writeHead
with a hash rather than an array.
Update all dependant packages to their latest versions.
fakeredis
and primus
Published by evantahler over 7 years ago
dirty-chai
, to enforce that the chai matchers we use in our test suite follow proper JS convention, and avoid assertions on access.Published by evantahler over 7 years ago
(web server) Allows Actionhero to pipe streams of unknown length to web clients, skipping the Content-Length
header
When booting Actionhero, if you have initializers with duplicated names (including those which would overwrite a core initializer) the server will exit with a relevant error message.
(when booting the web server) cleanSocket
and chmodSocket
both assumed port
to be a string. While this should be the case, there are no prior checks for this condition so the error thrown is quite confusing for the end user. The code has been modified to check that the port
is a string type before calling indexOf
on it.
cross-env
in test environment so windows users can play along at homeChai
assertion library in tests, dropping should
Published by evantahler almost 8 years ago
Version 16 is a re-write of many parts of ActionHero's internals to follow the Standard JavaScript Style Guide. This new guide replaces ESLint as our linting tool, and comes with good opinions on how to write safe, readable JS code. ActionHero now passes this linter, and as such, should be much easier to work with
All new contributions to ActionHero must follow this style, and will be tested as part of the test suite automatically.
To conform with proper JS style, some breaking changes were introduced:
api.Connection()
rather than api.connection()
api.GenericServer()
rather than api.genericServer()
api.ActionProcessor()
rather than api.actionProcessor()
require("actionhero")
not require("actionhero").actionheroPrototype
should you be using ActionHero programatically.By @evantahler via https://github.com/evantahler/actionhero/pull/983
node-uuid
with uuid
(https://github.com/evantahler/actionhero/pull/984)Published by evantahler almost 8 years ago
api.config.servers.web.allowedRequestHosts
, we will noe maintain the path of the request when redirectingstring
or array
, and there is an error, we should return the error as a string, and not attempt to return response.error = error
, as this creates an improper javascript object. This may be a breaking change if you relied on this improper behavior
specHelper
actions to include metadata (data.response.serverInformation
, data.response.requesterInformation
, and data.response.messageCount
) from the server, you can configure api.specHelper.returnMetadata = false
in your tests.Published by evantahler almost 8 years ago
This release updates the logger (api.log
) in 2 meaningful ways:
api.config.logger.localizeLogMessages
which allows developers to opt-into localizing all system log messages (api.log).
Published by evantahler almost 8 years ago
Fixes a bug introduced with v15.1.4 which was improperly detecting client protocols (http
vs https
) when using the new api.config.servers.web.allowedRequestHosts
host restrictions.
Published by evantahler almost 8 years ago
ActionHero now allows you to define a collection of host headers which this API server will allow access from. You can set these via api.config.servers.web.allowedRequestHosts
. If the Host
header of a client does not match one of those listed (protocol counts!), they will be redirected to the first one present.
You can also set process.env.ALLOWED_HOSTS
which will be parsed as a comma-separated list of Hosts which will set api.config.servers.web.allowedRequestHosts
By @evantahler via https://github.com/evantahler/actionhero/pull/973
Published by evantahler almost 8 years ago
This release contains no fixes over v15.1.2.
We re-published on NPM to ensure that this was the latest version.
Published by evantahler almost 8 years ago
This is a backport of https://github.com/evantahler/actionhero/releases/tag/v15.1.2 to ActionHero v12
Published by evantahler almost 8 years ago
This is a backport of https://github.com/evantahler/actionhero/releases/tag/v15.1.2 to ActionHero v14
Published by evantahler almost 8 years ago
This is a security release which solves the following:
Previously, the default error responder when a client asked for a static-file which was missing (404) returned the name the of that file
api.config.errors.fileNotFound = function(connection){
return connection.localize(['That file is not found (%s)', connection.params.file]);
}
This is dangerous because a malicious actor could request a filename with an executable javascript tag and harm the requester. We now will no longer return the file name:
api.config.errors.fileNotFound = function(connection){
return connection.localize(['That file is not found']);
}
When requesting an action via JSONp, it was possible (though unlikely) that the callback
string you were providing contained malicious javascript which would harm the requester. We will now sanitize the provided callback
in the following way:
function callbackHtmlEscape(str){
return str
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/\)/g, '')
.replace(/\(/g, '');
}
This fix has been backported to:
A huge thank you to @submitteddenied is earned for reporting these issues and working to fix them.
Published by evantahler almost 8 years ago
Check out www.actionherojs.com! We've overhauled our website to be more pleasant to read and the documentation easier to work with. We've also moved back to a plain Jekyll website. We can utilize GitHub's automatic site hosting from within the master branch, and we no longer need a publishing workflow nor do we need a gh-pages
branch.
sendFile
with buffers.run: function (api, data, next) {
const buffer = 'Example of data buffer';
let bufferStream = new stream.PassThrough();
bufferStream.end(buffer);
data.connection.rawConnection.responseHeaders.push(['Content-Disposition', 'attachment; filename=test.csv']);
api.servers.servers.web.sendFile(data.connection, null, bufferStream, 'text/csv', buffer.length, new Date());
data.toRender = false;
next();
}
if-modified-since
header issue on a 404api.config.general.fileRequestLogLevel
. We will show both the file on disk and the requested file path from the URL.NODE_ENV=production
will allow locale files to be written by defaultREDIS_PASSWORD
actionhero version
will now return the version of ActionHero in useactionhero help
, actionhero generate
and actionhero version
can be run when installed globally outside of an ActionHero project directoryPublished by evantahler about 8 years ago
A collection of fixes have been included to properly handle ETAG headers and cache priority.
ETAG
vs expires
and last-modified
)
Node Resque v4.0.0 removes the use of domains
within tasks. This feature of node.js has been deprecated for some time. However, this means now that if your task raises an uncaught exception/rejection, the ActionHero application will not crash, rather than logging an error.
Furthermore, since the application has crashed, the job which caused the crash will not be moved into the error
queue within resque.
The behavior for tasks which properly return an error has not changed.
--workerTitlePrefix
which was showing NaN
titleES6 transition.
var
in favor of const
and let
, and to use arrow functions to better handle scope (no more self = this
)actionhero link
properly (@dangerdespain via https://github.com/evantahler/actionhero/pull/942)Published by evantahler about 8 years ago
api.commands.start()
/stop
/restart
this
to these commands. You can call them directly.Users with a misconfigured ioredis
config, or those running Docker containers where the Redis service may not yet be fully started, may see heavy log spam during AH's boot cycle. The default ioredis
configuration auto-reconnects every 50ms and can rapidly exhaust a log before an admin sees what's going on.
This change does two things:
2016-08-23T15:50:41.378Z - notice: * Starting ActionHero *
>> 2016-08-23T15:50:41.389Z - error: Redis connection `client` error Error: connect ECONNREFUSED 127.0.0.1:6379
>> at Object.exports._errnoException (util.js:870:11)
>> at exports._exceptionWithHostPort (util.js:893:20)
>> at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1063:14)
>> 2016-08-23T15:50:41.390Z - error: Unable to connect to Redis - please check your Redis config!
When you listen on the "connected" event on the websocket connect and you fire immediately a action over the client lib the "actionWeb" function is used instead of the "actionWebSocket" function because self.state = 'connected';
is set after the "connected" event is emitted. This change corrects this.
workerTitlePrefix
option to start cluster
to modify your child process names (thanks @ericli1018!)startCluster
(it is start
cluster` now)!Published by evantahler about 8 years ago
api.tasks.addMiddleware
no longer requires a callback. Errors will be thrown directly.
ioredis
-> ^2.3.0
is-running
-> ^2.0.1
uglify-js
-> ^2.7.2
should
-> ^11.0.0
eslint
-> ^3.3.1
Published by evantahler about 8 years ago
Published by evantahler about 8 years ago
before_perform
, after_perform
, before_enqueue
, and after_enqueue
functions of Resque plugins through preProcessor
, postProcessor
, preEnqueue
, and postEnqueue
methods. Each middleware requires a name
and at least one function. In addition, a middleware can be global, in which case it also requires a priority
.preProcessor
, you can access the original task params
through this.args[0]
.postProcessor
, you can access the task result at this.worker.result
.preEnqueue
and postEnqueue
you can access the task params
through this.args[0]
. - If you wish to prevent a task from being enqueued using the preEnqueue
middleware you must explicitly set the toRun
value to false
in the callback. Because the task middleware is executed by Resque this
is an instance of a Resque Worker and contains a number of other elements which may be useful in a middleware.'use strict';
module.exports = {
loadPriority: 1000,
initialize: function(api, next){
api.taskTimer = {
middleware: {
name: 'timer',
global: true,
priority: 90,
preProcessor: function(next){
var worker = this.worker;
worker.start = process.hrtime();
next();
},
postProcessor: function(next){
var worker = this.worker;
var elapsed = process.hrtime(worker.start);
var seconds = elapsed[0];
var millis = elapsed[1] / 1000000;
api.log('Task ' + worker.job.class + ' finished in ' + seconds + ' s and ' + millis + ' ms.', 'info');
next();
},
preEnqueue: function(next){
var params = this.args[0];
//Validate params
next(null, true); //callback is in form cb(error, toRun)
},
postEnqueue: function(next){
api.log("Task successfully enqueued!");
next();
}
}
};
api.tasks.addMiddleware(api.taskTimer.middleware, function(error){
next(error);
});
}
};
`actionhero generateAction --name=[name]` -> `actionhero generate action --name=[name]`
`actionhero generateInitializer --name=[name]` -> `actionhero generate initializer --name=[name]`
`actionhero generateServer --name=[name]` -> `actionhero generate server --name=[name]`
`actionhero generateTask --name=[name]` -> `actionhero generate task --name=[name]`
--startPriority
, --stopPriority
and --loadPriority
debug
status to quiet down ActionHero when starting up.Published by evantahler about 8 years ago
node-resque
updated to version 2.1.2 (fixes an error clearing task locks when a job fails due to an uncaughtException)async
updated to version 2.0.1primus
updated to version 6.0 (may include some breaking transport changes)