onfido-sdk-ui
Version:
JavaScript SDK view layer for Onfido identity verification
187 lines (169 loc) • 5.65 kB
text/typescript
import { EventEmitter2 } from 'eventemitter2'
import { BaseURL } from './AuthConfig'
import { FaceTecSDK } from '~auth-sdk/FaceTecSDK.js/FaceTecSDK'
import type {
FaceTecSessionResult,
FaceTecFaceScanResultCallback,
FaceTecFaceScanProcessor,
} from '~auth-sdk/FaceTecSDK.js/FaceTecPublicApi'
type AuthConfigType = {
token: string
production_key_text: string
device_key_identifier: string
public_key: string
}
export class AuthCheckProcessor implements FaceTecFaceScanProcessor {
latestNetworkRequest = new XMLHttpRequest()
success
sdkToken
nextStep
goBack
events
authConfig
retryCount
maxRetries
constructor(
authConfig: AuthConfigType,
maxRetries: number,
sdkToken: string | undefined,
nextStep: () => void,
goBack: () => void,
events?: EventEmitter2.emitter
) {
this.sdkToken = sdkToken
this.success = false
this.nextStep = nextStep
this.goBack = goBack
this.events = events
this.authConfig = authConfig
this.retryCount = 0
this.maxRetries = maxRetries
//
// Part 1: Starting the FaceTec Session
//
new FaceTecSDK.FaceTecSession(this, authConfig.token)
}
//
// Part 2: Handling the Result of a FaceScan
//
processSessionResultWhileFaceTecSDKWaits = (
sessionResult: FaceTecSessionResult,
faceScanResultCallback: FaceTecFaceScanResultCallback
): void => {
//
// Part 3: Handles early exit scenarios where there is no FaceScan to handle -- i.e. User Cancellation, Timeouts, etc.
//
if (
sessionResult.status !==
FaceTecSDK.FaceTecSessionStatus.SessionCompletedSuccessfully
) {
console.info(
`Session was not completed successfully, cancelling. Status: ${sessionResult.status}`
)
this.latestNetworkRequest.abort()
faceScanResultCallback.cancel()
return
}
//
// Part 4: Get essential data off the FaceTecSessionResult
//
const parameters = {
face_scan: sessionResult.faceScan,
audit_trail_image: sessionResult.auditTrail[0],
low_quality_audit_trail_image: sessionResult.lowQualityAuditTrail[0],
metadata: {
sdk_source: 'onfido_web_sdk',
sdk_version: process.env.SDK_VERSION,
sdk_metadata: {
system: {
fingerprint: '',
model: '',
manufacturer: '',
brand: '',
product: '',
hardware: '',
},
},
},
}
//
// Part 5: Make the Networking Call to the Onfido Servers.
//
this.latestNetworkRequest = new XMLHttpRequest()
this.latestNetworkRequest.open('POST', `${BaseURL}/v3/auth_3d`)
this.latestNetworkRequest.setRequestHeader(
'Authorization',
`Bearer ${this.sdkToken}`
)
this.latestNetworkRequest.setRequestHeader(
'Content-Type',
'application/json'
)
this.latestNetworkRequest.onreadystatechange = () => {
//
// Part 6: We evaluate a boolean response and treat true as success, false as "User Needs to Retry".
if (this.latestNetworkRequest.readyState === XMLHttpRequest.DONE) {
const responseJSON = JSON.parse(this.latestNetworkRequest.responseText)
try {
const responseObj = responseJSON
if (responseObj.success === true) {
this.success = true
faceScanResultCallback.succeed()
} else if (responseObj.success === false) {
this.success = false
this.retryCount = this.retryCount + 1
console.warn('User needs to retry, invoking retry.')
if (this.retryCount < this.maxRetries) {
faceScanResultCallback.retry()
} else faceScanResultCallback.cancel()
} else {
this.success = false
console.error('Unexpected API response, cancelling out.')
faceScanResultCallback.cancel()
}
this.nextStep()
this.events?.emit('complete', {
type: 'complete',
...responseObj,
})
} catch {
this.success = false
const message =
'Exception while handling API response, cancelling out.'
this.events?.emit('error', { type: 'exception', message })
faceScanResultCallback.cancel()
this.nextStep()
}
}
}
this.latestNetworkRequest.onerror = () => {
const message = 'XHR error, cancelling.'
this.events?.emit('error', { type: 'exception', message })
console.error(message)
faceScanResultCallback.cancel()
}
//
// Part 7: Demonstrates updating the Progress Bar based on the progress event.
//
this.latestNetworkRequest.upload.onprogress = function name(event) {
const progress = event.loaded / event.total
faceScanResultCallback.uploadProgress(progress)
}
//
// Part 8: Actually send the request.
//
const jsonStringToUpload = JSON.stringify(parameters)
this.latestNetworkRequest.send(jsonStringToUpload)
}
//
// Part 10: This function gets called after the FaceTec SDK is completely done.
//
onFaceTecSDKCompletelyDone = (): void => {
// DEVELOPER NOTE: onFaceTecSDKCompletelyDone() is called after logic signals the FaceTec SDK with a success() or cancel().
// Calling a custom function on the Sample App Controller is done for demonstration purposes to show you that here is where you get control back from the FaceTec SDK.
if (!this.success) this.goBack()
console.info(
'FaceTecSDK session has finished. Session results are unknown.'
)
}
}