WIPP
This commit is contained in:
parent
0bf54fa1d8
commit
30071151ff
6 changed files with 107 additions and 242 deletions
180
lib/routes.js
180
lib/routes.js
|
|
@ -3,15 +3,12 @@
|
|||
const morgan = require('morgan')
|
||||
const helmet = require('helmet')
|
||||
const bodyParser = require('body-parser')
|
||||
const BigNumber = require('bignumber.js')
|
||||
const _ = require('lodash/fp')
|
||||
const express = require('express')
|
||||
|
||||
const options = require('./options')
|
||||
const logger = require('./logger')
|
||||
const configManager = require('./config-manager')
|
||||
const db = require('./db')
|
||||
const dbm = require('./postgresql_interface')
|
||||
const pairing = require('./pairing')
|
||||
const settingsLoader = require('./settings-loader')
|
||||
const plugins = require('./plugins')
|
||||
|
|
@ -35,11 +32,11 @@ function poll (req, res, next) {
|
|||
const pid = req.query.pid
|
||||
const settings = req.settings
|
||||
const config = configManager.machineScoped(deviceId, settings.config)
|
||||
const pi = plugins(settings)
|
||||
const pi = plugins(settings, deviceId)
|
||||
|
||||
pids[deviceId] = {pid, ts: Date.now()}
|
||||
|
||||
pi.pollQueries(deviceTime, deviceId, req.query)
|
||||
pi.pollQueries(deviceTime, req.query)
|
||||
.then(results => {
|
||||
const cartridges = results.cartridges
|
||||
|
||||
|
|
@ -82,77 +79,38 @@ function poll (req, res, next) {
|
|||
}
|
||||
|
||||
function postTx (req, res, next) {
|
||||
return Tx.post(req.body)
|
||||
console.log('DEBUG60: %j', req.settings)
|
||||
const pi = plugins(req.settings, req.deviceId)
|
||||
|
||||
return Tx.post(_.set('deviceId', req.deviceId, req.body), pi)
|
||||
.then(tx => res.json(tx))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function trade (req, res, next) {
|
||||
const tx = req.body
|
||||
const pi = plugins(req.settings)
|
||||
|
||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||
|
||||
pi.trade(req.deviceId, tx)
|
||||
.then(() => cacheAndRespond(req, res))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function stateChange (req, res, next) {
|
||||
helpers.stateChange(req.deviceId, req.deviceTime, req.body)
|
||||
.then(() => cacheAndRespond(req, res))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function send (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
const tx = req.body
|
||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||
|
||||
return pi.sendCoins(req.deviceId, tx)
|
||||
.then(status => {
|
||||
const body = {txId: status && status.txId}
|
||||
return cacheAndRespond(req, res, body)
|
||||
})
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function cashOut (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
logger.info({tx: req.body, cmd: 'cashOut'})
|
||||
const tx = req.body
|
||||
tx.cryptoAtoms = new BigNumber(tx.cryptoAtoms)
|
||||
|
||||
return pi.cashOut(req.deviceId, tx)
|
||||
.then(cryptoAddress => cacheAndRespond(req, res, {toAddress: cryptoAddress}))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function dispenseAck (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
pi.dispenseAck(req.deviceId, req.body.tx)
|
||||
.then(() => cacheAndRespond(req, res))
|
||||
.then(() => respond(req, res))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function deviceEvent (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
pi.logEvent(req.deviceId, req.body)
|
||||
.then(() => cacheAndRespond(req, res))
|
||||
const pi = plugins(req.settings, req.deviceId)
|
||||
pi.logEvent(req.body)
|
||||
.then(() => respond(req, res))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function verifyUser (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
const pi = plugins(req.settings, req.deviceId)
|
||||
pi.verifyUser(req.body)
|
||||
.then(idResult => cacheAndRespond(req, res, idResult))
|
||||
.then(idResult => respond(req, res, idResult))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function verifyTx (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
const pi = plugins(req.settings, req.deviceId)
|
||||
pi.verifyTransaction(req.body)
|
||||
.then(idResult => cacheAndRespond(req, res, idResult))
|
||||
.then(idResult => respond(req, res, idResult))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
|
|
@ -177,11 +135,11 @@ function pair (req, res, next) {
|
|||
}
|
||||
|
||||
function phoneCode (req, res, next) {
|
||||
const pi = plugins(req.settings)
|
||||
const pi = plugins(req.settings, req.deviceId)
|
||||
const phone = req.body.phone
|
||||
|
||||
return pi.getPhoneCode(phone)
|
||||
.then(code => cacheAndRespond(req, res, {code}))
|
||||
.then(code => respond(req, res, {code}))
|
||||
.catch(err => {
|
||||
if (err.name === 'BadNumberError') throw httpError('Bad number', 410)
|
||||
throw err
|
||||
|
|
@ -189,88 +147,6 @@ function phoneCode (req, res, next) {
|
|||
.catch(next)
|
||||
}
|
||||
|
||||
function updatePhone (req, res, next) {
|
||||
const notified = req.query.notified === 'true'
|
||||
const tx = req.body
|
||||
|
||||
return dbm.updatePhone(tx, notified)
|
||||
.then(r => cacheAndRespond(req, res, r))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function fetchPhoneTx (req, res, next) {
|
||||
return helpers.fetchPhoneTx(req.query.phone)
|
||||
.then(r => res.json(r))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function registerRedeem (req, res, next) {
|
||||
const txId = req.params.txId
|
||||
return dbm.registerRedeem(txId)
|
||||
.then(() => cacheAndRespond(req, res))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function waitForDispense (req, res, next) {
|
||||
logger.debug('waitForDispense')
|
||||
return dbm.fetchTx(req.params.txId)
|
||||
.then(tx => {
|
||||
logger.debug('tx fetched')
|
||||
logger.debug(tx)
|
||||
if (!tx) return res.sendStatus(404)
|
||||
if (tx.status === req.query.status) return res.sendStatus(304)
|
||||
res.json({tx})
|
||||
})
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function dispense (req, res, next) {
|
||||
const tx = req.body.tx
|
||||
|
||||
return dbm.addDispenseRequest(tx)
|
||||
.then(dispenseRec => cacheAndRespond(req, res, dispenseRec))
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
function isUniqueViolation (err) {
|
||||
return err.code === '23505'
|
||||
}
|
||||
|
||||
function cacheAction (req, res, next) {
|
||||
const requestId = req.headers['request-id']
|
||||
if (!requestId) return next()
|
||||
|
||||
const sql = `insert into idempotents (request_id, device_id, body, status, pending)
|
||||
values ($1, $2, $3, $4, $5)`
|
||||
|
||||
const deviceId = req.deviceId
|
||||
|
||||
db.none(sql, [requestId, deviceId, {}, 204, true])
|
||||
.then(() => next())
|
||||
.catch(err => {
|
||||
if (!isUniqueViolation(err)) throw err
|
||||
|
||||
const sql2 = 'select body, status, pending from idempotents where request_id=$1'
|
||||
return db.one(sql2, [requestId])
|
||||
.then(row => {
|
||||
if (row.pending) return res.status(204).end()
|
||||
return res.status(row.status).json(row.body)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function updateCachedAction (req, body, status) {
|
||||
const requestId = req.headers['request-id']
|
||||
if (!requestId) return Promise.resolve()
|
||||
|
||||
const sql = `update idempotents set body=$1, status=$2, pending=$3
|
||||
where request_id=$4 and device_id=$5 and pending=$6`
|
||||
|
||||
const deviceId = req.deviceId
|
||||
|
||||
return db.none(sql, [body, status, false, requestId, deviceId, true])
|
||||
}
|
||||
|
||||
function errorHandler (err, req, res, next) {
|
||||
const statusCode = err.name === 'HttpError'
|
||||
? err.code || 500
|
||||
|
|
@ -280,22 +156,14 @@ function errorHandler (err, req, res, next) {
|
|||
|
||||
logger.error(err)
|
||||
|
||||
return updateCachedAction(req, json, statusCode)
|
||||
.then(() => res.status(statusCode).json(json))
|
||||
return res.status(statusCode).json(json)
|
||||
}
|
||||
|
||||
function cacheAndRespond (req, res, _body, _status) {
|
||||
function respond (req, res, _body, _status) {
|
||||
const status = _status || 200
|
||||
const body = _body || {}
|
||||
|
||||
return updateCachedAction(req, body, status)
|
||||
.then(() => res.status(status).json(body))
|
||||
}
|
||||
|
||||
function pruneIdempotents () {
|
||||
const sql = "delete from idempotents where created < now() - interval '24 hours'"
|
||||
|
||||
return db.none(sql)
|
||||
return res.status(status).json(body)
|
||||
}
|
||||
|
||||
function httpError (msg, code) {
|
||||
|
|
@ -339,14 +207,11 @@ const skip = options.logLevel === 'debug'
|
|||
|
||||
const configRequiredRoutes = [
|
||||
'/poll',
|
||||
'/trade',
|
||||
'/send',
|
||||
'/cash_out',
|
||||
'/dispense_ack',
|
||||
'/event',
|
||||
'/verify_user',
|
||||
'/verify_transaction',
|
||||
'/phone_code'
|
||||
'/phone_code',
|
||||
'/tx'
|
||||
]
|
||||
|
||||
const app = express()
|
||||
|
|
@ -364,7 +229,6 @@ app.use(populateDeviceId)
|
|||
if (!devMode) app.use(authorize)
|
||||
app.use(configRequiredRoutes, populateSettings)
|
||||
app.use(filterOldRequests)
|
||||
app.post('*', cacheAction)
|
||||
|
||||
app.get('/poll', poll)
|
||||
app.post('/state', stateChange)
|
||||
|
|
@ -435,6 +299,4 @@ function populateSettings (req, res, next) {
|
|||
.catch(next)
|
||||
}
|
||||
|
||||
setInterval(pruneIdempotents, 60000)
|
||||
|
||||
module.exports = {app, localApp}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue