Merge branch 'release-10.0' into feat/lam-1111/customer-last-used-machine
* release-10.0: chore: use map instead of foreach chore: v10.0.1 (#1696) Add InforU SMS plugin (#1695) fix: add machine name and timestamp to pending notifs messages refactor: drop unused debug logs refactor: replace `fs`+`util.promisify` with `fs/promises` refactor: drop unnecessary use of `_.curry` refactor: destruct in parameters list refactor: drop unnecessary curly braces chore: drop unused import refactor: destruct in parameters list to build object refactor: destruct in parameters list instead refactor: use `set` from `lodash/fp` instead of syntax feat: notifications and flow fixes fix: generic external auth on ui fix: admin ui refactor: yagni and flow of external compliance fix: change sumsub usage away from self-hosted solutions feat: implement sumsub API module chore: remove unused files
This commit is contained in:
commit
4b4af106a8
338 changed files with 1005 additions and 81792 deletions
106
lib/customers.js
106
lib/customers.js
|
|
@ -17,6 +17,9 @@ const NUM_RESULTS = 1000
|
|||
const sms = require('./sms')
|
||||
const settingsLoader = require('./new-settings-loader')
|
||||
const logger = require('./logger')
|
||||
const externalCompliance = require('./compliance-external')
|
||||
|
||||
const { APPROVED, RETRY } = require('./plugins/compliance/consts')
|
||||
|
||||
const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel', 'scoreThresholdReached', 'walletScoringError']
|
||||
|
||||
|
|
@ -243,7 +246,7 @@ function deleteEditedData (id, data) {
|
|||
'id_card_data',
|
||||
'id_card_photo',
|
||||
'us_ssn',
|
||||
'subcriber_info',
|
||||
'subscriber_info',
|
||||
'name'
|
||||
]
|
||||
const filteredData = _.pick(defaults, _.mapKeys(_.snakeCase, data))
|
||||
|
|
@ -322,6 +325,7 @@ function getById (id) {
|
|||
return db.oneOrNone(sql, [id])
|
||||
.then(assignCustomerData)
|
||||
.then(getCustomInfoRequestsData)
|
||||
.then(getExternalComplianceMachine)
|
||||
.then(camelize)
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +346,11 @@ function camelize (customer) {
|
|||
function camelizeDeep (customer) {
|
||||
return _.flow(
|
||||
camelize,
|
||||
it => ({ ...it, notes: (it.notes ?? []).map(camelize) })
|
||||
it => ({
|
||||
...it,
|
||||
notes: (it.notes ?? []).map(camelize),
|
||||
externalCompliance: (it.externalCompliance ?? []).map(camelize)
|
||||
})
|
||||
)(customer)
|
||||
}
|
||||
|
||||
|
|
@ -587,6 +595,7 @@ function getCustomerById (id) {
|
|||
return db.oneOrNone(sql, [passableErrorCodes, id])
|
||||
.then(assignCustomerData)
|
||||
.then(getCustomInfoRequestsData)
|
||||
.then(getExternalCompliance)
|
||||
.then(camelizeDeep)
|
||||
.then(formatSubscriberInfo)
|
||||
}
|
||||
|
|
@ -926,6 +935,95 @@ function updateLastAuthAttempt (customerId) {
|
|||
return db.none(sql, [customerId])
|
||||
}
|
||||
|
||||
function getExternalComplianceMachine (customer) {
|
||||
return settingsLoader.loadLatest()
|
||||
.then(settings => externalCompliance.getStatusMap(settings, customer.id))
|
||||
.then(statusMap => {
|
||||
return updateExternalComplianceByMap(customer.id, statusMap)
|
||||
.then(() => customer.externalCompliance = statusMap)
|
||||
.then(() => customer)
|
||||
})
|
||||
}
|
||||
|
||||
function updateExternalCompliance(customerId, service, status) {
|
||||
const sql = `
|
||||
UPDATE customer_external_compliance SET last_known_status = $1, last_updated = now()
|
||||
WHERE customer_id=$2 AND service=$3
|
||||
`
|
||||
return db.none(sql, [status, customerId, service])
|
||||
}
|
||||
|
||||
function updateExternalComplianceByMap(customerId, serviceMap) {
|
||||
const sql = `
|
||||
UPDATE customer_external_compliance SET last_known_status = $1, last_updated = now()
|
||||
WHERE customer_id=$2 AND service=$3
|
||||
`
|
||||
const pairs = _.toPairs(serviceMap)
|
||||
const promises = _.map(([service, status]) => db.none(sql, [status.answer, customerId, service]))(pairs)
|
||||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
function getExternalCompliance(customer) {
|
||||
const sql = `SELECT external_id, service, last_known_status, last_updated
|
||||
FROM customer_external_compliance where customer_id=$1`
|
||||
return db.manyOrNone(sql, [customer.id])
|
||||
.then(compliance => {
|
||||
customer.externalCompliance = compliance
|
||||
})
|
||||
.then(() => customer)
|
||||
}
|
||||
|
||||
function getOpenExternalCompliance() {
|
||||
const sql = `SELECT customer_id, service, last_known_status FROM customer_external_compliance where last_known_status in ('PENDING', 'RETRY') or last_known_status is null`
|
||||
return db.manyOrNone(sql)
|
||||
}
|
||||
|
||||
function notifyRetryExternalCompliance(settings, customerId, service) {
|
||||
const sql = 'SELECT phone FROM customers WHERE id=$1'
|
||||
const promises = [db.one(sql, [customerId]), externalCompliance.createLink(settings, service, customerId)]
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(([toNumber, link]) => {
|
||||
const body = `Your external compliance verification has failed. Please try again. Link for retry: ${link}`
|
||||
|
||||
return sms.sendMessage(settings, { toNumber, body })
|
||||
})
|
||||
}
|
||||
|
||||
function notifyApprovedExternalCompliance(settings, customerId) {
|
||||
const sql = 'SELECT phone FROM customers WHERE id=$1'
|
||||
return db.one(sql, [customerId])
|
||||
.then((toNumber) => {
|
||||
const body = 'Your external compliance verification has been approved.'
|
||||
|
||||
return sms.sendMessage(settings, { toNumber, body })
|
||||
})
|
||||
}
|
||||
|
||||
function checkExternalCompliance(settings) {
|
||||
return getOpenExternalCompliance()
|
||||
.then(externals => {
|
||||
console.log(externals)
|
||||
const promises = _.map(external => {
|
||||
return externalCompliance.getStatus(settings, external.service, external.customer_id)
|
||||
.then(status => {
|
||||
console.log('status', status, external.customer_id, external.service)
|
||||
if (status.status.answer === RETRY) notifyRetryExternalCompliance(settings, external.customer_id, status.service)
|
||||
if (status.status.answer === APPROVED) notifyApprovedExternalCompliance(settings, external.customer_id)
|
||||
|
||||
return updateExternalCompliance(external.customer_id, external.service, status.status.answer)
|
||||
})
|
||||
}, externals)
|
||||
return Promise.all(promises)
|
||||
})
|
||||
}
|
||||
|
||||
function addExternalCompliance(customerId, service, id) {
|
||||
const sql = `INSERT INTO customer_external_compliance (customer_id, external_id, service) VALUES ($1, $2, $3)`
|
||||
return db.none(sql, [customerId, id, service])
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
add,
|
||||
addWithEmail,
|
||||
|
|
@ -949,5 +1047,7 @@ module.exports = {
|
|||
updateTxCustomerPhoto,
|
||||
enableTestCustomer,
|
||||
disableTestCustomer,
|
||||
updateLastAuthAttempt
|
||||
updateLastAuthAttempt,
|
||||
addExternalCompliance,
|
||||
checkExternalCompliance
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue