Merge branch 'dev' into fix/lam-235/lamassu-coins-install
This commit is contained in:
commit
0e9f3e5863
66 changed files with 1544 additions and 638 deletions
|
|
@ -73,8 +73,9 @@ function unmergeCassettes(cassettes, output) {
|
|||
}
|
||||
|
||||
function makeChangeDuo(cassettes, amount) {
|
||||
const small = cassettes[0]
|
||||
const large = cassettes[1]
|
||||
// Initialize empty cassettes in case of undefined, due to same denomination across all cassettes results in a single merged cassette
|
||||
const small = cassettes[0] ?? { denomination: 0, count: 0 }
|
||||
const large = cassettes[1] ?? { denomination: 0, count: 0 }
|
||||
|
||||
const largeDenom = large.denomination
|
||||
const smallDenom = small.denomination
|
||||
|
|
|
|||
|
|
@ -23,18 +23,18 @@ module.exports = {
|
|||
|
||||
const BINARIES = {
|
||||
BTC: {
|
||||
defaultUrl: 'https://bitcoincore.org/bin/bitcoin-core-0.20.0/bitcoin-0.20.0-x86_64-linux-gnu.tar.gz',
|
||||
defaultDir: 'bitcoin-0.20.0/bin',
|
||||
defaultUrl: 'https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz',
|
||||
defaultDir: 'bitcoin-0.20.1/bin',
|
||||
url: 'https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'bitcoin-22.0/bin'
|
||||
},
|
||||
ETH: {
|
||||
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.10.13-7a0c19f8.tar.gz',
|
||||
dir: 'geth-linux-amd64-1.10.13-7a0c19f8'
|
||||
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.10.15-8be800ff.tar.gz',
|
||||
dir: 'geth-linux-amd64-1.10.15-8be800ff'
|
||||
},
|
||||
ZEC: {
|
||||
url: 'https://z.cash/downloads/zcash-4.5.1-1-linux64-debian-stretch.tar.gz',
|
||||
dir: 'zcash-4.5.1-1/bin'
|
||||
url: 'https://z.cash/downloads/zcash-4.6.0-1-linux64-debian-stretch.tar.gz',
|
||||
dir: 'zcash-4.6.0-1/bin'
|
||||
},
|
||||
DASH: {
|
||||
url: 'https://github.com/dashpay/dash/releases/download/v0.17.0.3/dashcore-0.17.0.3-x86_64-linux-gnu.tar.gz',
|
||||
|
|
@ -50,8 +50,8 @@ const BINARIES = {
|
|||
files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']]
|
||||
},
|
||||
XMR: {
|
||||
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.2.0.tar.bz2',
|
||||
dir: 'monero-x86_64-linux-gnu-v0.17.2.0',
|
||||
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.3.0.tar.bz2',
|
||||
dir: 'monero-x86_64-linux-gnu-v0.17.3.0',
|
||||
files: [['monerod', 'monerod'], ['monero-wallet-rpc', 'monero-wallet-rpc']]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,8 +117,9 @@ function run () {
|
|||
_.filter(c => c.type !== 'erc-20'),
|
||||
_.map(c => {
|
||||
const checked = isInstalledSoftware(c) && isInstalledVolume(c)
|
||||
const name = c.code === 'ethereum' ? 'Ethereum and/or USDT' : c.display
|
||||
return {
|
||||
name: c.display,
|
||||
name,
|
||||
value: c.code,
|
||||
checked,
|
||||
disabled: checked && 'Installed'
|
||||
|
|
|
|||
|
|
@ -631,8 +631,8 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
|
|||
const sql = `SELECT id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_override,
|
||||
phone, sms_override, id_card_data, id_card_data_override, id_card_data_expiration,
|
||||
id_card_photo_path, id_card_photo_override, us_ssn, us_ssn_override, sanctions, sanctions_at,
|
||||
sanctions_override, total_txs, total_spent, created AS last_active, fiat AS last_tx_fiat,
|
||||
fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, custom_fields, notes
|
||||
sanctions_override, total_txs, total_spent, LEAST(created, last_transaction) AS last_active, fiat AS last_tx_fiat,
|
||||
fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, custom_fields, notes, is_test_customer
|
||||
FROM (
|
||||
SELECT c.id, c.authorized_override,
|
||||
greatest(0, date_part('day', c.suspended_until - NOW())) AS days_suspended,
|
||||
|
|
@ -640,13 +640,13 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
|
|||
c.front_camera_path, c.front_camera_override,
|
||||
c.phone, c.sms_override, c.id_card_data, c.id_card_data_override, c.id_card_data_expiration,
|
||||
c.id_card_photo_path, c.id_card_photo_override, c.us_ssn, c.us_ssn_override, c.sanctions,
|
||||
c.sanctions_at, c.sanctions_override, t.tx_class, t.fiat, t.fiat_code, t.created, cn.notes,
|
||||
c.sanctions_at, c.sanctions_override, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
|
||||
row_number() OVER (partition by c.id order by t.created desc) AS rn,
|
||||
sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (partition by c.id) AS total_txs,
|
||||
coalesce(sum(CASE WHEN error_code IS NULL OR error_code NOT IN ($1^) THEN t.fiat ELSE 0 END) OVER (partition by c.id), 0) AS total_spent, ccf.custom_fields
|
||||
FROM customers c LEFT OUTER JOIN (
|
||||
SELECT 'cashIn' AS tx_class, id, fiat, fiat_code, created, customer_id, error_code
|
||||
FROM cash_in_txs WHERE send_confirmed = true UNION
|
||||
FROM cash_in_txs WHERE send_confirmed = true OR batched = true UNION
|
||||
SELECT 'cashOut' AS tx_class, id, fiat, fiat_code, created, customer_id, error_code
|
||||
FROM cash_out_txs WHERE confirmed_at IS NOT NULL) AS t ON c.id = t.customer_id
|
||||
LEFT OUTER JOIN (
|
||||
|
|
@ -686,8 +686,8 @@ function getCustomerById (id) {
|
|||
const sql = `SELECT id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_at, front_camera_override,
|
||||
phone, sms_override, id_card_data_at, id_card_data, id_card_data_override, id_card_data_expiration,
|
||||
id_card_photo_path, id_card_photo_at, id_card_photo_override, us_ssn_at, us_ssn, us_ssn_override, sanctions, sanctions_at,
|
||||
sanctions_override, total_txs, total_spent, created AS last_active, fiat AS last_tx_fiat,
|
||||
fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, subscriber_info, custom_fields, notes
|
||||
sanctions_override, total_txs, total_spent, LEAST(created, last_transaction) AS last_active, fiat AS last_tx_fiat,
|
||||
fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, subscriber_info, custom_fields, notes, is_test_customer
|
||||
FROM (
|
||||
SELECT c.id, c.authorized_override,
|
||||
greatest(0, date_part('day', c.suspended_until - now())) AS days_suspended,
|
||||
|
|
@ -695,13 +695,13 @@ function getCustomerById (id) {
|
|||
c.front_camera_path, c.front_camera_override, c.front_camera_at,
|
||||
c.phone, c.sms_override, c.id_card_data, c.id_card_data_at, c.id_card_data_override, c.id_card_data_expiration,
|
||||
c.id_card_photo_path, c.id_card_photo_at, c.id_card_photo_override, c.us_ssn, c.us_ssn_at, c.us_ssn_override, c.sanctions,
|
||||
c.sanctions_at, c.sanctions_override, c.subscriber_info, t.tx_class, t.fiat, t.fiat_code, t.created, cn.notes,
|
||||
c.sanctions_at, c.sanctions_override, c.subscriber_info, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
|
||||
row_number() OVER (PARTITION BY c.id ORDER BY t.created DESC) AS rn,
|
||||
sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (PARTITION BY c.id) AS total_txs,
|
||||
sum(CASE WHEN error_code IS NULL OR error_code NOT IN ($1^) THEN t.fiat ELSE 0 END) OVER (PARTITION BY c.id) AS total_spent, ccf.custom_fields
|
||||
FROM customers c LEFT OUTER JOIN (
|
||||
SELECT 'cashIn' AS tx_class, id, fiat, fiat_code, created, customer_id, error_code
|
||||
FROM cash_in_txs WHERE send_confirmed = true UNION
|
||||
FROM cash_in_txs WHERE send_confirmed = true OR batched = true UNION
|
||||
SELECT 'cashOut' AS tx_class, id, fiat, fiat_code, created, customer_id, error_code
|
||||
FROM cash_out_txs WHERE confirmed_at IS NOT NULL) t ON c.id = t.customer_id
|
||||
LEFT OUTER JOIN (
|
||||
|
|
@ -993,6 +993,7 @@ function addCustomField (customerId, label, value) {
|
|||
}
|
||||
})
|
||||
)
|
||||
.then(res => !_.isNil(res))
|
||||
}
|
||||
|
||||
function saveCustomField (customerId, fieldId, newValue) {
|
||||
|
|
@ -1022,6 +1023,16 @@ function getCustomInfoRequestsData (customer) {
|
|||
return db.any(sql, [customer.id]).then(res => _.set('custom_info_request_data', res, customer))
|
||||
}
|
||||
|
||||
function enableTestCustomer (customerId) {
|
||||
const sql = `UPDATE customers SET is_test_customer=true WHERE id=$1`
|
||||
return db.none(sql, [customerId])
|
||||
}
|
||||
|
||||
function disableTestCustomer (customerId) {
|
||||
const sql = `UPDATE customers SET is_test_customer=false WHERE id=$1`
|
||||
return db.none(sql, [customerId])
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
add,
|
||||
get,
|
||||
|
|
@ -1040,5 +1051,7 @@ module.exports = {
|
|||
edit,
|
||||
deleteEditedData,
|
||||
updateEditedPhoto,
|
||||
updateTxCustomerPhoto
|
||||
updateTxCustomerPhoto,
|
||||
enableTestCustomer,
|
||||
disableTestCustomer
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,30 +12,35 @@ const configManager = require('./new-config-manager')
|
|||
const settingsLoader = require('./new-settings-loader')
|
||||
const notifierUtils = require('./notifier/utils')
|
||||
const notifierQueries = require('./notifier/queries')
|
||||
const { ApolloError } = require('apollo-server-errors');
|
||||
|
||||
const fullyFunctionalStatus = { label: 'Fully functional', type: 'success' }
|
||||
const unresponsiveStatus = { label: 'Unresponsive', type: 'error' }
|
||||
const stuckStatus = { label: 'Stuck', type: 'error' }
|
||||
|
||||
function toMachineObject (r) {
|
||||
return {
|
||||
deviceId: r.device_id,
|
||||
cashbox: r.cashbox,
|
||||
cassette1: r.cassette1,
|
||||
cassette2: r.cassette2,
|
||||
cassette3: r.cassette3,
|
||||
cassette4: r.cassette4,
|
||||
numberOfCassettes: r.number_of_cassettes,
|
||||
version: r.version,
|
||||
model: r.model,
|
||||
pairedAt: new Date(r.created),
|
||||
lastPing: new Date(r.last_online),
|
||||
name: r.name,
|
||||
paired: r.paired
|
||||
// TODO: we shall start using this JSON field at some point
|
||||
// location: r.location,
|
||||
}
|
||||
}
|
||||
|
||||
function getMachines () {
|
||||
return db.any('SELECT * FROM devices WHERE display=TRUE ORDER BY created')
|
||||
.then(rr => rr.map(r => ({
|
||||
deviceId: r.device_id,
|
||||
cashbox: r.cashbox,
|
||||
cassette1: r.cassette1,
|
||||
cassette2: r.cassette2,
|
||||
cassette3: r.cassette3,
|
||||
cassette4: r.cassette4,
|
||||
numberOfCassettes: r.number_of_cassettes,
|
||||
version: r.version,
|
||||
model: r.model,
|
||||
pairedAt: new Date(r.created),
|
||||
lastPing: new Date(r.last_online),
|
||||
name: r.name,
|
||||
// TODO: we shall start using this JSON field at some point
|
||||
// location: r.location,
|
||||
paired: r.paired
|
||||
})))
|
||||
.then(rr => rr.map(toMachineObject))
|
||||
}
|
||||
|
||||
function getConfig (defaultConfig) {
|
||||
|
|
@ -100,21 +105,10 @@ function getMachineName (machineId) {
|
|||
|
||||
function getMachine (machineId, config) {
|
||||
const sql = 'SELECT * FROM devices WHERE device_id=$1'
|
||||
const queryMachine = db.oneOrNone(sql, [machineId]).then(r => ({
|
||||
deviceId: r.device_id,
|
||||
cashbox: r.cashbox,
|
||||
cassette1: r.cassette1,
|
||||
cassette2: r.cassette2,
|
||||
cassette3: r.cassette3,
|
||||
cassette4: r.cassette4,
|
||||
numberOfCassettes: r.number_of_cassettes,
|
||||
version: r.version,
|
||||
model: r.model,
|
||||
pairedAt: new Date(r.created),
|
||||
lastPing: new Date(r.last_online),
|
||||
name: r.name,
|
||||
paired: r.paired
|
||||
}))
|
||||
const queryMachine = db.oneOrNone(sql, [machineId]).then(r => {
|
||||
if (r === null) throw new ApolloError('Resource doesn\'t exist', 'NOT_FOUND')
|
||||
else return toMachineObject(r)
|
||||
})
|
||||
|
||||
return Promise.all([queryMachine, dbm.machineEvents(), config])
|
||||
.then(([machine, events, config]) => {
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ const reset2FA = (token, userID, code, context) => {
|
|||
}
|
||||
|
||||
const getToken = context => {
|
||||
if (_.isNil(context.req.cookies.lid) || _.isNil(context.req.session.user.id))
|
||||
if (_.isNil(context.req.cookies['lamassu_sid']) || _.isNil(context.req.session.user.id))
|
||||
throw new authErrors.AuthenticationError('Authentication failed')
|
||||
|
||||
return context.req.session.user.id
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
const authentication = require('../modules/userManagement')
|
||||
const queries = require('../../services/customInfoRequests')
|
||||
const DataLoader = require('dataloader')
|
||||
|
||||
|
|
@ -21,7 +22,10 @@ const resolvers = {
|
|||
insertCustomInfoRequest: (...[, { customRequest }]) => queries.addCustomInfoRequest(customRequest),
|
||||
removeCustomInfoRequest: (...[, { id }]) => queries.removeCustomInfoRequest(id),
|
||||
editCustomInfoRequest: (...[, { id, customRequest }]) => queries.editCustomInfoRequest(id, customRequest),
|
||||
setAuthorizedCustomRequest: (...[, { customerId, infoRequestId, isAuthorized }]) => queries.setAuthorizedCustomRequest(customerId, infoRequestId, isAuthorized),
|
||||
setAuthorizedCustomRequest: (...[, { customerId, infoRequestId, override }, context]) => {
|
||||
const token = authentication.getToken(context)
|
||||
return queries.setAuthorizedCustomRequest(customerId, infoRequestId, override, token)
|
||||
},
|
||||
setCustomerCustomInfoRequest: (...[, { customerId, infoRequestId, data }]) => queries.setCustomerData(customerId, infoRequestId, data)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const resolvers = {
|
|||
return customers.updateCustomer(customerId, customerInput, token)
|
||||
},
|
||||
addCustomField: (...[, { customerId, label, value }]) => customers.addCustomField(customerId, label, value),
|
||||
saveCustomField: (...[, { customerId, fieldId, newValue }]) => customers.saveCustomField(customerId, fieldId, newValue),
|
||||
saveCustomField: (...[, { customerId, fieldId, value }]) => customers.saveCustomField(customerId, fieldId, value),
|
||||
removeCustomField: (...[, [ { customerId, fieldId } ]]) => customers.removeCustomField(customerId, fieldId),
|
||||
editCustomer: async (root, { customerId, customerEdit }, context) => {
|
||||
const token = authentication.getToken(context)
|
||||
|
|
@ -49,7 +49,12 @@ const resolvers = {
|
|||
},
|
||||
deleteCustomerNote: (...[, { noteId }]) => {
|
||||
return customerNotes.deleteCustomerNote(noteId)
|
||||
}
|
||||
},
|
||||
createCustomer: (...[, { phoneNumber }]) => customers.add({ phone: phoneNumber }),
|
||||
enableTestCustomer: (...[, { customerId }]) =>
|
||||
customers.enableTestCustomer(customerId),
|
||||
disableTestCustomer: (...[, { customerId }]) =>
|
||||
customers.disableTestCustomer(customerId)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ const resolvers = {
|
|||
isAnonymous: parent => (parent.customerId === anonymous.uuid)
|
||||
},
|
||||
Query: {
|
||||
transactions: (...[, { from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status }]) =>
|
||||
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status),
|
||||
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, timezone, simplified }]) =>
|
||||
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, simplified)
|
||||
transactions: (...[, { from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers }]) =>
|
||||
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers),
|
||||
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, timezone, excludeTestingCustomers, simplified }]) =>
|
||||
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers, simplified)
|
||||
.then(data => parseAsync(logDateFormat(timezone, data, ['created', 'sendTime']), { fields: txLogFields })),
|
||||
transactionCsv: (...[, { id, txClass, timezone }]) =>
|
||||
transactions.getTx(id, txClass).then(data =>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ const typeDef = gql`
|
|||
type CustomRequestData {
|
||||
customerId: ID
|
||||
infoRequestId: ID
|
||||
approved: Boolean
|
||||
override: String
|
||||
overrideAt: Date
|
||||
overrideBy: ID
|
||||
customerData: JSON
|
||||
customInfoRequest: CustomInfoRequest
|
||||
}
|
||||
|
|
@ -47,7 +49,7 @@ const typeDef = gql`
|
|||
insertCustomInfoRequest(customRequest: CustomRequestInput!): CustomInfoRequest @auth
|
||||
removeCustomInfoRequest(id: ID!): CustomInfoRequest @auth
|
||||
editCustomInfoRequest(id: ID!, customRequest: CustomRequestInput!): CustomInfoRequest @auth
|
||||
setAuthorizedCustomRequest(customerId: ID!, infoRequestId: ID!, isAuthorized: Boolean!): Boolean @auth
|
||||
setAuthorizedCustomRequest(customerId: ID!, infoRequestId: ID!, override: String!): Boolean @auth
|
||||
setCustomerCustomInfoRequest(customerId: ID!, infoRequestId: ID!, data: JSON!): Boolean @auth
|
||||
}
|
||||
`
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
const { gql } = require('apollo-server-express')
|
||||
|
||||
const typeDef = gql`
|
||||
type CustomerCustomField {
|
||||
id: ID
|
||||
label: String
|
||||
value: String
|
||||
}
|
||||
|
||||
type Customer {
|
||||
id: ID!
|
||||
authorizedOverride: String
|
||||
|
|
@ -42,6 +36,7 @@ const typeDef = gql`
|
|||
customFields: [CustomerCustomField]
|
||||
customInfoRequests: [CustomRequestData]
|
||||
notes: [CustomerNote]
|
||||
isTestCustomer: Boolean
|
||||
}
|
||||
|
||||
input CustomerInput {
|
||||
|
|
@ -86,6 +81,12 @@ const typeDef = gql`
|
|||
content: String
|
||||
}
|
||||
|
||||
type CustomerCustomField {
|
||||
id: ID
|
||||
label: String
|
||||
value: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
customers(phone: String, name: String, address: String, id: String): [Customer] @auth
|
||||
customer(customerId: ID!): Customer @auth
|
||||
|
|
@ -94,15 +95,18 @@ const typeDef = gql`
|
|||
|
||||
type Mutation {
|
||||
setCustomer(customerId: ID!, customerInput: CustomerInput): Customer @auth
|
||||
addCustomField(customerId: ID!, label: String!, value: String!): CustomerCustomField @auth
|
||||
saveCustomField(customerId: ID!, fieldId: ID!, value: String!): CustomerCustomField @auth
|
||||
removeCustomField(customerId: ID!, fieldId: ID!): CustomerCustomField @auth
|
||||
addCustomField(customerId: ID!, label: String!, value: String!): Boolean @auth
|
||||
saveCustomField(customerId: ID!, fieldId: ID!, value: String!): Boolean @auth
|
||||
removeCustomField(customerId: ID!, fieldId: ID!): Boolean @auth
|
||||
editCustomer(customerId: ID!, customerEdit: CustomerEdit): Customer @auth
|
||||
deleteEditedData(customerId: ID!, customerEdit: CustomerEdit): Customer @auth
|
||||
replacePhoto(customerId: ID!, photoType: String, newPhoto: UploadGQL): Customer @auth
|
||||
createCustomerNote(customerId: ID!, title: String!, content: String!): Boolean @auth
|
||||
editCustomerNote(noteId: ID!, newContent: String!): Boolean @auth
|
||||
deleteCustomerNote(noteId: ID!): Boolean @auth
|
||||
createCustomer(phoneNumber: String): Customer @auth
|
||||
enableTestCustomer(customerId: ID!): Boolean @auth
|
||||
disableTestCustomer(customerId: ID!): Boolean @auth
|
||||
}
|
||||
`
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ const typeDef = gql`
|
|||
}
|
||||
|
||||
type Query {
|
||||
transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String): [Transaction] @auth
|
||||
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, timezone: String, simplified: Boolean): String @auth
|
||||
transactions(from: Date, until: Date, limit: Int, offset: Int, deviceId: ID, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, excludeTestingCustomers: Boolean): [Transaction] @auth
|
||||
transactionsCsv(from: Date, until: Date, limit: Int, offset: Int, txClass: String, machineName: String, customerName: String, fiatCode: String, cryptoCode: String, toAddress: String, status: String, timezone: String, excludeTestingCustomers: Boolean, simplified: Boolean): String @auth
|
||||
transactionCsv(id: ID, txClass: String, timezone: String): String @auth
|
||||
txAssociatedDataCsv(id: ID, txClass: String, timezone: String): String @auth
|
||||
transactionFilters: [Filter] @auth
|
||||
|
|
|
|||
|
|
@ -35,8 +35,10 @@ const getAllCustomInfoRequestsForCustomer = (customerId) => {
|
|||
return db.any(sql, [customerId]).then(res => res.map(item => ({
|
||||
customerId: item.customer_id,
|
||||
infoRequestId: item.info_request_id,
|
||||
approved: item.approved,
|
||||
customerData: item.customer_data
|
||||
customerData: item.customer_data,
|
||||
override: item.override,
|
||||
overrideAt: item.override_at,
|
||||
overrideBy: item.override_by
|
||||
})))
|
||||
}
|
||||
|
||||
|
|
@ -46,8 +48,10 @@ const getCustomInfoRequestForCustomer = (customerId, infoRequestId) => {
|
|||
return {
|
||||
customerId: item.customer_id,
|
||||
infoRequestId: item.info_request_id,
|
||||
approved: item.approved,
|
||||
customerData: item.customer_data
|
||||
customerData: item.customer_data,
|
||||
override: item.override,
|
||||
overrideAt: item.override_at,
|
||||
overrideBy: item.override_by
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -61,8 +65,10 @@ const batchGetAllCustomInfoRequestsForCustomer = (customerIds) => {
|
|||
return items.map(item => ({
|
||||
customerId: item.customer_id,
|
||||
infoRequestId: item.info_request_id,
|
||||
approved: item.approved,
|
||||
customerData: item.customer_data
|
||||
customerData: item.customer_data,
|
||||
override: item.override,
|
||||
overrideAt: item.override_at,
|
||||
overrideBy: item.override_by
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
|
@ -93,9 +99,9 @@ const batchGetCustomInfoRequest = (infoRequestIds) => {
|
|||
})
|
||||
}
|
||||
|
||||
const setAuthorizedCustomRequest = (customerId, infoRequestId, isAuthorized) => {
|
||||
const sql = `UPDATE customers_custom_info_requests SET approved = $1 WHERE customer_id = $2 AND info_request_id = $3`
|
||||
return db.none(sql, [isAuthorized, customerId, infoRequestId]).then(() => true)
|
||||
const setAuthorizedCustomRequest = (customerId, infoRequestId, override, token) => {
|
||||
const sql = `UPDATE customers_custom_info_requests SET override = $1, override_by = $2, override_at = now() WHERE customer_id = $3 AND info_request_id = $4`
|
||||
return db.none(sql, [override, token, customerId, infoRequestId]).then(() => true)
|
||||
}
|
||||
|
||||
const setCustomerData = (customerId, infoRequestId, data) => {
|
||||
|
|
@ -103,7 +109,7 @@ const setCustomerData = (customerId, infoRequestId, data) => {
|
|||
INSERT INTO customers_custom_info_requests (customer_id, info_request_id, customer_data)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (customer_id, info_request_id)
|
||||
DO UPDATE SET customer_data = $3, approved = null`
|
||||
DO UPDATE SET customer_data = $3`
|
||||
return db.none(sql, [customerId, infoRequestId, data])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ function batch (
|
|||
cryptoCode = null,
|
||||
toAddress = null,
|
||||
status = null,
|
||||
excludeTestingCustomers = false,
|
||||
simplified = false
|
||||
) {
|
||||
const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addNames)
|
||||
|
|
@ -67,6 +68,7 @@ function batch (
|
|||
AND ($11 is null or txs.crypto_code = $11)
|
||||
AND ($12 is null or txs.to_address = $12)
|
||||
AND ($13 is null or txs.txStatus = $13)
|
||||
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
||||
AND (fiat > 0)
|
||||
ORDER BY created DESC limit $4 offset $5`
|
||||
|
||||
|
|
@ -98,6 +100,7 @@ function batch (
|
|||
AND ($11 is null or txs.crypto_code = $11)
|
||||
AND ($12 is null or txs.to_address = $12)
|
||||
AND ($13 is null or txs.txStatus = $13)
|
||||
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
||||
AND (fiat > 0)
|
||||
ORDER BY created DESC limit $4 offset $5`
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const _ = require('lodash/fp')
|
||||
const { getCustomInfoRequests } = require('./new-admin/services/customInfoRequests')
|
||||
|
||||
const namespaces = {
|
||||
WALLETS: 'wallets',
|
||||
|
|
@ -107,22 +108,29 @@ const getGlobalNotifications = config => getNotifications(null, null, config)
|
|||
const getTriggers = _.get('triggers')
|
||||
|
||||
const getTriggersAutomation = config => {
|
||||
const defaultAutomation = _.get('triggersConfig_automation')(config)
|
||||
const requirements = {
|
||||
sanctions: defaultAutomation,
|
||||
idCardPhoto: defaultAutomation,
|
||||
idCardData: defaultAutomation,
|
||||
facephoto: defaultAutomation,
|
||||
usSsn: defaultAutomation
|
||||
}
|
||||
return getCustomInfoRequests(true)
|
||||
.then(infoRequests => {
|
||||
const defaultAutomation = _.get('triggersConfig_automation')(config)
|
||||
const requirements = {
|
||||
sanctions: defaultAutomation,
|
||||
idCardPhoto: defaultAutomation,
|
||||
idCardData: defaultAutomation,
|
||||
facephoto: defaultAutomation,
|
||||
usSsn: defaultAutomation
|
||||
}
|
||||
|
||||
const overrides = _.get('triggersConfig_overrides')(config)
|
||||
_.forEach(it => {
|
||||
requirements[it.id] = defaultAutomation
|
||||
}, infoRequests)
|
||||
|
||||
const requirementsOverrides = _.reduce((acc, override) => {
|
||||
return _.assign(acc, { [override.requirement]: override.automation })
|
||||
}, {}, overrides)
|
||||
const overrides = _.get('triggersConfig_overrides')(config)
|
||||
|
||||
return _.assign(requirements, requirementsOverrides)
|
||||
const requirementsOverrides = _.reduce((acc, override) => {
|
||||
return _.assign(acc, { [override.requirement]: override.automation })
|
||||
}, {}, overrides)
|
||||
|
||||
return _.assign(requirements, requirementsOverrides)
|
||||
})
|
||||
}
|
||||
|
||||
const splitGetFirst = _.compose(_.head, _.split('_'))
|
||||
|
|
|
|||
|
|
@ -20,8 +20,13 @@ const machineLoader = require('../machine-loader')
|
|||
const { loadLatestConfig } = require('../new-settings-loader')
|
||||
const customInfoRequestQueries = require('../new-admin/services/customInfoRequests')
|
||||
|
||||
function updateCustomerCustomInfoRequest (customerId, dataToSave, req, res) {
|
||||
return customInfoRequestQueries.setCustomerData(customerId, dataToSave.info_request_id, dataToSave)
|
||||
function updateCustomerCustomInfoRequest (customerId, patch, req, res) {
|
||||
if (_.isNil(patch.data)) {
|
||||
return customers.getById(customerId)
|
||||
.then(customer => respond(req, res, { customer }))
|
||||
}
|
||||
|
||||
return customInfoRequestQueries.setCustomerData(customerId, patch.infoRequestId, patch)
|
||||
.then(() => customers.getById(customerId))
|
||||
.then(customer => respond(req, res, { customer }))
|
||||
}
|
||||
|
|
@ -35,7 +40,7 @@ function updateCustomer (req, res, next) {
|
|||
const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
|
||||
|
||||
if (patch.customRequestPatch) {
|
||||
return updateCustomerCustomInfoRequest(id, patch.dataToSave, req, res).catch(next)
|
||||
return updateCustomerCustomInfoRequest(id, patch.customRequestPatch, req, res).catch(next)
|
||||
}
|
||||
|
||||
customers.getById(id)
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ const createTerms = terms => (terms.active && terms.text) ? ({
|
|||
const buildTriggers = (allTriggers) => {
|
||||
const normalTriggers = []
|
||||
const customTriggers = _.filter(o => {
|
||||
if (o.customInfoRequestId === '') normalTriggers.push(o)
|
||||
return o.customInfoRequestId !== ''
|
||||
if (_.isEmpty(o.customInfoRequestId) || _.isNil(o.customInfoRequestId)) normalTriggers.push(o)
|
||||
return !_.isNil(o.customInfoRequestId) && !_.isEmpty(o.customInfoRequestId)
|
||||
}, allTriggers)
|
||||
|
||||
return _.flow([_.map(_.get('customInfoRequestId')), customRequestQueries.batchGetCustomInfoRequest])(customTriggers)
|
||||
|
|
@ -73,7 +73,7 @@ function poll (req, res, next) {
|
|||
const pi = plugins(settings, deviceId)
|
||||
const hasLightning = checkHasLightning(settings)
|
||||
|
||||
const triggersAutomation = configManager.getTriggersAutomation(settings.config)
|
||||
const triggersAutomationPromise = configManager.getTriggersAutomation(settings.config)
|
||||
const triggersPromise = buildTriggers(configManager.getTriggers(settings.config))
|
||||
|
||||
const operatorInfo = configManager.getOperatorInfo(settings.config)
|
||||
|
|
@ -84,8 +84,8 @@ function poll (req, res, next) {
|
|||
|
||||
state.pids[operatorId] = { [deviceId]: { pid, ts: Date.now() } }
|
||||
|
||||
return Promise.all([pi.pollQueries(serialNumber, deviceTime, req.query, machineVersion, machineModel), triggersPromise])
|
||||
.then(([results, triggers]) => {
|
||||
return Promise.all([pi.pollQueries(serialNumber, deviceTime, req.query, machineVersion, machineModel), triggersPromise, triggersAutomationPromise])
|
||||
.then(([results, triggers, triggersAutomation]) => {
|
||||
const cassettes = results.cassettes
|
||||
|
||||
const reboot = pid && state.reboots?.[operatorId]?.[deviceId] === pid
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue