UNPKG

tom-microservice

Version:

Tom creates customers, subscriptions plans & send notifications.

124 lines (104 loc) 2.96 kB
'use strict' const { eq, forEach, noop } = require('lodash') const { buffer, text } = require('http-body') const requestIp = require('request-ip') const toQuery = require('to-query')() const Router = require('router-http') const send = require('./send') const withRoute = require('./interface/route') const createTom = require('.') const { TOM_API_KEY, TOM_ALLOWED_ORIGIN, NODE_ENV } = process.env const UNAUTHENTICATED_PATHS = [ '/', '/robots.txt', '/favicon.ico', '/ping', '/payment/webhook' ] const getBody = async req => { if (req.path === '/payment/webhook') return buffer(req) const body = await text(req) if (body === '') return body try { return JSON.parse(body) } catch (_) { return body } } const isTest = NODE_ENV === 'test' const finalhandler = (error, req, res) => { const hasError = error !== undefined return hasError ? send.error( res, { message: error.mesage || 'Internal Server Error' }, error.statusCode ) : send.fail(res, { message: 'HTTP Method Not Allowed' }, 405) } const createRouter = () => { const router = Router(finalhandler) router .use(require('helmet')()) .use(require('http-compression')()) .use( require('cors')({ methods: ['GET', 'OPTIONS', 'POST'], origin: TOM_ALLOWED_ORIGIN ? TOM_ALLOWED_ORIGIN.replace(/\s/g, '').split(',') : '*', allowedHeaders: [ 'content-type', 'x-amz-date', 'authorization', 'x-api-key', 'x-amz-security-token', 'x-csrf-token' ] }) ) .use(async (req, res, next) => { req.query = toQuery(req.url) req.ipAddress = requestIp.getClientIp(req) req.body = await getBody(req) next() }) if (!isTest) router.use(require('morgan')('tiny')) if (TOM_API_KEY) { router.use((req, res, next) => { if (UNAUTHENTICATED_PATHS.includes(req.path)) return next() const apiKey = req.headers['x-api-key'] ?? req.query.apiKey return eq(apiKey, TOM_API_KEY) ? next() : send.fail( res, { message: 'Invalid API token in x-api-key header.' }, 401 ) }) } router .get('/', (_, res) => send(res, 204)) .get('/robots.txt', (_, res) => send(res, 204)) .get('/favicon.ico', (_, res) => send(res, 204)) .get('/ping', (_, res) => send(res, 200, 'pong')) return router } module.exports = (tomConfig, fn = noop) => { if (!tomConfig) throw TypeError('You need to provide tom configuration file.') const router = createRouter() const tom = createTom(tomConfig) forEach(tom, (cmd, cmdName) => { forEach(cmd, (fn, actionName) => { const eventName = `${cmdName}.${actionName}` router.post( `/${cmdName}/${actionName}`, withRoute({ tom, fn, eventName }) ) }) }) fn({ tom, router, send }) return router }