Comparing version 0.1.0 to 0.1.1
@@ -6,3 +6,3 @@ #!node | ||
init: require('../lib/main'), | ||
confPath: process.env.APIJOE_CONF || './conf.toml' | ||
confPath: process.argv[2] | ||
}); |
@@ -8,2 +8,19 @@ # API Joe Changelog | ||
## [v0.1.1] - 2020-02-12 | ||
### Added | ||
- setting for the auth request timeout | ||
- optional command line argument for setting config file path | ||
- setting for triggering a webhook on successful auth | ||
### Fixed | ||
- bug when using miliseconds as sesison expiration time (expects seconds) | ||
- docker image error when no external config file was mounted | ||
- docker image to use unprevilleged user by default | ||
- cookie clearing when accessing expired session | ||
### Changed | ||
- logging strategy to new Nodecaf stdout logging | ||
- default port to 9000 regardless of HTTPS | ||
## [v0.1.0] - 2019-10-16 | ||
@@ -13,1 +30,2 @@ - First officially published version. | ||
[v0.1.0]: https://gitlab.com/GCSBOSS/api-joe/-/tags/v0.1.0 | ||
[v0.1.1]: https://gitlab.com/GCSBOSS/api-joe/-/tags/v0.1.1 |
@@ -9,3 +9,3 @@ const periodo = require('periodo'); | ||
app.name = 'API Gateway'; | ||
app.version = '0.0.0'; | ||
app.version = '0.1.1'; | ||
app.shouldParseBody = false; | ||
@@ -21,3 +21,3 @@ app.alwaysRebuildAPI = true; | ||
conf.session.timeout = periodo(conf.session.timeout).time / 1000; | ||
conf.session.timeout = Math.floor(periodo(conf.session.timeout).time / 1000); | ||
@@ -24,0 +24,0 @@ var rclient = redis.createClient(conf.redis); |
@@ -23,3 +23,3 @@ const httpProxy = require('http-proxy'); | ||
res.status(503).end(); | ||
log.warn({ req: req }, 'PROXY ERROR ' + this.service.url); | ||
log.warn({ req: req }, 'Proxy error calling %s', this.service.url); | ||
}); | ||
@@ -26,0 +26,0 @@ } |
@@ -1,7 +0,13 @@ | ||
const { request } = require('muhb'); | ||
const { request, post } = require('muhb'); | ||
const { authn } = require('nodecaf').assertions; | ||
function eraseCookie(conf, res){ | ||
let opts = { ...conf.cookie }; | ||
delete opts.maxAge; | ||
res.clearCookie(conf.cookie.name, opts); | ||
} | ||
module.exports = { | ||
async match({ redis, req, flash, next, conf }){ | ||
async match({ redis, req, flash, next, conf, res }){ | ||
let claim = req.signedCookies[conf.cookie.name]; | ||
@@ -12,7 +18,9 @@ | ||
if(await redis.exists(claim) === 0) | ||
if(await redis.exists(claim) === 0){ | ||
eraseCookie(conf, res); | ||
return next(); | ||
} | ||
flash.claim = claim; | ||
redis.expire(flash.claim, conf.session.timeout); | ||
redis.expire(claim, conf.session.timeout); | ||
next(); | ||
@@ -31,4 +39,4 @@ }, | ||
let { status, body: authData } = await request({ | ||
timeout: 3000, body, | ||
method: conf.auth.method.toLowerCase(), | ||
timeout: conf.auth.timeout, body, | ||
method: conf.auth.method, | ||
url: conf.auth.url, | ||
@@ -45,8 +53,9 @@ headers: { 'Content-Type': 'application/json' } | ||
redis.expire(authData, conf.session.timeout); | ||
if(typeof conf.auth.onSuccess == 'string') | ||
post(conf.auth.onSuccess, { 'X-Joe-Auth': 'success' }, authData); | ||
}, | ||
destroy({ flash, res, redis, conf }){ | ||
let opts = { ...conf.cookie }; | ||
delete opts.maxAge; | ||
res.clearCookie(conf.cookie.name, opts); | ||
eraseCookie(conf, res); | ||
res.end(); | ||
@@ -53,0 +62,0 @@ redis.del(flash.claim); |
{ | ||
"name": "api-joe", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"description": "An API Gateway to easily expose your services to web clients", | ||
@@ -13,4 +13,8 @@ "main": "lib/main.js", | ||
"bugs": { | ||
"url": "https://gitlab.com/GCSBOSS/api-joe/issues" | ||
"url": "https://gitlab.com/GCSBOSS/api-joe/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://gitlab.com/GCSBOSS/api-joe.git" | ||
}, | ||
"scripts": { | ||
@@ -21,13 +25,13 @@ "test": "mocha -b --no-diff test/*.js", | ||
"keywords": [ | ||
"api", | ||
"gateway", | ||
"proxy", | ||
"filter", | ||
"session", | ||
"log", | ||
"expose", | ||
"rest", | ||
"service", | ||
"cookie", | ||
"signed" | ||
"api", | ||
"gateway", | ||
"proxy", | ||
"filter", | ||
"session", | ||
"log", | ||
"expose", | ||
"rest", | ||
"service", | ||
"cookie", | ||
"signed" | ||
], | ||
@@ -37,6 +41,6 @@ "dependencies": { | ||
"http-proxy": "^1.18.0", | ||
"muhb": "^2.0.3", | ||
"nodecaf": "^0.7.10", | ||
"muhb": "^3.0.0", | ||
"nodecaf": "^0.8.0", | ||
"periodo": "^0.1.1" | ||
} | ||
} |
@@ -8,5 +8,4 @@ # [API Joe](https://gitlab.com/GCSBOSS/api-joe) | ||
1. Install with: `npm i -g api-joe`. | ||
2. Point `APIJOE_CONF` env var to a TOML [config file](#configuration). | ||
3. Setup your [services](#services). | ||
4. Run in the terminal with: `api-joe`. | ||
2. Setup your [services](#services). | ||
3. Run in the terminal with: `api-joe` (optional argument for the [config file](#configuration) path). | ||
@@ -17,3 +16,3 @@ ## Get Started with Docker | ||
Run like this: `docker run -p 10080:80 -v /your/conf.toml:/usr/src/app/conf.toml gcsboss/api-joe` | ||
Run like this: `docker run -p 9000:9000 gcsboss/api-joe` | ||
@@ -24,11 +23,9 @@ ## Configuration | ||
port = 80 | ||
port = 9000 | ||
[log] | ||
level = 'debug' | ||
file = './api-joe.log' | ||
[auth] | ||
method = 'POST' | ||
url = 'http://auth-api/path' | ||
timeout = 3000 | ||
onSuccess = 'http://webhook.com/auth-success' | ||
@@ -35,0 +32,0 @@ [redis] |
const assert = require('assert'); | ||
const { context } = require('muhb'); | ||
process.env.NODE_ENV = 'testing'; | ||
const init = require('../lib/main'); | ||
@@ -144,3 +146,3 @@ | ||
it('Should create signed cookie when succeeds [cookie.name]', async function(){ | ||
it('Should create signed cookie when auth succeeds [cookie.name]', async function(){ | ||
await app.restart({ cookie: { name: 'foobar' } }); | ||
@@ -166,2 +168,16 @@ let { cookies } = await base.post('login'); | ||
it('Should POST to specified URL when auth succeeds [auth.onSuccess]', function(done){ | ||
let serv = require('http').createServer((req, res) => { | ||
assert.strictEqual(req.headers['x-joe-auth'], 'success'); | ||
serv.close(); | ||
res.end(); | ||
done(); | ||
}); | ||
serv.listen(2345); | ||
(async () => { | ||
await app.restart({ auth: { onSuccess: 'http://localhost:2345' } }); | ||
await base.post('login'); | ||
})(); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
20246
19
286
3
74
2
+ Addedmuhb@3.2.1(transitive)
+ Addednodecaf@0.8.5(transitive)
+ Addedws@7.5.10(transitive)
- Removedgolog@0.1.2(transitive)
- Removedmuhb@2.1.1(transitive)
- Removednodecaf@0.7.10(transitive)
Updatedmuhb@^3.0.0
Updatednodecaf@^0.8.0