Merge pull request #1689 from RafaelTaranto/chore/sumsub-rebase-simplified

chore: sumsub rebase simplified
This commit is contained in:
Rafael Taranto 2024-07-16 09:34:07 +01:00 committed by GitHub
commit 09c3fb8a70
29 changed files with 828 additions and 73 deletions

View file

@ -0,0 +1,6 @@
module.exports = {
PENDING: 'PENDING',
RETRY: 'RETRY',
APPROVED: 'APPROVED',
REJECTED: 'REJECTED'
}

View file

@ -0,0 +1,31 @@
const uuid = require('uuid')
const {APPROVED} = require('../consts')
const CODE = 'mock-compliance'
const createLink = (settings, userId, level) => {
return `this is a mock external link, ${userId}, ${level}`
}
const getApplicantStatus = (account, userId) => {
return Promise.resolve({
service: CODE,
status: {
level: account.applicantLevel, answer: APPROVED
}
})
}
const createApplicant = () => {
return Promise.resolve({
id: uuid.v4()
})
}
module.exports = {
CODE,
createApplicant,
getApplicantStatus,
createLink
}

View file

@ -0,0 +1,34 @@
const axios = require('axios')
const crypto = require('crypto')
const _ = require('lodash/fp')
const FormData = require('form-data')
const axiosConfig = {
baseURL: 'https://api.sumsub.com'
}
const getSigBuilder = (apiToken, secretKey) => config => {
const timestamp = Math.floor(Date.now() / 1000)
const signature = crypto.createHmac('sha256', secretKey)
signature.update(`${timestamp}${_.toUpper(config.method)}${config.url}`)
if (config.data instanceof FormData) {
signature.update(config.data.getBuffer())
} else if (config.data) {
signature.update(JSON.stringify(config.data))
}
config.headers['X-App-Token'] = apiToken
config.headers['X-App-Access-Sig'] = signature.digest('hex')
config.headers['X-App-Access-Ts'] = timestamp
return config
}
const request = ((account, config) => {
const instance = axios.create(axiosConfig)
instance.interceptors.request.use(getSigBuilder(account.apiToken, account.secretKey), Promise.reject)
return instance(config)
})
module.exports = request

View file

@ -0,0 +1,98 @@
const request = require('./request')
const createApplicant = (account, userId, level) => {
if (!userId || !level) {
return Promise.reject(`Missing required fields: userId: ${userId}, level: ${level}`)
}
const config = {
method: 'POST',
url: `/resources/applicants?levelName=${level}`,
data: {
externalUserId: userId,
sourceKey: 'lamassu'
},
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
return request(account, config)
}
const createLink = (account, userId, level) => {
if (!userId || !level) {
return Promise.reject(`Missing required fields: userId: ${userId}, level: ${level}`)
}
const config = {
method: 'POST',
url: `/resources/sdkIntegrations/levels/${level}/websdkLink?ttlInSecs=${600}&externalUserId=${userId}`,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}
return request(account, config)
}
const getApplicantByExternalId = (account, id) => {
if (!id) {
return Promise.reject('Missing required fields: id')
}
const config = {
method: 'GET',
url: `/resources/applicants/-;externalUserId=${id}/one`,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
return request(account, config)
}
const getApplicantStatus = (account, id) => {
if (!id) {
return Promise.reject(`Missing required fields: id`)
}
const config = {
method: 'GET',
url: `/resources/applicants/${id}/status`,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
return request(account, config)
}
const getApplicantById = (account, id) => {
if (!id) {
return Promise.reject(`Missing required fields: id`)
}
const config = {
method: 'GET',
url: `/resources/applicants/${id}/one`,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}
return request(account, config)
}
module.exports = {
createLink,
createApplicant,
getApplicantByExternalId,
getApplicantById,
getApplicantStatus
}

View file

@ -0,0 +1,52 @@
const _ = require('lodash/fp')
const sumsubApi = require('./sumsub.api')
const { PENDING, RETRY, APPROVED, REJECTED } = require('../consts')
const CODE = 'sumsub'
const getApplicantByExternalId = (account, userId) => {
return sumsubApi.getApplicantByExternalId(account, userId)
.then(r => r.data)
}
const createApplicant = (account, userId, level) => {
return sumsubApi.createApplicant(account, userId, level)
.then(r => r.data)
.catch(err => {
if (err.response.status === 409) return getApplicantByExternalId(account, userId)
throw err
})
}
const createLink = (account, userId, level) => {
return sumsubApi.createLink(account, userId, level)
.then(r => r.data.url)
}
const getApplicantStatus = (account, userId) => {
return sumsubApi.getApplicantByExternalId(account, userId)
.then(r => {
const levelName = _.get('data.review.levelName', r)
const reviewStatus = _.get('data.review.reviewStatus', r)
const reviewAnswer = _.get('data.review.reviewResult.reviewAnswer', r)
const reviewRejectType = _.get('data.review.reviewResult.reviewRejectType', r)
// if last review was from a different level, return the current level and RETRY
if (levelName !== account.applicantLevel) return { level: account.applicantLevel, answer: RETRY }
let answer = PENDING
if (reviewAnswer === 'GREEN' && reviewStatus === 'completed') answer = APPROVED
if (reviewAnswer === 'RED' && reviewRejectType === 'RETRY') answer = RETRY
if (reviewAnswer === 'RED' && reviewRejectType === 'FINAL') answer = REJECTED
return { level: levelName, answer }
})
}
module.exports = {
CODE,
createApplicant,
getApplicantStatus,
createLink
}