Feat: enable notify operator for OFAC matches

Fix: fix lack of newline in some SVGs

Chore: fix rebase issues
This commit is contained in:
Cesar 2021-01-21 17:04:02 +00:00 committed by Josh Harvey
parent 69d3e4cb9b
commit 05373e83db
6 changed files with 46 additions and 40 deletions

View file

@ -3,8 +3,7 @@ const axios = require('axios')
const db = require('./db') const db = require('./db')
const pairing = require('./pairing') const pairing = require('./pairing')
const checkPings = require('./notifier').checkPings const { checkPings, checkStuckScreen } = require('./notifier')
const checkStuckScreen = require('./notifier').checkStuckScreen
const dbm = require('./postgresql_interface') const dbm = require('./postgresql_interface')
const configManager = require('./new-config-manager') const configManager = require('./new-config-manager')
const settingsLoader = require('./new-settings-loader') const settingsLoader = require('./new-settings-loader')

View file

@ -136,8 +136,8 @@ function transactionNotify (tx, rec) {
const isCashOut = tx.direction === 'cashOut' const isCashOut = tx.direction === 'cashOut'
// for notification center // for notification center
const directionDisplay = tx.direction === 'cashOut' ? 'cash-out' : 'cash-in' const directionDisplay = isCashOut ? 'cash-out' : 'cash-in'
const readyToNotify = tx.direction === 'cashIn' || (tx.direction === 'cashOut' && rec.isRedemption) const readyToNotify = !isCashOut || (tx.direction === 'cashOut' && rec.isRedemption)
// awaiting for redesign. notification should not be sent if toggle in the settings table is disabled, // awaiting for redesign. notification should not be sent if toggle in the settings table is disabled,
// but currently we're sending notifications of high value tx even with the toggle disabled // but currently we're sending notifications of high value tx even with the toggle disabled
if (readyToNotify && !highValueTx) { if (readyToNotify && !highValueTx) {
@ -204,21 +204,13 @@ function sendTransactionMessage (rec, isHighValueTx) {
}) })
} }
const notificationCenterFunctions = {
'customerComplianceNotify': notificationCenter.customerComplianceNotify,
'blacklistNotify': notificationCenter.blacklistNotify,
'balancesNotify': notificationCenter.balancesNotify,
'errorAlertsNotify': notificationCenter.errorAlertsNotify,
'notifCenterTransactionNotify': notificationCenter.notifCenterTransactionNotify
}
// for notification center, check if type of notification is active before calling the respective notify function // for notification center, check if type of notification is active before calling the respective notify function
const notifyIfActive = (type, fnName, ...args) => { const notifyIfActive = (type, fnName, ...args) => {
return settingsLoader.loadLatest().then(settings => { return settingsLoader.loadLatest().then(settings => {
const notificationSettings = configManager.getGlobalNotifications(settings.config).notificationCenter const notificationSettings = configManager.getGlobalNotifications(settings.config).notificationCenter
if (!notificationCenterFunctions[fnName]) return Promise.reject(new Error(`Notification function ${fnName} for type ${type} does not exist`)) if (!notificationCenter[fnName]) return Promise.reject(new Error(`Notification function ${fnName} for type ${type} does not exist`))
if (!(notificationSettings.active && notificationSettings[type])) return Promise.resolve() if (!(notificationSettings.active && notificationSettings[type])) return Promise.resolve()
return notificationCenterFunctions[fnName](...args) return notificationCenter[fnName](...args)
}) })
} }

View file

