diff --git a/dev/ofac-match.js b/dev/ofac-match.js index ecc13dc5..931b0c84 100644 --- a/dev/ofac-match.js +++ b/dev/ofac-match.js @@ -1,9 +1,10 @@ const compliance = require('../lib/compliance') const ofac = require('../lib/ofac/index') -const [firstName, lastName, dateOfBirth] = process.argv.slice(2) +const [customerId, firstName, lastName, dateOfBirth] = process.argv.slice(2) const customer = { + id: customerId, idCardData: {firstName, lastName, dateOfBirth} } @@ -11,7 +12,9 @@ const config = { sanctionsVerificationActive: true } +const deviceId = 'test-device' + ofac.load() - .then(() => compliance.validateCustomer(config, customer)) - .then(() => console.log('SUCCESS!')) + .then(() => compliance.validationPatch(deviceId, config, customer)) + .then(console.log) .catch(err => console.log(err)) diff --git a/lib/compliance.js b/lib/compliance.js index c6f74251..dd416e0c 100644 --- a/lib/compliance.js +++ b/lib/compliance.js @@ -1,54 +1,75 @@ const _ = require('lodash/fp') +const uuid = require('uuid') const logger = require('./logger') +const db = require('./db') const ofac = require('./ofac/index') -function matchOfac (customer) { - // Probably because we haven't asked for ID yet - if (!_.isPlainObject(customer.idCardData)) { - return true - } +function logSanctionsMatch (deviceId, customer, sanctionsId, alias) { + const sql = `insert into sanctions_logs + (id, device_id, sanctioned_id, sanctioned_alias_id, sanctioned_alias_full_name, customer_id) + values + ($1, $2, $3, $4, $5, $6)` - const nameParts = { - firstName: customer.idCardData.firstName, - lastName: customer.idCardData.lastName - } - - if (_.some(_.isNil, _.values(nameParts))) { - logger.error(new Error(`Insufficient idCardData while matching OFAC for: ${customer.id}`)) - return true - } - - const birthDate = customer.idCardData.dateOfBirth - - if (_.isNil(birthDate)) { - logger.error(new Error(`No birth date while matching OFAC for: ${customer.id}`)) - return true - } - - const options = { - threshold: 0.85, - fullNameThreshold: 0.95, - debug: false - } - - const results = ofac.match(nameParts, birthDate, options) - - return !_.isEmpty(results) + return db.none(sql, [uuid.v4(), deviceId, sanctionsId, alias.id, alias.fullName, customer.id]) } -function validateOfac (customer) { +function logSanctionsMatches (deviceId, customer, results) { + const logAlias = resultId => alias => logSanctionsMatch(deviceId, customer, resultId, alias) + const logResult = result => _.map(logAlias(result.id), result.aliases) + + return Promise.all(_.flatMap(logResult, results)) +} + +function matchOfac (deviceId, customer) { + return Promise.resolve() + .then(() => { + // Probably because we haven't asked for ID yet + if (!_.isPlainObject(customer.idCardData)) { + return true + } + + const nameParts = { + firstName: customer.idCardData.firstName, + lastName: customer.idCardData.lastName + } + + if (_.some(_.isNil, _.values(nameParts))) { + logger.error(new Error(`Insufficient idCardData while matching OFAC for: ${customer.id}`)) + return true + } + + const birthDate = customer.idCardData.dateOfBirth + + if (_.isNil(birthDate)) { + logger.error(new Error(`No birth date while matching OFAC for: ${customer.id}`)) + return true + } + + const options = { + threshold: 0.85, + fullNameThreshold: 0.95, + debug: false + } + + const results = ofac.match(nameParts, birthDate, options) + + return logSanctionsMatches(deviceId, customer, results) + .then(() => !_.isEmpty(results)) + }) +} + +function validateOfac (deviceId, customer) { if (customer.sanctionsOverride === 'blocked') return false if (customer.sanctionsOverride === 'verified') return true - return !matchOfac(customer) + return matchOfac(deviceId, customer) + .then(didMatch => !didMatch) } -function validationPatch (config, customer) { - return Promise.resolve() - .then(() => { - const ofacValidation = validateOfac(customer) - +function validationPatch (deviceId, config, customer) { + return validateOfac(deviceId, customer) + .then(ofacValidation => { if (_.isNil(customer.sanctions) || customer.sanctions !== ofacValidation) { return {sanctions: ofacValidation} } diff --git a/migrations/1525671972351-add_sanctions_logs.js b/migrations/1525671972351-add_sanctions_logs.js new file mode 100644 index 00000000..591ea108 --- /dev/null +++ b/migrations/1525671972351-add_sanctions_logs.js @@ -0,0 +1,20 @@ +var db = require('./db') + +exports.up = function (next) { + const sql = + [`create table sanctions_logs ( + id uuid PRIMARY KEY, + device_id text not null, + sanctioned_id text not null, + sanctioned_alias_id text, + sanctioned_alias_full_name text not null, + customer_id uuid not null references customers, + created timestamptz not null default now() )` + ] + + db.multi(sql, next) +} + +exports.down = function (next) { + next() +}