Merge branch 'dev' into fix/lam-298/custom_info_requests_flow
This commit is contained in:
commit
c5bf50b932
46 changed files with 441 additions and 149 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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: {
|
||||
|
|
|
|||
|
|
@ -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 {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ const typeDef = gql`
|
|||
txCustomerPhotoAt: Date
|
||||
batched: Boolean
|
||||
batchTime: Date
|
||||
walletScore: Int
|
||||
}
|
||||
|
||||
type Filter {
|
||||
|
|
|
|||
|
|
@ -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 ``
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue