diff --git a/lib/cash-in-tx.js b/lib/cash-in-tx.js index f8b8643b..1b4777cf 100644 --- a/lib/cash-in-tx.js +++ b/lib/cash-in-tx.js @@ -72,7 +72,7 @@ function isMonotonic (oldField, newField, fieldKey) { function ensureRatchet (oldField, newField, fieldKey) { const monotonic = ['cryptoAtoms', 'fiat', 'send', 'sendConfirmed', 'operatorCompleted', 'timedout'] - const free = ['sendPending', 'error', 'errorCode'] + const free = ['sendPending', 'error', 'errorCode', 'customerId'] if (_.isNil(oldField)) return true if (_.includes(fieldKey, monotonic)) return isMonotonic(oldField, newField, fieldKey) diff --git a/lib/customers.js b/lib/customers.js new file mode 100644 index 00000000..47cdccd1 --- /dev/null +++ b/lib/customers.js @@ -0,0 +1,35 @@ +const db = require('./db') +const uuid = require('uuid') +const _ = require('lodash/fp') +const BN = require('./bn') + +function add (customer) { + const sql = 'insert into customers (id, phone, phone_at) values ($1, $2, now()) returning *' + return db.one(sql, [uuid.v4(), customer.phone]) +} + +function get (phone) { + const sql = 'select id, phone from customers where phone=$1' + return db.oneOrNone(sql, [phone]) + .then(customer => { + if (!customer) return + return getDailyVolume(customer.id).then(dailyVolume => { + return _.set('dailyVolume', dailyVolume, customer) + }) + }) +} + +function getDailyVolume (id) { + return Promise.all([ + db.one(`select coalesce(sum(fiat), 0) as total from cash_in_txs + where customer_id=$1 + and created > now() - interval '1 day'`, [id]), + db.one(`select COALESCE(sum(fiat), 0) as total from cash_out_txs + where customer_id=$1 + and created > now() - interval '1 day'`, [id]) + ]).then(([cashInTotal, cashOutTotal]) => { + return BN(cashInTotal.total).add(cashOutTotal.total) + }) +} + +module.exports = { add, get } diff --git a/lib/routes.js b/lib/routes.js index c5969d0e..d80c3efc 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -15,6 +15,7 @@ const plugins = require('./plugins') const helpers = require('./route-helpers') const poller = require('./poller') const Tx = require('./tx') +const customers = require('./customers') const argv = require('minimist')(process.argv.slice(2)) @@ -138,6 +139,24 @@ function verifyTx (req, res, next) { .catch(next) } +function getCustomerWithPhoneCode (req, res, next) { + const pi = plugins(req.settings, req.deviceId) + const phone = req.body.phone + return pi.getPhoneCode(phone) + .then(code => { + return customers.get(phone.phone).then(customer => { + if (customer) return respond(req, res, {code, customer}) + return customers.add(req.body) + .then(customer => respond(req, res, {code, customer})) + }) + }) + .catch(err => { + if (err.name === 'BadNumberError') throw httpError('Bad number', 410) + throw err + }) + .catch(next) +} + function ca (req, res) { const token = req.query.token @@ -264,7 +283,7 @@ app.post('/event', deviceEvent) app.post('/verify_user', verifyUser) app.post('/verify_transaction', verifyTx) -app.post('/phone_code', phoneCode) +app.post('/phone_code', getCustomerWithPhoneCode) app.post('/tx', postTx) app.get('/tx/:id', getTx) app.get('/tx', getPhoneTx)