Merge branch 'dev' into fix/lam-298/custom_info_requests_flow

This commit is contained in:
André Sá 2022-01-27 11:13:41 +00:00
commit c5bf50b932
46 changed files with 441 additions and 149 deletions

View file

@ -14,6 +14,7 @@ const SMS = 'sms'
const ID_VERIFIER = 'idVerifier'
const EMAIL = 'email'
const ZERO_CONF = 'zeroConf'
const WALLET_SCORING = 'wallet_scoring'
const ALL_ACCOUNTS = [
{ code: 'binanceus', display: 'Binance.us', class: TICKER, cryptos: binanceus.CRYPTO },
@ -50,7 +51,9 @@ const ALL_ACCOUNTS = [
{ code: 'mailgun', display: 'Mailgun', class: EMAIL },
{ code: 'none', display: 'None', class: ZERO_CONF, cryptos: [BTC, ZEC, LTC, DASH, BCH, ETH, XMR] },
{ code: 'blockcypher', display: 'Blockcypher', class: ZERO_CONF, cryptos: [BTC] },
{ code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: ALL_CRYPTOS, dev: true }
{ code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: ALL_CRYPTOS, dev: true },
{ code: 'ciphertrace', display: 'CipherTrace', class: WALLET_SCORING, cryptos: [BTC, ETH, LTC, BCH] },
{ code: 'mock-scoring', display: 'Mock scoring', class: WALLET_SCORING, cryptos: ALL_CRYPTOS, dev: true }
]
const devMode = require('minimist')(process.argv.slice(2)).dev

View file

@ -4,25 +4,20 @@ const _ = require('lodash/fp')
const userManagement = require('../userManagement')
const credentials = require('../../../../hardware-credentials')
const options = require('../../../../options')
const T = require('../../../../time')
const users = require('../../../../users')
const domain = options.hostname
const devMode = require('minimist')(process.argv.slice(2)).dev
const REMEMBER_ME_AGE = 90 * T.day
const rpID = devMode ? `localhost:3001` : domain
const expectedOrigin = `https://${rpID}`
const generateAttestationOptions = (session, options) => {
return users.getUserById(options.userId).then(user => {
return Promise.all([credentials.getHardwareCredentialsByUserId(user.id), user])
}).then(([userDevices, user]) => {
const options = simpleWebauthn.generateAttestationOptions({
const opts = simpleWebauthn.generateAttestationOptions({
rpName: 'Lamassu',
rpID,
rpID: options.domain,
userName: user.username,
userID: user.id,
timeout: 60000,
@ -40,11 +35,11 @@ const generateAttestationOptions = (session, options) => {
session.webauthn = {
attestation: {
challenge: options.challenge
challenge: opts.challenge
}
}
return options
return opts
})
}
@ -59,7 +54,7 @@ const generateAssertionOptions = (session, options) => {
transports: ['usb', 'ble', 'nfc', 'internal']
})),
userVerification: 'discouraged',
rpID
rpID: options.domain
})
session.webauthn = {
@ -82,8 +77,8 @@ const validateAttestation = (session, options) => {
simpleWebauthn.verifyAttestationResponse({
credential: options.attestationResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain
})
])
.then(([user, verification]) => {
@ -142,8 +137,8 @@ const validateAssertion = (session, options) => {
verification = simpleWebauthn.verifyAssertionResponse({
credential: options.assertionResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID,
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain,
authenticator: convertedAuthenticator
})
} catch (err) {

View file

@ -3,25 +3,20 @@ const base64url = require('base64url')
const _ = require('lodash/fp')
const credentials = require('../../../../hardware-credentials')
const options = require('../../../../options')
const T = require('../../../../time')
const users = require('../../../../users')
const domain = options.hostname
const devMode = require('minimist')(process.argv.slice(2)).dev
const REMEMBER_ME_AGE = 90 * T.day
const rpID = devMode ? `localhost:3001` : domain
const expectedOrigin = `https://${rpID}`
const generateAttestationOptions = (session, options) => {
return users.getUserById(options.userId).then(user => {
return Promise.all([credentials.getHardwareCredentialsByUserId(user.id), user])
}).then(([userDevices, user]) => {
const opts = simpleWebauthn.generateAttestationOptions({
rpName: 'Lamassu',
rpID,
rpID: options.domain,
userName: user.username,
userID: user.id,
timeout: 60000,
@ -58,7 +53,7 @@ const generateAssertionOptions = (session, options) => {
transports: ['usb', 'ble', 'nfc', 'internal']
})),
userVerification: 'discouraged',
rpID
rpID: options.domain
})
session.webauthn = {
@ -81,8 +76,8 @@ const validateAttestation = (session, options) => {
simpleWebauthn.verifyAttestationResponse({
credential: options.attestationResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain
})
])
.then(([user, verification]) => {
@ -141,8 +136,8 @@ const validateAssertion = (session, options) => {
verification = simpleWebauthn.verifyAssertionResponse({
credential: options.assertionResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID,
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain,
authenticator: convertedAuthenticator
})
} catch (err) {

View file

@ -3,23 +3,18 @@ const base64url = require('base64url')
const _ = require('lodash/fp')
const credentials = require('../../../../hardware-credentials')
const options = require('../../../../options')
const T = require('../../../../time')
const users = require('../../../../users')
const domain = options.hostname
const devMode = require('minimist')(process.argv.slice(2)).dev
const REMEMBER_ME_AGE = 90 * T.day
const rpID = devMode ? `localhost:3001` : domain
const expectedOrigin = `https://${rpID}`
const generateAttestationOptions = (session, options) => {
return credentials.getHardwareCredentials().then(devices => {
const opts = simpleWebauthn.generateAttestationOptions({
rpName: 'Lamassu',
rpID,
rpID: options.domain,
userName: `Usernameless user created at ${new Date().toISOString()}`,
userID: options.userId,
timeout: 60000,
@ -46,9 +41,9 @@ const generateAttestationOptions = (session, options) => {
})
}
const generateAssertionOptions = session => {
const generateAssertionOptions = (session, options) => {
return credentials.getHardwareCredentials().then(devices => {
const options = simpleWebauthn.generateAssertionOptions({
const opts = simpleWebauthn.generateAssertionOptions({
timeout: 60000,
allowCredentials: devices.map(dev => ({
id: dev.data.credentialID,
@ -56,15 +51,15 @@ const generateAssertionOptions = session => {
transports: ['usb', 'ble', 'nfc', 'internal']
})),
userVerification: 'discouraged',
rpID
rpID: options.domain
})
session.webauthn = {
assertion: {
challenge: options.challenge
challenge: opts.challenge
}
}
return options
return opts
})
}
@ -77,8 +72,8 @@ const validateAttestation = (session, options) => {
simpleWebauthn.verifyAttestationResponse({
credential: options.attestationResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain
})
])
.then(([user, verification]) => {
@ -146,8 +141,8 @@ const validateAssertion = (session, options) => {
verification = simpleWebauthn.verifyAssertionResponse({
credential: options.assertionResponse,
expectedChallenge: `${expectedChallenge}`,
expectedOrigin,
expectedRPID: rpID,
expectedOrigin: `https://${options.domain}${devMode ? `:3001` : ``}`,
expectedRPID: options.domain,
authenticator: convertedAuthenticator
})
} catch (err) {

View file

@ -20,7 +20,7 @@ const txLogFields = ['txClass', 'id', 'deviceId', 'toAddress', 'cryptoAtoms',
'commissionPercentage', 'rawTickerPrice', 'receivedCryptoAtoms',
'discount', 'txHash', 'customerPhone', 'customerIdCardDataNumber',
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName']
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName', 'walletScore']
const resolvers = {
Customer: {

View file

@ -6,11 +6,11 @@ const sessionManager = require('../../../session-manager')
const getAttestationQueryOptions = variables => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return { userId: variables.userID }
return { userId: variables.userID, domain: variables.domain }
case 'FIDOPasswordless':
return { userId: variables.userID }
return { userId: variables.userID, domain: variables.domain }
case 'FIDOUsernameless':
return { userId: variables.userID }
return { userId: variables.userID, domain: variables.domain }
default:
return {}
}
@ -19,11 +19,11 @@ const getAttestationQueryOptions = variables => {
const getAssertionQueryOptions = variables => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return { username: variables.username, password: variables.password }
return { username: variables.username, password: variables.password, domain: variables.domain }
case 'FIDOPasswordless':
return { username: variables.username }
return { username: variables.username, domain: variables.domain }
case 'FIDOUsernameless':
return {}
return { domain: variables.domain }
default:
return {}
}
@ -32,11 +32,11 @@ const getAssertionQueryOptions = variables => {
const getAttestationMutationOptions = variables => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return { userId: variables.userID, attestationResponse: variables.attestationResponse }
return { userId: variables.userID, attestationResponse: variables.attestationResponse, domain: variables.domain }
case 'FIDOPasswordless':
return { userId: variables.userID, attestationResponse: variables.attestationResponse }
return { userId: variables.userID, attestationResponse: variables.attestationResponse, domain: variables.domain }
case 'FIDOUsernameless':
return { userId: variables.userID, attestationResponse: variables.attestationResponse }
return { userId: variables.userID, attestationResponse: variables.attestationResponse, domain: variables.domain }
default:
return {}
}
@ -45,11 +45,11 @@ const getAttestationMutationOptions = variables => {
const getAssertionMutationOptions = variables => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return { username: variables.username, password: variables.password, rememberMe: variables.rememberMe, assertionResponse: variables.assertionResponse }
return { username: variables.username, password: variables.password, rememberMe: variables.rememberMe, assertionResponse: variables.assertionResponse, domain: variables.domain }
case 'FIDOPasswordless':
return { username: variables.username, rememberMe: variables.rememberMe, assertionResponse: variables.assertionResponse }
return { username: variables.username, rememberMe: variables.rememberMe, assertionResponse: variables.assertionResponse, domain: variables.domain }
case 'FIDOUsernameless':
return { assertionResponse: variables.assertionResponse }
return { assertionResponse: variables.assertionResponse, domain: variables.domain }
default:
return {}
}

View file

@ -47,6 +47,7 @@ const typeDef = gql`
txCustomerPhotoAt: Date
batched: Boolean
batchTime: Date
walletScore: Int
}
type Filter {

View file

@ -3,14 +3,14 @@ const authentication = require('../modules/authentication')
const getFIDOStrategyQueryTypes = () => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return `generateAttestationOptions(userID: ID!): JSONObject
generateAssertionOptions(username: String!, password: String!): JSONObject`
return `generateAttestationOptions(userID: ID!, domain: String!): JSONObject
generateAssertionOptions(username: String!, password: String!, domain: String!): JSONObject`
case 'FIDOPasswordless':
return `generateAttestationOptions(userID: ID!): JSONObject
generateAssertionOptions(username: String!): JSONObject`
return `generateAttestationOptions(userID: ID!, domain: String!): JSONObject
generateAssertionOptions(username: String!, domain: String!): JSONObject`
case 'FIDOUsernameless':
return `generateAttestationOptions(userID: ID!): JSONObject
generateAssertionOptions: JSONObject`
return `generateAttestationOptions(userID: ID!, domain: String!): JSONObject
generateAssertionOptions(domain: String!): JSONObject`
default:
return ``
}
@ -19,14 +19,14 @@ const getFIDOStrategyQueryTypes = () => {
const getFIDOStrategyMutationsTypes = () => {
switch (authentication.CHOSEN_STRATEGY) {
case 'FIDO2FA':
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!): Boolean
validateAssertion(username: String!, password: String!, rememberMe: Boolean!, assertionResponse: JSONObject!): Boolean`
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!, domain: String!): Boolean
validateAssertion(username: String!, password: String!, rememberMe: Boolean!, assertionResponse: JSONObject!, domain: String!): Boolean`
case 'FIDOPasswordless':
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!): Boolean
validateAssertion(username: String!, rememberMe: Boolean!, assertionResponse: JSONObject!): Boolean`
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!, domain: String!): Boolean
validateAssertion(username: String!, rememberMe: Boolean!, assertionResponse: JSONObject!, domain: String!): Boolean`
case 'FIDOUsernameless':
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!): Boolean
validateAssertion(assertionResponse: JSONObject!): Boolean`
return `validateAttestation(userID: ID!, attestationResponse: JSONObject!, domain: String!): Boolean
validateAssertion(assertionResponse: JSONObject!, domain: String!): Boolean`
default:
return ``
}

View file

@ -21,7 +21,6 @@ router.use('*', async (req, res, next) => getOperatorId('authentication').then((
cookie: {
httpOnly: true,
secure: true,
domain: hostname,
sameSite: true,
maxAge: 60 * 10 * 1000 // 10 minutes
}

View file

@ -69,7 +69,7 @@ function batch (
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)
AND (error IS NOT null OR fiat > 0)
ORDER BY created DESC limit $4 offset $5`
const cashOutSql = `SELECT 'cashOut' AS tx_class,