eagle-id
Version:
A React based component to perform identity verification
305 lines (275 loc) • 11.2 kB
JSX
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { isMobile } from 'react-device-detect'
import axios from 'axios'
import http from 'http'
import https from 'https'
import { routes } from './constants'
import * as constants from './constants'
import { defaultStyles } from './config'
import PrivacyNotice from './PrivacyNotice.jsx'
import DocumentSelection from './DocumentSelection.jsx'
import WebcamCapture from './WebcamCapture.jsx'
import ConfirmationScreen from './ConfirmationScreen.jsx'
import Selfie from './Selfie.jsx'
import Upload from './Upload.jsx'
import Response from './Response.jsx'
class Controller extends Component {
constructor(props) {
super(props)
this.state = {
config: this.props.config,
screen: routes.PRIVACY_SCREEN,
documentType: constants.OTHER,
images: {},
loading: false
}
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.config != this.props.config) {
this.setState({
config: this.props.config
})
}
}
componentDidMount() {
if(this.state.config.privacy.show === true &&
localStorage.getItem('TermsAndConditions') !== "true") {
this.setState({
screen: routes.PRIVACY_SCREEN,
}, this.forceUpdate())
} else {
this.setState({
screen: routes.DOCUMENT_SCREEN,
}, this.forceUpdate())
}
}
switchScreen = (nextScreen) => {
this.setState({
screen: nextScreen
}, this.forceUpdate())
}
setDocumentType = (type) => {
this.setState({
documentType: type
})
}
processImage = (image) => {
this.setState({
loading: true
})
var Jimp = require('jimp')
Jimp.read(image).then((image) => {
var x = 50
var y = 25
var width = image.bitmap.width - 100
var height = image.bitmap.height - (window.innerHeight / 4.5)
if(isMobile) {
x = 25
width = image.bitmap.width - 50
height = image.bitmap.height - (window.innerHeight / 1.5)
}
if(this.state.documentType === constants.SELFIE) {
x = 100
y = 25
width = image.bitmap.width - 200
height = image.bitmap.height - (window.innerHeight / 4)
if(isMobile) {
x = 50
width = image.bitmap.width - 100
height = image.bitmap.height - (window.innerHeight / 2)
}
}
image.crop(x, y, width, height).getBase64Async(Jimp.MIME_JPEG).then((image) => {
fetch(image).then(res => res.blob()).then(imageBlob => {
this.setState({
loading: false
})
var images = this.state.images
if(this.state.documentType === constants.SELFIE) {
images.user_selfie_base64 = image.replace("data:image/jpeg;base64,", "")
images.user_selfie = imageBlob
this.setState({
images: images
});
this.switchScreen(routes.UPLOAD_SCREEN)
this.callEynAPI()
}
if(this.state.documentType === constants.ID_FRONT) {
images.identity_document_image_front_base64 = image.replace("data:image/jpeg;base64,", "")
images.identity_document_image_front = imageBlob
this.setState({
images: images,
documentType: constants.ID_BACK
})
return
}
if(this.state.documentType === constants.ID_BACK ||
this.state.documentType === constants.VISA ||
this.state.documentType === constants.PASSPORT ||
this.state.documentType === constants.OTHER) {
images.identity_document_image_mrz_base64 = image.replace("data:image/jpeg;base64,", "")
images.identity_document_image_mrz = imageBlob
this.setState({
images: images
}, this.switchScreen(routes.CONFIRMATION_SCREEN))
}
})
})
})
}
callEynAPI = async () => {
this.setState({
loading: true
})
var startTime = Math.floor(Date.now())
var payload = {}
if ('identity_document_image_front_base64' in this.state.images) {
payload.document_front_base64_encoded = this.state.images.identity_document_image_front_base64
payload.document_back_base64_encoded = this.state.images.identity_document_image_mrz_base64
} else {
payload.document_front_base64_encoded = this.state.images.identity_document_image_mrz_base64
}
payload.selfie_base64_encoded = this.state.images.user_selfie_base64
payload.eyn_ocr_token = this.state.config.apiSecret
let axiosInstance = axios.create({
timeout: 120000,
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
maxRedirects: 10,
maxContentLength: 50 * 1000 * 1000
})
axiosInstance({
url: this.state.config.baseUrl,
method: "POST",
data: payload
}).then((response) => {
var endTime = Math.floor(Date.now())
var responseTime = (endTime - startTime) / 1000
this.setState({
response: response.data,
responseTime: responseTime,
loading: false
})
console.log(response)
this.switchScreen(routes.RESPONSE_SCREEN)
}).catch((error) => {
this.setState({
loading: false
})
console.log(error)
this.props.enqueueSnackbar(
"An error occured during the upload of your document. Please try again.", {
variant: "error",
anchorOrigin: {
vertical: 'bottom',
horizontal: 'center',
}})
})
}
render() {
return (
<div>
{ /* Header */ }
<div style={defaultStyles.container}>
<div style={defaultStyles.header}>
<table>
<tbody>
<tr>
<td>
<img
src={this.state.config.resources.images.logoTitle}
height="40"
alt="logo">
</img>
</td>
<td>
<p style={{
position: "absolute",
top: 0,
bottom: 0,
margin: "auto",
marginTop: 10,
whiteSpace: "nowrap",
fontWeight: 400
}}>
{this.state.config.title}
</p>
</td>
</tr>
</tbody>
</table>
</div>
{ /* Privacy Notice */ }
{ this.state.screen === routes.PRIVACY_SCREEN?
<PrivacyNotice
config={this.props.config}
switchScreen={() => { this.switchScreen(routes.DOCUMENT_SCREEN) }}
/>
: <div></div>
}
{ /* Document Selection */ }
{ this.state.screen === routes.DOCUMENT_SCREEN?
<DocumentSelection
config={this.props.config}
selectDocument={(type) => {
this.setDocumentType(type)
this.switchScreen(routes.WEBCAM_SCREEN)
}}
/>
: <div></div>
}
{ /* Webcam Capture */ }
{ this.state.screen === routes.WEBCAM_SCREEN?
<WebcamCapture
config={this.props.config}
loading={this.state.loading}
open={this.state.screen === routes.WEBCAM_SCREEN}
close={() => {}}
documentType={this.state.documentType}
processImage={(image) => { this.processImage(image) }}
/>
: <div></div>
}
{ /* Confirmation Screen */ }
{ this.state.screen === routes.CONFIRMATION_SCREEN?
<ConfirmationScreen
config={this.props.config}
images={this.state.images}
confirm={() => {
this.setDocumentType(constants.SELFIE)
this.switchScreen(routes.SELFIE_SCREEN)
}}
retake={() => { this.switchScreen(routes.WEBCAM_SCREEN) }}
/>
: <div></div>
}
{ /* Selfie */ }
{ this.state.screen === routes.SELFIE_SCREEN?
<Selfie
config={this.props.config}
takeSelfie={() => { this.switchScreen(routes.WEBCAM_SCREEN) }}
/>
: <div></div>
}
{ /* Upload */ }
{ this.state.screen === routes.UPLOAD_SCREEN?
<Upload
config={this.props.config}
/>
: <div></div>
}
{ /* Response */ }
{ this.state.screen === routes.RESPONSE_SCREEN?
<Response
config={this.props.config}
responseTime={this.state.responseTime}
/>
: <div></div>
}
</div>
</div>
)
}
}
export default Controller;