UNPKG

@house-agency/brewsession

Version:

The Brewery Session Manager

145 lines (135 loc) 3.55 kB
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 };