UNPKG

@onfido/react-native-sdk

Version:

Onfido React Native SDK

192 lines (155 loc) 7.19 kB
import {NativeModules, Platform, NativeEventEmitter} from 'react-native'; import { OnfidoAlpha2CountryCode, OnfidoCaptureType, OnfidoConfig, OnfidoCountryCode, OnfidoDocumentPages, OnfidoDocumentType, OnfidoError, OnfidoMediaResult, OnfidoResult } from "./config_constants"; import { Base64 } from 'js-base64'; const OnfidoSdk: { start(config: OnfidoConfig): Promise<OnfidoResult> withMediaCallbacksEnabled(): void withBiometricTokenCallback(): void withAnalyticsCallback(): void provideBiometricToken(token: string): void } = NativeModules.OnfidoSdk export type OnfidoEvent = { type: string, properties: Record<string, unknown> } const OnfidoSdkModule = NativeModules.OnfidoSdk const eventEmitter = new NativeEventEmitter(OnfidoSdkModule) type BiometricTokenCallback = { onTokenGenerated: (customerUserHash: string, biometricToken: string) => void; onTokenRequested: (customerUserHash: string, provideToken: (biometricToken: string) => void) => void; }; const Onfido = { start(config: OnfidoConfig): Promise<OnfidoResult> { if (!config) { return configError("config is missing"); } if (!config.sdkToken) { return configError("sdkToken is missing"); } if (!config.sdkToken.match(/^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$/)) { return configError("sdkToken is not a valid jwt"); } if (config.workflowRunId === undefined) { if (!config.flowSteps) { return configError("flowSteps configuration is missing"); } if (config.flowSteps.captureDocument) { if (config.flowSteps.captureDocument.docType && !config.flowSteps.captureDocument.countryCode) { return configError("countryCode needs to be a ISO 3166-1 3 letter code if docType is specified"); } if (!config.flowSteps.captureDocument.docType && config.flowSteps.captureDocument.countryCode) { return configError("docType needs to be provided if countryCode is specified"); } if (config.flowSteps.captureDocument.docType && !(config.flowSteps.captureDocument.docType in OnfidoDocumentType)) { return configError("docType is invalid"); } if (config.flowSteps.captureDocument.docType === OnfidoDocumentType.GENERIC) { if (!config.flowSteps.captureDocument.title) { return configError("title is required for GENERIC docType"); } if (!config.flowSteps.captureDocument.pages || !(config.flowSteps.captureDocument.pages in OnfidoDocumentPages)) { return configError("pages is required and must one of OnfidoDocumentPages for GENERIC docType"); } } if (config.flowSteps.captureDocument.countryCode) { if (!(config.flowSteps.captureDocument.countryCode in OnfidoCountryCode)) { return configError("countryCode is not a ISO 3166-1 3 letter code"); } if (Platform.OS === "android") { config.flowSteps.captureDocument.alpha2CountryCode = OnfidoAlpha2CountryCode[config.flowSteps.captureDocument.countryCode]; } } if ( config.flowSteps.captureDocument.allowedDocumentTypes && config.flowSteps.captureDocument.allowedDocumentTypes.length > 0 ) { if(!config.flowSteps.captureDocument.allowedDocumentTypes.every(doc => doc in OnfidoDocumentType)){ let invalidList = config.flowSteps.captureDocument.allowedDocumentTypes .filter((value) => value !in OnfidoDocumentType) return configError(`allowedDocumentTypes is invalid ${invalidList}`) } if(config.flowSteps.captureDocument.docType && config.flowSteps.captureDocument.countryCode){ return configError("We can either filter the documents on DocumentSelection screen, or skip the selection and go directly to capture") } } } if ( !config.flowSteps.captureDocument && !config.flowSteps.captureFace && !config.flowSteps.proofOfAddress ) { return configError("flowSteps is empty"); } if (config.flowSteps.captureFace && !(config.flowSteps.captureFace.type in OnfidoCaptureType)) { return configError("Capture Face type is invalid"); } } return OnfidoSdk.start(config).catch((error: any) => { console.log(error); throw error; }); }, addAnalyticsCallback(callback: (event: OnfidoEvent) => void) { const eventType = 'onfidoAnalyticsCallback'; OnfidoSdk.withAnalyticsCallback() eventEmitter.removeAllListeners(eventType); return eventEmitter.addListener(eventType, callback); }, addCustomMediaCallback(callback: (result: OnfidoMediaResult) => OnfidoMediaResult) { OnfidoSdk.withMediaCallbacksEnabled() // Removing any previously-added listener to avoid multiple invocations eventEmitter.removeAllListeners('onfidoMediaCallback'); return eventEmitter.addListener('onfidoMediaCallback', callback); }, addBiometricTokenCallback(callback: BiometricTokenCallback): void { OnfidoSdk.withBiometricTokenCallback(); eventEmitter.removeAllListeners('onTokenGenerated'); eventEmitter.removeAllListeners('onTokenRequested'); eventEmitter.addListener('onTokenGenerated', (event) => { callback.onTokenGenerated(event.customerUserHash, event.biometricToken) }); eventEmitter.addListener('onTokenRequested', (event) => { callback.onTokenRequested(event.customerUserHash, (biometricToken) => { OnfidoSdk.provideBiometricToken(biometricToken) }) }); }, byteArrayStringToBase64(byteArrayString: String) { let charString = ''; // Iterate through the string and convert each number to string // Iteration starts from the 1st element to ignore brackets let currentNumber = ''; for (let i = 1; i < byteArrayString.length; i++) { const char = byteArrayString.charAt(i); if ((char >= '0' && char <= '9') || char === '-') { currentNumber += char; } else { // Convert the collected number to string if (currentNumber) { const number = parseInt(currentNumber, 10); charString += String.fromCharCode(number & 0xFF); currentNumber = ''; } } } // Convert to base64 return Base64.btoa(charString); } }; const configError = (message: string): Promise<OnfidoResult> => { const error: OnfidoError = new Error(message); error.code = "config_error"; console.log(error); return Promise.reject(error); }; export default Onfido