@house-agency/brewsession
Version:
The Brewery Session Manager
145 lines (135 loc) • 3.55 kB
JavaScript
const body_parser = require('body-parser');
const express = require('express');
const log = require('@house-agency/brewtils/log');
const q = require('q');
const router = new express.Router();
const service = require('./service');
router.use(body_parser.json());
/**
* Get the session token from request.
*
* It'll first try to parse it from the header with
* "Authorization: Beared <token>". If that fails, it'll
* try to find it as a cookie - named "Authorization".
*
* @param {object} req Request object
*
* @return {string} Promise with token string
*/
function get_http_request_token(req) {
return q.try(() => {
return q(req.get('Authorization'))
.invoke('match', /^Bearer ([^ ]+)$/)
.get(1);
})
.catch(() => {
return q(req.get('Cookie'))
.invoke('match', /Authorization=([^;]+)/)
.get(1);
});
}
/**
* Looks for protocol and User-Agent in
* request header. And fails if they're missing.
*
* @param {object} req Request object
*
* @return {array} Promise with an array of header values
*/
function get_required_http_headers(req) {
return q.try(() => {
return q.all([
req.protocol,
req.get('User-Agent')
]);
})
.then(headers => {
return headers.map(value => {
if (typeof value === 'undefined') {
throw new Error('Invalid header');
}
return value;
});
});
}
/**
* Verify an http request session
* Header must contain Authorization: Bearer <token>
* If verified, it'll exceed the expire timestamp
*
* @param {object} req Request object
* @param {object} res Response object
*
* @returns {void}
*/
function verify_http_request(req, res, next) {
q.all([
get_http_request_token(req),
get_required_http_headers(req)
])
.spread((token, headers) => {
return service.verify.apply(null, [token].concat(headers));
})
.then(service.exceed)
.then(() => next())
.catch(error => {
log('error', 'Could not verify http request', error);
res.status(403).json({
status: 403,
message: 'Invalid session token'
});
});
}
/**
* Creates session by api key found in request header.
*
* Response with the created session token and a signed cookie.
*
* @param {object} req Request object
* @param {object} res Response object
*
* @returns {void}
*/
function create_session(req, res) {
q.try(() => {
return q.all([
req.body.key,
get_required_http_headers(req)
]);
})
.spread((key, headers) => {
return service.create.apply(null, [key].concat(headers));
})
.then(token => {
res.cookie('Authorization', token);
res.json({token: token});
})
.catch(error => {
log('error', 'Could not create session', error);
res.status(403).json({
status: 403,
message: 'Invalid api-key'
});
})
.done();
}
/**
* Verifies provided token and response with a status
*
* @param {object} req Request object
* @param {object} res Response object
*
* @returns {void}
*/
function session_status(req, res) {
verify_http_request(req, res, () => {
res.json({ status: 'ok' });
});
}
router.post('/create', create_session);
router.get('/status', session_status);
module.exports = {
routes: router,
get_http_request_token: get_http_request_token,
verify_http_request: verify_http_request
};