@ -3,6 +3,7 @@ const _ = require('lodash/fp')
const queries = require('./queries') const queries = require('./queries')
const utils = require('./utils') const utils = require('./utils')
const codes = require('./codes') const codes = require('./codes')
const customers = require('../customers')
const { NOTIFICATION_TYPES: { const { NOTIFICATION_TYPES: {
COMPLIANCE, COMPLIANCE,
@ -15,6 +16,17 @@ const { NOTIFICATION_TYPES: {
const { STALE, PING } = codes const { STALE, PING } = codes
const sanctionsNotify = (customer, phone) => {
const code = 'SANCTIONS'
const detailB = utils.buildDetail({ customerId: customer.id, code })
// if it's a new customer then phone comes as undefined
if (phone) {
return queries.addNotification(COMPLIANCE, `Blocked customer with phone ${phone} for being on the OFAC sanctions list`, detailB)
}
return customers.getById(customer.id).then(c => queries.addNotification(COMPLIANCE, `Blocked customer with phone ${c.phone} for being on the OFAC sanctions list`, detailB))
}
const clearOldCustomerSuspendedNotifications = (customerId, deviceId) => { const clearOldCustomerSuspendedNotifications = (customerId, deviceId) => {
const detailB = utils.buildDetail({ code: 'SUSPENDED', customerId, deviceId }) const detailB = utils.buildDetail({ code: 'SUSPENDED', customerId, deviceId })
return queries.invalidateNotification(detailB, 'compliance') return queries.invalidateNotification(detailB, 'compliance')
@ -167,4 +179,11 @@ const blacklistNotify = (tx, isAddressReuse) => {
return queries.addNotification(COMPLIANCE, message, detailB) return queries.addNotification(COMPLIANCE, message, detailB)
} }
module.exports = { customerComplianceNotify, balancesNotify, errorAlertsNotify, notifCenterTransactionNotify, blacklistNotify } module.exports = {
sanctionsNotify,
customerComplianceNotify,
balancesNotify,
errorAlertsNotify,
notifCenterTransactionNotify,
blacklistNotify
}

View file

@ -21,7 +21,7 @@ function getMachineName (machineId) {
} }
const addNotification = (type, message, detail) => { const addNotification = (type, message, detail) => {
const sql = `INSERT INTO notifications (id, type, message, detail) values ($1, $2, $3, $4)` const sql = `INSERT INTO notifications (id, type, message, detail) VALUES ($1, $2, $3, $4)`
return db.oneOrNone(sql, [uuidv4(), type, message, detail]) return db.oneOrNone(sql, [uuidv4(), type, message, detail])
} }

View file

@ -2,8 +2,6 @@ const BigNumber = require('../../../lib/bn')
const notifier = require('..') const notifier = require('..')
const utils = require('../utils') const utils = require('../utils')
const queries = require("../queries")
const emailFuncs = require('../email')
const smsFuncs = require('../sms') const smsFuncs = require('../sms')
afterEach(() => { afterEach(() => {
@ -152,7 +150,6 @@ test('Checkpings returns empty array as the value for the id prop, if the lastPi
}) })
}) })
test('Check notification resolves to undefined if shouldNotAlert is called and is true', async () => { test('Check notification resolves to undefined if shouldNotAlert is called and is true', async () => {
const mockShouldNotAlert = jest.spyOn(utils, 'shouldNotAlert') const mockShouldNotAlert = jest.spyOn(utils, 'shouldNotAlert')
mockShouldNotAlert.mockReturnValue(true) mockShouldNotAlert.mockReturnValue(true)
@ -280,7 +277,7 @@ test('checkStuckScreen returns empty array if age < STALE_STATE', () => {
expect(result2).toEqual([]) expect(result2).toEqual([])
}) })
test("calls sendRedemptionMessage if !zeroConf and rec.isRedemption", async () => { test('calls sendRedemptionMessage if !zeroConf and rec.isRedemption', async () => {
const configManager = require('../../new-config-manager') const configManager = require('../../new-config-manager')
const settingsLoader = require('../../new-settings-loader') const settingsLoader = require('../../new-settings-loader')
@ -291,15 +288,9 @@ test("calls sendRedemptionMessage if !zeroConf and rec.isRedemption", async () =
// sendRedemptionMessage will cause this func to be called // sendRedemptionMessage will cause this func to be called
jest.spyOn(smsFuncs, 'sendMessage').mockImplementation((_, rec) => rec) jest.spyOn(smsFuncs, 'sendMessage').mockImplementation((_, rec) => rec)
<<<<<<< HEAD
getCashOut.mockReturnValue({zeroConfLimit: -Infinity})
loadLatest.mockReturnValue({})
getGlobalNotifications.mockReturnValue({... notifSettings, sms: { active: true, errors: true, transactions: true }})
=======
getCashOut.mockReturnValue({ zeroConfLimit: -Infinity }) getCashOut.mockReturnValue({ zeroConfLimit: -Infinity })
loadLatest.mockReturnValue(Promise.resolve({})) loadLatest.mockReturnValue(Promise.resolve({}))
getGlobalNotifications.mockReturnValue({ ...notifSettings, sms: { active: true, errors: true, transactions: true }, notificationCenter: { active: true } }) getGlobalNotifications.mockReturnValue({ ...notifSettings, sms: { active: true, errors: true, transactions: true }, notificationCenter: { active: true } })
>>>>>>> a7a9fd3... Feat: move notif center fns to own file on the notifier module
const response = await notifier.transactionNotify(tx, { isRedemption: true }) const response = await notifier.transactionNotify(tx, { isRedemption: true })
@ -315,7 +306,7 @@ test("calls sendRedemptionMessage if !zeroConf and rec.isRedemption", async () =
}) })
}) })
test("calls sendTransactionMessage if !zeroConf and !rec.isRedemption", async () => { test('calls sendTransactionMessage if !zeroConf and !rec.isRedemption', async () => {
const configManager = require('../../new-config-manager') const configManager = require('../../new-config-manager')
const settingsLoader = require('../../new-settings-loader') const settingsLoader = require('../../new-settings-loader')
const machineLoader = require('../../machine-loader') const machineLoader = require('../../machine-loader')
@ -328,7 +319,7 @@ test("calls sendTransactionMessage if !zeroConf and !rec.isRedemption", async ()
// sendMessage on emailFuncs isn't called because it is disabled in getGlobalNotifications.mockReturnValue // sendMessage on emailFuncs isn't called because it is disabled in getGlobalNotifications.mockReturnValue
jest.spyOn(smsFuncs, 'sendMessage').mockImplementation((_, rec) => ({ prop: rec })) jest.spyOn(smsFuncs, 'sendMessage').mockImplementation((_, rec) => ({ prop: rec }))
buildTransactionMessage.mockImplementation(() => ["mock message", false]) buildTransactionMessage.mockImplementation(() => ['mock message', false])
getMachineName.mockReturnValue('mockMachineName') getMachineName.mockReturnValue('mockMachineName')
getCashOut.mockReturnValue({ zeroConfLimit: -Infinity }) getCashOut.mockReturnValue({ zeroConfLimit: -Infinity })

View file

@ -429,6 +429,11 @@ 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 || {}
const customer = _.getOr({ sanctions: true }, ['customer'], body)
// sanctions can be null for new customers so we can't use falsy checks
if (customer.sanctions === false) {
notifier.notifyIfActive('compliance', 'sanctionsNotify', customer, req.body.phone).catch(console.error)
}
return res.status(status).json(body) return res.status(status).json(body)
} }