Feat: user compliance saving to DB
This commit is contained in:
parent
204e421b3d
commit
2a9e8dadba
7 changed files with 79 additions and 29 deletions
|
|
@ -13,10 +13,11 @@ const getBlacklist = () => {
|
||||||
|
|
||||||
// Delete row from blacklist table by crypto code and address
|
// Delete row from blacklist table by crypto code and address
|
||||||
const deleteFromBlacklist = (cryptoCode, address) => {
|
const deleteFromBlacklist = (cryptoCode, address) => {
|
||||||
return db.none(
|
const sql = `DELETE FROM blacklist WHERE crypto_code = $1 AND address = $2;
|
||||||
`DELETE FROM blacklist WHERE created_by_operator = 't' AND crypto_code = $1 AND address = $2`,
|
UPDATE notifications SET valid = 'f', read = 't' WHERE valid = 't' AND detail IN ($3^)`
|
||||||
[cryptoCode, address]
|
|
||||||
)
|
const detail = `'${cryptoCode}_BLOCKED_${address}', '${cryptoCode}_REUSED_${address}'`
|
||||||
|
return db.none(sql, [cryptoCode, address, detail])
|
||||||
}
|
}
|
||||||
|
|
||||||
const insertIntoBlacklist = (cryptoCode, address) => {
|
const insertIntoBlacklist = (cryptoCode, address) => {
|
||||||
|
|
@ -27,12 +28,12 @@ const insertIntoBlacklist = (cryptoCode, address) => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function blocked(address, cryptoCode) {
|
function blocked (address, cryptoCode) {
|
||||||
const sql = `select * from blacklist where address = $1 and crypto_code = $2`
|
const sql = `select * from blacklist where address = $1 and crypto_code = $2`
|
||||||
return db.any(sql, [address, cryptoCode])
|
return db.any(sql, [address, cryptoCode])
|
||||||
}
|
}
|
||||||
|
|
||||||
function addToUsedAddresses(address, cryptoCode) {
|
function addToUsedAddresses (address, cryptoCode) {
|
||||||
// ETH reuses addresses
|
// ETH reuses addresses
|
||||||
if (cryptoCode === 'ETH') return Promise.resolve()
|
if (cryptoCode === 'ETH') return Promise.resolve()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ function post (machineTx, pi) {
|
||||||
|
|
||||||
if (_.some(it => it.created_by_operator === true)(blacklistItems)) {
|
if (_.some(it => it.created_by_operator === true)(blacklistItems)) {
|
||||||
blacklisted = true
|
blacklisted = true
|
||||||
notifier.addBlacklistNotification(r.tx, false)
|
notifier.blacklistNotify(r.tx, false)
|
||||||
} else if (_.some(it => it.created_by_operator === false)(blacklistItems) && rejectAddressReuseActive) {
|
} else if (_.some(it => it.created_by_operator === false)(blacklistItems) && rejectAddressReuseActive) {
|
||||||
notifier.addBlacklistNotification(r.tx, true)
|
notifier.blacklistNotify(r.tx, true)
|
||||||
addressReuse = true
|
addressReuse = true
|
||||||
}
|
}
|
||||||
return postProcess(r, pi, blacklisted, addressReuse)
|
return postProcess(r, pi, blacklisted, addressReuse)
|
||||||
|
|
|
||||||
|
|
@ -115,12 +115,22 @@ async function updateCustomer (id, data, userToken) {
|
||||||
|
|
||||||
const sql = Pgp.helpers.update(updateData, _.keys(updateData), 'customers') +
|
const sql = Pgp.helpers.update(updateData, _.keys(updateData), 'customers') +
|
||||||
' where id=$1'
|
' where id=$1'
|
||||||
|
invalidateCustomerNotifications(id, formattedData)
|
||||||
|
|
||||||
await db.none(sql, [id])
|
await db.none(sql, [id])
|
||||||
|
|
||||||
return getCustomerById(id)
|
return getCustomerById(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const invalidateCustomerNotifications = (id, data) => {
|
||||||
|
let detail = '';
|
||||||
|
if(data.authorized_override === 'verified') {
|
||||||
|
detail = `BLOCKED_${id}`
|
||||||
|
}
|
||||||
|
const sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE valid = 't' AND detail = $1`
|
||||||
|
return db.none(sql, [detail])
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get customer by id
|
* Get customer by id
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ function renameMachine (rec) {
|
||||||
function resetCashOutBills (rec) {
|
function resetCashOutBills (rec) {
|
||||||
const sql = `
|
const sql = `
|
||||||
update devices set cassette1=$1, cassette2=$2 where device_id=$3;
|
update devices set cassette1=$1, cassette2=$2 where device_id=$3;
|
||||||
update notifications set read = 't', valid = 'f' where read = 'f' AND device_id = $3 AND type = 'fiatBalance';
|
update notifications set read = 't', valid = 'f' where read = 'f' AND valid = 't' AND device_id = $3 AND type = 'fiatBalance';
|
||||||
`
|
`
|
||||||
return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
|
return db.none(sql, [rec.cassettes[0], rec.cassettes[1], rec.deviceId])
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -225,11 +225,11 @@ const cashCassettesNotify = (cassettes, deviceId) => {
|
||||||
Promise.all([queries.getUnreadCassetteNotifications(1, deviceId), queries.getUnreadCassetteNotifications(2, deviceId)]).then(res => {
|
Promise.all([queries.getUnreadCassetteNotifications(1, deviceId), queries.getUnreadCassetteNotifications(2, deviceId)]).then(res => {
|
||||||
if(res[0].length === 0 && cassette1Count < cassette1Threshold) {
|
if(res[0].length === 0 && cassette1Count < cassette1Threshold) {
|
||||||
console.log("Adding fiatBalance alert for cashbox 1 in database - count & threshold: ", cassette1Count, cassette1Threshold )
|
console.log("Adding fiatBalance alert for cashbox 1 in database - count & threshold: ", cassette1Count, cassette1Threshold )
|
||||||
queries.addCashCassetteWarning(1, deviceId)
|
return queries.addCashCassetteWarning(1, deviceId)
|
||||||
}
|
}
|
||||||
if(res[1].length === 0 && cassette2Count < cassette2Threshold) {
|
if(res[1].length === 0 && cassette2Count < cassette2Threshold) {
|
||||||
console.log("Adding fiatBalance alert for cashbox 2 in database - count & threshold: ", cassette2Count, cassette2Threshold )
|
console.log("Adding fiatBalance alert for cashbox 2 in database - count & threshold: ", cassette2Count, cassette2Threshold )
|
||||||
queries.addCashCassetteWarning(2, deviceId)
|
return queries.addCashCassetteWarning(2, deviceId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +269,7 @@ const clearOldCryptoNotifications = (balances) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// if the notification doesn't exist in the new balances object, then it is outdated and is not valid anymore
|
// if the notification doesn't exist in the new balances object, then it is outdated and is not valid anymore
|
||||||
queries.invalidateNotification(notification.id)
|
return queries.invalidateNotification(notification.id)
|
||||||
}, notifications)
|
}, notifications)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ const balancesNotify = (balances) => {
|
||||||
}
|
}
|
||||||
console.log("Adding high balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
console.log("Adding high balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
||||||
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
||||||
queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `High balance in ${warning.cryptoCode} [${balance}]`)
|
return queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `High balance in ${warning.cryptoCode} [${balance}]`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
lowWarnings.forEach(warning => {
|
lowWarnings.forEach(warning => {
|
||||||
|
|
@ -299,7 +299,7 @@ const balancesNotify = (balances) => {
|
||||||
}
|
}
|
||||||
console.log("Adding low balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
console.log("Adding low balance alert for " + warning.cryptoCode + " - " + warning.fiatBalance.balance)
|
||||||
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
const balance = utils.formatCurrency(warning.fiatBalance.balance, warning.fiatCode)
|
||||||
queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `Low balance in ${warning.cryptoCode} [${balance}]`)
|
return queries.addCryptoBalanceWarning(`${warning.cryptoCode}_${warning.code}`, `Low balance in ${warning.cryptoCode} [${balance}]`)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -314,7 +314,7 @@ const clearOldErrorNotifications = (alerts) => {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// if the notification doesn't exist, then it is outdated and is not valid anymore
|
// if the notification doesn't exist, then it is outdated and is not valid anymore
|
||||||
queries.invalidateNotification(notification.id)
|
return queries.invalidateNotification(notification.id)
|
||||||
}, res)
|
}, res)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -346,7 +346,7 @@ const errorAlertsNotify = (alertRec) => {
|
||||||
}
|
}
|
||||||
console.log("Adding PING alert on database for " + alert.machineName)
|
console.log("Adding PING alert on database for " + alert.machineName)
|
||||||
const message = `Machine down`
|
const message = `Machine down`
|
||||||
queries.addErrorNotification(`${PING}_${alert.age ? alert.age : '-1'}`, message, alert.deviceId)
|
return queries.addErrorNotification(`${PING}_${alert.age ? alert.age : '-1'}`, message, alert.deviceId)
|
||||||
})
|
})
|
||||||
case STALE:
|
case STALE:
|
||||||
return queries.getValidNotifications('error', STALE, alert.deviceId).then(res => {
|
return queries.getValidNotifications('error', STALE, alert.deviceId).then(res => {
|
||||||
|
|
@ -355,26 +355,51 @@ const errorAlertsNotify = (alertRec) => {
|
||||||
}
|
}
|
||||||
console.log("Adding STALE alert on database for " + alert.machineName)
|
console.log("Adding STALE alert on database for " + alert.machineName)
|
||||||
const message = `Machine is stuck on ${alert.state} screen`
|
const message = `Machine is stuck on ${alert.state} screen`
|
||||||
queries.addErrorNotification(STALE, message, alert.deviceId)
|
return queries.addErrorNotification(STALE, message, alert.deviceId)
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
break
|
return
|
||||||
}
|
}
|
||||||
}, alerts)
|
}, alerts)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addBlacklistNotification = (tx, isAddressReuse) => {
|
const blacklistNotify = (tx, isAddressReuse) => {
|
||||||
let detail = ''
|
let detail = ''
|
||||||
let message = ''
|
let message = ''
|
||||||
if(isAddressReuse) {
|
if(isAddressReuse) {
|
||||||
detail = `${tx.cryptoCode}_REUSED_${tx.toAddress}`
|
detail = `${tx.cryptoCode}_REUSED_${tx.toAddress}`
|
||||||
message = `Blocked address reuse: ${tx.cryptoCode} ${tx.toAddress.substr(0,10)}...`
|
message = `Blocked reused address: ${tx.cryptoCode} ${tx.toAddress.substr(0,10)}...`
|
||||||
} else {
|
} else {
|
||||||
detail = `${tx.cryptoCode}_BLOCKED_${tx.toAddress}`
|
detail = `${tx.cryptoCode}_BLOCKED_${tx.toAddress}`
|
||||||
message = `Blocked blacklisted address: ${tx.cryptoCode} ${tx.toAddress.substr(0,10)}...`
|
message = `Blocked blacklisted address: ${tx.cryptoCode} ${tx.toAddress.substr(0,10)}...`
|
||||||
}
|
}
|
||||||
|
|
||||||
queries.addComplianceNotification(tx.deviceId, detail, message)
|
return queries.addComplianceNotification(tx.deviceId, detail, message)
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearOldCustomerSuspendedNotifications = (customerId, deviceId) => {
|
||||||
|
const detail = `SUSPENDED_${customerId}`
|
||||||
|
return queries.invalidateNotification(null, detail, deviceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const customerComplianceNotify = (customer, deviceId, prefix, days = null) => {
|
||||||
|
// prefix can be "BLOCKED", "SUSPENDED", etc
|
||||||
|
const detail = `${prefix}_${customer.id}`
|
||||||
|
const date = new Date()
|
||||||
|
if (days) {
|
||||||
|
date.setDate(date.getDate() + days)
|
||||||
|
}
|
||||||
|
const message = prefix === "SUSPENDED" ? `Customer suspended until ${date.toLocaleString()}` : `Customer blocked`
|
||||||
|
|
||||||
|
// we have to clear every notification for this user where the suspension ended before the current date
|
||||||
|
clearOldCustomerSuspendedNotifications(customer.id, deviceId).then(() => {
|
||||||
|
return queries.getValidNotifications('compliance', detail, deviceId)
|
||||||
|
}).then(res => {
|
||||||
|
if (res.length > 0) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
return queries.addComplianceNotification(deviceId, detail, message)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
@ -384,5 +409,6 @@ module.exports = {
|
||||||
checkStuckScreen,
|
checkStuckScreen,
|
||||||
sendRedemptionMessage,
|
sendRedemptionMessage,
|
||||||
cashCassettesNotify,
|
cashCassettesNotify,
|
||||||
addBlacklistNotification
|
blacklistNotify,
|
||||||
|
customerComplianceNotify,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,9 +55,16 @@ const getValidNotifications = (type, detail, deviceId = null) => {
|
||||||
return db.any(sql, [type, `%${detail}%`, deviceId])
|
return db.any(sql, [type, `%${detail}%`, deviceId])
|
||||||
}
|
}
|
||||||
|
|
||||||
const invalidateNotification = (id) => {
|
const invalidateNotification = (id, detail = null, deviceId = null) => {
|
||||||
const sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE id = $1`
|
let sql = ''
|
||||||
return db.none(sql, [id])
|
if(id) {
|
||||||
|
sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE valid = 't' AND id = $1`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sql = `UPDATE notifications SET valid = 'f', read = 't' WHERE valid = 't' AND detail LIKE $2`
|
||||||
|
sql = deviceId ? sql + ' AND device_id = $3' : sql
|
||||||
|
}
|
||||||
|
return db.none(sql, [id, `%${detail}%`, deviceId])
|
||||||
}
|
}
|
||||||
|
|
||||||
const addComplianceNotification = (deviceId, detail, message) => {
|
const addComplianceNotification = (deviceId, detail, message) => {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ const compliance = require('./compliance')
|
||||||
const promoCodes = require('./promo-codes')
|
const promoCodes = require('./promo-codes')
|
||||||
const BN = require('./bn')
|
const BN = require('./bn')
|
||||||
const commissionMath = require('./commission-math')
|
const commissionMath = require('./commission-math')
|
||||||
|
const notifier = require('./notifier/index')
|
||||||
|
|
||||||
const version = require('../package.json').version
|
const version = require('../package.json').version
|
||||||
|
|
||||||
|
|
@ -108,7 +109,6 @@ function poll (req, res, next) {
|
||||||
operatorInfo,
|
operatorInfo,
|
||||||
triggers
|
triggers
|
||||||
}
|
}
|
||||||
|
|
||||||
// BACKWARDS_COMPATIBILITY 7.5
|
// BACKWARDS_COMPATIBILITY 7.5
|
||||||
// machines before 7.5 expect old compliance
|
// machines before 7.5 expect old compliance
|
||||||
if (!machineVersion || semver.lt(machineVersion, '7.5.0-beta.0')) {
|
if (!machineVersion || semver.lt(machineVersion, '7.5.0-beta.0')) {
|
||||||
|
|
@ -324,6 +324,7 @@ function updateCustomer (req, res, next) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function triggerSanctions (req, res, next) {
|
function triggerSanctions (req, res, next) {
|
||||||
|
console.log("SANCTIONS TRIGGERED")
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
|
|
||||||
customers.getById(id)
|
customers.getById(id)
|
||||||
|
|
@ -342,7 +343,10 @@ function triggerBlock (req, res, next) {
|
||||||
const id = req.params.id
|
const id = req.params.id
|
||||||
|
|
||||||
customers.update(id, { authorizedOverride: 'blocked' })
|
customers.update(id, { authorizedOverride: 'blocked' })
|
||||||
.then(customer => respond(req, res, { customer }))
|
.then(customer => {
|
||||||
|
notifier.customerComplianceNotify(customer, req.deviceId, 'BLOCKED')
|
||||||
|
return respond(req, res, { customer })
|
||||||
|
})
|
||||||
.catch(next)
|
.catch(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,7 +362,10 @@ function triggerSuspend (req, res, next) {
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
date.setDate(date.getDate() + days);
|
date.setDate(date.getDate() + days);
|
||||||
customers.update(id, { suspendedUntil: date })
|
customers.update(id, { suspendedUntil: date })
|
||||||
.then(customer => respond(req, res, { customer }))
|
.then(customer => {
|
||||||
|
notifier.customerComplianceNotify(customer, req.deviceId, 'SUSPENDED', days)
|
||||||
|
respond(req, res, { customer })
|
||||||
|
})
|
||||||
.catch(next)
|
.catch(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -423,7 +430,6 @@ function errorHandler (err, req, res, next) {
|
||||||
function respond (req, res, _body, _status) {
|
function respond (req, res, _body, _status) {
|
||||||
const status = _status || 200
|
const status = _status || 200
|
||||||
const body = _body || {}
|
const body = _body || {}
|
||||||
|
|
||||||
return res.status(status).json(body)
|
return res.status(status).json(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue