import initialiseFrontDocumentScan from './sdk/initialiseFrontDocumentScan'; import type { GetidSdkConfig, InitialiseDocumentScanProps, InitialiseLivenessScanProps, InitialiseLivenessScanResult, InitialiseSdkProps, InitialiseSelfieProps, InitialiseSelfieScanResult, UploadDocFile, UploadSelfieFile, PassiveLivenessInfo, } from './types/sdkTypes'; import Logger from './utils/logger'; import * as GetidSdkTypes from './types/sdkTypes'; import initialiseBackDocumentScan from './sdk/initialiseBackDocumentScan'; import submitForVerification from './sdk/submitForVerification'; import initialiseLivenessScan from './sdk/initialiseLivenessScan'; import initialiseSelfieScan from './sdk/initialiseSelfieScan'; import type { LivenessCommandSuccess } from './components/LivenessScan/useLiveness'; import tracking from './sdk/internal/tracking'; import { Platform } from 'react-native'; import { mergeStyles } from './utils/theme'; import { normalizeProfile } from './utils/profile'; const { version } = require('../package'); class GetIdSdk { /** * @hidden */ docFiles: UploadDocFile[] = []; /** * @hidden */ selfieResult: UploadSelfieFile | null = null; /** * @hidden */ livenessResult: LivenessCommandSuccess | null = null; /** * @hidden */ passiveLivenessResult: PassiveLivenessInfo | null = null; /** * @hidden */ config: GetidSdkConfig; /** * @hidden */ tracking: ReturnType; /** * @hidden */ private constructor({ token, apiUrl, flow, configuration, stepsConfigs, acceptableDocuments, profile, externalId, }: GetidSdkConfig) { this.config = { token, apiUrl, flow, configuration, stepsConfigs, acceptableDocuments, profile, externalId, }; this.tracking = tracking(this, configuration, flow); this.tracking.trySendEvent('init-sdk', 'started'); Logger.log('SDK succesfully initialised'); this.tracking.trySendEvent('init-sdk', 'check-prediction', { prediction: { initState: 'running' }, }); } /** * Initialise the SDK with the given properties. The SDK will fetch the matching flow configuration from the backend and initialise the SDK with it. * * @param props The properties to initialise the SDK with. * * @returns A promise that resolves to the result of the initialisation. */ public static async initialiseSDK({ token, flow = '', apiUrl: apiUrlParam, customerId, sdkKey, acceptableDocuments, profile, externalId, styles, }: InitialiseSdkProps): Promise { const apiUrl = apiUrlParam.replace(/\/+$/, ''); if (sdkKey) { Logger.log( "Using SDK key for authentication. Don't use this in production, use a backend generated token instead." ); const app = await this.generateApplication(sdkKey, apiUrl, customerId); if (app?.statusCode === 'customerid_exists') { throw new GetidSdkTypes.GetIdSdkError( 'An application with this customerId already exists.', GetidSdkTypes.GeneralErrorCode.CUSTOMER_ID_EXISTS ); } if (app?.statusCode === 'sdkkey_invalid') { throw new GetidSdkTypes.GetIdSdkError( 'The provided SDK key is invalid', GetidSdkTypes.GeneralErrorCode.INVALID_SDK_KEY ); } token = app.token; } if (!token) { throw new GetidSdkTypes.GetIdSdkError( 'Something went wrong while initialising the SDK. Please try again.', GetidSdkTypes.GeneralErrorCode.UNKNOWN_ERROR ); } profile = normalizeProfile(profile); const configuration = await this.getConfig(apiUrl, token, flow, externalId); configuration.styles.theme = mergeStyles( configuration.styles.theme, styles ); const stepsConfigs = Object.fromEntries( configuration.flow.map((step: any) => [step.component, step]) ); return new GetIdSdk({ token, flow, apiUrl, acceptableDocuments, configuration, stepsConfigs, profile, externalId, }); } /** * Method to initialise Front Document Scan * * @param props The properties to initialise the Document Scan with. * * @returns A promise that resolves to the result of the initialisation. */ public initialiseFrontDocumentScan = (props: InitialiseDocumentScanProps) => { return initialiseFrontDocumentScan(props, this); }; /** * Method to initialise scan of a document's back side * * @param props The properties to initialise the Document Scan with. * * @returns A promise that resolves to the result of the initialisation. */ public initialiseBackDocumentScan = (props: InitialiseDocumentScanProps) => { return initialiseBackDocumentScan(props, this); }; /** * Method to initialise taking a selfie * * @param props The properties to initialise selfie capturing with. * * @returns A promise that resolves to the result of the initialisation. */ public initialiseSelfie = ( props: InitialiseSelfieProps ): Promise => { return initialiseSelfieScan(props, this); }; /** * Method to initialise liveness check * * @param props The properties to initialise liveness check with. * * @returns A promise that resolves to the result of the initialisation. */ public initialiseLivenessScan = ( props: InitialiseLivenessScanProps ): Promise => { return initialiseLivenessScan(props, this); }; /** * Abort method that can be called to abort the identification process and fully reset the SDK state. * This gracefully closes the camera stream and stops any active work in the SDK. */ public abort = async () => { Logger.log('Aborting process'); }; public submitForVerification = async ( props: GetidSdkTypes.SubmitForVerificationProps ) => { return submitForVerification({ ...props, sdk: this }); }; /** * @hidden */ addDocFile = (docFile: UploadDocFile) => { this.docFiles.push(docFile); }; /** * @hidden */ addSelfieFile = (selfieFile: UploadSelfieFile) => { this.selfieResult = selfieFile; }; /** * @hidden */ addPassiveLivenessInfo = (passiveLivenessResult: PassiveLivenessInfo) => { this.passiveLivenessResult = passiveLivenessResult; }; /** * @hidden */ addLivenessResult = (livenessResult: LivenessCommandSuccess) => { this.livenessResult = livenessResult; }; private static generateApplication = async ( sdkKey: string, apiUrl: string, customerId?: string ) => { const response = await fetch(apiUrl + '/sdk/v2/token', { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-sdk-key': sdkKey, 'x-sdk-version': version || '', 'x-sdk-platform': Platform.OS, }, body: JSON.stringify({ ...(customerId && { customerId: customerId }) }), }); return response.json(); }; /** * @hidden */ private static getConfig = async ( apiUrl: string, token: string, name: string, externalId?: string ): Promise => { const response = await fetch( apiUrl + '/sdk/v2/configuration?name=' + name, { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, 'x-sdk-platform': Platform.OS, 'x-created-by': 'react native', 'x-sdk-version': version || '', ...(externalId && { 'x-external-id': externalId }), }, } ); const data = await response.json(); return data; }; /** * @hidden */ sendLivenessEvent = async (livenessServerMessage: any) => this.tracking.trySendEvent('liveness', null, null, livenessServerMessage); } export { GetIdSdk, GetidSdkTypes };