From 7b47b8d28cdae7ed508286fa849f4b44bc4ba0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 10:01:41 -0300 Subject: [PATCH 01/43] feat: created `FaceProcessor` to android --- README.md | 3 +- .../com/capitual/processors/FaceConfig.java | 75 ++++++++++ .../capitual/processors/FaceProcessor.java | 137 ++++++++++++++++++ .../capitual/processors/KeyFaceProcessor.java | 7 + .../ReactNativeCapfaceSdkModule.java | 29 ++++ package-lock.json | 2 + src/constants/index.ts | 27 ++++ src/index.tsx | 34 +++++ src/types/index.ts | 74 ++++++++++ 9 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 android/src/main/java/com/capitual/processors/FaceConfig.java create mode 100644 android/src/main/java/com/capitual/processors/FaceProcessor.java create mode 100644 android/src/main/java/com/capitual/processors/KeyFaceProcessor.java create mode 100644 src/constants/index.ts diff --git a/README.md b/README.md index f61a90c..9374ad0 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,8 @@ import { ScrollView, NativeEventEmitter, } from 'react-native'; -import ReactNativeCapfaceSdk, { +import { + ReactNativeCapfaceSdk, authenticate, enroll, initialize, diff --git a/android/src/main/java/com/capitual/processors/FaceConfig.java b/android/src/main/java/com/capitual/processors/FaceConfig.java new file mode 100644 index 0000000..14af348 --- /dev/null +++ b/android/src/main/java/com/capitual/processors/FaceConfig.java @@ -0,0 +1,75 @@ +package com.capitual.processors; + +import com.capitual.processors.KeyFaceProcessor; + +import com.facebook.react.bridge.ReadableMap; + +import java.util.Map; + +public class FaceConfig { + private final Map config; + + public FaceConfig(ReadableMap config) { + this.config = config.toHashMap(); + } + + private boolean hasProperty(String key) { + if (this.config == null) { + return false; + } + + return this.config.isEmpty() || this.config.containsKey(key); + } + + private String getValue(String key) { + return this.hasProperty(key) ? this.config.get(key).toString() : null; + } + + public String getKey() { + if (this.hasProperty("key")) { + final String key = this.getValue("key"); + final boolean isAutheticate = key.equals(KeyFaceProcessor.authenticateMessage); + final boolean isEnroll = key.equals(KeyFaceProcessor.enrollMessage); + final boolean isLiveness = key.equals(KeyFaceProcessor.livenessMessage); + final boolean isValidKey = isAutheticate || isEnroll || isLiveness; + if (isValidKey) { + return key; + } + } + return null; + } + + public String getEndpoint() { + return this.hasProperty("endpoint") ? this.getValue("endpoint") : null; + } + + public String getSuccessMessage() { + final String key = this.getKey(); + if (key != null) { + final boolean isAutheticate = key.equals(KeyFaceProcessor.authenticateMessage); + final String defaultMessage = isAutheticate ? "Authenticated" : "Liveness\nConfirmed"; + if (this.hasProperty("successMessage")) { + return this.getValue("successMessage"); + } + } + return null; + } + + public boolean getHasExternalDatabaseRefID() { + final String key = this.getKey(); + if (key != null) { + final boolean isLiveness = key.equals(KeyFaceProcessor.livenessMessage); + if (isLiveness) { + return false; + } + if (this.hasProperty("hasExternalDatabaseRefID")) { + return this.getValue("hasExternalDatabaseRefID").equals("true"); + } + } + return false; + } + + public Map getParameters() { + return hasProperty("parameters") ? (Map) this.config.get("parameters") : null; + } +} diff --git a/android/src/main/java/com/capitual/processors/FaceProcessor.java b/android/src/main/java/com/capitual/processors/FaceProcessor.java new file mode 100644 index 0000000..b877453 --- /dev/null +++ b/android/src/main/java/com/capitual/processors/FaceProcessor.java @@ -0,0 +1,137 @@ +package com.capitual.processors; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.MediaType; +import okhttp3.RequestBody; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.util.Map; + +import com.capitual.processors.FaceConfig; +import com.capitual.processors.helpers.ThemeUtils; +import com.capitual.reactnativecapfacesdk.ReactNativeCapfaceSdkModule; +import com.facetec.sdk.*; + +public class FaceProcessor extends Processor implements FaceTecFaceScanProcessor { + private boolean success = false; + private final String key; + private final ReactNativeCapfaceSdkModule capFaceModule; + private final FaceConfig faceConfig; + private final ThemeUtils capThemeUtils = new ThemeUtils(); + + public FaceProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, + FaceConfig faceConfig) { + this.capFaceModule = capFaceModule; + this.faceConfig = faceConfig; + this.key = faceConfig.getKey(); + + capFaceModule.sendEvent("onCloseModal", true); + FaceTecSessionActivity.createAndLaunchSession(context, FaceProcessor.this, sessionToken); + } + + public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessionResult, + final FaceTecFaceScanResultCallback faceScanResultCallback) { + capFaceModule.setLatestSessionResult(sessionResult); + + if (sessionResult.getStatus() != FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) { + NetworkingHelpers.cancelPendingRequests(); + faceScanResultCallback.cancel(); + capFaceModule.sendEvent("onCloseModal", false); + capFaceModule.processorPromise.reject("The session status has not been completed!", "FaceTecDifferentStatus"); + return; + } + + JSONObject parameters = new JSONObject(); + try { + final Map extraParameters = this.faceConfig.getParameters(); + if (extraParameters != null) { + parameters.put("data", new JSONObject(extraParameters)); + } + parameters.put("faceScan", sessionResult.getFaceScanBase64()); + parameters.put("auditTrailImage", sessionResult.getAuditTrailCompressedBase64()[0]); + parameters.put("lowQualityAuditTrailImage", sessionResult.getLowQualityAuditTrailCompressedBase64()[0]); + + final boolean hasExternalDatabaseRefID = this.faceConfig.getHasExternalDatabaseRefID(); + if (hasExternalDatabaseRefID) { + parameters.put("externalDatabaseRefID", capFaceModule.getLatestExternalDatabaseRefID()); + } + } catch (JSONException e) { + e.printStackTrace(); + Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); + capFaceModule.sendEvent("onCloseModal", false); + capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", + "JSONError"); + } + + final String endpoint = this.faceConfig.getEndpoint(); + okhttp3.Request request = new okhttp3.Request.Builder() + .url(Config.BaseURL + endpoint) + .headers(Config.getHeaders("POST")) + .post(new ProgressRequestBody( + RequestBody.create(MediaType.parse("application/json; charset=utf-8"), parameters.toString()), + new ProgressRequestBody.Listener() { + @Override + public void onUploadProgressChanged(long bytesWritten, long totalBytes) { + final float uploadProgressPercent = ((float) bytesWritten) / ((float) totalBytes); + faceScanResultCallback.uploadProgress(uploadProgressPercent); + } + })) + .build(); + + NetworkingHelpers.getApiClient().newCall(request).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException { + String responseString = response.body().string(); + response.body().close(); + try { + JSONObject responseJSON = new JSONObject(responseString); + boolean wasProcessed = responseJSON.getBoolean("wasProcessed"); + String scanResultBlob = responseJSON.getString("scanResultBlob"); + + if (wasProcessed) { + final String message = faceConfig.getSuccessMessage(); + FaceTecCustomization.overrideResultScreenSuccessMessage = capThemeUtils + .handleMessage(key, "successMessage", message); + success = faceScanResultCallback.proceedToNextStep(scanResultBlob); + if (success) { + capFaceModule.processorPromise.resolve(true); + } + } else { + faceScanResultCallback.cancel(); + capFaceModule.sendEvent("onCloseModal", false); + capFaceModule.processorPromise.reject("FaceTec SDK wasn't have to values processed!", + "FaceTecWasntProcessed"); + } + } catch (JSONException e) { + e.printStackTrace(); + Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); + faceScanResultCallback.cancel(); + capFaceModule.sendEvent("onCloseModal", false); + capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", + "JSONError"); + } + } + + @Override + public void onFailure(@NonNull Call call, IOException e) { + Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); + faceScanResultCallback.cancel(); + capFaceModule.sendEvent("onCloseModal", false); + capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); + } + }); + } + + public boolean isSuccess() { + return this.success; + } +} diff --git a/android/src/main/java/com/capitual/processors/KeyFaceProcessor.java b/android/src/main/java/com/capitual/processors/KeyFaceProcessor.java new file mode 100644 index 0000000..419f871 --- /dev/null +++ b/android/src/main/java/com/capitual/processors/KeyFaceProcessor.java @@ -0,0 +1,7 @@ +package com.capitual.processors; + +public enum KeyFaceProcessor { + livenessMessage, + authenticateMessage, + enrollMessage, +} diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index 9d5be31..8950009 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -308,6 +308,35 @@ public void onSessionTokenReceived(String sessionToken) { }); } + @ReactMethod + public void handleFaceUser(ReadableMap config, Promise promise) { + setProcessorPromise(promise); + if (!isInitialized) { + Log.d("Capitual - SDK", "FaceTecSDK doesn't initialized!"); + this.processorPromise.reject("FaceTecSDK doesn't initialized!", "FaceTecDoenstInitialized"); + return; + } + + if (config == null) { + Log.d("Capitual - SDK", "No config provided!"); + this.processorPromise.reject("No configurations provided!", "NoConfigurationsProvided"); + return; + } + + isSessionPreparingToLaunch = true; + + getSessionToken(new SessionTokenCallback() { + @Override + public void onSessionTokenReceived(String sessionToken) { + resetLatestResults(); + isSessionPreparingToLaunch = false; + final FaceConfig faceConfig = new FaceConfig(config); + latestProcessor = new FaceProcessor(sessionToken, reactContext.getCurrentActivity(), + ReactNativeCapfaceSdkModule.this, faceConfig); + } + }); + } + @ReactMethod public void handleTheme(ReadableMap options) { ThemeHelpers.setAppTheme(options); diff --git a/package-lock.json b/package-lock.json index 89e9d0c..50c4209 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2238,6 +2238,7 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "optional": true, + "peer": true, "engines": { "node": ">=0.1.90" } @@ -8022,6 +8023,7 @@ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, + "peer": true, "dependencies": { "string-width": "^4.2.0" }, diff --git a/src/constants/index.ts b/src/constants/index.ts new file mode 100644 index 0000000..4372daf --- /dev/null +++ b/src/constants/index.ts @@ -0,0 +1,27 @@ +import type { CapfaceSdk } from '..'; + +export const NATIVE_CONSTANTS = ( + data?: Omit +): Record => ({ + authenticate: { + key: 'authenticateMessage', + hasExternalDatabaseRefID: true, + parameters: data?.parameters || null, + endpoint: data?.endpoint || '/match-3d-3d', + successMessage: data?.successMessage || 'Authenticated', + }, + enroll: { + key: 'enrollMessage', + hasExternalDatabaseRefID: true, + parameters: data?.parameters || null, + endpoint: data?.endpoint || '/enrollment-3d', + successMessage: data?.successMessage || 'Liveness\nConfirmed', + }, + liveness: { + key: 'livenessMessage', + hasExternalDatabaseRefID: false, + parameters: data?.parameters || null, + endpoint: data?.endpoint || '/liveness-3d', + successMessage: data?.successMessage || 'Liveness\nConfirmed', + }, +}); diff --git a/src/index.tsx b/src/index.tsx index ee563fd..60a5cc6 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,3 +1,4 @@ +import { NATIVE_CONSTANTS } from './constants'; import { CapfaceSdk, ReactNativeCapfaceSdk } from './types'; /** @@ -81,6 +82,39 @@ export async function authenticate(data?: Object): Promise { }); } +/** + * @description This method is called to make enrollment, authenticate and + * liveness available. + * + * @description This method makes a 3D reading of the user's face. But, you + * must use to **subscribe** user in Capface SDK or in your server. + * + * @description This method makes a 3D reading of the user's face. But, you + * must use to **authenticate** user in Capface SDK or in your server. + * + * @description This method makes a 3D reading of the user's face. + * + * @param {CapfaceSdk.MatchType} type - The type of flow to be called. + * @param {Omit|undefined} data - + * The object with data to be will send by headers on the requests. The data is + * optional. + * + * @return {Promise} Represents if flow was a successful. + * @throws If was a unsuccessful or occurred some interference. + */ +export async function faceMatch( + type: CapfaceSdk.MatchType, + data?: Omit +): Promise { + return await ReactNativeCapfaceSdk.handleFaceUser( + NATIVE_CONSTANTS(data)[type] + ) + .then((successful: boolean) => successful) + .catch((error: Error) => { + throw new Error(error.message); + }); +} + /** * @description This method must be used to **set** the **theme** of the Capface * SDK screen. diff --git a/src/types/index.ts b/src/types/index.ts index 6ac7496..4644fa5 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -798,6 +798,55 @@ export declare namespace CapfaceSdk { CapfaceScanWasntProcessed = 'CapfaceScanWasntProcessed', } + /** + * @type + * + * @description This is the type of face match. + */ + type MatchType = 'enroll' | 'liveness' | 'authenticate'; + + /** + * @type + * + * @description This is the type of face key. + */ + type MatchKey = 'enrollMessage' | 'livenessMessage' | 'authenticateMessage'; + + /** + * @interface MatchConfig + * + * @description There are all configurations from face match. + */ + interface MatchConfig { + /** + * @description The key to will be used to like identificator of the face match. + */ + key: MatchKey; + + /** + * @description If the face match has external database reference ID. + * It's optional. + */ + hasExternalDatabaseRefID: boolean; + + /** + * @description The endpoint to will be used to make requests. It's optional. + */ + endpoint?: string | null; + + /** + * @description The success message to will be used to show to user on the + * flow end. It's optional. + */ + successMessage?: string | null; + + /** + * @description The parameters to will be used to sent data by headers. + * It's optional. + */ + parameters?: Object | null; + } + /** * @interface Methods * @@ -859,6 +908,31 @@ export declare namespace CapfaceSdk { */ handleAuthenticateUser(data?: Object): Promise; + /** + * @description This method is called to make enrollment, authenticate and + * liveness available. + * + * @description This method makes a 3D reading of the user's face. But, you + * must use to **subscribe** user in Capface SDK or in your server. + * + * @description This method makes a 3D reading of the user's face. But, you + * must use to **authenticate** user in Capface SDK or in your server. + * + * @description This method makes a 3D reading of the user's face. + * + * @param {Omit|undefined} data - + * The object with data to be will send by headers on the requests. The data + * is optional. + * + * @return {Promise} Represents if flow was a successful. + * @throws If was a unsuccessful or occurred some interference. + */ + handleFaceUser( + data?: + | Omit + | undefined + ): Promise; + /** * @description This method must be used to **set** the **theme** of the * Capface SDK screen. From a8b34acdf6d7af98beb4c0274f8721c749c44574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 10:05:28 -0300 Subject: [PATCH 02/43] feat: added `uploadMessageIos` property to iOS --- src/constants/index.ts | 3 +++ src/types/index.ts | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/constants/index.ts b/src/constants/index.ts index 4372daf..81f9f60 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -9,6 +9,7 @@ export const NATIVE_CONSTANTS = ( parameters: data?.parameters || null, endpoint: data?.endpoint || '/match-3d-3d', successMessage: data?.successMessage || 'Authenticated', + uploadMessageIos: data?.uploadMessageIos || 'Still Uploading...', }, enroll: { key: 'enrollMessage', @@ -16,6 +17,7 @@ export const NATIVE_CONSTANTS = ( parameters: data?.parameters || null, endpoint: data?.endpoint || '/enrollment-3d', successMessage: data?.successMessage || 'Liveness\nConfirmed', + uploadMessageIos: data?.uploadMessageIos || 'Still Uploading...', }, liveness: { key: 'livenessMessage', @@ -23,5 +25,6 @@ export const NATIVE_CONSTANTS = ( parameters: data?.parameters || null, endpoint: data?.endpoint || '/liveness-3d', successMessage: data?.successMessage || 'Liveness\nConfirmed', + uploadMessageIos: data?.uploadMessageIos || 'Still Uploading...', }, }); diff --git a/src/types/index.ts b/src/types/index.ts index 4644fa5..1199b54 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -840,6 +840,12 @@ export declare namespace CapfaceSdk { */ successMessage?: string | null; + /** + * @description The upload message to will be used to show to user on loading + * flow. It's optional. + */ + uploadMessageIos?: string | null; + /** * @description The parameters to will be used to sent data by headers. * It's optional. From 3482f0197ff93f72620f35dfd033b7b727ca8c24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 10:11:32 -0300 Subject: [PATCH 03/43] fix: changed error messages and added more one send event on close modal in `FaceProcessor` --- .../main/java/com/capitual/processors/FaceProcessor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/FaceProcessor.java b/android/src/main/java/com/capitual/processors/FaceProcessor.java index b877453..0316751 100644 --- a/android/src/main/java/com/capitual/processors/FaceProcessor.java +++ b/android/src/main/java/com/capitual/processors/FaceProcessor.java @@ -46,7 +46,7 @@ public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessio NetworkingHelpers.cancelPendingRequests(); faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("The session status has not been completed!", "FaceTecDifferentStatus"); + capFaceModule.processorPromise.reject("The session status has not been completed!", "CapFaceInvalidSession"); return; } @@ -103,13 +103,14 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t .handleMessage(key, "successMessage", message); success = faceScanResultCallback.proceedToNextStep(scanResultBlob); if (success) { + capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.resolve(true); } } else { faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("FaceTec SDK wasn't have to values processed!", - "FaceTecWasntProcessed"); + capFaceModule.processorPromise.reject("CapFace SDK values were not processed!", + "CapFaceValuesWereNotProcessed"); } } catch (JSONException e) { e.printStackTrace(); From 6d35b518c85d8947010c793a79732743c4ceb33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 11:30:40 -0300 Subject: [PATCH 04/43] feat: removed `Processors`, upgraded types and documentation --- README.md | 140 ++++++++++-------- .../processors/AuthenticateProcessor.java | 129 ---------------- .../processors/EnrollmentProcessor.java | 129 ---------------- .../processors/LivenessCheckProcessor.java | 127 ---------------- .../ReactNativeCapfaceSdkModule.java | 81 +--------- example/src/App.tsx | 36 +++-- src/constants/index.ts | 2 +- src/index.tsx | 93 ++++-------- src/types/index.ts | 63 +++----- 9 files changed, 158 insertions(+), 642 deletions(-) delete mode 100644 android/src/main/java/com/capitual/processors/AuthenticateProcessor.java delete mode 100644 android/src/main/java/com/capitual/processors/EnrollmentProcessor.java delete mode 100644 android/src/main/java/com/capitual/processors/LivenessCheckProcessor.java diff --git a/README.md b/README.md index 9374ad0..ca43e00 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ Capface sdk adapter to react native. πŸ“± - [Usage](#usage) - [API](#api) - [`initialize(init: CapfaceSdk.Initialize)`](#initializeinit-capfacesdkinitialize) - - [`enroll(data?: Object)`](#enrolldata-capfacesdkdata) - - [`authenticate(data?: Object)`](#authenticatedata-capfacesdkdata) + - [`faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData)`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) - [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) - [`setTheme(options?: CapfaceSdk.Theme)`](#setthemeoptions-capfacesdktheme) - [Types](#types) @@ -21,6 +20,8 @@ Capface sdk adapter to react native. πŸ“± - [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) - [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) - [`CapfaceSdk.Errors`](#capfacesdkerrors) + - [`CapfaceSdk.MatchType`](#capfacesdkmatchtype) + - [`CapfaceSdk.MatchData`](#capfacesdkmatchdata) - [Native Events](#native-events) - [`Event Types`](#event-types) - [How to add images in CapfaceSDK module?](#how-to-add-images-in-capfacesdk-module) @@ -55,10 +56,10 @@ import { NativeEventEmitter, } from 'react-native'; import { + CapfaceSdk, ReactNativeCapfaceSdk, - authenticate, - enroll, initialize, + faceMatch, photoMatch, } from '@capitual/react-native-capface-sdk'; @@ -109,18 +110,12 @@ export default function App() { } }; - const onPressEnroll = async () => { + const onPressFaceMatch = async ( + type: CapfaceSdk.MatchType, + data?: CapfaceSdk.MatchData + ) => { try { - const isSuccess = await enroll(); - console.log(isSuccess); - } catch (error: any) { - console.error(error.message); - } - }; - - const onPressAuthenticate = async () => { - try { - const isSuccess = await authenticate(); + const isSuccess = await faceMatch(type, data); console.log(isSuccess); } catch (error: any) { console.error(error.message); @@ -130,21 +125,32 @@ export default function App() { return ( - await init()} - > + Init Capface Module Open Photo Match - + await onPressFaceMatch('enroll')} + > Open Enroll - + + await onPressFaceMatch('authenticate', { id: '123456' }) + } + > Open Authenticate + await onPressFaceMatch('liveness')} + > + Open Liveness + ); @@ -181,13 +187,12 @@ const styles = StyleSheet.create({ ## API -| Methods | Return Type | iOS | Android | -| --------------------------------------------------------------------------------- | ------------------ | --- | ------- | -| [`initialize(init: CapfaceSdk.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | -| [`enroll(data?: Object)`](#enrolldata-capfacesdkdata) | `Promise` | βœ… | βœ… | -| [`authenticate(data?: Object)`](#authenticatedata-capfacesdkdata) | `Promise` | βœ… | βœ… | -| [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) | `Promise` | βœ… | βœ… | -| [`setTheme(options?: CapfaceSdk.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | +| Methods | Return Type | iOS | Android | +| ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ | --- | ------- | +| [`initialize(init: CapfaceSdk.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | +| [`faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) | `Promise` | βœ… | βœ… | +| [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) | `Promise` | βœ… | βœ… | +| [`setTheme(options?: CapfaceSdk.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | ### `initialize(init: CapfaceSdk.Initialize)` @@ -198,29 +203,18 @@ This is the **principal** method to be called, he must be **called first** to in | `params` | [`CapfaceSdk.Params`](#capfacesdkparams) | βœ… | - | | `headers` | [`CapfaceSdk.Headers`](#capfacesdkheaders) | ❌ | `undefined` | -### `enroll(data?: Object)` +### `faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData)` -This method makes a 3D reading of the user's face. But, you must use to **subscribe** user in Capface SDK or in your server. +This method is called to make enrollment, authenticate and liveness available. The type is required and it must provided to select which flow you are interested. -| `Object` | type | Required | Default | -| -------- | -------- | -------- | ----------- | -| `data` | `Object` | ❌ | `undefined` | +- **Enrollment**: This method makes a 3D reading of the user's face. But, you must use to **subscribe** user in Capface SDK or in your server. +- **Authenticate**: This method makes a 3D reading of the user's face. But, you must use to **authenticate** user in Capface SDK or in your server. +- **Liveness**: This method makes a 3D reading of the user's face. -### `authenticate(data?: Object)` - -This method makes a 3D reading of the user's face. But, you must use to **authenticate** user in Capface SDK or in your server. - -| `Object` | type | Required | Default | -| -------- | -------- | -------- | ----------- | -| `data` | `Object` | ❌ | `undefined` | - -### `photoScan(data?: Object)` - -This method make to read from documents for user. - -| `Object` | type | Required | Default | -| -------- | -------- | -------- | ----------- | -| `data` | `Object` | ❌ | `undefined` | +| `Object` | type | Required | Default | +| -------- | ---------------------------------------------- | -------- | ----------- | +| `type` | [`CapfaceSdk.MatchType`](#capfacesdkmatchtype) | βœ… | - | +| `data` | [`CapfaceSdk.MatchData`](#capfacesdkmatchdata) | ❌ | `undefined` | ### `photoMatch(data?: Object)` @@ -252,7 +246,9 @@ This method must be used to **set** the **theme** of the Capface SDK screen. | [`CapfaceSdk.FeedbackBackgroundColor`](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | | [`CapfaceSdk.Point`](#capfacesdkpoint-ios-only) | βœ… | ❌ | | [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | -| [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | +| [`CapfaceSdk.Errors`](#capfacesdkerrors) | βœ… | βœ… | +| [`CapfaceSdk.MatchType`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | +| [`CapfaceSdk.MatchData`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | ### `CapfaceSdk.Params` @@ -424,15 +420,39 @@ This interface represents the all scan messages during to CapfaceSDK flow. It in ### `CapfaceSdk.Errors` -| `CapfaceSdk.Errors` | Description | iOS | Android | -| ------------------------------- | ------------------------------------------------------------------------------------ | --- | ------- | -| `CapFaceHasNotBeenInitialized` | When some processors method is runned, but CapfaceSDK **has not been initialized**. | βœ… | βœ… | -| `CapFaceValuesWereNotProcessed` | When the image sent to the processors cannot be processed due to inconsistency. | βœ… | βœ… | -| `HTTPSError` | When exists some network error. | βœ… | βœ… | -| `JSONError` | When exists some problem in getting data in request of **base URL** information. | ❌ | βœ… | -| `CapFaceInvalidSession` | When session status is invalid. | ❌ | βœ… | -| `CapFaceLivenessWasntProcessed` | When the image user sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | -| `CapFaceScanWasntProcessed` | When the image ID sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | +This enum represents all errors that are encountered on the CapFace SDK. + +| `CapfaceSdk.Errors` | Description | iOS | Android | +| ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --- | ------- | +| `CapFaceHasNotBeenInitialized` | When some processors method is runned, but CapfaceSDK **has not been initialized**. | βœ… | βœ… | +| `CapFaceValuesWereNotProcessed` | When the image sent to the processors cannot be processed due to inconsistency. | βœ… | βœ… | +| `HTTPSError` | When exists some network error. | βœ… | βœ… | +| `NoConfigurationsProvided` | When the configurations [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) doesn't provided. | βœ… | βœ… | +| `JSONError` | When exists some problem in getting data in request of **base URL** information. | ❌ | βœ… | +| `CapFaceInvalidSession` | When session status is invalid. | ❌ | βœ… | +| `CapFaceLivenessWasntProcessed` | When the image user sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | +| `CapFaceScanWasntProcessed` | When the image ID sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | + +### `CapfaceSdk.MatchType` + +This enum represents all the possible types of flow that can be used on the [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) method. + +| `CapfaceSdk.MatchType` | Description | iOS | Android | +| ---------------------- | ---------------------------------------- | --- | ------- | +| `authenticate` | When you want to make authenticate flow. | βœ… | βœ… | +| `enroll` | When you want to make enroll flow. | βœ… | βœ… | +| `liveness` | When you want to make liveness flow. | βœ… | βœ… | + +### `CapfaceSdk.MatchData` + +The object with properties that will be sent to native modules to make the requests, change text labels and sent parameters via headers. + +| `CapfaceSdk.MatchData` | type | iOS | Android | Required | Default | +| ---------------------- | ------------------ | --- | ------- | -------- | --------------------------------------------------------------------------------------- | +| `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enroll and liveness) | +| `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | +| `successMessage` | `string` or `null` | βœ… | βœ… | ❌ | `/match-3d-3d` (authenticate) or `/enrollment-3d` (enroll) or `/liveness-3d` (liveness) | +| `uploadMessageIos` | `string` or `null` | βœ… | βœ… | ❌ | `Still Uploading...` |
@@ -473,7 +493,7 @@ import React, { useEffect } from 'react'; import { View, TouchableOpacity, Text } from 'react-native'; import { initialize, - enroll, + faceMatch, setTheme, } from '@capitual/react-native-capface-sdk'; @@ -516,7 +536,7 @@ export default function App() { }} onPress={async () => { try { - const isSuccess = await enroll(); + const isSuccess = await faceMatch('enroll'); console.log(isSuccess); } catch (error: any) { console.error(error); diff --git a/android/src/main/java/com/capitual/processors/AuthenticateProcessor.java b/android/src/main/java/com/capitual/processors/AuthenticateProcessor.java deleted file mode 100644 index aa6db7f..0000000 --- a/android/src/main/java/com/capitual/processors/AuthenticateProcessor.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.capitual.processors; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.MediaType; -import okhttp3.RequestBody; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; - -import com.capitual.processors.helpers.ThemeUtils; -import com.capitual.reactnativecapfacesdk.ReactNativeCapfaceSdkModule; -import com.facebook.react.bridge.ReadableMap; -import com.facetec.sdk.*; - -public class AuthenticateProcessor extends Processor implements FaceTecFaceScanProcessor { - private boolean success = false; - private final String principalKey = "authenticateMessage"; - private final ReactNativeCapfaceSdkModule capFaceModule; - private final ReadableMap data; - private final ThemeUtils capThemeUtils = new ThemeUtils(); - - public AuthenticateProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, - ReadableMap data) { - this.capFaceModule = capFaceModule; - this.data = data; - - capFaceModule.sendEvent("onCloseModal", true); - FaceTecSessionActivity.createAndLaunchSession(context, AuthenticateProcessor.this, sessionToken); - } - - public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessionResult, - final FaceTecFaceScanResultCallback faceScanResultCallback) { - capFaceModule.setLatestSessionResult(sessionResult); - - if (sessionResult.getStatus() != FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) { - NetworkingHelpers.cancelPendingRequests(); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("The session status has not been completed!", "CapFaceInvalidSession"); - return; - } - - JSONObject parameters = new JSONObject(); - try { - if (this.data != null) { - parameters.put("data", new JSONObject(this.data.toHashMap())); - } - parameters.put("faceScan", sessionResult.getFaceScanBase64()); - parameters.put("auditTrailImage", sessionResult.getAuditTrailCompressedBase64()[0]); - parameters.put("lowQualityAuditTrailImage", sessionResult.getLowQualityAuditTrailCompressedBase64()[0]); - parameters.put("externalDatabaseRefID", capFaceModule.getLatestExternalDatabaseRefID()); - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", - "JSONError"); - } - - okhttp3.Request request = new okhttp3.Request.Builder() - .url(Config.BaseURL + "/match-3d-3d") - .headers(Config.getHeaders("POST")) - .post(new ProgressRequestBody( - RequestBody.create(MediaType.parse("application/json; charset=utf-8"), parameters.toString()), - new ProgressRequestBody.Listener() { - @Override - public void onUploadProgressChanged(long bytesWritten, long totalBytes) { - final float uploadProgressPercent = ((float) bytesWritten) / ((float) totalBytes); - faceScanResultCallback.uploadProgress(uploadProgressPercent); - } - })) - .build(); - - NetworkingHelpers.getApiClient().newCall(request).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException { - String responseString = response.body().string(); - response.body().close(); - try { - JSONObject responseJSON = new JSONObject(responseString); - boolean wasProcessed = responseJSON.getBoolean("wasProcessed"); - String scanResultBlob = responseJSON.getString("scanResultBlob"); - - if (wasProcessed) { - FaceTecCustomization.overrideResultScreenSuccessMessage = capThemeUtils - .handleMessage(principalKey, "successMessage", "Authenticated"); - success = faceScanResultCallback.proceedToNextStep(scanResultBlob); - if (success) { - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.resolve(true); - } - } else { - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("CapFace SDK values were not processed!", - "CapFaceValuesWereNotProcessed"); - } - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); - } - } - - @Override - public void onFailure(@NonNull Call call, IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); - } - }); - } - - public boolean isSuccess() { - return this.success; - } -} diff --git a/android/src/main/java/com/capitual/processors/EnrollmentProcessor.java b/android/src/main/java/com/capitual/processors/EnrollmentProcessor.java deleted file mode 100644 index aa80e55..0000000 --- a/android/src/main/java/com/capitual/processors/EnrollmentProcessor.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.capitual.processors; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.MediaType; -import okhttp3.RequestBody; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; - -import com.capitual.processors.helpers.ThemeUtils; -import com.capitual.reactnativecapfacesdk.ReactNativeCapfaceSdkModule; -import com.facebook.react.bridge.ReadableMap; -import com.facetec.sdk.*; - -public class EnrollmentProcessor extends Processor implements FaceTecFaceScanProcessor { - private boolean success = false; - private final String principalKey = "enrollMessage"; - private final ReactNativeCapfaceSdkModule capFaceModule; - private final ReadableMap data; - private final ThemeUtils capThemeUtils = new ThemeUtils(); - - public EnrollmentProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, - ReadableMap data) { - this.capFaceModule = capFaceModule; - this.data = data; - - capFaceModule.sendEvent("onCloseModal", true); - FaceTecSessionActivity.createAndLaunchSession(context, EnrollmentProcessor.this, sessionToken); - } - - public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessionResult, - final FaceTecFaceScanResultCallback faceScanResultCallback) { - capFaceModule.setLatestSessionResult(sessionResult); - - if (sessionResult.getStatus() != FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) { - NetworkingHelpers.cancelPendingRequests(); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("The session status has not been completed!", "CapFaceInvalidSession"); - return; - } - - JSONObject parameters = new JSONObject(); - try { - if (this.data != null) { - parameters.put("data", new JSONObject(this.data.toHashMap())); - } - parameters.put("faceScan", sessionResult.getFaceScanBase64()); - parameters.put("auditTrailImage", sessionResult.getAuditTrailCompressedBase64()[0]); - parameters.put("lowQualityAuditTrailImage", sessionResult.getLowQualityAuditTrailCompressedBase64()[0]); - parameters.put("externalDatabaseRefID", capFaceModule.getLatestExternalDatabaseRefID()); - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", - "JSONError"); - } - - okhttp3.Request request = new okhttp3.Request.Builder() - .url(Config.BaseURL + "/enrollment-3d") - .headers(Config.getHeaders("POST")) - .post(new ProgressRequestBody( - RequestBody.create(MediaType.parse("application/json; charset=utf-8"), parameters.toString()), - new ProgressRequestBody.Listener() { - @Override - public void onUploadProgressChanged(long bytesWritten, long totalBytes) { - final float uploadProgressPercent = ((float) bytesWritten) / ((float) totalBytes); - faceScanResultCallback.uploadProgress(uploadProgressPercent); - } - })) - .build(); - - NetworkingHelpers.getApiClient().newCall(request).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException { - String responseString = response.body().string(); - response.body().close(); - try { - JSONObject responseJSON = new JSONObject(responseString); - boolean wasProcessed = responseJSON.getBoolean("wasProcessed"); - String scanResultBlob = responseJSON.getString("scanResultBlob"); - - if (wasProcessed) { - FaceTecCustomization.overrideResultScreenSuccessMessage = capThemeUtils.handleMessage(principalKey, - "successMessage", "Liveness\nConfirmed"); - success = faceScanResultCallback.proceedToNextStep(scanResultBlob); - if (success) { - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.resolve(true); - } - } else { - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("CapFace SDK values were not processed!", - "CapFaceValuesWereNotProcessed"); - } - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); - } - } - - @Override - public void onFailure(@NonNull Call call, IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); - } - }); - } - - public boolean isSuccess() { - return this.success; - } -} diff --git a/android/src/main/java/com/capitual/processors/LivenessCheckProcessor.java b/android/src/main/java/com/capitual/processors/LivenessCheckProcessor.java deleted file mode 100644 index 1ced138..0000000 --- a/android/src/main/java/com/capitual/processors/LivenessCheckProcessor.java +++ /dev/null @@ -1,127 +0,0 @@ -package com.capitual.processors; - -import android.content.Context; -import android.util.Log; - -import androidx.annotation.NonNull; - -import okhttp3.Call; -import okhttp3.Callback; -import okhttp3.MediaType; -import okhttp3.RequestBody; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; - -import com.capitual.processors.helpers.ThemeUtils; -import com.capitual.reactnativecapfacesdk.ReactNativeCapfaceSdkModule; -import com.facebook.react.bridge.ReadableMap; -import com.facetec.sdk.*; - -public class LivenessCheckProcessor extends Processor implements FaceTecFaceScanProcessor { - private boolean success = false; - private final String principalKey = "livenessMessage"; - private final ReactNativeCapfaceSdkModule capFaceModule; - private final ReadableMap data; - private final ThemeUtils capThemeUtils = new ThemeUtils(); - - public LivenessCheckProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, - ReadableMap data) { - this.capFaceModule = capFaceModule; - this.data = data; - - capFaceModule.sendEvent("onCloseModal", true); - FaceTecSessionActivity.createAndLaunchSession(context, LivenessCheckProcessor.this, sessionToken); - } - - public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessionResult, - final FaceTecFaceScanResultCallback faceScanResultCallback) { - capFaceModule.setLatestSessionResult(sessionResult); - - if (sessionResult.getStatus() != FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) { - NetworkingHelpers.cancelPendingRequests(); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("The session status has not been completed!", "CapFaceInvalidSession"); - return; - } - - JSONObject parameters = new JSONObject(); - try { - if (this.data != null) { - parameters.put("data", new JSONObject(this.data.toHashMap())); - } - parameters.put("faceScan", sessionResult.getFaceScanBase64()); - parameters.put("auditTrailImage", sessionResult.getAuditTrailCompressedBase64()[0]); - parameters.put("lowQualityAuditTrailImage", sessionResult.getLowQualityAuditTrailCompressedBase64()[0]); - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", - "JSONError"); - } - - okhttp3.Request request = new okhttp3.Request.Builder() - .url(Config.BaseURL + "/liveness-3d") - .headers(Config.getHeaders("POST")) - .post(new ProgressRequestBody( - RequestBody.create(MediaType.parse("application/json; charset=utf-8"), parameters.toString()), - new ProgressRequestBody.Listener() { - @Override - public void onUploadProgressChanged(long bytesWritten, long totalBytes) { - final float uploadProgressPercent = ((float) bytesWritten) / ((float) totalBytes); - faceScanResultCallback.uploadProgress(uploadProgressPercent); - } - })) - .build(); - - NetworkingHelpers.getApiClient().newCall(request).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException { - String responseString = response.body().string(); - response.body().close(); - try { - JSONObject responseJSON = new JSONObject(responseString); - boolean wasProcessed = responseJSON.getBoolean("wasProcessed"); - String scanResultBlob = responseJSON.getString("scanResultBlob"); - if (wasProcessed) { - FaceTecCustomization.overrideResultScreenSuccessMessage = capThemeUtils.handleMessage(principalKey, - "successMessage", "Liveness\nConfirmed"); - success = faceScanResultCallback.proceedToNextStep(scanResultBlob); - if (success) { - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.resolve(true); - } - } else { - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("CapFace SDK values were not processed!", - "CapFaceValuesWereNotProcessed"); - } - } catch (JSONException e) { - e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); - } - } - - @Override - public void onFailure(@NonNull Call call, IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); - faceScanResultCallback.cancel(); - capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); - } - }); - } - - public boolean isSuccess() { - return this.success; - } -} diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index 8950009..6f9cbdd 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -197,29 +197,7 @@ public void removeListeners(Integer count) { } @ReactMethod - public void handleLivenessCheck(ReadableMap data, Promise promise) { - setProcessorPromise(promise); - if (!isInitialized) { - Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); - this.processorPromise.reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized"); - return; - } - - isSessionPreparingToLaunch = true; - - getSessionToken(new SessionTokenCallback() { - @Override - public void onSessionTokenReceived(String sessionToken) { - resetLatestResults(); - isSessionPreparingToLaunch = false; - latestProcessor = new LivenessCheckProcessor(sessionToken, reactContext.getCurrentActivity(), - ReactNativeCapfaceSdkModule.this, data); - } - }); - } - - @ReactMethod - public void handleEnrollUser(ReadableMap data, Promise promise) { + public void handleFaceUser(ReadableMap config, Promise promise) { setProcessorPromise(promise); if (!isInitialized) { Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); @@ -227,26 +205,9 @@ public void handleEnrollUser(ReadableMap data, Promise promise) { return; } - isSessionPreparingToLaunch = true; - - getSessionToken(new SessionTokenCallback() { - @Override - public void onSessionTokenReceived(String sessionToken) { - resetLatestResults(); - isSessionPreparingToLaunch = false; - setLatestExternalDatabaseRefID("android_capitual_app_" + randomUUID()); - latestProcessor = new EnrollmentProcessor(sessionToken, reactContext.getCurrentActivity(), - ReactNativeCapfaceSdkModule.this, data); - } - }); - } - - @ReactMethod - public void handleAuthenticateUser(ReadableMap data, Promise promise) { - setProcessorPromise(promise); - if (!isInitialized) { - Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); - this.processorPromise.reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized"); + if (config == null) { + Log.d("Capitual - SDK", "No configurations provided!"); + this.processorPromise.reject("No configurations provided!", "NoConfigurationsProvided"); return; } @@ -257,8 +218,9 @@ public void handleAuthenticateUser(ReadableMap data, Promise promise) { public void onSessionTokenReceived(String sessionToken) { resetLatestResults(); isSessionPreparingToLaunch = false; - latestProcessor = new AuthenticateProcessor(sessionToken, reactContext.getCurrentActivity(), - ReactNativeCapfaceSdkModule.this, data); + final FaceConfig faceConfig = new FaceConfig(config); + latestProcessor = new FaceProcessor(sessionToken, reactContext.getCurrentActivity(), + ReactNativeCapfaceSdkModule.this, faceConfig); } }); } @@ -308,35 +270,6 @@ public void onSessionTokenReceived(String sessionToken) { }); } - @ReactMethod - public void handleFaceUser(ReadableMap config, Promise promise) { - setProcessorPromise(promise); - if (!isInitialized) { - Log.d("Capitual - SDK", "FaceTecSDK doesn't initialized!"); - this.processorPromise.reject("FaceTecSDK doesn't initialized!", "FaceTecDoenstInitialized"); - return; - } - - if (config == null) { - Log.d("Capitual - SDK", "No config provided!"); - this.processorPromise.reject("No configurations provided!", "NoConfigurationsProvided"); - return; - } - - isSessionPreparingToLaunch = true; - - getSessionToken(new SessionTokenCallback() { - @Override - public void onSessionTokenReceived(String sessionToken) { - resetLatestResults(); - isSessionPreparingToLaunch = false; - final FaceConfig faceConfig = new FaceConfig(config); - latestProcessor = new FaceProcessor(sessionToken, reactContext.getCurrentActivity(), - ReactNativeCapfaceSdkModule.this, faceConfig); - } - }); - } - @ReactMethod public void handleTheme(ReadableMap options) { ThemeHelpers.setAppTheme(options); diff --git a/example/src/App.tsx b/example/src/App.tsx index 03b67d3..71b32a1 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -10,9 +10,9 @@ import { } from 'react-native'; import { ReactNativeCapfaceSdk, - authenticate, - enroll, + CapfaceSdk, initialize, + faceMatch, photoMatch, } from '@capitual/react-native-capface-sdk'; @@ -63,18 +63,12 @@ export default function App() { } }; - const onPressEnroll = async () => { + const onPressFaceMatch = async ( + type: CapfaceSdk.MatchType, + data?: CapfaceSdk.MatchData + ) => { try { - const isSuccess = await enroll(); - console.log(isSuccess); - } catch (error: any) { - console.error(error.message); - } - }; - - const onPressAuthenticate = async () => { - try { - const isSuccess = await authenticate(); + const isSuccess = await faceMatch(type, data); console.log(isSuccess); } catch (error: any) { console.error(error.message); @@ -90,12 +84,24 @@ export default function App() { Open Photo Match - + await onPressFaceMatch('enroll', {})} + > Open Enroll - + await onPressFaceMatch('authenticate', {})} + > Open Authenticate + await onPressFaceMatch('liveness', {})} + > + Open Liveness + ); diff --git a/src/constants/index.ts b/src/constants/index.ts index 81f9f60..9028f78 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,7 +1,7 @@ import type { CapfaceSdk } from '..'; export const NATIVE_CONSTANTS = ( - data?: Omit + data?: CapfaceSdk.MatchData ): Record => ({ authenticate: { key: 'authenticateMessage', diff --git a/src/index.tsx b/src/index.tsx index 60a5cc6..b8d5566 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -29,35 +29,29 @@ export function initialize({ } /** - * @description This method make to read from face and documents for user, - * after comparate face and face documents from user to check veracity. - * - * @param {Object|undefined} data - The object with data to be will send on - * photo ID match. The data is optional. - * - * @return {Promise} Represents if photo match was a successful. - * @throws If photo ID match was a unsuccessful or occurred some interference. - */ -export async function photoMatch(data?: Object): Promise { - return await ReactNativeCapfaceSdk.handlePhotoIDMatch(data) - .then((successful: boolean) => successful) - .catch((error: Error) => { - throw new Error(error.message); - }); -} - -/** - * @description This method makes a 3D reading of the user's face. But, you must - * use to **subscribe** user in Capface SDK or in your server. + * @description This method is called to make enrollment, authenticate and + * liveness available. The **enrollment method** makes a 3D reading of the + * user's face. But, you must use to **subscribe** user in Capface SDK or in + * your server. The **authenticate method** makes a 3D reading of the user's + * face. But, you must use to **authenticate** user in Capface SDK or in + * your server. Finally, the **liveness** method makes a 3D reading of the + * user's face. * - * @param {Object|undefined} data - The object with data to be will send on - * enrollment. The data is optional. + * @param {CapfaceSdk.MatchType} type - The type of flow to be called. + * @param {CapfaceSdk.MatchData|undefined} data - The object with properties + * that will be sent to native modules to make the requests, change text labels + * and sent parameters via headers. * - * @return {Promise} Represents if enrollment was a successful. - * @throws If enrollment was a unsuccessful or occurred some interference. + * @return {Promise} Represents if flow was a successful. + * @throws If was a unsuccessful or occurred some interference. */ -export async function enroll(data?: Object): Promise { - return await ReactNativeCapfaceSdk.handleEnrollUser(data) +export async function faceMatch( + type: CapfaceSdk.MatchType, + data?: CapfaceSdk.MatchData +): Promise { + return await ReactNativeCapfaceSdk.handleFaceUser( + NATIVE_CONSTANTS(data)[type] + ) .then((successful: boolean) => successful) .catch((error: Error) => { throw new Error(error.message); @@ -65,50 +59,17 @@ export async function enroll(data?: Object): Promise { } /** - * @description This method makes a 3D reading of the user's face. But, you must - * use to **authenticate** user in Capface SDK or in your server. + * @description This method make to read from face and documents for user, + * after comparate face and face documents from user to check veracity. * * @param {Object|undefined} data - The object with data to be will send on - * authentication. The data is optional. - * - * @return {Promise} Represents if authentication was a successful. - * @throws If authenticate was a unsuccessful or occurred some interference. - */ -export async function authenticate(data?: Object): Promise { - return await ReactNativeCapfaceSdk.handleAuthenticateUser(data) - .then((successful: boolean) => successful) - .catch((error: Error) => { - throw new Error(error.message); - }); -} - -/** - * @description This method is called to make enrollment, authenticate and - * liveness available. - * - * @description This method makes a 3D reading of the user's face. But, you - * must use to **subscribe** user in Capface SDK or in your server. - * - * @description This method makes a 3D reading of the user's face. But, you - * must use to **authenticate** user in Capface SDK or in your server. - * - * @description This method makes a 3D reading of the user's face. - * - * @param {CapfaceSdk.MatchType} type - The type of flow to be called. - * @param {Omit|undefined} data - - * The object with data to be will send by headers on the requests. The data is - * optional. + * photo ID match. The data is optional. * - * @return {Promise} Represents if flow was a successful. - * @throws If was a unsuccessful or occurred some interference. + * @return {Promise} Represents if photo match was a successful. + * @throws If photo ID match was a unsuccessful or occurred some interference. */ -export async function faceMatch( - type: CapfaceSdk.MatchType, - data?: Omit -): Promise { - return await ReactNativeCapfaceSdk.handleFaceUser( - NATIVE_CONSTANTS(data)[type] - ) +export async function photoMatch(data?: Object): Promise { + return await ReactNativeCapfaceSdk.handlePhotoIDMatch(data) .then((successful: boolean) => successful) .catch((error: Error) => { throw new Error(error.message); diff --git a/src/types/index.ts b/src/types/index.ts index 1199b54..a23e7e8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -774,6 +774,11 @@ export declare namespace CapfaceSdk { */ HTTPSError = 'HTTPSError', + /** + * @description When the configurations doesn't provided to **faceMatch**. + */ + NoConfigurationsProvided = 'NoConfigurationsProvided', + /** * @description When exists some problem in getting data in request of * **base URL** information. Only Android. @@ -853,6 +858,14 @@ export declare namespace CapfaceSdk { parameters?: Object | null; } + /** + * @type + * + * @description The object with properties that will be sent to native modules + * to make the requests, change text labels and sent parameters via headers. + */ + type MatchData = Omit; + /** * @interface Methods * @@ -890,54 +903,22 @@ export declare namespace CapfaceSdk { */ handlePhotoIDMatch(data?: Object): Promise; - /** - * @description This method makes a 3D reading of the user's face. But, you - * must use to **subscribe** user in Capface SDK or in your server. - * - * @param {Object|undefined} data - The object with data to be will send on - * enrollment. The data is optional. - * - * @return {Promise} Represents if enrollment was a successful. - * @throws If enrollment was a unsuccessful or occurred some interference. - */ - handleEnrollUser(data?: Object): Promise; - - /** - * @description This method makes a 3D reading of the user's face. But, you - * must use to **authenticate** user in Capface SDK or in your server. - * - * @param {Object|undefined} data - The object with data to be will send on - * authentication. The data is optional. - * - * @return {Promise} Represents if authentication was a successful. - * @throws If authenticate was a unsuccessful or occurred some interference. - */ - handleAuthenticateUser(data?: Object): Promise; - /** * @description This method is called to make enrollment, authenticate and - * liveness available. - * - * @description This method makes a 3D reading of the user's face. But, you - * must use to **subscribe** user in Capface SDK or in your server. + * liveness available. The **enrollment method** makes a 3D reading of the + * user's face. But, you must use to **subscribe** user in Capface SDK or in + * your server. The **authenticate method** makes a 3D reading of the user's + * face. But, you must use to **authenticate** user in Capface SDK or in + * your server. Finally, the **liveness** method makes a 3D reading of the + * user's face. * - * @description This method makes a 3D reading of the user's face. But, you - * must use to **authenticate** user in Capface SDK or in your server. - * - * @description This method makes a 3D reading of the user's face. - * - * @param {Omit|undefined} data - - * The object with data to be will send by headers on the requests. The data - * is optional. + * @param {CapfaceSdk.MatchData|undefined} data - The object with data to + * be will send by headers on the requests. The data is optional. * * @return {Promise} Represents if flow was a successful. * @throws If was a unsuccessful or occurred some interference. */ - handleFaceUser( - data?: - | Omit - | undefined - ): Promise; + handleFaceUser(data?: CapfaceSdk.MatchData | undefined): Promise; /** * @description This method must be used to **set** the **theme** of the From 75bd3fb35b286581edb1cd7e0ee908d754cba973 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 11:51:30 -0300 Subject: [PATCH 05/43] fix: small adjusts on `hasProperty` method when map contains no key-value mappings --- android/src/main/java/com/capitual/processors/FaceConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/src/main/java/com/capitual/processors/FaceConfig.java b/android/src/main/java/com/capitual/processors/FaceConfig.java index 14af348..4b4a8cb 100644 --- a/android/src/main/java/com/capitual/processors/FaceConfig.java +++ b/android/src/main/java/com/capitual/processors/FaceConfig.java @@ -18,7 +18,7 @@ private boolean hasProperty(String key) { return false; } - return this.config.isEmpty() || this.config.containsKey(key); + return !this.config.isEmpty() || this.config.containsKey(key); } private String getValue(String key) { From 45d3384d65d6939d0ccf59e0fafb2738221399ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 14:17:11 -0300 Subject: [PATCH 06/43] fix: small adjusts in compare enum and key value that returned `false` --- .../com/capitual/processors/FaceConfig.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/FaceConfig.java b/android/src/main/java/com/capitual/processors/FaceConfig.java index 4b4a8cb..214feaf 100644 --- a/android/src/main/java/com/capitual/processors/FaceConfig.java +++ b/android/src/main/java/com/capitual/processors/FaceConfig.java @@ -25,13 +25,17 @@ private String getValue(String key) { return this.hasProperty(key) ? this.config.get(key).toString() : null; } + private boolean isWhichFlow(KeyFaceProcessor keyFlow, String key) { + return keyFlow.toString().equalsIgnoreCase(key); + } + public String getKey() { if (this.hasProperty("key")) { final String key = this.getValue("key"); - final boolean isAutheticate = key.equals(KeyFaceProcessor.authenticateMessage); - final boolean isEnroll = key.equals(KeyFaceProcessor.enrollMessage); - final boolean isLiveness = key.equals(KeyFaceProcessor.livenessMessage); - final boolean isValidKey = isAutheticate || isEnroll || isLiveness; + final boolean isAuthenticate = this.isWhichFlow(KeyFaceProcessor.authenticateMessage, key); + final boolean isEnroll = this.isWhichFlow(KeyFaceProcessor.enrollMessage, key); + final boolean isLiveness = this.isWhichFlow(KeyFaceProcessor.livenessMessage, key); + final boolean isValidKey = isAuthenticate || isEnroll || isLiveness; if (isValidKey) { return key; } @@ -46,8 +50,8 @@ public String getEndpoint() { public String getSuccessMessage() { final String key = this.getKey(); if (key != null) { - final boolean isAutheticate = key.equals(KeyFaceProcessor.authenticateMessage); - final String defaultMessage = isAutheticate ? "Authenticated" : "Liveness\nConfirmed"; + final boolean isAuthenticate = this.isWhichFlow(KeyFaceProcessor.authenticateMessage, key); + final String defaultMessage = isAuthenticate ? "Authenticated" : "Liveness\nConfirmed"; if (this.hasProperty("successMessage")) { return this.getValue("successMessage"); } @@ -58,12 +62,12 @@ public String getSuccessMessage() { public boolean getHasExternalDatabaseRefID() { final String key = this.getKey(); if (key != null) { - final boolean isLiveness = key.equals(KeyFaceProcessor.livenessMessage); + final boolean isLiveness = this.isWhichFlow(KeyFaceProcessor.livenessMessage, key); if (isLiveness) { return false; } if (this.hasProperty("hasExternalDatabaseRefID")) { - return this.getValue("hasExternalDatabaseRefID").equals("true"); + return this.getValue("hasExternalDatabaseRefID").equalsIgnoreCase("true"); } } return false; From f1bd9c2810103d1f67fd0544f17786d464294f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 14:53:31 -0300 Subject: [PATCH 07/43] fix: added if conditional to check if is flow enroll to set external database ref id --- .../src/main/java/com/capitual/processors/FaceConfig.java | 5 +++-- .../src/main/java/com/capitual/processors/FaceProcessor.java | 1 - .../reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/FaceConfig.java b/android/src/main/java/com/capitual/processors/FaceConfig.java index 214feaf..1ad383e 100644 --- a/android/src/main/java/com/capitual/processors/FaceConfig.java +++ b/android/src/main/java/com/capitual/processors/FaceConfig.java @@ -1,6 +1,6 @@ package com.capitual.processors; -import com.capitual.processors.KeyFaceProcessor; +import androidx.annotation.NonNull; import com.facebook.react.bridge.ReadableMap; @@ -25,7 +25,7 @@ private String getValue(String key) { return this.hasProperty(key) ? this.config.get(key).toString() : null; } - private boolean isWhichFlow(KeyFaceProcessor keyFlow, String key) { + public boolean isWhichFlow(@NonNull KeyFaceProcessor keyFlow, String key) { return keyFlow.toString().equalsIgnoreCase(key); } @@ -55,6 +55,7 @@ public String getSuccessMessage() { if (this.hasProperty("successMessage")) { return this.getValue("successMessage"); } + return defaultMessage; } return null; } diff --git a/android/src/main/java/com/capitual/processors/FaceProcessor.java b/android/src/main/java/com/capitual/processors/FaceProcessor.java index 0316751..e5f88ff 100644 --- a/android/src/main/java/com/capitual/processors/FaceProcessor.java +++ b/android/src/main/java/com/capitual/processors/FaceProcessor.java @@ -16,7 +16,6 @@ import java.io.IOException; import java.util.Map; -import com.capitual.processors.FaceConfig; import com.capitual.processors.helpers.ThemeUtils; import com.capitual.reactnativecapfacesdk.ReactNativeCapfaceSdkModule; import com.facetec.sdk.*; diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index 6f9cbdd..91f71d2 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -219,6 +219,9 @@ public void onSessionTokenReceived(String sessionToken) { resetLatestResults(); isSessionPreparingToLaunch = false; final FaceConfig faceConfig = new FaceConfig(config); + if (faceConfig.isWhichFlow(KeyFaceProcessor.enrollMessage, faceConfig.getKey())) { + setLatestExternalDatabaseRefID("android_app_" + randomUUID()); + } latestProcessor = new FaceProcessor(sessionToken, reactContext.getCurrentActivity(), ReactNativeCapfaceSdkModule.this, faceConfig); } From 0c0c275e37c37772d17d3a84e7f69920050a923b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 15:18:45 -0300 Subject: [PATCH 08/43] fix: removed `photoIdScan` method references --- README.md | 1 - src/types/index.ts | 6 ------ 2 files changed, 7 deletions(-) diff --git a/README.md b/README.md index ca43e00..3fe0002 100644 --- a/README.md +++ b/README.md @@ -325,7 +325,6 @@ This is a list of theme properties that can be used to styling. Note, we recomme | `idScanCaptureFrameStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `autheticanteMessage` | [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | | `enrollMessage` | [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | -| `photoIdScanMessage` | [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) | | `photoIdMatchMessage` | [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`DefaultMessage`](#capfacesdkdefaultmessage) | ### `CapfaceSdk.ButtonLocation` diff --git a/src/types/index.ts b/src/types/index.ts index a23e7e8..cbd58fb 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -676,12 +676,6 @@ export declare namespace CapfaceSdk { */ livenessMessage?: DefaultMessage; - /** - * @description An object with all messages to will be used the during the - * photo ID scan flow. - */ - photoIdScanMessage?: DefaultScanMessage; - /** * @description An object with all messages to will be used the during the * photo ID match flow. From 31c13de4539b6fb3b5fc153f00f17f53caacf3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 15:44:10 -0300 Subject: [PATCH 09/43] feat: added default value to custom comments and rename `principalKey` to `key` --- .../processors/PhotoIDMatchProcessor.java | 72 +++++++++---------- .../processors/PhotoIDScanProcessor.java | 70 +++++++++--------- src/types/index.ts | 25 ++++++- 3 files changed, 94 insertions(+), 73 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java b/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java index c0337ac..3643b09 100644 --- a/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java +++ b/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java @@ -22,7 +22,7 @@ import com.facetec.sdk.*; public class PhotoIDMatchProcessor extends Processor implements FaceTecFaceScanProcessor, FaceTecIDScanProcessor { - private final String principalKey = "photoIdMatchMessage"; + private final String key = "photoIdMatchMessage"; private final String latestExternalDatabaseRefID; private final ReadableMap data; private final ReactNativeCapfaceSdkModule capFaceModule; @@ -38,73 +38,73 @@ public PhotoIDMatchProcessor(String sessionToken, Context context, ReactNativeCa FaceTecCustomization.setIDScanUploadMessageOverrides( // Upload of ID front-side has started. - capThemeUtils.handleMessage(principalKey, "frontSideUploadStarted", "Uploading\nEncrypted\nID Scan"), + capThemeUtils.handleMessage(key, "frontSideUploadStarted", "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "frontSideStillUploading", + capThemeUtils.handleMessage(key, "frontSideStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID front-side to the Server is complete. - capThemeUtils.handleMessage(principalKey, "frontSideUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "frontSideUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID front-side is complete and we are waiting for the Server to // finish processing and respond. - capThemeUtils.handleMessage(principalKey, "frontSideUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "frontSideUploadCompleteAwaitingProcessing", "Processing ID Scan"), // Upload of ID back-side has started. - capThemeUtils.handleMessage(principalKey, "backSideUploadStarted", + capThemeUtils.handleMessage(key, "backSideUploadStarted", "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "backSideStillUploading", + capThemeUtils.handleMessage(key, "backSideStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID back-side to Server is complete. - capThemeUtils.handleMessage(principalKey, "backSideUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "backSideUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID back-side is complete and we are waiting for the Server to // finish processing and respond. - capThemeUtils.handleMessage(principalKey, "backSideUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "backSideUploadCompleteAwaitingProcessing", "Processing Back of ID"), // Upload of User Confirmed Info has started. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadStarted", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadStarted", "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info is still uploading to Server after an extended // period of time. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoStillUploading", + capThemeUtils.handleMessage(key, "userConfirmedInfoStillUploading", "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info to the Server is complete. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of User Confirmed Info is complete and we are waiting for the Server // to finish processing and respond. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadCompleteAwaitingProcessing", "Processing"), // Upload of NFC Details has started. - capThemeUtils.handleMessage(principalKey, "nfcUploadStarted", + capThemeUtils.handleMessage(key, "nfcUploadStarted", "Uploading Encrypted\nNFC Details"), // Upload of NFC Details is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "nfcStillUploading", + capThemeUtils.handleMessage(key, "nfcStillUploading", "Still Uploading...\nSlow Connection"), // Upload of NFC Details to the Server is complete. - capThemeUtils.handleMessage(principalKey, "nfcUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "nfcUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of NFC Details is complete and we are waiting for the Server to finish // processing and respond. - capThemeUtils.handleMessage(principalKey, "nfcUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "nfcUploadCompleteAwaitingProcessing", "Processing\nNFC Details"), // Upload of ID Details has started. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadStarted", + capThemeUtils.handleMessage(key, "skippedNFCUploadStarted", "Uploading Encrypted\nID Details"), // Upload of ID Details is still uploading to Server after an extended period of // time. - capThemeUtils.handleMessage(principalKey, "skippedNFCStillUploading", + capThemeUtils.handleMessage(key, "skippedNFCStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID Details to the Server is complete. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "skippedNFCUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID Details is complete and we are waiting for the Server to finish // processing and respond. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "skippedNFCUploadCompleteAwaitingProcessing", "Processing\nID Details")); capFaceModule.sendEvent("onCloseModal", true); @@ -167,7 +167,7 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t if (wasProcessed) { FaceTecCustomization.overrideResultScreenSuccessMessage = capThemeUtils.handleMessage( - principalKey, "successMessage", + key, "successMessage", "Liveness\nConfirmed"); faceScanWasSuccessful = faceScanResultCallback.proceedToNextStep(scanResultBlob); } else { @@ -259,52 +259,52 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t if (wasProcessed) { FaceTecCustomization.setIDScanResultScreenMessageOverrides( // Successful scan of ID front-side (ID Types with no back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSide", + capThemeUtils.handleMessage(key, "successFrontSide", "ID Scan Complete"), // Successful scan of ID front-side (ID Types that have a back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSideBackNext", + capThemeUtils.handleMessage(key, "successFrontSideBackNext", "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a // back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSideNFCNext", + capThemeUtils.handleMessage(key, "successFrontSideNFCNext", "Front of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do not have NFC). - capThemeUtils.handleMessage(principalKey, "successBackSide", + capThemeUtils.handleMessage(key, "successBackSide", "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do have NFC). - capThemeUtils.handleMessage(principalKey, "successBackSideNFCNext", + capThemeUtils.handleMessage(key, "successBackSideNFCNext", "Back of ID\nScanned"), // Successful scan of a Passport that does not have NFC. - capThemeUtils.handleMessage(principalKey, "successPassport", + capThemeUtils.handleMessage(key, "successPassport", "Passport Scan Complete"), // Successful scan of a Passport that does have NFC. - capThemeUtils.handleMessage(principalKey, "successPassportNFCNext", + capThemeUtils.handleMessage(key, "successPassportNFCNext", "Passport Scanned"), // Successful upload of final IDScan containing User-Confirmed ID Text. - capThemeUtils.handleMessage(principalKey, "successUserConfirmation", + capThemeUtils.handleMessage(key, "successUserConfirmation", "Photo ID Scan\nComplete"), // Successful upload of the scanned NFC chip information. - capThemeUtils.handleMessage(principalKey, "successNFC", + capThemeUtils.handleMessage(key, "successNFC", "ID Scan Complete"), // Case where a Retry is needed because the Face on the Photo ID did not Match // the User's Face highly enough. - capThemeUtils.handleMessage(principalKey, "retryFaceDidNotMatch", + capThemeUtils.handleMessage(key, "retryFaceDidNotMatch", "Face Didn't Match\nHighly Enough"), // Case where a Retry is needed because a Full ID was not detected with high // enough confidence. - capThemeUtils.handleMessage(principalKey, "retryIDNotFullyVisible", + capThemeUtils.handleMessage(key, "retryIDNotFullyVisible", "ID Document\nNot Fully Visible"), // Case where a Retry is needed because the OCR did not produce good enough // results and the User should Retry with a better capture. - capThemeUtils.handleMessage(principalKey, "retryOCRResultsNotGoodEnough", + capThemeUtils.handleMessage(key, "retryOCRResultsNotGoodEnough", "ID Text Not Legible"), // Case where there is likely no OCR Template installed for the document the // User is attempting to scan. - capThemeUtils.handleMessage(principalKey, "retryIDTypeNotSupported", + capThemeUtils.handleMessage(key, "retryIDTypeNotSupported", "ID Type Mismatch\nPlease Try Again"), // Case where NFC Scan was skipped due to the user's interaction or an // unexpected error. - capThemeUtils.handleMessage(principalKey, "skipOrErrorNFC", + capThemeUtils.handleMessage(key, "skipOrErrorNFC", "ID Details\nUploaded")); success = idScanResultCallback.proceedToNextStep(scanResultBlob); diff --git a/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java b/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java index 5ce3ec9..c2e637b 100644 --- a/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java +++ b/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java @@ -29,7 +29,7 @@ public class PhotoIDScanProcessor extends Processor implements FaceTecIDScanProcessor { private boolean success = false; - private final String principalKey = "photoIdScanMessage"; + private final String key = "photoIdScanMessage"; private final ReadableMap data; private final ReactNativeCapfaceSdkModule capFaceModule; private final ThemeUtils capThemeUtils = new ThemeUtils(); @@ -41,73 +41,73 @@ public PhotoIDScanProcessor(String sessionToken, Context context, ReactNativeCap FaceTecCustomization.setIDScanUploadMessageOverrides( // Upload of ID front-side has started. - capThemeUtils.handleMessage(principalKey, "frontSideUploadStarted", "Uploading\nEncrypted\nID Scan"), + capThemeUtils.handleMessage(key, "frontSideUploadStarted", "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "frontSideStillUploading", + capThemeUtils.handleMessage(key, "frontSideStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID front-side to the Server is complete. - capThemeUtils.handleMessage(principalKey, "frontSideUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "frontSideUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID front-side is complete and we are waiting for the Server to // finish processing and respond. - capThemeUtils.handleMessage(principalKey, "frontSideUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "frontSideUploadCompleteAwaitingProcessing", "Processing ID Scan"), // Upload of ID back-side has started. - capThemeUtils.handleMessage(principalKey, "backSideUploadStarted", + capThemeUtils.handleMessage(key, "backSideUploadStarted", "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "backSideStillUploading", + capThemeUtils.handleMessage(key, "backSideStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID back-side to Server is complete. - capThemeUtils.handleMessage(principalKey, "backSideUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "backSideUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID back-side is complete and we are waiting for the Server to // finish processing and respond. - capThemeUtils.handleMessage(principalKey, "backSideUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "backSideUploadCompleteAwaitingProcessing", "Processing Back of ID"), // Upload of User Confirmed Info has started. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadStarted", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadStarted", "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info is still uploading to Server after an extended // period of time. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoStillUploading", + capThemeUtils.handleMessage(key, "userConfirmedInfoStillUploading", "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info to the Server is complete. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of User Confirmed Info is complete and we are waiting for the Server // to finish processing and respond. - capThemeUtils.handleMessage(principalKey, "userConfirmedInfoUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "userConfirmedInfoUploadCompleteAwaitingProcessing", "Processing"), // Upload of NFC Details has started. - capThemeUtils.handleMessage(principalKey, "nfcUploadStarted", + capThemeUtils.handleMessage(key, "nfcUploadStarted", "Uploading Encrypted\nNFC Details"), // Upload of NFC Details is still uploading to Server after an extended period // of time. - capThemeUtils.handleMessage(principalKey, "nfcStillUploading", + capThemeUtils.handleMessage(key, "nfcStillUploading", "Still Uploading...\nSlow Connection"), // Upload of NFC Details to the Server is complete. - capThemeUtils.handleMessage(principalKey, "nfcUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "nfcUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of NFC Details is complete and we are waiting for the Server to finish // processing and respond. - capThemeUtils.handleMessage(principalKey, "nfcUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "nfcUploadCompleteAwaitingProcessing", "Processing\nNFC Details"), // Upload of ID Details has started. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadStarted", + capThemeUtils.handleMessage(key, "skippedNFCUploadStarted", "Uploading Encrypted\nID Details"), // Upload of ID Details is still uploading to Server after an extended period of // time. - capThemeUtils.handleMessage(principalKey, "skippedNFCStillUploading", + capThemeUtils.handleMessage(key, "skippedNFCStillUploading", "Still Uploading...\nSlow Connection"), // Upload of ID Details to the Server is complete. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadCompleteAwaitingResponse", + capThemeUtils.handleMessage(key, "skippedNFCUploadCompleteAwaitingResponse", "Upload Complete"), // Upload of ID Details is complete and we are waiting for the Server to finish // processing and respond. - capThemeUtils.handleMessage(principalKey, "skippedNFCUploadCompleteAwaitingProcessing", + capThemeUtils.handleMessage(key, "skippedNFCUploadCompleteAwaitingProcessing", "Processing\nID Details")); capFaceModule.sendEvent("onCloseModal", true); @@ -176,52 +176,52 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t if (wasProcessed) { FaceTecCustomization.setIDScanResultScreenMessageOverrides( // Successful scan of ID front-side (ID Types with no back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSide", + capThemeUtils.handleMessage(key, "successFrontSide", "ID Scan Complete"), // Successful scan of ID front-side (ID Types that have a back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSideBackNext", + capThemeUtils.handleMessage(key, "successFrontSideBackNext", "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a // back-side). - capThemeUtils.handleMessage(principalKey, "successFrontSideNFCNext", + capThemeUtils.handleMessage(key, "successFrontSideNFCNext", "Front of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do not have NFC). - capThemeUtils.handleMessage(principalKey, "successBackSide", + capThemeUtils.handleMessage(key, "successBackSide", "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do have NFC). - capThemeUtils.handleMessage(principalKey, "successBackSideNFCNext", + capThemeUtils.handleMessage(key, "successBackSideNFCNext", "Back of ID\nScanned"), // Successful scan of a Passport that does not have NFC. - capThemeUtils.handleMessage(principalKey, "successPassport", + capThemeUtils.handleMessage(key, "successPassport", "Passport Scan Complete"), // Successful scan of a Passport that does have NFC. - capThemeUtils.handleMessage(principalKey, "successPassportNFCNext", + capThemeUtils.handleMessage(key, "successPassportNFCNext", "Passport Scanned"), // Successful upload of final IDScan containing User-Confirmed ID Text. - capThemeUtils.handleMessage(principalKey, "successUserConfirmation", + capThemeUtils.handleMessage(key, "successUserConfirmation", "Photo ID Scan\nComplete"), // Successful upload of the scanned NFC chip information. - capThemeUtils.handleMessage(principalKey, "successNFC", + capThemeUtils.handleMessage(key, "successNFC", "ID Scan Complete"), // Case where a Retry is needed because the Face on the Photo ID did not Match // the User's Face highly enough. - capThemeUtils.handleMessage(principalKey, "retryFaceDidNotMatch", + capThemeUtils.handleMessage(key, "retryFaceDidNotMatch", "Face Didn't Match\nHighly Enough"), // Case where a Retry is needed because a Full ID was not detected with high // enough confidence. - capThemeUtils.handleMessage(principalKey, "retryIDNotFullyVisible", + capThemeUtils.handleMessage(key, "retryIDNotFullyVisible", "ID Document\nNot Fully Visible"), // Case where a Retry is needed because the OCR did not produce good enough // results and the User should Retry with a better capture. - capThemeUtils.handleMessage(principalKey, "retryOCRResultsNotGoodEnough", + capThemeUtils.handleMessage(key, "retryOCRResultsNotGoodEnough", "ID Text Not Legible"), // Case where there is likely no OCR Template installed for the document the // User is attempting to scan. - capThemeUtils.handleMessage(principalKey, "retryIDTypeNotSupported", + capThemeUtils.handleMessage(key, "retryIDTypeNotSupported", "ID Type Mismatch\nPlease Try Again"), // Case where NFC Scan was skipped due to the user's interaction or an // unexpected error. - capThemeUtils.handleMessage(principalKey, "skipOrErrorNFC", + capThemeUtils.handleMessage(key, "skipOrErrorNFC", "ID Details\nUploaded")); success = idScanResultCallback.proceedToNextStep(scanResultBlob); diff --git a/src/types/index.ts b/src/types/index.ts index cbd58fb..3b983ff 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -740,7 +740,10 @@ export declare namespace CapfaceSdk { productionKey: string; /** - * @description Option to select production or developement mode for initialize CapfaceSDK. + * @description Option to select production or developement mode for + * initialize CapfaceSDK. + * + * @default false */ isDeveloperMode?: boolean; } @@ -830,24 +833,42 @@ export declare namespace CapfaceSdk { /** * @description The endpoint to will be used to make requests. It's optional. + * + * @description To the `authenticate` method. + * @default "/match-3d-3d" + * + * @description To the `enroll` method. + * @default "/enrollment-3d" + * + * @description To the `liveness` method. + * @default "/liveness-3d" */ endpoint?: string | null; /** * @description The success message to will be used to show to user on the * flow end. It's optional. + * + * @default "Liveness Confirmed" + * + * @description Exception to `authenticate` method. + * @default "Autheticated" */ successMessage?: string | null; /** * @description The upload message to will be used to show to user on loading - * flow. It's optional. + * flow. It's optional. Only iOS. + * + * @default "Still Uploading..." */ uploadMessageIos?: string | null; /** * @description The parameters to will be used to sent data by headers. * It's optional. + * + * @default null */ parameters?: Object | null; } From c84a53bdbb96266a7d3c4cd3c398c1849b0b4704 Mon Sep 17 00:00:00 2001 From: Bruno Fialho Date: Tue, 12 Sep 2023 16:19:44 -0300 Subject: [PATCH 10/43] feat: starting merge processors on ios --- example/ios/Podfile.lock | 4 +- .../project.pbxproj | 116 +++++++------- example/package-lock.json | 108 ++++++------- ios/Processors/FaceConfig.swift | 74 +++++++++ ios/Processors/FaceProcessor.swift | 147 ++++++++++++++++++ ios/Processors/KeyFaceProcessor.swift | 15 ++ ios/ReactNativeCapfaceSdk.mm | 8 +- ios/ReactNativeCapfaceSdk.swift | 22 +-- .../project.pbxproj | 22 +-- .../CapFaceViewController.swift | 25 +-- package-lock.json | 102 ++++++------ 11 files changed, 419 insertions(+), 224 deletions(-) create mode 100644 ios/Processors/FaceConfig.swift create mode 100644 ios/Processors/FaceProcessor.swift create mode 100644 ios/Processors/KeyFaceProcessor.swift diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index 6990bac..057a2a3 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -1,6 +1,6 @@ PODS: - boost (1.76.0) - - capitual-react-native-capface-sdk (1.0.2): + - capitual-react-native-capface-sdk (1.0.4): - RCT-Folly (= 2021.07.22.00) - React-Core - CocoaAsyncSocket (7.6.5) @@ -666,7 +666,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 57d2868c099736d80fcd648bf211b4431e51a558 - capitual-react-native-capface-sdk: 3079ff981a8d2ad019ff68a0e443de285c48ae8e + capitual-react-native-capface-sdk: 0083411179373f8c83b3f5887fae5f498f3ea73c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 diff --git a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj index 4fffdbc..3b5b86f 100644 --- a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj +++ b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj @@ -11,9 +11,9 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; + 30ED54A08B1857CC018258D1 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; - CB255FC707E2F530E1B995AC /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 26C5254A47C132AA2BC47DB9 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; - DF2AB585A6654B045D095FB2 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1804952A6144EF2DA2DB5A02 /* libPods-ReactNativeCapfaceSdkExample.a */; }; + F29AFA0877BFE3096EC9A2B1 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -30,20 +30,20 @@ 00E356EE1AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeCapfaceSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCapfaceSdkExampleTests.m; sourceTree = ""; }; + 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* ReactNativeCapfaceSdkExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeCapfaceSdkExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ReactNativeCapfaceSdkExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = ReactNativeCapfaceSdkExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeCapfaceSdkExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeCapfaceSdkExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeCapfaceSdkExample/main.m; sourceTree = ""; }; - 1804952A6144EF2DA2DB5A02 /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 26C5254A47C132AA2BC47DB9 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 3AAC3DC3CD8ABCF119F3BC64 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; - 3BBD96623BA09EFE601BB453 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; + 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeCapfaceSdkExample/LaunchScreen.storyboard; sourceTree = ""; }; - DCA0B393B1DD5829C5F5AE7D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; + DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; + EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; - F9B047B24668249FAD18C5CA /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; + F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -51,7 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CB255FC707E2F530E1B995AC /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, + F29AFA0877BFE3096EC9A2B1 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DF2AB585A6654B045D095FB2 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, + 30ED54A08B1857CC018258D1 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,8 +100,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - 1804952A6144EF2DA2DB5A02 /* libPods-ReactNativeCapfaceSdkExample.a */, - 26C5254A47C132AA2BC47DB9 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, + 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */, + F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, ); name = Frameworks; sourceTree = ""; @@ -140,10 +140,10 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - F9B047B24668249FAD18C5CA /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, - DCA0B393B1DD5829C5F5AE7D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, - 3BBD96623BA09EFE601BB453 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, - 3AAC3DC3CD8ABCF119F3BC64 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, + EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, + DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, + 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, + 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -155,12 +155,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExampleTests" */; buildPhases = ( - 862EDA293B4EF758F181572C /* [CP] Check Pods Manifest.lock */, + 4ED8069BB55C71FD73F316E6 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 639FB8AF6571AB739DACB3EB /* [CP] Embed Pods Frameworks */, - C6B9AC3E1C54A860D9A0CE5C /* [CP] Copy Pods Resources */, + 8D2F60CF7E07FA008C9D6CA8 /* [CP] Embed Pods Frameworks */, + 650591FC5209931A342BF378 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -176,14 +176,14 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExample" */; buildPhases = ( - 5D8CDA0A8AE9FC2E6E32527E /* [CP] Check Pods Manifest.lock */, + 6E47E5EDDB44289A43B14A27 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 764B447EB5808F2312C89E0D /* [CP] Embed Pods Frameworks */, - 60FF9CAA9FC0DA640840B325 /* [CP] Copy Pods Resources */, + 29E1986A3746A3C2E9CD66F5 /* [CP] Embed Pods Frameworks */, + 0B99F53FDD0BDE18FA68EAC0 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -266,80 +266,80 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 5D8CDA0A8AE9FC2E6E32527E /* [CP] Check Pods Manifest.lock */ = { + 0B99F53FDD0BDE18FA68EAC0 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 60FF9CAA9FC0DA640840B325 /* [CP] Copy Pods Resources */ = { + 29E1986A3746A3C2E9CD66F5 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 639FB8AF6571AB739DACB3EB /* [CP] Embed Pods Frameworks */ = { + 4ED8069BB55C71FD73F316E6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 764B447EB5808F2312C89E0D /* [CP] Embed Pods Frameworks */ = { + 650591FC5209931A342BF378 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 862EDA293B4EF758F181572C /* [CP] Check Pods Manifest.lock */ = { + 6E47E5EDDB44289A43B14A27 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -354,28 +354,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - C6B9AC3E1C54A860D9A0CE5C /* [CP] Copy Pods Resources */ = { + 8D2F60CF7E07FA008C9D6CA8 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FD10A7F022414F080027D42C /* Start Packager */ = { @@ -430,7 +430,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3BBD96623BA09EFE601BB453 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; + baseConfigurationReference = 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -457,7 +457,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3AAC3DC3CD8ABCF119F3BC64 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; + baseConfigurationReference = 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -481,7 +481,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F9B047B24668249FAD18C5CA /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; + baseConfigurationReference = EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -509,7 +509,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DCA0B393B1DD5829C5F5AE7D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; + baseConfigurationReference = DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/example/package-lock.json b/example/package-lock.json index a5a5321..aa7e44d 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -1979,9 +1979,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -2100,9 +2100,9 @@ "peer": true }, "node_modules/@jest/create-cache-key-function": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.6.3.tgz", - "integrity": "sha512-kzSK9XAxtD1kRPJKxsmD0YKw2fyXveP+5ikeQkCYCHeacWW1EGYMTgjDIM/Di4Uhttx7lnHwrNpz2xn+0rTp8g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", "dependencies": { "@jest/types": "^29.6.3" }, @@ -2111,30 +2111,30 @@ } }, "node_modules/@jest/environment": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz", - "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dependencies": { - "@jest/fake-timers": "^29.6.4", + "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.3" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz", - "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.6.3", - "jest-mock": "^29.6.3", - "jest-util": "^29.6.3" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -2208,9 +2208,9 @@ } }, "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", - "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -4969,9 +4969,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001529", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz", - "integrity": "sha512-n2pUQYGAkrLG4QYj2desAh+NqsJpHbNmVZz87imptDdxLAtjxary7Df/psdfyDGmskJK/9Dt9cPnx5RZ3CU4Og==", + "version": "1.0.30001533", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001533.tgz", + "integrity": "sha512-9aY/b05NKU4Yl2sbcJhn4A7MsGwR1EPfW/nrqsnqVA0Oq50wpmPaGI+R1Z0UKlUl96oxUkGEOILWtOHck0eCWw==", "funding": [ { "type": "opencollective", @@ -5409,9 +5409,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.512", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.512.tgz", - "integrity": "sha512-1W8wRbYlQE4ph7eoj3TJ+uqwO6+xvAE/L+KGU7WTQQvX3tnSIGZAb90MTsMoJqzntamiwJhBAj4WZmygXhsOUg==" + "version": "1.4.516", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.516.tgz", + "integrity": "sha512-A8xs6nie7jw/9GFRrCPrrE+maux1M3gSnFe1HVstK6ubH+7v5hMDFq3qoNxTRssYyz6jdzk/1wLebT+9tisLKA==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -7290,16 +7290,16 @@ } }, "node_modules/jest-environment-node": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", - "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dependencies": { - "@jest/environment": "^29.6.4", - "@jest/fake-timers": "^29.6.4", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.3", - "jest-util": "^29.6.3" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7373,9 +7373,9 @@ } }, "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", - "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -7408,9 +7408,9 @@ } }, "node_modules/jest-message-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz", - "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", @@ -7418,7 +7418,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.6.3", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -7491,13 +7491,13 @@ } }, "node_modules/jest-mock": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz", - "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.6.3" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -7571,9 +7571,9 @@ } }, "node_modules/jest-mock/node_modules/jest-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", - "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -7723,16 +7723,16 @@ } }, "node_modules/jest-validate": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", - "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.6.3" + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -9713,9 +9713,9 @@ } }, "node_modules/pretty-format": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", - "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", diff --git a/ios/Processors/FaceConfig.swift b/ios/Processors/FaceConfig.swift new file mode 100644 index 0000000..203e852 --- /dev/null +++ b/ios/Processors/FaceConfig.swift @@ -0,0 +1,74 @@ +// +// FaceConfig.swift +// ReactNativeCapfaceSdk +// +// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 12/09/23. +// Copyright Β© 2023 Facebook. All rights reserved. +// + +import Foundation + +public class FaceConfig { + private let config: NSDictionary + + init(config: NSDictionary) { + self.config = config + } + + private func hasProperty(key: String) -> Bool { + if self.config.count == 0 { + return false + } + + return (self.config.value(forKey: key) != nil) + } + + private func getValue(key: String) -> String? { + return self.hasProperty(key: key) ? "\(self.config[key]!)" : nil + } + + func getKey() -> String? { + if let key = self.getValue(key: "key") { + let isAuthenticate = key == KeyFaceProcessor.authenticateMessage.rawValue + let isEnroll = key == KeyFaceProcessor.enrollMessage.rawValue + let isLiveness = key == KeyFaceProcessor.livenessMessage.rawValue + let isValidKey = isAuthenticate || isEnroll || isLiveness + if isValidKey { + return key + } + } + return nil + } + + func getEndpoint() -> String? { + return self.hasProperty(key: "endpoint") ? self.getValue(key: "endpoint") : nil + } + + func getSuccessMessage() -> String? { + if let key = self.getKey() { + let isAuthenticate = key == KeyFaceProcessor.authenticateMessage.rawValue + let defaultMessage = isAuthenticate ? "Authenticated" : "Liveness\nConfirmed" + if self.hasProperty(key: "successMessage") { + return self.getValue(key: "successMessage") + } + } + return nil + } + + func getHasExternalDatabaseRefID() -> Bool { + if let key = self.getKey() { + let isLiveness = key == KeyFaceProcessor.livenessMessage.rawValue + if isLiveness { + return false + } + if let hasExternalDatabaseRefID = self.getValue(key: "hasExternalDatabaseRefID") { + return hasExternalDatabaseRefID == "true" + } + } + return false + } + + func getParameters() -> [String: Any]? { + return self.hasProperty(key: "parameters") ? self.config["parameters"] as? [String: Any] : nil + } +} diff --git a/ios/Processors/FaceProcessor.swift b/ios/Processors/FaceProcessor.swift new file mode 100644 index 0000000..732c006 --- /dev/null +++ b/ios/Processors/FaceProcessor.swift @@ -0,0 +1,147 @@ +// +// LivenessCheckProcessor.swift +// ReactNativeCapfaceSdk +// +// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 12/09/23. +// Copyright Β© 2023 Capitual. All rights reserved. +// + +import UIKit +import Foundation +import FaceTecSDK + +class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { + var success = false + var config: NSDictionary! + var latestNetworkRequest: URLSessionTask! + var fromViewController: CapFaceViewController! + var faceScanResultCallback: FaceTecFaceScanResultCallback! + private let faceConfig: FaceConfig! + private let principalKey: String! + private let CapThemeUtils: ThemeUtils! = ThemeUtils(); + + init(sessionToken: String, fromViewController: CapFaceViewController, config: NSDictionary) { + self.fromViewController = fromViewController + self.config = config + self.faceConfig = FaceConfig(config: config) + self.principalKey = faceConfig.getKey() + super.init() + + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); + + let faceViewController = FaceTec.sdk.createSessionVC(faceScanProcessorDelegate: self, sessionToken: sessionToken) + + FaceTecUtilities.getTopMostViewController()?.present(faceViewController, animated: true, completion: nil) + } + + func processSessionWhileFaceTecSDKWaits(sessionResult: FaceTecSessionResult, faceScanResultCallback: FaceTecFaceScanResultCallback) { + fromViewController.setLatestSessionResult(sessionResult: sessionResult) + + self.faceScanResultCallback = faceScanResultCallback + + if sessionResult.status != FaceTecSessionStatus.sessionCompletedSuccessfully { + if latestNetworkRequest != nil { + latestNetworkRequest.cancel() + } + + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return + } + + var parameters: [String : Any] = [:] + if (self.config != nil) { + parameters["data"] = self.config + } + parameters["faceScan"] = sessionResult.faceScanBase64 + parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] + parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] + + var request: URLRequest + + switch principalKey { + case "enrollMessage": + request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") + case "authenticateMessage": + request = Config.makeRequest(url: "/match-3d-3d", httpMethod: "POST") + case "livenessMessage": + request = Config.makeRequest(url: "/liveness-3d", httpMethod: "POST") + default: + request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") + } + + request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) + + let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) + latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in + if let httpResponse = response as? HTTPURLResponse { + if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { + print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return + } + } + + if let error = error { + print("Exception raised while attempting HTTPS call.") + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return + } + + guard let data = data else { + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return + } + + guard let responseJSON = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] else { + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return + } + + guard let scanResultBlob = responseJSON["scanResultBlob"] as? String, + let wasProcessed = responseJSON["wasProcessed"] as? Bool else { + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return; + } + + if wasProcessed == true { + let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); + FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); + + self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); + } else { + ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); + faceScanResultCallback.onFaceScanResultCancel() + return; + } + }) + + latestNetworkRequest.resume() + + DispatchQueue.main.asyncAfter(deadline: .now() + 6) { + if self.latestNetworkRequest.state == .completed { return } + + let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); + let uploadMessage: NSMutableAttributedString = NSMutableAttributedString.init(string: message); + faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); + } + } + + func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { + let uploadProgress: Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend) + faceScanResultCallback.onFaceScanUploadProgress(uploadedPercent: uploadProgress) + } + + func onFaceTecSDKCompletelyDone() { + self.fromViewController.onComplete(); + } + + func isSuccess() -> Bool { + return success + } +} diff --git a/ios/Processors/KeyFaceProcessor.swift b/ios/Processors/KeyFaceProcessor.swift new file mode 100644 index 0000000..44fdee0 --- /dev/null +++ b/ios/Processors/KeyFaceProcessor.swift @@ -0,0 +1,15 @@ +// +// KeyFaceProcessor.swift +// ReactNativeCapfaceSdk +// +// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 12/09/23. +// Copyright Β© 2023 Facebook. All rights reserved. +// + +import Foundation + +public enum KeyFaceProcessor: String { + case livenessMessage + case authenticateMessage + case enrollMessage +} diff --git a/ios/ReactNativeCapfaceSdk.mm b/ios/ReactNativeCapfaceSdk.mm index b3604f4..060a31a 100644 --- a/ios/ReactNativeCapfaceSdk.mm +++ b/ios/ReactNativeCapfaceSdk.mm @@ -16,13 +16,7 @@ @interface RCT_EXTERN_MODULE(ReactNativeCapfaceSdk, RCTEventEmitter) RCT_EXTERN_METHOD(initializeSdk:(NSDictionary *)params headers:(NSDictionary *)headers callback:(RCTResponseSenderBlock)callback) -RCT_EXTERN_METHOD(handleLivenessCheck:(NSDictionary *)data - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject) -RCT_EXTERN_METHOD(handleEnrollUser:(NSDictionary *)data - resolve:(RCTPromiseResolveBlock)resolve - reject:(RCTPromiseRejectBlock)reject) -RCT_EXTERN_METHOD(handleAuthenticateUser:(NSDictionary *)data +RCT_EXTERN_METHOD(handleFaceUser:(NSDictionary *)config resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) RCT_EXTERN_METHOD(handlePhotoIDMatch:(NSDictionary *)data diff --git a/ios/ReactNativeCapfaceSdk.swift b/ios/ReactNativeCapfaceSdk.swift index 1f043e0..da70f2f 100644 --- a/ios/ReactNativeCapfaceSdk.swift +++ b/ios/ReactNativeCapfaceSdk.swift @@ -81,27 +81,9 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { return ["onCloseModal"]; } - @objc func handleLivenessCheck(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + @objc func handleFaceUser(_ config: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { if self.isInitialized { - self.capFaceViewController.onLivenessCheck(data, resolve: resolve, reject: reject); - } else { - print("CapFace SDK has not been initialized!"); - return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); - } - } - - @objc func handleEnrollUser(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - if self.isInitialized { - self.capFaceViewController.onEnrollUser(data, resolve: resolve, reject: reject); - } else { - print("CapFace SDK has not been initialized!"); - return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); - } - } - - @objc func handleAuthenticateUser(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - if self.isInitialized { - self.capFaceViewController.onAuthenticateUser(data, resolve: resolve, reject: reject); + self.capFaceViewController.onFaceUser(config, resolve: resolve, reject: reject); } else { print("CapFace SDK has not been initialized!"); return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); diff --git a/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj b/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj index d02b05b..90f3601 100644 --- a/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj +++ b/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj @@ -18,6 +18,9 @@ CEBC6EB02AA66FF300A76DE0 /* PhotoIDScanProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */; }; CEBC6EB12AA66FF300A76DE0 /* AuthenticateProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EAB2AA66FF300A76DE0 /* AuthenticateProcessor.swift */; }; CEE455C32AA6869C0063FD54 /* ThemeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE455C22AA6869C0063FD54 /* ThemeUtils.swift */; }; + CEE7AF452AB09DDF00E90A50 /* FaceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE7AF442AB09DDF00E90A50 /* FaceConfig.swift */; }; + CEE7AF472AB09E7000E90A50 /* FaceProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE7AF462AB09E7000E90A50 /* FaceProcessor.swift */; }; + CEE7AF492AB09FBD00E90A50 /* KeyFaceProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE7AF482AB09FBD00E90A50 /* KeyFaceProcessor.swift */; }; CEFB5DC12AA8C04300A33DAB /* FaceTecSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEFB5DC02AA8C04300A33DAB /* FaceTecSDK.framework */; }; F4FF95D7245B92E800C19C63 /* ReactNativeCapfaceSdk.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4FF95D6245B92E800C19C63 /* ReactNativeCapfaceSdk.swift */; }; /* End PBXBuildFile section */ @@ -37,7 +40,6 @@ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libReactNativeCapfaceSdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativeCapfaceSdk.a; sourceTree = BUILT_PRODUCTS_DIR; }; B3E7B5891CC2AC0600A0062D /* ReactNativeCapfaceSdk.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCapfaceSdk.mm; sourceTree = ""; }; - CE5E1A0E2AAF67B9005BC6DF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; CEBC6E912AA66F3900A76DE0 /* Config.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; CEBC6E942AA66F4900A76DE0 /* FaceTecViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaceTecViewController.swift; sourceTree = ""; }; CEBC6E972AA66F5800A76DE0 /* FaceTecUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaceTecUtilities.swift; sourceTree = ""; }; @@ -49,6 +51,9 @@ CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoIDScanProcessor.swift; sourceTree = ""; }; CEBC6EAB2AA66FF300A76DE0 /* AuthenticateProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticateProcessor.swift; sourceTree = ""; }; CEE455C22AA6869C0063FD54 /* ThemeUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeUtils.swift; sourceTree = ""; }; + CEE7AF442AB09DDF00E90A50 /* FaceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaceConfig.swift; sourceTree = ""; }; + CEE7AF462AB09E7000E90A50 /* FaceProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaceProcessor.swift; sourceTree = ""; }; + CEE7AF482AB09FBD00E90A50 /* KeyFaceProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyFaceProcessor.swift; sourceTree = ""; }; CEFB5DC02AA8C04300A33DAB /* FaceTecSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = FaceTecSDK.framework; sourceTree = ""; }; F4FF95D5245B92E700C19C63 /* ReactNativeCapfaceSdk-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativeCapfaceSdk-Bridging-Header.h"; sourceTree = ""; }; F4FF95D6245B92E800C19C63 /* ReactNativeCapfaceSdk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactNativeCapfaceSdk.swift; sourceTree = ""; }; @@ -77,7 +82,6 @@ 58B511D21A9E6C8500147676 = { isa = PBXGroup; children = ( - CE5E1A0D2AAF43F0005BC6DF /* SupportingFiles */, CEF929EB2AA6836600777D78 /* Frameworks */, CEBC6EA22AA66FC900A76DE0 /* Processors */, CEBC6E962AA66F4E00A76DE0 /* Utilities */, @@ -90,14 +94,6 @@ ); sourceTree = ""; }; - CE5E1A0D2AAF43F0005BC6DF /* SupportingFiles */ = { - isa = PBXGroup; - children = ( - CE5E1A0E2AAF67B9005BC6DF /* Assets.xcassets */, - ); - path = SupportingFiles; - sourceTree = ""; - }; CEBC6E932AA66F4000A76DE0 /* ViewController */ = { isa = PBXGroup; children = ( @@ -124,6 +120,9 @@ CEBC6EA92AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift */, CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */, CEBC6EA72AA66FF300A76DE0 /* ProcesingDelegate.swift */, + CEE7AF442AB09DDF00E90A50 /* FaceConfig.swift */, + CEE7AF462AB09E7000E90A50 /* FaceProcessor.swift */, + CEE7AF482AB09FBD00E90A50 /* KeyFaceProcessor.swift */, ); path = Processors; sourceTree = ""; @@ -203,11 +202,14 @@ buildActionMask = 2147483647; files = ( CEBC6E982AA66F5800A76DE0 /* FaceTecUtilities.swift in Sources */, + CEE7AF452AB09DDF00E90A50 /* FaceConfig.swift in Sources */, CEBC6E952AA66F4900A76DE0 /* FaceTecViewController.swift in Sources */, F4FF95D7245B92E800C19C63 /* ReactNativeCapfaceSdk.swift in Sources */, CEE455C32AA6869C0063FD54 /* ThemeUtils.swift in Sources */, CEBC6EAD2AA66FF300A76DE0 /* ProcesingDelegate.swift in Sources */, CEBC6EA52AA66FDD00A76DE0 /* ThemeHelpers.swift in Sources */, + CEE7AF492AB09FBD00E90A50 /* KeyFaceProcessor.swift in Sources */, + CEE7AF472AB09E7000E90A50 /* FaceProcessor.swift in Sources */, CEBC6EAF2AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift in Sources */, CEBC6EB12AA66FF300A76DE0 /* AuthenticateProcessor.swift in Sources */, CEBC6EB02AA66FF300A76DE0 /* PhotoIDScanProcessor.swift in Sources */, diff --git a/ios/ViewController/CapFaceViewController.swift b/ios/ViewController/CapFaceViewController.swift index bf41e7e..dea577f 100644 --- a/ios/ViewController/CapFaceViewController.swift +++ b/ios/ViewController/CapFaceViewController.swift @@ -22,32 +22,13 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { override func viewDidLoad() { super.viewDidLoad() } - - func onLivenessCheck(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - setProcessorPromise(resolve, rejecter: reject); - - getSessionToken() { sessionToken in - self.resetLatestResults() - self.latestProcessor = LivenessCheckProcessor(sessionToken: sessionToken, fromViewController: self, data: data) - } - } - - func onEnrollUser(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { - setProcessorPromise(resolve, rejecter: reject); - - getSessionToken() { sessionToken in - self.resetLatestResults() - self.latestExternalDatabaseRefID = "ios_capitual_app_" + UUID().uuidString - self.latestProcessor = EnrollmentProcessor(sessionToken: sessionToken, fromViewController: self, data: data) - } - } - - func onAuthenticateUser(_ data: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + + func onFaceUser(_ config: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { setProcessorPromise(resolve, rejecter: reject); getSessionToken() { sessionToken in self.resetLatestResults() - self.latestProcessor = AuthenticateProcessor(sessionToken: sessionToken, fromViewController: self, data: data) + self.latestProcessor = FaceProcessor(sessionToken: sessionToken, fromViewController: self, config: config) } } diff --git a/package-lock.json b/package-lock.json index 50c4209..075d097 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2782,9 +2782,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.0.tgz", - "integrity": "sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.8.1.tgz", + "integrity": "sha512-PWiOzLIUAjN/w5K17PoF4n6sKBw0gqLHPhywmYHP4t1VFQQVYeb1yWsJwnMVEMl3tUHME7X/SJPZLmtG7XBDxQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -3268,9 +3268,9 @@ } }, "node_modules/@jest/create-cache-key-function": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.6.3.tgz", - "integrity": "sha512-kzSK9XAxtD1kRPJKxsmD0YKw2fyXveP+5ikeQkCYCHeacWW1EGYMTgjDIM/Di4Uhttx7lnHwrNpz2xn+0rTp8g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz", + "integrity": "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA==", "dev": true, "dependencies": { "@jest/types": "^29.6.3" @@ -7890,9 +7890,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001529", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001529.tgz", - "integrity": "sha512-n2pUQYGAkrLG4QYj2desAh+NqsJpHbNmVZz87imptDdxLAtjxary7Df/psdfyDGmskJK/9Dt9cPnx5RZ3CU4Og==", + "version": "1.0.30001533", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001533.tgz", + "integrity": "sha512-9aY/b05NKU4Yl2sbcJhn4A7MsGwR1EPfW/nrqsnqVA0Oq50wpmPaGI+R1Z0UKlUl96oxUkGEOILWtOHck0eCWw==", "dev": true, "funding": [ { @@ -9323,9 +9323,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.512", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.512.tgz", - "integrity": "sha512-1W8wRbYlQE4ph7eoj3TJ+uqwO6+xvAE/L+KGU7WTQQvX3tnSIGZAb90MTsMoJqzntamiwJhBAj4WZmygXhsOUg==", + "version": "1.4.516", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.516.tgz", + "integrity": "sha512-A8xs6nie7jw/9GFRrCPrrE+maux1M3gSnFe1HVstK6ubH+7v5hMDFq3qoNxTRssYyz6jdzk/1wLebT+9tisLKA==", "dev": true }, "node_modules/emittery": { @@ -15784,9 +15784,9 @@ } }, "node_modules/metro-config/node_modules/jest-validate": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.6.3.tgz", - "integrity": "sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", @@ -15794,7 +15794,7 @@ "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.6.3" + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -15840,9 +15840,9 @@ } }, "node_modules/metro-config/node_modules/pretty-format": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", - "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.3", @@ -21601,32 +21601,32 @@ } }, "node_modules/react-native/node_modules/@jest/environment": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.6.4.tgz", - "integrity": "sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.6.4", + "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.3" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/react-native/node_modules/@jest/fake-timers": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.6.4.tgz", - "integrity": "sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.6.3", - "jest-mock": "^29.6.3", - "jest-util": "^29.6.3" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -21744,26 +21744,26 @@ } }, "node_modules/react-native/node_modules/jest-environment-node": { - "version": "29.6.4", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.6.4.tgz", - "integrity": "sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "dependencies": { - "@jest/environment": "^29.6.4", - "@jest/fake-timers": "^29.6.4", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.6.3", - "jest-util": "^29.6.3" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/react-native/node_modules/jest-message-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.6.3.tgz", - "integrity": "sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", @@ -21772,7 +21772,7 @@ "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.6.3", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -21793,9 +21793,9 @@ } }, "node_modules/react-native/node_modules/jest-message-util/node_modules/pretty-format": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.6.3.tgz", - "integrity": "sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "dependencies": { "@jest/schemas": "^29.6.3", @@ -21807,23 +21807,23 @@ } }, "node_modules/react-native/node_modules/jest-mock": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.6.3.tgz", - "integrity": "sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.6.3" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/react-native/node_modules/jest-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.6.3.tgz", - "integrity": "sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "dependencies": { "@jest/types": "^29.6.3", From 985dba26b37a04f1984306a87657e4d61d878d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 16:47:44 -0300 Subject: [PATCH 11/43] fix: small adjusts in code iOS --- ios/Processors/FaceConfig.swift | 17 +++-- ios/Processors/FaceProcessor.swift | 26 ++++---- ios/Processors/PhotoIDMatchProcessor.swift | 74 +++++++++++----------- ios/Processors/PhotoIDScanProcessor.swift | 70 ++++++++++---------- 4 files changed, 96 insertions(+), 91 deletions(-) diff --git a/ios/Processors/FaceConfig.swift b/ios/Processors/FaceConfig.swift index 203e852..d14a4dd 100644 --- a/ios/Processors/FaceConfig.swift +++ b/ios/Processors/FaceConfig.swift @@ -9,7 +9,7 @@ import Foundation public class FaceConfig { - private let config: NSDictionary + private var config: NSDictionary = NSDictionary() init(config: NSDictionary) { self.config = config @@ -27,11 +27,15 @@ public class FaceConfig { return self.hasProperty(key: key) ? "\(self.config[key]!)" : nil } + func isWhichFlow(_ keyFlow: KeyFaceProcessor, key: String) -> Bool { + return key == keyFlow.rawValue + } + func getKey() -> String? { if let key = self.getValue(key: "key") { - let isAuthenticate = key == KeyFaceProcessor.authenticateMessage.rawValue - let isEnroll = key == KeyFaceProcessor.enrollMessage.rawValue - let isLiveness = key == KeyFaceProcessor.livenessMessage.rawValue + let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key) + let isEnroll = self.isWhichFlow(KeyFaceProcessor.enrollMessage, key) + let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key) let isValidKey = isAuthenticate || isEnroll || isLiveness if isValidKey { return key @@ -46,18 +50,19 @@ public class FaceConfig { func getSuccessMessage() -> String? { if let key = self.getKey() { - let isAuthenticate = key == KeyFaceProcessor.authenticateMessage.rawValue + let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key) let defaultMessage = isAuthenticate ? "Authenticated" : "Liveness\nConfirmed" if self.hasProperty(key: "successMessage") { return self.getValue(key: "successMessage") } + return defaultMessage } return nil } func getHasExternalDatabaseRefID() -> Bool { if let key = self.getKey() { - let isLiveness = key == KeyFaceProcessor.livenessMessage.rawValue + let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key) if isLiveness { return false } diff --git a/ios/Processors/FaceProcessor.swift b/ios/Processors/FaceProcessor.swift index 732c006..e9526ab 100644 --- a/ios/Processors/FaceProcessor.swift +++ b/ios/Processors/FaceProcessor.swift @@ -16,15 +16,15 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS var latestNetworkRequest: URLSessionTask! var fromViewController: CapFaceViewController! var faceScanResultCallback: FaceTecFaceScanResultCallback! + private let key: String! private let faceConfig: FaceConfig! - private let principalKey: String! private let CapThemeUtils: ThemeUtils! = ThemeUtils(); init(sessionToken: String, fromViewController: CapFaceViewController, config: NSDictionary) { self.fromViewController = fromViewController self.config = config self.faceConfig = FaceConfig(config: config) - self.principalKey = faceConfig.getKey() + self.key = faceConfig.getKey() super.init() ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); @@ -59,15 +59,15 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS var request: URLRequest - switch principalKey { - case "enrollMessage": - request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") - case "authenticateMessage": - request = Config.makeRequest(url: "/match-3d-3d", httpMethod: "POST") - case "livenessMessage": - request = Config.makeRequest(url: "/liveness-3d", httpMethod: "POST") - default: - request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") + switch key { + case "enrollMessage": + request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") + case "authenticateMessage": + request = Config.makeRequest(url: "/match-3d-3d", httpMethod: "POST") + case "livenessMessage": + request = Config.makeRequest(url: "/liveness-3d", httpMethod: "POST") + default: + request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") } request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) @@ -110,7 +110,7 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); + let message = self.CapThemeUtils.handleMessage(self.key, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); @@ -126,7 +126,7 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS DispatchQueue.main.asyncAfter(deadline: .now() + 6) { if self.latestNetworkRequest.state == .completed { return } - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); + let message = self.CapThemeUtils.handleMessage(self.key, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); let uploadMessage: NSMutableAttributedString = NSMutableAttributedString.init(string: message); faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); } diff --git a/ios/Processors/PhotoIDMatchProcessor.swift b/ios/Processors/PhotoIDMatchProcessor.swift index ccdaab2..1ea2c7e 100644 --- a/ios/Processors/PhotoIDMatchProcessor.swift +++ b/ios/Processors/PhotoIDMatchProcessor.swift @@ -19,7 +19,7 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega var fromViewController: CapFaceViewController! var faceScanResultCallback: FaceTecFaceScanResultCallback! var idScanResultCallback: FaceTecIDScanResultCallback! - private let principalKey = "photoIdMatchMessage"; + private let key = "photoIdMatchMessage"; private let CapThemeUtils: ThemeUtils! = ThemeUtils(); @@ -30,26 +30,26 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega super.init() FaceTecCustomization.setIDScanUploadMessageOverrides( - frontSideUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side has started. - frontSideStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID front-side is still uploading to Server after an extended period of time. - frontSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID front-side to the Server is complete. - frontSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Scan"), // Upload of ID front-side is complete and we are waiting for the Server to finish processing and respond. - backSideUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side has started. - backSideStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID back-side is still uploading to Server after an extended period of time. - backSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID back-side to Server is complete. - backSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nBack of ID"), // Upload of ID back-side is complete and we are waiting for the Server to finish processing and respond. - userConfirmedInfoUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadStarted", defaultMessage: "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info has started. - userConfirmedInfoStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info is still uploading to Server after an extended period of time. - userConfirmedInfoUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of User Confirmed Info to the Server is complete. - userConfirmedInfoUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadCompleteAwaitingProcessing", defaultMessage: "Processing"), // Upload of User Confirmed Info is complete and we are waiting for the Server to finish processing and respond. - nfcUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadStarted", defaultMessage: "Uploading Encrypted\nNFC Details"), // Upload of NFC Details has started. - nfcStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of NFC Details is still uploading to Server after an extended period of time. - nfcUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of NFC Details to the Server is complete. - nfcUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nNFC Details"), // Upload of NFC Details is complete and we are waiting for the Server to finish processing and respond. - skippedNFCUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadStarted", defaultMessage: "Uploading Encrypted\nID Details"), // Upload of ID Details has started. - skippedNFCStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID Details is still uploading to Server after an extended period of time. - skippedNFCUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID Details to the Server is complete. - skippedNFCUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Details") // Upload of ID Details is complete and we are waiting for the Server to finish processing and respond. + frontSideUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side has started. + frontSideStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "frontSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID front-side is still uploading to Server after an extended period of time. + frontSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID front-side to the Server is complete. + frontSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Scan"), // Upload of ID front-side is complete and we are waiting for the Server to finish processing and respond. + backSideUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side has started. + backSideStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "backSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID back-side is still uploading to Server after an extended period of time. + backSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID back-side to Server is complete. + backSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nBack of ID"), // Upload of ID back-side is complete and we are waiting for the Server to finish processing and respond. + userConfirmedInfoUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadStarted", defaultMessage: "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info has started. + userConfirmedInfoStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info is still uploading to Server after an extended period of time. + userConfirmedInfoUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of User Confirmed Info to the Server is complete. + userConfirmedInfoUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadCompleteAwaitingProcessing", defaultMessage: "Processing"), // Upload of User Confirmed Info is complete and we are waiting for the Server to finish processing and respond. + nfcUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadStarted", defaultMessage: "Uploading Encrypted\nNFC Details"), // Upload of NFC Details has started. + nfcStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "nfcStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of NFC Details is still uploading to Server after an extended period of time. + nfcUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of NFC Details to the Server is complete. + nfcUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nNFC Details"), // Upload of NFC Details is complete and we are waiting for the Server to finish processing and respond. + skippedNFCUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadStarted", defaultMessage: "Uploading Encrypted\nID Details"), // Upload of ID Details has started. + skippedNFCStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID Details is still uploading to Server after an extended period of time. + skippedNFCUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID Details to the Server is complete. + skippedNFCUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Details") // Upload of ID Details is complete and we are waiting for the Server to finish processing and respond. ); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); @@ -124,7 +124,7 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega } if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); + let message = self.CapThemeUtils.handleMessage(self.key, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); self.faceScanWasSuccessful = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); @@ -140,7 +140,7 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega DispatchQueue.main.asyncAfter(deadline: .now() + 6) { if self.latestNetworkRequest.state == .completed { return } - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); + let message = self.CapThemeUtils.handleMessage(self.key, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); let uploadMessage:NSMutableAttributedString = NSMutableAttributedString.init(string: message); faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); } @@ -216,20 +216,20 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega if wasProcessed == true { FaceTecCustomization.setIDScanResultScreenMessageOverrides( - successFrontSide: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSide", defaultMessage: "ID Scan Complete"), // Successful scan of ID front-side (ID Types with no back-side). - successFrontSideBackNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSideBackNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have a back-side). - successFrontSideNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSideNFCNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a back-side). - successBackSide: self.CapThemeUtils.handleMessage(self.principalKey, child: "successBackSide", defaultMessage: "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do not have NFC). - successBackSideNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successBackSideNFCNext", defaultMessage: "Back of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do have NFC). - successPassport: self.CapThemeUtils.handleMessage(self.principalKey, child: "successPassport", defaultMessage: "Passport Scan Complete"), // Successful scan of a Passport that does not have NFC. - successPassportNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successPassportNFCNext", defaultMessage: "Passport Scanned"), // Successful scan of a Passport that does have NFC. - successUserConfirmation: self.CapThemeUtils.handleMessage(self.principalKey, child: "successUserConfirmation", defaultMessage: "Photo ID Scan\nComplete"), // Successful upload of final IDScan containing User-Confirmed ID Text. - successNFC: self.CapThemeUtils.handleMessage(self.principalKey, child: "successNFC", defaultMessage: "ID Scan Complete"), // Successful upload of the scanned NFC chip information. - retryFaceDidNotMatch: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryFaceDidNotMatch", defaultMessage: "Face Didn’t Match\nHighly Enough"), // Case where a Retry is needed because the Face on the Photo ID did not Match the User's Face highly enough. - retryIDNotFullyVisible: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryIDNotFullyVisible", defaultMessage: "ID Document\nNot Fully Visible"), // Case where a Retry is needed because a Full ID was not detected with high enough confidence. - retryOCRResultsNotGoodEnough: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryOCRResultsNotGoodEnough", defaultMessage: "ID Text Not Legible"), // Case where a Retry is needed because the OCR did not produce good enough results and the User should Retry with a better capture. - retryIDTypeNotSupported: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryIDTypeNotSupported", defaultMessage: "ID Type Mismatch\nPlease Try Again"), // Case where there is likely no OCR Template installed for the document the User is attempting to scan. - skipOrErrorNFC: self.CapThemeUtils.handleMessage(self.principalKey, child: "skipOrErrorNFC", defaultMessage: "ID Details\nUploaded") // Case where NFC Scan was skipped due to the user's interaction or an unexpected error. + successFrontSide: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSide", defaultMessage: "ID Scan Complete"), // Successful scan of ID front-side (ID Types with no back-side). + successFrontSideBackNext: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSideBackNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have a back-side). + successFrontSideNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSideNFCNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a back-side). + successBackSide: self.CapThemeUtils.handleMessage(self.key, child: "successBackSide", defaultMessage: "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do not have NFC). + successBackSideNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successBackSideNFCNext", defaultMessage: "Back of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do have NFC). + successPassport: self.CapThemeUtils.handleMessage(self.key, child: "successPassport", defaultMessage: "Passport Scan Complete"), // Successful scan of a Passport that does not have NFC. + successPassportNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successPassportNFCNext", defaultMessage: "Passport Scanned"), // Successful scan of a Passport that does have NFC. + successUserConfirmation: self.CapThemeUtils.handleMessage(self.key, child: "successUserConfirmation", defaultMessage: "Photo ID Scan\nComplete"), // Successful upload of final IDScan containing User-Confirmed ID Text. + successNFC: self.CapThemeUtils.handleMessage(self.key, child: "successNFC", defaultMessage: "ID Scan Complete"), // Successful upload of the scanned NFC chip information. + retryFaceDidNotMatch: self.CapThemeUtils.handleMessage(self.key, child: "retryFaceDidNotMatch", defaultMessage: "Face Didn’t Match\nHighly Enough"), // Case where a Retry is needed because the Face on the Photo ID did not Match the User's Face highly enough. + retryIDNotFullyVisible: self.CapThemeUtils.handleMessage(self.key, child: "retryIDNotFullyVisible", defaultMessage: "ID Document\nNot Fully Visible"), // Case where a Retry is needed because a Full ID was not detected with high enough confidence. + retryOCRResultsNotGoodEnough: self.CapThemeUtils.handleMessage(self.key, child: "retryOCRResultsNotGoodEnough", defaultMessage: "ID Text Not Legible"), // Case where a Retry is needed because the OCR did not produce good enough results and the User should Retry with a better capture. + retryIDTypeNotSupported: self.CapThemeUtils.handleMessage(self.key, child: "retryIDTypeNotSupported", defaultMessage: "ID Type Mismatch\nPlease Try Again"), // Case where there is likely no OCR Template installed for the document the User is attempting to scan. + skipOrErrorNFC: self.CapThemeUtils.handleMessage(self.key, child: "skipOrErrorNFC", defaultMessage: "ID Details\nUploaded") // Case where NFC Scan was skipped due to the user's interaction or an unexpected error. ) self.success = idScanResultCallback.onIDScanResultProceedToNextStep(scanResultBlob: scanResultBlob) diff --git a/ios/Processors/PhotoIDScanProcessor.swift b/ios/Processors/PhotoIDScanProcessor.swift index e6c7b6c..3fa2d4b 100644 --- a/ios/Processors/PhotoIDScanProcessor.swift +++ b/ios/Processors/PhotoIDScanProcessor.swift @@ -16,7 +16,7 @@ class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, var latestNetworkRequest: URLSessionTask! var fromViewController: CapFaceViewController! var idScanResultCallback: FaceTecIDScanResultCallback! - private let principalKey = "photoIdScanMessage"; + private let key = "photoIdScanMessage"; private let CapThemeUtils: ThemeUtils! = ThemeUtils(); init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { @@ -25,26 +25,26 @@ class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, super.init() FaceTecCustomization.setIDScanUploadMessageOverrides( - frontSideUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side has started. - frontSideStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID front-side is still uploading to Server after an extended period of time. - frontSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID front-side to the Server is complete. - frontSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "frontSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Scan"), // Upload of ID front-side is complete and we are waiting for the Server to finish processing and respond. - backSideUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side has started. - backSideStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID back-side is still uploading to Server after an extended period of time. - backSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID back-side to Server is complete. - backSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "backSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nBack of ID"), // Upload of ID back-side is complete and we are waiting for the Server to finish processing and respond. - userConfirmedInfoUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadStarted", defaultMessage: "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info has started. - userConfirmedInfoStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info is still uploading to Server after an extended period of time. - userConfirmedInfoUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of User Confirmed Info to the Server is complete. - userConfirmedInfoUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "userConfirmedInfoUploadCompleteAwaitingProcessing", defaultMessage: "Processing"), // Upload of User Confirmed Info is complete and we are waiting for the Server to finish processing and respond. - nfcUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadStarted", defaultMessage: "Uploading Encrypted\nNFC Details"), // Upload of NFC Details has started. - nfcStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of NFC Details is still uploading to Server after an extended period of time. - nfcUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of NFC Details to the Server is complete. - nfcUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "nfcUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nNFC Details"), // Upload of NFC Details is complete and we are waiting for the Server to finish processing and respond. - skippedNFCUploadStarted: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadStarted", defaultMessage: "Uploading Encrypted\nID Details"), // Upload of ID Details has started. - skippedNFCStillUploading: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID Details is still uploading to Server after an extended period of time. - skippedNFCUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID Details to the Server is complete. - skippedNFCUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.principalKey, child: "skippedNFCUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Details") // Upload of ID Details is complete and we are waiting for the Server to finish processing and respond. + frontSideUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nID Scan"), // Upload of ID front-side has started. + frontSideStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "frontSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID front-side is still uploading to Server after an extended period of time. + frontSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID front-side to the Server is complete. + frontSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "frontSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Scan"), // Upload of ID front-side is complete and we are waiting for the Server to finish processing and respond. + backSideUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadStarted", defaultMessage: "Uploading\nEncrypted\nBack of ID"), // Upload of ID back-side has started. + backSideStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "backSideStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID back-side is still uploading to Server after an extended period of time. + backSideUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID back-side to Server is complete. + backSideUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "backSideUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nBack of ID"), // Upload of ID back-side is complete and we are waiting for the Server to finish processing and respond. + userConfirmedInfoUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadStarted", defaultMessage: "Uploading\nYour Confirmed Info"), // Upload of User Confirmed Info has started. + userConfirmedInfoStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of User Confirmed Info is still uploading to Server after an extended period of time. + userConfirmedInfoUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of User Confirmed Info to the Server is complete. + userConfirmedInfoUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "userConfirmedInfoUploadCompleteAwaitingProcessing", defaultMessage: "Processing"), // Upload of User Confirmed Info is complete and we are waiting for the Server to finish processing and respond. + nfcUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadStarted", defaultMessage: "Uploading Encrypted\nNFC Details"), // Upload of NFC Details has started. + nfcStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "nfcStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of NFC Details is still uploading to Server after an extended period of time. + nfcUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of NFC Details to the Server is complete. + nfcUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "nfcUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nNFC Details"), // Upload of NFC Details is complete and we are waiting for the Server to finish processing and respond. + skippedNFCUploadStarted: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadStarted", defaultMessage: "Uploading Encrypted\nID Details"), // Upload of ID Details has started. + skippedNFCStillUploading: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCStillUploading", defaultMessage: "Still Uploading...\nSlow Connection"), // Upload of ID Details is still uploading to Server after an extended period of time. + skippedNFCUploadCompleteAwaitingResponse: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadCompleteAwaitingResponse", defaultMessage: "Upload Complete"), // Upload of ID Details to the Server is complete. + skippedNFCUploadCompleteAwaitingProcessing: self.CapThemeUtils.handleMessage(self.key, child: "skippedNFCUploadCompleteAwaitingProcessing", defaultMessage: "Processing\nID Details") // Upload of ID Details is complete and we are waiting for the Server to finish processing and respond. ); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); @@ -123,20 +123,20 @@ class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, if wasProcessed == true { FaceTecCustomization.setIDScanResultScreenMessageOverrides( - successFrontSide: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSide", defaultMessage: "ID Scan Complete"), // Successful scan of ID front-side (ID Types with no back-side). - successFrontSideBackNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSideBackNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have a back-side). - successFrontSideNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successFrontSideNFCNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a back-side). - successBackSide: self.CapThemeUtils.handleMessage(self.principalKey, child: "successBackSide", defaultMessage: "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do not have NFC). - successBackSideNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successBackSideNFCNext", defaultMessage: "Back of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do have NFC). - successPassport: self.CapThemeUtils.handleMessage(self.principalKey, child: "successPassport", defaultMessage: "Passport Scan Complete"), // Successful scan of a Passport that does not have NFC. - successPassportNFCNext: self.CapThemeUtils.handleMessage(self.principalKey, child: "successPassportNFCNext", defaultMessage: "Passport Scanned"), // Successful scan of a Passport that does have NFC. - successUserConfirmation: self.CapThemeUtils.handleMessage(self.principalKey, child: "successUserConfirmation", defaultMessage: "Photo ID Scan\nComplete"), // Successful upload of final IDScan containing User-Confirmed ID Text. - successNFC: self.CapThemeUtils.handleMessage(self.principalKey, child: "successNFC", defaultMessage: "ID Scan Complete"), // Successful upload of the scanned NFC chip information. - retryFaceDidNotMatch: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryFaceDidNotMatch", defaultMessage: "Face Didn’t Match\nHighly Enough"), // Case where a Retry is needed because the Face on the Photo ID did not Match the User's Face highly enough. - retryIDNotFullyVisible: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryIDNotFullyVisible", defaultMessage: "ID Document\nNot Fully Visible"), // Case where a Retry is needed because a Full ID was not detected with high enough confidence. - retryOCRResultsNotGoodEnough: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryOCRResultsNotGoodEnough", defaultMessage: "ID Text Not Legible"), // Case where a Retry is needed because the OCR did not produce good enough results and the User should Retry with a better capture. - retryIDTypeNotSupported: self.CapThemeUtils.handleMessage(self.principalKey, child: "retryIDTypeNotSupported", defaultMessage: "ID Type Mismatch\nPlease Try Again"), // Case where there is likely no OCR Template installed for the document the User is attempting to scan. - skipOrErrorNFC: self.CapThemeUtils.handleMessage(self.principalKey, child: "skipOrErrorNFC", defaultMessage: "ID Details\nUploaded") // Case where NFC Scan was skipped due to the user's interaction or an unexpected error. + successFrontSide: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSide", defaultMessage: "ID Scan Complete"), // Successful scan of ID front-side (ID Types with no back-side). + successFrontSideBackNext: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSideBackNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have a back-side). + successFrontSideNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successFrontSideNFCNext", defaultMessage: "Front of ID\nScanned"), // Successful scan of ID front-side (ID Types that do have NFC but do not have a back-side). + successBackSide: self.CapThemeUtils.handleMessage(self.key, child: "successBackSide", defaultMessage: "ID Scan Complete"), // Successful scan of the ID back-side (ID Types that do not have NFC). + successBackSideNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successBackSideNFCNext", defaultMessage: "Back of ID\nScanned"), // Successful scan of the ID back-side (ID Types that do have NFC). + successPassport: self.CapThemeUtils.handleMessage(self.key, child: "successPassport", defaultMessage: "Passport Scan Complete"), // Successful scan of a Passport that does not have NFC. + successPassportNFCNext: self.CapThemeUtils.handleMessage(self.key, child: "successPassportNFCNext", defaultMessage: "Passport Scanned"), // Successful scan of a Passport that does have NFC. + successUserConfirmation: self.CapThemeUtils.handleMessage(self.key, child: "successUserConfirmation", defaultMessage: "Photo ID Scan\nComplete"), // Successful upload of final IDScan containing User-Confirmed ID Text. + successNFC: self.CapThemeUtils.handleMessage(self.key, child: "successNFC", defaultMessage: "ID Scan Complete"), // Successful upload of the scanned NFC chip information. + retryFaceDidNotMatch: self.CapThemeUtils.handleMessage(self.key, child: "retryFaceDidNotMatch", defaultMessage: "Face Didn’t Match\nHighly Enough"), // Case where a Retry is needed because the Face on the Photo ID did not Match the User's Face highly enough. + retryIDNotFullyVisible: self.CapThemeUtils.handleMessage(self.key, child: "retryIDNotFullyVisible", defaultMessage: "ID Document\nNot Fully Visible"), // Case where a Retry is needed because a Full ID was not detected with high enough confidence. + retryOCRResultsNotGoodEnough: self.CapThemeUtils.handleMessage(self.key, child: "retryOCRResultsNotGoodEnough", defaultMessage: "ID Text Not Legible"), // Case where a Retry is needed because the OCR did not produce good enough results and the User should Retry with a better capture. + retryIDTypeNotSupported: self.CapThemeUtils.handleMessage(self.key, child: "retryIDTypeNotSupported", defaultMessage: "ID Type Mismatch\nPlease Try Again"), // Case where there is likely no OCR Template installed for the document the User is attempting to scan. + skipOrErrorNFC: self.CapThemeUtils.handleMessage(self.key, child: "skipOrErrorNFC", defaultMessage: "ID Details\nUploaded") // Case where NFC Scan was skipped due to the user's interaction or an unexpected error. ) self.success = idScanResultCallback.onIDScanResultProceedToNextStep(scanResultBlob: scanResultBlob) From f319cb09e2814e398745a798da78bdcf606ddbd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 17:13:02 -0300 Subject: [PATCH 12/43] feat: changed name from external database ref id from iOS and Android --- .../reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java | 2 +- ios/ViewController/CapFaceViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index 91f71d2..216146e 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -244,7 +244,7 @@ public void handlePhotoIDMatch(ReadableMap data, Promise promise) { public void onSessionTokenReceived(String sessionToken) { resetLatestResults(); isSessionPreparingToLaunch = false; - setLatestExternalDatabaseRefID("android_capitual_app_" + randomUUID()); + setLatestExternalDatabaseRefID("android_app_" + randomUUID()); latestProcessor = new PhotoIDMatchProcessor(sessionToken, reactContext.getCurrentActivity(), ReactNativeCapfaceSdkModule.this, data); } diff --git a/ios/ViewController/CapFaceViewController.swift b/ios/ViewController/CapFaceViewController.swift index dea577f..1cca905 100644 --- a/ios/ViewController/CapFaceViewController.swift +++ b/ios/ViewController/CapFaceViewController.swift @@ -37,7 +37,7 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { getSessionToken() { sessionToken in self.resetLatestResults() - self.latestExternalDatabaseRefID = "ios_capitual_app_" + UUID().uuidString + self.latestExternalDatabaseRefID = "ios_app_" + UUID().uuidString self.latestProcessor = PhotoIDMatchProcessor(sessionToken: sessionToken, fromViewController: self, data: data) } } From ace955ad367bce72e3d82e5371228b502393f245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Tue, 12 Sep 2023 17:17:24 -0300 Subject: [PATCH 13/43] fix: created `getUploadMessage` method and used the `FaceConfig` methods in `FaceProcessor` on iOS --- ios/Processors/FaceConfig.swift | 20 ++++++++++++----- ios/Processors/FaceProcessor.swift | 35 +++++++++++++----------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/ios/Processors/FaceConfig.swift b/ios/Processors/FaceConfig.swift index d14a4dd..b756d53 100644 --- a/ios/Processors/FaceConfig.swift +++ b/ios/Processors/FaceConfig.swift @@ -33,9 +33,9 @@ public class FaceConfig { func getKey() -> String? { if let key = self.getValue(key: "key") { - let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key) - let isEnroll = self.isWhichFlow(KeyFaceProcessor.enrollMessage, key) - let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key) + let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key: key) + let isEnroll = self.isWhichFlow(KeyFaceProcessor.enrollMessage, key: key) + let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key: key) let isValidKey = isAuthenticate || isEnroll || isLiveness if isValidKey { return key @@ -50,7 +50,7 @@ public class FaceConfig { func getSuccessMessage() -> String? { if let key = self.getKey() { - let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key) + let isAuthenticate = self.isWhichFlow(KeyFaceProcessor.authenticateMessage, key: key) let defaultMessage = isAuthenticate ? "Authenticated" : "Liveness\nConfirmed" if self.hasProperty(key: "successMessage") { return self.getValue(key: "successMessage") @@ -59,10 +59,20 @@ public class FaceConfig { } return nil } + + func getUploadMessage() -> String { + let defaultMessage = "Still Uploading..." + if let key = self.getKey() { + if self.hasProperty(key: "uploadMessageIos") { + return self.getValue(key: "uploadMessageIos") ?? defaultMessage + } + } + return defaultMessage + } func getHasExternalDatabaseRefID() -> Bool { if let key = self.getKey() { - let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key) + let isLiveness = self.isWhichFlow(KeyFaceProcessor.livenessMessage, key: key) if isLiveness { return false } diff --git a/ios/Processors/FaceProcessor.swift b/ios/Processors/FaceProcessor.swift index e9526ab..70842e4 100644 --- a/ios/Processors/FaceProcessor.swift +++ b/ios/Processors/FaceProcessor.swift @@ -12,7 +12,6 @@ import FaceTecSDK class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { var success = false - var config: NSDictionary! var latestNetworkRequest: URLSessionTask! var fromViewController: CapFaceViewController! var faceScanResultCallback: FaceTecFaceScanResultCallback! @@ -22,7 +21,6 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS init(sessionToken: String, fromViewController: CapFaceViewController, config: NSDictionary) { self.fromViewController = fromViewController - self.config = config self.faceConfig = FaceConfig(config: config) self.key = faceConfig.getKey() super.init() @@ -50,26 +48,21 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } var parameters: [String : Any] = [:] - if (self.config != nil) { - parameters["data"] = self.config + let extraParameters = self.faceConfig.getParameters() + if (extraParameters != nil) { + parameters["data"] = extraParameters } parameters["faceScan"] = sessionResult.faceScanBase64 parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] - - var request: URLRequest - - switch key { - case "enrollMessage": - request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") - case "authenticateMessage": - request = Config.makeRequest(url: "/match-3d-3d", httpMethod: "POST") - case "livenessMessage": - request = Config.makeRequest(url: "/liveness-3d", httpMethod: "POST") - default: - request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") + + let hasExternalDatabaseRefID = self.faceConfig.getHasExternalDatabaseRefID() + if (hasExternalDatabaseRefID) { + parameters["externalDatabaseRefID"] = fromViewController.getLatestExternalDatabaseRefID() } + let endpoint = self.faceConfig.getEndpoint() + var request = Config.makeRequest(url: endpoint ?? "", httpMethod: "POST") request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) @@ -110,7 +103,8 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.key, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); + let successMessage = self.faceConfig.getSuccessMessage() + let message = self.CapThemeUtils.handleMessage(self.key, child: "successMessage", defaultMessage: successMessage ?? ""); FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); @@ -126,9 +120,10 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS DispatchQueue.main.asyncAfter(deadline: .now() + 6) { if self.latestNetworkRequest.state == .completed { return } - let message = self.CapThemeUtils.handleMessage(self.key, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); - let uploadMessage: NSMutableAttributedString = NSMutableAttributedString.init(string: message); - faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); + let uploadMessage = self.faceConfig.getUploadMessage() + let message = self.CapThemeUtils.handleMessage(self.key, child: "uploadMessageIos", defaultMessage: uploadMessage); + let uploadMessageOverride: NSMutableAttributedString = NSMutableAttributedString.init(string: message); + faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessageOverride); } } From 25a766c301e46dccf2f69c6f39fa83600af36d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Wed, 13 Sep 2023 10:51:37 -0300 Subject: [PATCH 14/43] chore: upgraded documentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3fe0002..f8a0791 100644 --- a/README.md +++ b/README.md @@ -426,8 +426,8 @@ This enum represents all errors that are encountered on the CapFace SDK. | `CapFaceHasNotBeenInitialized` | When some processors method is runned, but CapfaceSDK **has not been initialized**. | βœ… | βœ… | | `CapFaceValuesWereNotProcessed` | When the image sent to the processors cannot be processed due to inconsistency. | βœ… | βœ… | | `HTTPSError` | When exists some network error. | βœ… | βœ… | -| `NoConfigurationsProvided` | When the configurations [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) doesn't provided. | βœ… | βœ… | -| `JSONError` | When exists some problem in getting data in request of **base URL** information. | ❌ | βœ… | +| `JSONError` | When exists some problem in getting data in request of **base URL** information. | βœ… | βœ… | +| `NoConfigurationsProvided` | When the configurations [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) doesn't provided. | ❌ | βœ… | | `CapFaceInvalidSession` | When session status is invalid. | ❌ | βœ… | | `CapFaceLivenessWasntProcessed` | When the image user sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | | `CapFaceScanWasntProcessed` | When the image ID sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | From 77f2ca0d1d500a1d60eaa33e5f9ba617aaffa943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Wed, 13 Sep 2023 10:56:06 -0300 Subject: [PATCH 15/43] chore: refactored messages in Android --- .../java/com/capitual/processors/Config.java | 2 +- .../capitual/processors/FaceProcessor.java | 6 +--- .../processors/PhotoIDMatchProcessor.java | 22 +++++-------- .../processors/PhotoIDScanProcessor.java | 6 +--- .../ReactNativeCapfaceSdkModule.java | 31 ++++++++----------- 5 files changed, 23 insertions(+), 44 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/Config.java b/android/src/main/java/com/capitual/processors/Config.java index fe8d011..956ae99 100644 --- a/android/src/main/java/com/capitual/processors/Config.java +++ b/android/src/main/java/com/capitual/processors/Config.java @@ -14,13 +14,13 @@ import okhttp3.Request; public class Config { + private static final ThemeUtils CapThemeUtils = new ThemeUtils(); public static String DeviceKeyIdentifier; public static String BaseURL; public static String PublicFaceScanEncryptionKey; public static String ProductionKeyText; public static ReadableMap Theme; public static ReadableMap RequestHeaders; - private static final ThemeUtils CapThemeUtils = new ThemeUtils(); private static Map parseReadableMapToMap() { Map headers = new HashMap(); diff --git a/android/src/main/java/com/capitual/processors/FaceProcessor.java b/android/src/main/java/com/capitual/processors/FaceProcessor.java index e5f88ff..bc58b0e 100644 --- a/android/src/main/java/com/capitual/processors/FaceProcessor.java +++ b/android/src/main/java/com/capitual/processors/FaceProcessor.java @@ -1,7 +1,6 @@ package com.capitual.processors; import android.content.Context; -import android.util.Log; import androidx.annotation.NonNull; @@ -21,11 +20,11 @@ import com.facetec.sdk.*; public class FaceProcessor extends Processor implements FaceTecFaceScanProcessor { - private boolean success = false; private final String key; private final ReactNativeCapfaceSdkModule capFaceModule; private final FaceConfig faceConfig; private final ThemeUtils capThemeUtils = new ThemeUtils(); + private boolean success = false; public FaceProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, FaceConfig faceConfig) { @@ -65,7 +64,6 @@ public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessio } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", "JSONError"); @@ -113,7 +111,6 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", @@ -123,7 +120,6 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t @Override public void onFailure(@NonNull Call call, IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); diff --git a/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java b/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java index 3643b09..170e1d2 100644 --- a/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java +++ b/android/src/main/java/com/capitual/processors/PhotoIDMatchProcessor.java @@ -1,7 +1,6 @@ package com.capitual.processors; import android.content.Context; -import android.util.Log; import androidx.annotation.NonNull; @@ -23,6 +22,8 @@ public class PhotoIDMatchProcessor extends Processor implements FaceTecFaceScanProcessor, FaceTecIDScanProcessor { private final String key = "photoIdMatchMessage"; + private final String exceptionJsonMessage = "Exception raised while attempting to parse JSON result."; + private final String exceptionHttpMessage = "Exception raised while attempting HTTPS call."; private final String latestExternalDatabaseRefID; private final ReadableMap data; private final ReactNativeCapfaceSdkModule capFaceModule; @@ -135,7 +136,6 @@ public void processSessionWhileFaceTecSDKWaits(final FaceTecSessionResult sessio parameters.put("externalDatabaseRefID", this.latestExternalDatabaseRefID); } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", "JSONError"); @@ -178,20 +178,17 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); + capFaceModule.processorPromise.reject(exceptionJsonMessage, "JSONError"); } } @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); faceScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); + capFaceModule.processorPromise.reject(exceptionHttpMessage, "HTTPSError"); } }); } @@ -226,10 +223,8 @@ public void processIDScanWhileFaceTecSDKWaits(final FaceTecIDScanResult idScanRe } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); + capFaceModule.processorPromise.reject(this.exceptionJsonMessage, "JSONError"); } okhttp3.Request request = new okhttp3.Request.Builder() @@ -320,20 +315,17 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); idScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", - "JSONError"); + capFaceModule.processorPromise.reject(exceptionJsonMessage, "JSONError"); } } @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); idScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); - capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); + capFaceModule.processorPromise.reject(exceptionHttpMessage, "HTTPSError"); } }); } diff --git a/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java b/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java index c2e637b..125bce5 100644 --- a/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java +++ b/android/src/main/java/com/capitual/processors/PhotoIDScanProcessor.java @@ -1,7 +1,6 @@ package com.capitual.processors; import android.content.Context; -import android.util.Log; import androidx.annotation.NonNull; @@ -28,11 +27,11 @@ import com.capitual.processors.helpers.ThemeUtils; public class PhotoIDScanProcessor extends Processor implements FaceTecIDScanProcessor { - private boolean success = false; private final String key = "photoIdScanMessage"; private final ReadableMap data; private final ReactNativeCapfaceSdkModule capFaceModule; private final ThemeUtils capThemeUtils = new ThemeUtils(); + private boolean success = false; public PhotoIDScanProcessor(String sessionToken, Context context, ReactNativeCapfaceSdkModule capFaceModule, ReadableMap data) { @@ -143,7 +142,6 @@ public void processIDScanWhileFaceTecSDKWaits(final FaceTecIDScanResult idScanRe } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to create JSON payload for upload."); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting to create JSON payload for upload.", "JSONError"); @@ -237,7 +235,6 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); idScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting to parse JSON result.", @@ -247,7 +244,6 @@ public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) t @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); idScanResultCallback.cancel(); capFaceModule.sendEvent("onCloseModal", false); capFaceModule.processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index 216146e..e9b5b00 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -10,8 +10,6 @@ import com.facebook.react.bridge.ReactMethod; import com.facebook.react.module.annotations.ReactModule; -import android.util.Log; - import com.facebook.react.bridge.ReadableMap; import org.json.JSONException; @@ -32,8 +30,9 @@ @ReactModule(name = ReactNativeCapfaceSdkModule.NAME) public class ReactNativeCapfaceSdkModule extends ReactContextBaseJavaModule { - public static final String NAME = "ReactNativeCapfaceSdk"; private static final ThemeUtils capThemeUtils = new ThemeUtils(); + public static final String NAME = "ReactNativeCapfaceSdk"; + private final String initializationMessage = "CapFace SDK has not been initialized!"; private final ReactApplicationContext reactContext; private boolean isInitialized = false; private boolean isSessionPreparingToLaunch = false; @@ -62,6 +61,10 @@ private boolean isDeveloperMode(Map params) { return false; } + private String generateUUID() { + return "android_app_" + randomUUID(); + } + private String getKeyValue(@NonNull Map object, String key) { if (object.containsKey(key)) { return object.get(key).toString(); @@ -76,8 +79,8 @@ private void handleCapFaceConfiguration(@NonNull Map params, ReadableMap headers Config.setKey(getKeyValue(params, "key")); Config.setProductionKeyText(getKeyValue(params, "productionKey")); Config.setHeaders(headers); - } catch (Exception error) { - Log.d("Capitual - SDK", "CapFace SDK Configuration doesn't exists!"); + } catch (Exception e) { + e.printStackTrace(); } } @@ -86,7 +89,6 @@ public void initializeSdk(ReadableMap params, ReadableMap headers, com.facebook. if (params == null) { isInitialized = false; callback.invoke(false); - Log.d("Capitual - SDK", "No parameters provided!"); return; } @@ -103,7 +105,6 @@ public void onCompletion(final boolean successful) { } else { isInitialized = false; callback.invoke(false); - Log.d("Capitual - SDK", "CapFace SDK doesn't initialized!"); } this.handleTheme(Config.Theme); @@ -124,7 +125,6 @@ public void getSessionToken(final SessionTokenCallback sessionTokenCallback) { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); - Log.d("Capitual - HTTPS", "Exception raised while attempting HTTPS call."); if (processorPromise != null) { processorPromise.reject("Exception raised while attempting HTTPS call.", "HTTPSError"); } @@ -148,7 +148,6 @@ public void onResponse(Call call, okhttp3.Response response) throws IOException } } catch (JSONException e) { e.printStackTrace(); - Log.d("Capitual - JSON", "Exception raised while attempting to parse JSON result."); if (processorPromise != null) { processorPromise.reject("Exception raised while attempting to parse JSON result.", "JSONError"); } @@ -200,13 +199,11 @@ public void removeListeners(Integer count) { public void handleFaceUser(ReadableMap config, Promise promise) { setProcessorPromise(promise); if (!isInitialized) { - Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); - this.processorPromise.reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized"); + this.processorPromise.reject(this.initializationMessage, "CapFaceHasNotBeenInitialized"); return; } if (config == null) { - Log.d("Capitual - SDK", "No configurations provided!"); this.processorPromise.reject("No configurations provided!", "NoConfigurationsProvided"); return; } @@ -220,7 +217,7 @@ public void onSessionTokenReceived(String sessionToken) { isSessionPreparingToLaunch = false; final FaceConfig faceConfig = new FaceConfig(config); if (faceConfig.isWhichFlow(KeyFaceProcessor.enrollMessage, faceConfig.getKey())) { - setLatestExternalDatabaseRefID("android_app_" + randomUUID()); + setLatestExternalDatabaseRefID(generateUUID()); } latestProcessor = new FaceProcessor(sessionToken, reactContext.getCurrentActivity(), ReactNativeCapfaceSdkModule.this, faceConfig); @@ -232,8 +229,7 @@ public void onSessionTokenReceived(String sessionToken) { public void handlePhotoIDMatch(ReadableMap data, Promise promise) { setProcessorPromise(promise); if (!isInitialized) { - Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); - this.processorPromise.reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized"); + this.processorPromise.reject(this.initializationMessage, "CapFaceHasNotBeenInitialized"); return; } @@ -244,7 +240,7 @@ public void handlePhotoIDMatch(ReadableMap data, Promise promise) { public void onSessionTokenReceived(String sessionToken) { resetLatestResults(); isSessionPreparingToLaunch = false; - setLatestExternalDatabaseRefID("android_app_" + randomUUID()); + setLatestExternalDatabaseRefID(generateUUID()); latestProcessor = new PhotoIDMatchProcessor(sessionToken, reactContext.getCurrentActivity(), ReactNativeCapfaceSdkModule.this, data); } @@ -255,8 +251,7 @@ public void onSessionTokenReceived(String sessionToken) { public void handlePhotoIDScan(ReadableMap data, Promise promise) { setProcessorPromise(promise); if (!isInitialized) { - Log.d("Capitual - SDK", "CapFace SDK has not been initialized!"); - this.processorPromise.reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized"); + this.processorPromise.reject(this.initializationMessage, "CapFaceHasNotBeenInitialized"); return; } From 853851be969fcf475158ba5832fd7cea348b6093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Wed, 13 Sep 2023 11:22:26 -0300 Subject: [PATCH 16/43] chore: more informations to documentation about authentication flow --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f8a0791..cba945a 100644 --- a/README.md +++ b/README.md @@ -439,19 +439,21 @@ This enum represents all the possible types of flow that can be used on the [`fa | `CapfaceSdk.MatchType` | Description | iOS | Android | | ---------------------- | ---------------------------------------- | --- | ------- | | `authenticate` | When you want to make authenticate flow. | βœ… | βœ… | -| `enroll` | When you want to make enroll flow. | βœ… | βœ… | +| `enroll` | When you want to make enrollment flow. | βœ… | βœ… | | `liveness` | When you want to make liveness flow. | βœ… | βœ… | +> The **authenticate flow** depends on to enrollment flow to **work** because the authenticate flow is done using an **UUID** that's was created by enrollment flow. + ### `CapfaceSdk.MatchData` The object with properties that will be sent to native modules to make the requests, change text labels and sent parameters via headers. -| `CapfaceSdk.MatchData` | type | iOS | Android | Required | Default | -| ---------------------- | ------------------ | --- | ------- | -------- | --------------------------------------------------------------------------------------- | -| `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enroll and liveness) | -| `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | -| `successMessage` | `string` or `null` | βœ… | βœ… | ❌ | `/match-3d-3d` (authenticate) or `/enrollment-3d` (enroll) or `/liveness-3d` (liveness) | -| `uploadMessageIos` | `string` or `null` | βœ… | βœ… | ❌ | `Still Uploading...` | +| `CapfaceSdk.MatchData` | type | iOS | Android | Required | Default | +| ---------------------- | ------------------ | --- | ------- | -------- | ------------------------------------------------------------------------------------------- | +| `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enrollment and liveness) | +| `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | +| `successMessage` | `string` or `null` | βœ… | βœ… | ❌ | `/match-3d-3d` (authenticate) or `/enrollment-3d` (enrollment) or `/liveness-3d` (liveness) | +| `uploadMessageIos` | `string` or `null` | βœ… | βœ… | ❌ | `Still Uploading...` |
From 831bb9bee0bb49cd14b220ae3df80565e02b8c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Wed, 13 Sep 2023 14:30:56 -0300 Subject: [PATCH 17/43] fix: resolved problem with sent `externalDatabaseRefID` and merged `Processors` --- .../processors/helpers/ThemeUtils.java | 1 - ios/Config.swift | 2 +- ios/Processors/AuthenticateProcessor.swift | 133 ------------------ ios/Processors/EnrollmentProcessor.swift | 133 ------------------ ios/Processors/FaceConfig.swift | 3 +- ios/Processors/FaceProcessor.swift | 26 ++-- ios/Processors/LivenessCheckProcessor.swift | 132 ----------------- ios/Processors/PhotoIDMatchProcessor.swift | 8 +- ios/Processors/PhotoIDScanProcessor.swift | 6 +- ios/ReactNativeCapfaceSdk.swift | 12 +- .../project.pbxproj | 20 +-- .../CapFaceViewController.swift | 31 ++-- 12 files changed, 48 insertions(+), 459 deletions(-) delete mode 100644 ios/Processors/AuthenticateProcessor.swift delete mode 100644 ios/Processors/EnrollmentProcessor.swift delete mode 100644 ios/Processors/LivenessCheckProcessor.swift diff --git a/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java b/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java index 26baa75..751d7fe 100644 --- a/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java +++ b/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java @@ -37,7 +37,6 @@ public String handleMessage(String key, String child, String defaultMessage) { final Boolean childIsntExists = !message.has(child) || message.isNull(child); return childIsntExists ? defaultMessage : message.getString(child); } catch (Exception error) { - Log.d("JSONError", "Some error occurred while parsing JSON!"); return defaultMessage; } } diff --git a/ios/Config.swift b/ios/Config.swift index 0b0dac1..06815eb 100644 --- a/ios/Config.swift +++ b/ios/Config.swift @@ -11,13 +11,13 @@ import Foundation import FaceTecSDK public class Config { + private static let CapThemeUtils: ThemeUtils! = ThemeUtils(); public static var DeviceKeyIdentifier: String! public static var BaseURL: String! public static var PublicFaceScanEncryptionKey: String! public static var ProductionKeyText: String! public static var Headers: NSDictionary? public static var Theme: NSDictionary? - private static let CapThemeUtils: ThemeUtils! = ThemeUtils(); public static func setDevice(_ device: String) { Config.DeviceKeyIdentifier = device; diff --git a/ios/Processors/AuthenticateProcessor.swift b/ios/Processors/AuthenticateProcessor.swift deleted file mode 100644 index 673ef0e..0000000 --- a/ios/Processors/AuthenticateProcessor.swift +++ /dev/null @@ -1,133 +0,0 @@ -// -// AuthenticateProcessor.swift -// ReactNativeCapfaceSdk -// -// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 04/09/23. -// Copyright Β© 2023 Capitual. All rights reserved. -// - -import UIKit -import Foundation -import FaceTecSDK - -class AuthenticateProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { - var success = false - var data: NSDictionary! - var latestNetworkRequest: URLSessionTask! - var fromViewController: CapFaceViewController! - var faceScanResultCallback: FaceTecFaceScanResultCallback! - private let principalKey = "authenticateMessage"; - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); - - init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { - self.fromViewController = fromViewController - self.data = data - super.init() - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); - - let authenticateViewController = FaceTec.sdk.createSessionVC(faceScanProcessorDelegate: self, sessionToken: sessionToken) - - FaceTecUtilities.getTopMostViewController()?.present(authenticateViewController, animated: true, completion: nil) - } - - func processSessionWhileFaceTecSDKWaits(sessionResult: FaceTecSessionResult, faceScanResultCallback: FaceTecFaceScanResultCallback) { - fromViewController.setLatestSessionResult(sessionResult: sessionResult) - - self.faceScanResultCallback = faceScanResultCallback - - if sessionResult.status != FaceTecSessionStatus.sessionCompletedSuccessfully { - if latestNetworkRequest != nil { - latestNetworkRequest.cancel() - } - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - var parameters: [String : Any] = [:] - if (self.data != nil) { - parameters["data"] = self.data - } - parameters["faceScan"] = sessionResult.faceScanBase64 - parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] - parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] - parameters["externalDatabaseRefID"] = fromViewController.getLatestExternalDatabaseRefID() - - var request = Config.makeRequest(url: "/match-3d-3d", httpMethod: "POST") - request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) - latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in - if let httpResponse = response as? HTTPURLResponse { - if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); - faceScanResultCallback.onFaceScanResultCancel() - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - return - } - } - - if let error = error { - print("Exception raised while attempting HTTPS call.") - faceScanResultCallback.onFaceScanResultCancel() - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - return - } - - guard let data = data else { - faceScanResultCallback.onFaceScanResultCancel() - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - return - } - - guard let responseJSON = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] else { - faceScanResultCallback.onFaceScanResultCancel() - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - return - } - - guard let scanResultBlob = responseJSON["scanResultBlob"] as? String, - let wasProcessed = responseJSON["wasProcessed"] as? Bool else { - faceScanResultCallback.onFaceScanResultCancel() - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - return; - } - - if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Authenticated"); - FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); - - self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob) - } else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return; - } - }) - - latestNetworkRequest.resume() - - DispatchQueue.main.asyncAfter(deadline: .now() + 6) { - if self.latestNetworkRequest.state == .completed { return } - - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); - let uploadMessage:NSMutableAttributedString = NSMutableAttributedString.init(string: message); - faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); - } - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { - let uploadProgress: Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend) - faceScanResultCallback.onFaceScanUploadProgress(uploadedPercent: uploadProgress) - } - - func onFaceTecSDKCompletelyDone() { - self.fromViewController.onComplete(); - } - - func isSuccess() -> Bool { - return success - } -} diff --git a/ios/Processors/EnrollmentProcessor.swift b/ios/Processors/EnrollmentProcessor.swift deleted file mode 100644 index ef48c32..0000000 --- a/ios/Processors/EnrollmentProcessor.swift +++ /dev/null @@ -1,133 +0,0 @@ -// -// EnrollmentProcessor.swift -// ReactNativeCapfaceSdk -// -// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 04/09/23. -// Copyright Β© 2023 Capitual. All rights reserved. -// - -import UIKit -import Foundation -import FaceTecSDK - -class EnrollmentProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { - var success = false - var data: NSDictionary! - var latestNetworkRequest: URLSessionTask! - var fromViewController: CapFaceViewController! - var faceScanResultCallback: FaceTecFaceScanResultCallback! - private let principalKey = "enrollMessage"; - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); - - init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { - self.fromViewController = fromViewController - self.data = data - super.init() - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); - - let enrollmentViewController = FaceTec.sdk.createSessionVC(faceScanProcessorDelegate: self, sessionToken: sessionToken) - - FaceTecUtilities.getTopMostViewController()?.present(enrollmentViewController, animated: true, completion: nil) - } - - func processSessionWhileFaceTecSDKWaits(sessionResult: FaceTecSessionResult, faceScanResultCallback: FaceTecFaceScanResultCallback) { - fromViewController.setLatestSessionResult(sessionResult: sessionResult) - - self.faceScanResultCallback = faceScanResultCallback - - if sessionResult.status != FaceTecSessionStatus.sessionCompletedSuccessfully { - if latestNetworkRequest != nil { - latestNetworkRequest.cancel() - } - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - var parameters: [String : Any] = [:] - if (self.data != nil) { - parameters["data"] = self.data - } - parameters["faceScan"] = sessionResult.faceScanBase64 - parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] - parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] - parameters["externalDatabaseRefID"] = fromViewController.getLatestExternalDatabaseRefID() - - var request = Config.makeRequest(url: "/enrollment-3d", httpMethod: "POST") - request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) - latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in - if let httpResponse = response as? HTTPURLResponse { - if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - } - - if let error = error { - print("Exception raised while attempting HTTPS call.") - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let data = data else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let responseJSON = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let scanResultBlob = responseJSON["scanResultBlob"] as? String, - let wasProcessed = responseJSON["wasProcessed"] as? Bool else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return; - } - - if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); - FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); - - self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); - } else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return; - } - }) - - latestNetworkRequest.resume() - - DispatchQueue.main.asyncAfter(deadline: .now() + 6) { - if self.latestNetworkRequest.state == .completed { return } - - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); - let uploadMessage:NSMutableAttributedString = NSMutableAttributedString.init(string: message); - faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); - } - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { - let uploadProgress: Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend) - faceScanResultCallback.onFaceScanUploadProgress(uploadedPercent: uploadProgress) - } - - func onFaceTecSDKCompletelyDone() { - self.fromViewController.onComplete() - } - - func isSuccess() -> Bool { - return success - } -} diff --git a/ios/Processors/FaceConfig.swift b/ios/Processors/FaceConfig.swift index b756d53..3f7e5a0 100644 --- a/ios/Processors/FaceConfig.swift +++ b/ios/Processors/FaceConfig.swift @@ -77,7 +77,8 @@ public class FaceConfig { return false } if let hasExternalDatabaseRefID = self.getValue(key: "hasExternalDatabaseRefID") { - return hasExternalDatabaseRefID == "true" + // Warning: This case the string "1" means true and "0" means false + return hasExternalDatabaseRefID == "1" } } return false diff --git a/ios/Processors/FaceProcessor.swift b/ios/Processors/FaceProcessor.swift index 70842e4..49bdf6c 100644 --- a/ios/Processors/FaceProcessor.swift +++ b/ios/Processors/FaceProcessor.swift @@ -11,17 +11,17 @@ import Foundation import FaceTecSDK class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { + private let key: String! + private let faceConfig: FaceConfig! + private let CapThemeUtils: ThemeUtils! = ThemeUtils(); var success = false var latestNetworkRequest: URLSessionTask! var fromViewController: CapFaceViewController! var faceScanResultCallback: FaceTecFaceScanResultCallback! - private let key: String! - private let faceConfig: FaceConfig! - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); - init(sessionToken: String, fromViewController: CapFaceViewController, config: NSDictionary) { + init(sessionToken: String, fromViewController: CapFaceViewController, faceConfig: FaceConfig) { self.fromViewController = fromViewController - self.faceConfig = FaceConfig(config: config) + self.faceConfig = faceConfig self.key = faceConfig.getKey() super.init() @@ -48,20 +48,20 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } var parameters: [String : Any] = [:] - let extraParameters = self.faceConfig.getParameters() - if (extraParameters != nil) { + let extraParameters: [String: Any]? = self.faceConfig.getParameters() + if extraParameters != nil { parameters["data"] = extraParameters } parameters["faceScan"] = sessionResult.faceScanBase64 parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] - let hasExternalDatabaseRefID = self.faceConfig.getHasExternalDatabaseRefID() - if (hasExternalDatabaseRefID) { + let hasExternalDatabaseRefID: Bool = self.faceConfig.getHasExternalDatabaseRefID() + if hasExternalDatabaseRefID { parameters["externalDatabaseRefID"] = fromViewController.getLatestExternalDatabaseRefID() } - let endpoint = self.faceConfig.getEndpoint() + let endpoint: String? = self.faceConfig.getEndpoint() var request = Config.makeRequest(url: endpoint ?? "", httpMethod: "POST") request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) @@ -69,7 +69,6 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); faceScanResultCallback.onFaceScanResultCancel() return @@ -77,7 +76,6 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } if let error = error { - print("Exception raised while attempting HTTPS call.") ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); faceScanResultCallback.onFaceScanResultCancel() return @@ -103,7 +101,7 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS } if wasProcessed == true { - let successMessage = self.faceConfig.getSuccessMessage() + let successMessage: String? = self.faceConfig.getSuccessMessage() let message = self.CapThemeUtils.handleMessage(self.key, child: "successMessage", defaultMessage: successMessage ?? ""); FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); @@ -120,7 +118,7 @@ class FaceProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLS DispatchQueue.main.asyncAfter(deadline: .now() + 6) { if self.latestNetworkRequest.state == .completed { return } - let uploadMessage = self.faceConfig.getUploadMessage() + let uploadMessage: String = self.faceConfig.getUploadMessage() let message = self.CapThemeUtils.handleMessage(self.key, child: "uploadMessageIos", defaultMessage: uploadMessage); let uploadMessageOverride: NSMutableAttributedString = NSMutableAttributedString.init(string: message); faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessageOverride); diff --git a/ios/Processors/LivenessCheckProcessor.swift b/ios/Processors/LivenessCheckProcessor.swift deleted file mode 100644 index ad0169a..0000000 --- a/ios/Processors/LivenessCheckProcessor.swift +++ /dev/null @@ -1,132 +0,0 @@ -// -// LivenessCheckProcessor.swift -// ReactNativeCapfaceSdk -// -// Created by Nayara Dias, Bruno Fialho and Daniel SansΓ£o on 04/09/23. -// Copyright Β© 2023 Capitual. All rights reserved. -// - -import UIKit -import Foundation -import FaceTecSDK - -class LivenessCheckProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, URLSessionTaskDelegate { - var success = false - var data: NSDictionary! - var latestNetworkRequest: URLSessionTask! - var fromViewController: CapFaceViewController! - var faceScanResultCallback: FaceTecFaceScanResultCallback! - private let principalKey = "livenessMessage"; - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); - - init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { - self.fromViewController = fromViewController - self.data = data - super.init() - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: true); - - let livenessCheckViewController = FaceTec.sdk.createSessionVC(faceScanProcessorDelegate: self, sessionToken: sessionToken) - - FaceTecUtilities.getTopMostViewController()?.present(livenessCheckViewController, animated: true, completion: nil) - } - - func processSessionWhileFaceTecSDKWaits(sessionResult: FaceTecSessionResult, faceScanResultCallback: FaceTecFaceScanResultCallback) { - fromViewController.setLatestSessionResult(sessionResult: sessionResult) - - self.faceScanResultCallback = faceScanResultCallback - - if sessionResult.status != FaceTecSessionStatus.sessionCompletedSuccessfully { - if latestNetworkRequest != nil { - latestNetworkRequest.cancel() - } - - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - var parameters: [String : Any] = [:] - if (self.data != nil) { - parameters["data"] = self.data - } - parameters["faceScan"] = sessionResult.faceScanBase64 - parameters["auditTrailImage"] = sessionResult.auditTrailCompressedBase64![0] - parameters["lowQualityAuditTrailImage"] = sessionResult.lowQualityAuditTrailCompressedBase64![0] - - var request = Config.makeRequest(url: "/liveness-3d", httpMethod: "POST") - request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: JSONSerialization.WritingOptions(rawValue: 0)) - - let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main) - latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in - if let httpResponse = response as? HTTPURLResponse { - if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - } - - if let error = error { - print("Exception raised while attempting HTTPS call.") - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let data = data else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let responseJSON = try? JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as? [String: AnyObject] else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return - } - - guard let scanResultBlob = responseJSON["scanResultBlob"] as? String, - let wasProcessed = responseJSON["wasProcessed"] as? Bool else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return; - } - - if wasProcessed == true { - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "successMessage", defaultMessage: "Liveness\nConfirmed"); - FaceTecCustomization.setOverrideResultScreenSuccessMessage(message); - - self.success = faceScanResultCallback.onFaceScanGoToNextStep(scanResultBlob: scanResultBlob); - } else { - ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); - faceScanResultCallback.onFaceScanResultCancel() - return; - } - }) - - latestNetworkRequest.resume() - - DispatchQueue.main.asyncAfter(deadline: .now() + 6) { - if self.latestNetworkRequest.state == .completed { return } - - let message = self.CapThemeUtils.handleMessage(self.principalKey, child: "uploadMessageIos", defaultMessage: "Still Uploading..."); - let uploadMessage: NSMutableAttributedString = NSMutableAttributedString.init(string: message); - faceScanResultCallback.onFaceScanUploadMessageOverride(uploadMessageOverride: uploadMessage); - } - } - - func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) { - let uploadProgress: Float = Float(totalBytesSent) / Float(totalBytesExpectedToSend) - faceScanResultCallback.onFaceScanUploadProgress(uploadedPercent: uploadProgress) - } - - func onFaceTecSDKCompletelyDone() { - self.fromViewController.onComplete(); - } - - func isSuccess() -> Bool { - return success - } -} diff --git a/ios/Processors/PhotoIDMatchProcessor.swift b/ios/Processors/PhotoIDMatchProcessor.swift index 1ea2c7e..ea47be4 100644 --- a/ios/Processors/PhotoIDMatchProcessor.swift +++ b/ios/Processors/PhotoIDMatchProcessor.swift @@ -11,6 +11,8 @@ import Foundation import FaceTecSDK class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelegate, FaceTecIDScanProcessorDelegate, URLSessionTaskDelegate { + private let key = "photoIdMatchMessage"; + private let CapThemeUtils: ThemeUtils! = ThemeUtils(); var success = false var faceScanWasSuccessful = false var latestExternalDatabaseRefID: String! @@ -19,8 +21,6 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega var fromViewController: CapFaceViewController! var faceScanResultCallback: FaceTecFaceScanResultCallback! var idScanResultCallback: FaceTecIDScanResultCallback! - private let key = "photoIdMatchMessage"; - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { @@ -90,7 +90,6 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); faceScanResultCallback.onFaceScanResultCancel() return @@ -98,7 +97,6 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega } if let error = error { - print("Exception raised while attempting HTTPS call.") ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); faceScanResultCallback.onFaceScanResultCancel() return @@ -181,7 +179,6 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); idScanResultCallback.onIDScanResultCancel() return @@ -189,7 +186,6 @@ class PhotoIDMatchProcessor: NSObject, Processor, FaceTecFaceScanProcessorDelega } if let error = error { - print("Exception raised while attempting HTTPS call.") ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); idScanResultCallback.onIDScanResultCancel() return diff --git a/ios/Processors/PhotoIDScanProcessor.swift b/ios/Processors/PhotoIDScanProcessor.swift index 3fa2d4b..cfd8146 100644 --- a/ios/Processors/PhotoIDScanProcessor.swift +++ b/ios/Processors/PhotoIDScanProcessor.swift @@ -11,13 +11,13 @@ import Foundation import FaceTecSDK class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, URLSessionTaskDelegate { + private let key = "photoIdScanMessage"; + private let CapThemeUtils: ThemeUtils! = ThemeUtils(); var success = false var data: NSDictionary! var latestNetworkRequest: URLSessionTask! var fromViewController: CapFaceViewController! var idScanResultCallback: FaceTecIDScanResultCallback! - private let key = "photoIdScanMessage"; - private let CapThemeUtils: ThemeUtils! = ThemeUtils(); init(sessionToken: String, fromViewController: CapFaceViewController, data: NSDictionary) { self.fromViewController = fromViewController @@ -88,7 +88,6 @@ class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, latestNetworkRequest = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); idScanResultCallback.onIDScanResultCancel() return @@ -96,7 +95,6 @@ class PhotoIDScanProcessor: NSObject, Processor, FaceTecIDScanProcessorDelegate, } if let error = error { - print("Exception raised while attempting HTTPS call.") ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); idScanResultCallback.onIDScanResultCancel() return diff --git a/ios/ReactNativeCapfaceSdk.swift b/ios/ReactNativeCapfaceSdk.swift index da70f2f..9d218a9 100644 --- a/ios/ReactNativeCapfaceSdk.swift +++ b/ios/ReactNativeCapfaceSdk.swift @@ -13,6 +13,7 @@ import LocalAuthentication @objc(ReactNativeCapfaceSdk) class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { + private let initializationMessage = "CapFace SDK has not been initialized!" public static var emitter: RCTEventEmitter! var capFaceViewController: CapFaceViewController! var isInitialized: Bool = false; @@ -46,7 +47,6 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { if params.count == 0 { self.isInitialized = false; callback([false]); - print("No parameters provided!"); return; } @@ -60,7 +60,6 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { } else { self.isInitialized = false; callback([false]); - print("CapFace SDK Configuration doesn't exists!"); } } } @@ -85,8 +84,7 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { if self.isInitialized { self.capFaceViewController.onFaceUser(config, resolve: resolve, reject: reject); } else { - print("CapFace SDK has not been initialized!"); - return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); + return reject(self.initializationMessage, "CapFaceHasNotBeenInitialized", nil); } } @@ -94,8 +92,7 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { if self.isInitialized { self.capFaceViewController.onPhotoIDMatch(data, resolve: resolve, reject: reject); } else { - print("CapFace SDK has not been initialized!"); - return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); + return reject(self.initializationMessage, "CapFaceHasNotBeenInitialized", nil); } } @@ -103,8 +100,7 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { if self.isInitialized { self.capFaceViewController.onPhotoIDScan(data, resolve: resolve, reject: reject); } else { - print("CapFace SDK has not been initialized!"); - return reject("CapFace SDK has not been initialized!", "CapFaceHasNotBeenInitialized", nil); + return reject(self.initializationMessage, "CapFaceHasNotBeenInitialized", nil); } } diff --git a/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj b/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj index 90f3601..895b0d3 100644 --- a/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj +++ b/ios/ReactNativeCapfaceSdk.xcodeproj/project.pbxproj @@ -7,16 +7,13 @@ objects = { /* Begin PBXBuildFile section */ + 84F1C9812AB2257700A8261D /* CapFaceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F1C9802AB2257700A8261D /* CapFaceViewController.swift */; }; CEBC6E922AA66F3900A76DE0 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6E912AA66F3900A76DE0 /* Config.swift */; }; - CEBC6E952AA66F4900A76DE0 /* FaceTecViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6E942AA66F4900A76DE0 /* FaceTecViewController.swift */; }; CEBC6E982AA66F5800A76DE0 /* FaceTecUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6E972AA66F5800A76DE0 /* FaceTecUtilities.swift */; }; CEBC6EA52AA66FDD00A76DE0 /* ThemeHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EA42AA66FDD00A76DE0 /* ThemeHelpers.swift */; }; - CEBC6EAC2AA66FF300A76DE0 /* LivenessCheckProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EA62AA66FF300A76DE0 /* LivenessCheckProcessor.swift */; }; CEBC6EAD2AA66FF300A76DE0 /* ProcesingDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EA72AA66FF300A76DE0 /* ProcesingDelegate.swift */; }; - CEBC6EAE2AA66FF300A76DE0 /* EnrollmentProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EA82AA66FF300A76DE0 /* EnrollmentProcessor.swift */; }; CEBC6EAF2AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EA92AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift */; }; CEBC6EB02AA66FF300A76DE0 /* PhotoIDScanProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */; }; - CEBC6EB12AA66FF300A76DE0 /* AuthenticateProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEBC6EAB2AA66FF300A76DE0 /* AuthenticateProcessor.swift */; }; CEE455C32AA6869C0063FD54 /* ThemeUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE455C22AA6869C0063FD54 /* ThemeUtils.swift */; }; CEE7AF452AB09DDF00E90A50 /* FaceConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE7AF442AB09DDF00E90A50 /* FaceConfig.swift */; }; CEE7AF472AB09E7000E90A50 /* FaceProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE7AF462AB09E7000E90A50 /* FaceProcessor.swift */; }; @@ -39,17 +36,14 @@ /* Begin PBXFileReference section */ 134814201AA4EA6300B7C361 /* libReactNativeCapfaceSdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libReactNativeCapfaceSdk.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 84F1C9802AB2257700A8261D /* CapFaceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapFaceViewController.swift; sourceTree = ""; }; B3E7B5891CC2AC0600A0062D /* ReactNativeCapfaceSdk.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCapfaceSdk.mm; sourceTree = ""; }; CEBC6E912AA66F3900A76DE0 /* Config.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; - CEBC6E942AA66F4900A76DE0 /* FaceTecViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaceTecViewController.swift; sourceTree = ""; }; CEBC6E972AA66F5800A76DE0 /* FaceTecUtilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FaceTecUtilities.swift; sourceTree = ""; }; CEBC6EA42AA66FDD00A76DE0 /* ThemeHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThemeHelpers.swift; sourceTree = ""; }; - CEBC6EA62AA66FF300A76DE0 /* LivenessCheckProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LivenessCheckProcessor.swift; sourceTree = ""; }; CEBC6EA72AA66FF300A76DE0 /* ProcesingDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProcesingDelegate.swift; sourceTree = ""; }; - CEBC6EA82AA66FF300A76DE0 /* EnrollmentProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnrollmentProcessor.swift; sourceTree = ""; }; CEBC6EA92AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoIDMatchProcessor.swift; sourceTree = ""; }; CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoIDScanProcessor.swift; sourceTree = ""; }; - CEBC6EAB2AA66FF300A76DE0 /* AuthenticateProcessor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticateProcessor.swift; sourceTree = ""; }; CEE455C22AA6869C0063FD54 /* ThemeUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeUtils.swift; sourceTree = ""; }; CEE7AF442AB09DDF00E90A50 /* FaceConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaceConfig.swift; sourceTree = ""; }; CEE7AF462AB09E7000E90A50 /* FaceProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaceProcessor.swift; sourceTree = ""; }; @@ -97,7 +91,7 @@ CEBC6E932AA66F4000A76DE0 /* ViewController */ = { isa = PBXGroup; children = ( - CEBC6E942AA66F4900A76DE0 /* FaceTecViewController.swift */, + 84F1C9802AB2257700A8261D /* CapFaceViewController.swift */, ); path = ViewController; sourceTree = ""; @@ -114,9 +108,6 @@ isa = PBXGroup; children = ( CEBC6EA32AA66FD200A76DE0 /* Helpers */, - CEBC6EAB2AA66FF300A76DE0 /* AuthenticateProcessor.swift */, - CEBC6EA82AA66FF300A76DE0 /* EnrollmentProcessor.swift */, - CEBC6EA62AA66FF300A76DE0 /* LivenessCheckProcessor.swift */, CEBC6EA92AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift */, CEBC6EAA2AA66FF300A76DE0 /* PhotoIDScanProcessor.swift */, CEBC6EA72AA66FF300A76DE0 /* ProcesingDelegate.swift */, @@ -203,18 +194,15 @@ files = ( CEBC6E982AA66F5800A76DE0 /* FaceTecUtilities.swift in Sources */, CEE7AF452AB09DDF00E90A50 /* FaceConfig.swift in Sources */, - CEBC6E952AA66F4900A76DE0 /* FaceTecViewController.swift in Sources */, F4FF95D7245B92E800C19C63 /* ReactNativeCapfaceSdk.swift in Sources */, CEE455C32AA6869C0063FD54 /* ThemeUtils.swift in Sources */, CEBC6EAD2AA66FF300A76DE0 /* ProcesingDelegate.swift in Sources */, CEBC6EA52AA66FDD00A76DE0 /* ThemeHelpers.swift in Sources */, CEE7AF492AB09FBD00E90A50 /* KeyFaceProcessor.swift in Sources */, CEE7AF472AB09E7000E90A50 /* FaceProcessor.swift in Sources */, + 84F1C9812AB2257700A8261D /* CapFaceViewController.swift in Sources */, CEBC6EAF2AA66FF300A76DE0 /* PhotoIDMatchProcessor.swift in Sources */, - CEBC6EB12AA66FF300A76DE0 /* AuthenticateProcessor.swift in Sources */, CEBC6EB02AA66FF300A76DE0 /* PhotoIDScanProcessor.swift in Sources */, - CEBC6EAE2AA66FF300A76DE0 /* EnrollmentProcessor.swift in Sources */, - CEBC6EAC2AA66FF300A76DE0 /* LivenessCheckProcessor.swift in Sources */, CEBC6E922AA66F3900A76DE0 /* Config.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/ios/ViewController/CapFaceViewController.swift b/ios/ViewController/CapFaceViewController.swift index 1cca905..b02ce7b 100644 --- a/ios/ViewController/CapFaceViewController.swift +++ b/ios/ViewController/CapFaceViewController.swift @@ -11,6 +11,7 @@ import FaceTecSDK import LocalAuthentication class CapFaceViewController: UIViewController, URLSessionDelegate { + private let exceptionHttpMessage = "Exception raised while attempting HTTPS call." var isSuccess: Bool! = false var latestExternalDatabaseRefID: String = "" var latestSessionResult: FaceTecSessionResult! @@ -22,13 +23,21 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { override func viewDidLoad() { super.viewDidLoad() } + + private func generateUUID() -> String { + return "ios_app_" + UUID().uuidString + } func onFaceUser(_ config: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { setProcessorPromise(resolve, rejecter: reject); getSessionToken() { sessionToken in self.resetLatestResults() - self.latestProcessor = FaceProcessor(sessionToken: sessionToken, fromViewController: self, config: config) + let faceConfig = FaceConfig(config: config) + if (faceConfig.isWhichFlow(KeyFaceProcessor.enrollMessage, key: faceConfig.getKey() ?? "")) { + self.latestExternalDatabaseRefID = self.generateUUID() + } + self.latestProcessor = FaceProcessor(sessionToken: sessionToken, fromViewController: self, faceConfig: faceConfig) } } @@ -37,7 +46,7 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { getSessionToken() { sessionToken in self.resetLatestResults() - self.latestExternalDatabaseRefID = "ios_app_" + UUID().uuidString + self.latestExternalDatabaseRefID = self.generateUUID() self.latestProcessor = PhotoIDMatchProcessor(sessionToken: sessionToken, fromViewController: self, data: data) } } @@ -98,26 +107,23 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in if let httpResponse = response as? HTTPURLResponse { if httpResponse.statusCode < 200 || httpResponse.statusCode >= 299 { - print("Exception raised while attempting HTTPS call. Status code: \(httpResponse.statusCode)"); if self.processorRejecter != nil { - self.processorRejecter("Exception raised while attempting HTTPS call.", "HTTPSError", nil); + self.processorRejecter("Exception raised while attempting to parse JSON result.", "JSONError", nil); } return } } if let error = error { - print("Exception raised while attempting HTTPS call.") if self.processorRejecter != nil { - self.processorRejecter("Exception raised while attempting HTTPS call.", "HTTPSError", nil); + self.processorRejecter(self.exceptionHttpMessage, "HTTPSError", nil); } return } guard let data = data else { - print("Exception raised while attempting HTTPS call.") if self.processorRejecter != nil { - self.processorRejecter("Exception raised while attempting HTTPS call.", "HTTPSError", nil); + self.processorRejecter(self.exceptionHttpMessage, "HTTPSError", nil); } return } @@ -127,9 +133,14 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { sessionTokenCallback(responseJSONObj["sessionToken"] as! String) return } else { - print("Exception raised while attempting HTTPS call.") + var errorMessage: String! + if ((responseJSONObj["errorMessage"] as? String) != nil) { + errorMessage = responseJSONObj["errorMessage"] as! String + } else { + errorMessage = "Response JSON is missing sessionToken." + } if self.processorRejecter != nil { - self.processorRejecter("Exception raised while attempting HTTPS call.", "HTTPSError", nil); + self.processorRejecter(errorMessage, "JSONError", nil); } } } From b08ebede1e4f5cdb535d82009d854fa526ab122a Mon Sep 17 00:00:00 2001 From: Bruno Fialho Date: Wed, 13 Sep 2023 14:54:38 -0300 Subject: [PATCH 18/43] fix: statusBarStyle --- .../project.pbxproj | 90 +++++++++--------- example/package-lock.json | 68 ++++++++++---- ios/Utilities/FaceTecUtilities.swift | 19 ++-- .../CapFaceViewController.swift | 8 +- package-lock.json | 94 ++++++++++++------- 5 files changed, 172 insertions(+), 107 deletions(-) diff --git a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj index 3b5b86f..3f75430 100644 --- a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj +++ b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj @@ -11,9 +11,9 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 30ED54A08B1857CC018258D1 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */; }; + 22D0CFF7FEC440F271506AA9 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; - F29AFA0877BFE3096EC9A2B1 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; + C91F24D5EF32BD1F390D174B /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -30,20 +30,20 @@ 00E356EE1AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeCapfaceSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCapfaceSdkExampleTests.m; sourceTree = ""; }; - 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; + 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* ReactNativeCapfaceSdkExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeCapfaceSdkExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ReactNativeCapfaceSdkExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = ReactNativeCapfaceSdkExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeCapfaceSdkExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeCapfaceSdkExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeCapfaceSdkExample/main.m; sourceTree = ""; }; - 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; + 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeCapfaceSdkExample/LaunchScreen.storyboard; sourceTree = ""; }; - DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; - EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; + 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; + 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; + AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; + C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; - F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -51,7 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - F29AFA0877BFE3096EC9A2B1 /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, + C91F24D5EF32BD1F390D174B /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 30ED54A08B1857CC018258D1 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, + 22D0CFF7FEC440F271506AA9 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,8 +100,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - 0B4911760D9BD6DEE3E9101F /* libPods-ReactNativeCapfaceSdkExample.a */, - F76330764E716CF44FF843EE /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, + C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */, + 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, ); name = Frameworks; sourceTree = ""; @@ -140,10 +140,10 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, - DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, - 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, - 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, + AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, + 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, + 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, + 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -155,12 +155,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExampleTests" */; buildPhases = ( - 4ED8069BB55C71FD73F316E6 /* [CP] Check Pods Manifest.lock */, + C996117FAE27CC09311295E2 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 8D2F60CF7E07FA008C9D6CA8 /* [CP] Embed Pods Frameworks */, - 650591FC5209931A342BF378 /* [CP] Copy Pods Resources */, + 865C50E22E6C7C2E8DF1AF32 /* [CP] Embed Pods Frameworks */, + 3D0B7ADB0D87A0928F4CCFF3 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -176,14 +176,14 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExample" */; buildPhases = ( - 6E47E5EDDB44289A43B14A27 /* [CP] Check Pods Manifest.lock */, + 5D1D2A32F60AC8D524AB6C52 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 29E1986A3746A3C2E9CD66F5 /* [CP] Embed Pods Frameworks */, - 0B99F53FDD0BDE18FA68EAC0 /* [CP] Copy Pods Resources */, + FC65C77F5CDAB55C15DE1FFE /* [CP] Embed Pods Frameworks */, + 3C4B398EA6C5E7DC3EA9AA19 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -266,7 +266,7 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 0B99F53FDD0BDE18FA68EAC0 /* [CP] Copy Pods Resources */ = { + 3C4B398EA6C5E7DC3EA9AA19 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -283,24 +283,24 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 29E1986A3746A3C2E9CD66F5 /* [CP] Embed Pods Frameworks */ = { + 3D0B7ADB0D87A0928F4CCFF3 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 4ED8069BB55C71FD73F316E6 /* [CP] Check Pods Manifest.lock */ = { + 5D1D2A32F60AC8D524AB6C52 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -315,31 +315,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 650591FC5209931A342BF378 /* [CP] Copy Pods Resources */ = { + 865C50E22E6C7C2E8DF1AF32 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - 6E47E5EDDB44289A43B14A27 /* [CP] Check Pods Manifest.lock */ = { + C996117FAE27CC09311295E2 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -354,28 +354,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8D2F60CF7E07FA008C9D6CA8 /* [CP] Embed Pods Frameworks */ = { + FC65C77F5CDAB55C15DE1FFE /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FD10A7F022414F080027D42C /* Start Packager */ = { @@ -430,7 +430,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0CD820095DBF094DDCF3D300 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; + baseConfigurationReference = 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -457,7 +457,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4DF1F7AB0C64A60A80EA1AF1 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; + baseConfigurationReference = 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -481,7 +481,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = EC146EAED308793B7A34D8C1 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; + baseConfigurationReference = AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -509,7 +509,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DCFD841CDFE339649EB1D397 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; + baseConfigurationReference = 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/example/package-lock.json b/example/package-lock.json index aa7e44d..9163894 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -4969,9 +4969,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001533", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001533.tgz", - "integrity": "sha512-9aY/b05NKU4Yl2sbcJhn4A7MsGwR1EPfW/nrqsnqVA0Oq50wpmPaGI+R1Z0UKlUl96oxUkGEOILWtOHck0eCWw==", + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", "funding": [ { "type": "opencollective", @@ -5025,9 +5025,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", "engines": { "node": ">=6" }, @@ -5330,12 +5330,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -5409,9 +5424,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.516", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.516.tgz", - "integrity": "sha512-A8xs6nie7jw/9GFRrCPrrE+maux1M3gSnFe1HVstK6ubH+7v5hMDFq3qoNxTRssYyz6jdzk/1wLebT+9tisLKA==" + "version": "1.4.519", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz", + "integrity": "sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -10136,14 +10151,14 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -10461,6 +10476,20 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -10677,9 +10706,9 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz", - "integrity": "sha512-6i5hL3MqG/K2G43mWXWgP+qizFW/QH/7kCNN13JrJS5q48FN5IKksLDscexKP3dnmB6cdm9jlNgAsWNLpSykmA==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -10689,6 +10718,7 @@ "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", "side-channel": "^1.0.4" }, "funding": { diff --git a/ios/Utilities/FaceTecUtilities.swift b/ios/Utilities/FaceTecUtilities.swift index 10f11ef..179ff21 100644 --- a/ios/Utilities/FaceTecUtilities.swift +++ b/ios/Utilities/FaceTecUtilities.swift @@ -14,22 +14,25 @@ class FaceTecUtilities: NSObject { private static func preferredStatusBarStyle() -> UIStatusBarStyle { if #available(iOS 13, *) { - let statusBarColor: UIStatusBarStyle = CapThemeUtils.handleStatusBarStyle("defaultStatusBarColorIos") - return statusBarColor; + return CapThemeUtils.handleStatusBarStyle("defaultStatusBarColorIos") } else { - return DefaultStatusBarStyle; + return DefaultStatusBarStyle } } public static func getTopMostViewController() -> UIViewController? { - UIApplication.shared.statusBarStyle = preferredStatusBarStyle(); + if let topViewController = UIApplication.shared.windows.first?.rootViewController { + var topMostViewController = topViewController - var topMostViewController = UIApplication.shared.windows[0].rootViewController; + while let presentedViewController = topMostViewController.presentedViewController { + topMostViewController = presentedViewController + } - while let presentedViewController = topMostViewController?.presentedViewController { - topMostViewController = presentedViewController; + topMostViewController.setNeedsStatusBarAppearanceUpdate() + + return topMostViewController } - return topMostViewController; + return nil } } diff --git a/ios/ViewController/CapFaceViewController.swift b/ios/ViewController/CapFaceViewController.swift index b02ce7b..3456f47 100644 --- a/ios/ViewController/CapFaceViewController.swift +++ b/ios/ViewController/CapFaceViewController.swift @@ -28,6 +28,10 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { return "ios_app_" + UUID().uuidString } + override var preferredStatusBarStyle: UIStatusBarStyle { + return FaceTecUtilities.DefaultStatusBarStyle + } + func onFaceUser(_ config: NSDictionary, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { setProcessorPromise(resolve, rejecter: reject); @@ -61,11 +65,11 @@ class CapFaceViewController: UIViewController, URLSessionDelegate { } func onComplete() { - UIApplication.shared.statusBarStyle = FaceTecUtilities.DefaultStatusBarStyle; - if self.latestProcessor != nil { self.isSuccess = self.latestProcessor.isSuccess(); } + + setNeedsStatusBarAppearanceUpdate() ReactNativeCapfaceSdk.emitter.sendEvent(withName: "onCloseModal", body: false); diff --git a/package-lock.json b/package-lock.json index 075d097..b2b233c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2238,7 +2238,6 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, "optional": true, - "peer": true, "engines": { "node": ">=0.1.90" } @@ -2872,9 +2871,9 @@ } }, "node_modules/@evilmartians/lefthook": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.4.10.tgz", - "integrity": "sha512-pQ2GNFWix8+2V5/H7BkJjm92N+R1eDQu9Wmqv3FBZeVi1ReUGhMcYskGTJ0laR3PtS/xahMUsR6pX4u81G7iHw==", + "version": "1.4.11", + "resolved": "https://registry.npmjs.org/@evilmartians/lefthook/-/lefthook-1.4.11.tgz", + "integrity": "sha512-QYiOCtB4gYfIfj350CDjf5kjx25/ko/vhXZ1AD7+W/EwPn0B+6+rXDIrweaJFtIp/6TWcA/RVj/AFuckb5IKNw==", "cpu": [ "x64", "arm64", @@ -7890,9 +7889,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001533", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001533.tgz", - "integrity": "sha512-9aY/b05NKU4Yl2sbcJhn4A7MsGwR1EPfW/nrqsnqVA0Oq50wpmPaGI+R1Z0UKlUl96oxUkGEOILWtOHck0eCWw==", + "version": "1.0.30001534", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz", + "integrity": "sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==", "dev": true, "funding": [ { @@ -8007,9 +8006,9 @@ } }, "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.1.tgz", + "integrity": "sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ==", "dev": true, "engines": { "node": ">=6" @@ -8023,7 +8022,6 @@ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", "dev": true, - "peer": true, "dependencies": { "string-width": "^4.2.0" }, @@ -8486,9 +8484,9 @@ "dev": true }, "node_modules/cosmiconfig": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.5.tgz", - "integrity": "sha512-A5Xry3xfS96wy2qbiLkQLAg4JUrR2wvfybxj6yqLmrUfMAvhS3MZxIP2oQn0grgYIvJqzpeTEWu4vK0t+12NNw==", + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "dev": true, "dependencies": { "import-fresh": "^3.3.0", @@ -8897,6 +8895,20 @@ "node": ">=10" } }, + "node_modules/define-data-property": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.0.tgz", + "integrity": "sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/define-lazy-prop": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", @@ -8910,11 +8922,12 @@ } }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -9323,9 +9336,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.516", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.516.tgz", - "integrity": "sha512-A8xs6nie7jw/9GFRrCPrrE+maux1M3gSnFe1HVstK6ubH+7v5hMDFq3qoNxTRssYyz6jdzk/1wLebT+9tisLKA==", + "version": "1.4.519", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz", + "integrity": "sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==", "dev": true }, "node_modules/emittery": { @@ -22056,9 +22069,9 @@ } }, "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", - "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", "dev": true, "dependencies": { "lru-cache": "^10.0.1" @@ -22327,14 +22340,14 @@ } }, "node_modules/regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "set-function-name": "^2.0.0" }, "engines": { "node": ">= 0.4" @@ -23295,9 +23308,9 @@ } }, "node_modules/semantic-release/node_modules/hosted-git-info": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.0.tgz", - "integrity": "sha512-ICclEpTLhHj+zCuSb2/usoNXSVkxUSIopre+b1w8NDY9Dntp9LO4vLdHYI336TH8sAqwrRgnSfdkBG2/YpisHA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz", + "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==", "dev": true, "peer": true, "dependencies": { @@ -23664,6 +23677,20 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -24148,9 +24175,9 @@ } }, "node_modules/string.prototype.matchall": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.9.tgz", - "integrity": "sha512-6i5hL3MqG/K2G43mWXWgP+qizFW/QH/7kCNN13JrJS5q48FN5IKksLDscexKP3dnmB6cdm9jlNgAsWNLpSykmA==", + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz", + "integrity": "sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", @@ -24160,6 +24187,7 @@ "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", "side-channel": "^1.0.4" }, "funding": { From 6f20c2481e4d792de365c653c1ce3fb1c40f260a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 09:43:15 -0300 Subject: [PATCH 19/43] feat: created convert to rgb color to hexadecimal color helper --- src/helpers/colors.ts | 47 +++++++++++++++++++++++++++++++++++++++++++ src/helpers/index.ts | 1 + 2 files changed, 48 insertions(+) create mode 100644 src/helpers/colors.ts create mode 100644 src/helpers/index.ts diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts new file mode 100644 index 0000000..7d494c3 --- /dev/null +++ b/src/helpers/colors.ts @@ -0,0 +1,47 @@ +function parseFloat(value?: string): number { + if (!value || Number.isNaN(value)) return -1; + + return Number.parseFloat(value); +} + +function isRgbNumber(numberColor: number): boolean { + if (numberColor !== 0 && !numberColor) return false; + + const MIN_NUMBER_COLOR = 0; + const MAX_NUMBER_COLOR = 255; + + return numberColor >= MIN_NUMBER_COLOR && numberColor <= MAX_NUMBER_COLOR; +} + +export function rgbToHexadecimal(rgbColor: string): string | null { + const LENGTH_OF_RGB_COLOR = 3; + + const regexToRemoveCharacters = /[A-Z()\s]/gi; + const redGreenAndBlueNumbers = rgbColor + .toLowerCase() + .replace(regexToRemoveCharacters, '') + .split(','); + + if (redGreenAndBlueNumbers.length !== LENGTH_OF_RGB_COLOR) return null; + + const [red, green, blue] = redGreenAndBlueNumbers; + const allColorsExists = !!red && !!green && !!blue; + if (!allColorsExists) return null; + + const redNumber = parseFloat(red); + const greenNumber = parseFloat(green); + const blueNumber = parseFloat(blue); + + if ( + !isRgbNumber(redNumber) || + !isRgbNumber(greenNumber) || + !isRgbNumber(blueNumber) + ) { + return null; + } + + const byteNumbers = + (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; + + return '#' + byteNumbers.toString(16).slice(1).toUpperCase(); +} diff --git a/src/helpers/index.ts b/src/helpers/index.ts new file mode 100644 index 0000000..1bae1c0 --- /dev/null +++ b/src/helpers/index.ts @@ -0,0 +1 @@ +export * from './colors'; From 8404e07abe4817371e11f8df16f73300760888e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 09:43:52 -0300 Subject: [PATCH 20/43] chore: add `no-bitwise`eslint rule --- package.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/package.json b/package.json index 1824d8e..4272c73 100644 --- a/package.json +++ b/package.json @@ -111,6 +111,15 @@ "prettier" ], "rules": { + "no-bitwise": [ + "error", + { + "allow": [ + "<<", + "|" + ] + } + ], "prettier/prettier": [ "error", { From 274c158f598644f4abafc13d8fa6f4ef531807e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 10:24:47 -0300 Subject: [PATCH 21/43] feat: created format hexadecimal colors helper --- src/helpers/colors.ts | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index 7d494c3..fbd71dc 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -4,6 +4,11 @@ function parseFloat(value?: string): number { return Number.parseFloat(value); } +function isHexColor(hexColor: string): boolean { + const regexToCheckIfHexColor = /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3})$/; + return regexToCheckIfHexColor.test(hexColor); +} + function isRgbNumber(numberColor: number): boolean { if (numberColor !== 0 && !numberColor) return false; @@ -43,5 +48,24 @@ export function rgbToHexadecimal(rgbColor: string): string | null { const byteNumbers = (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; - return '#' + byteNumbers.toString(16).slice(1).toUpperCase(); + const hexColor = '#' + byteNumbers.toString(16).slice(1).toUpperCase(); + + if (!isHexColor(hexColor)) return null; + return hexColor; +} + +export function formatHexColor(hexColor: string): string | null { + if (!isHexColor(hexColor)) return null; + const MIN_LENGTH_HEX_COLOR = 4; + const MIDDLE_LENGTH_HEX_COLOR = 7; + const MAX_LENGTH_HEX_COLOR = 9; + + const isMiddleHexColor = hexColor.length === MIDDLE_LENGTH_HEX_COLOR; + const isMaxHexColor = hexColor.length === MAX_LENGTH_HEX_COLOR; + if (isMiddleHexColor || isMaxHexColor) return hexColor; + + if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; + + const [firstChar, secondChar, thirdChar] = hexColor.slice(1); + return `#${firstChar}${firstChar}${secondChar}${secondChar}${thirdChar}${thirdChar}`; } From e8438077ec92ccdfb159776cb6b05d63c159022e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 11:55:57 -0300 Subject: [PATCH 22/43] feat: created convert to rgba color to hexadecimal color helper --- src/helpers/colors.ts | 74 ++++++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index fbd71dc..a6e3df9 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -1,7 +1,6 @@ -function parseFloat(value?: string): number { +function parseInt(value?: string): number { if (!value || Number.isNaN(value)) return -1; - - return Number.parseFloat(value); + return Number.parseInt(value, 10); } function isHexColor(hexColor: string): boolean { @@ -9,16 +8,12 @@ function isHexColor(hexColor: string): boolean { return regexToCheckIfHexColor.test(hexColor); } -function isRgbNumber(numberColor: number): boolean { - if (numberColor !== 0 && !numberColor) return false; - - const MIN_NUMBER_COLOR = 0; - const MAX_NUMBER_COLOR = 255; - - return numberColor >= MIN_NUMBER_COLOR && numberColor <= MAX_NUMBER_COLOR; +function isNumberBetween(value: number, min: number, max: number): boolean { + if (value !== 0 && !value) return false; + return value >= min && value <= max; } -export function rgbToHexadecimal(rgbColor: string): string | null { +export function rgbToHex(rgbColor: string): string | null { const LENGTH_OF_RGB_COLOR = 3; const regexToRemoveCharacters = /[A-Z()\s]/gi; @@ -33,22 +28,63 @@ export function rgbToHexadecimal(rgbColor: string): string | null { const allColorsExists = !!red && !!green && !!blue; if (!allColorsExists) return null; - const redNumber = parseFloat(red); - const greenNumber = parseFloat(green); - const blueNumber = parseFloat(blue); + const redNumber = parseInt(red); + const greenNumber = parseInt(green); + const blueNumber = parseInt(blue); if ( - !isRgbNumber(redNumber) || - !isRgbNumber(greenNumber) || - !isRgbNumber(blueNumber) + !isNumberBetween(redNumber, 0, 255) || + !isNumberBetween(greenNumber, 0, 255) || + !isNumberBetween(blueNumber, 0, 255) ) { return null; } const byteNumbers = (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; + const hexCharacters = byteNumbers.toString(16).slice(1).toUpperCase(); + const hexColor = `#${hexCharacters}`; + + if (!isHexColor(hexColor)) return null; + return hexColor; +} + +export function rgbaToHex(rgbaColor: string): string | null { + const LENGTH_OF_RGBA_COLOR = 4; + + const regexToRemoveCharacters = /[A-Z()\s]/gi; + const redGreenAndBlueNumbers = rgbaColor + .toLowerCase() + .replace(regexToRemoveCharacters, '') + .split(','); + + if (redGreenAndBlueNumbers.length !== LENGTH_OF_RGBA_COLOR) return null; + + const [red, green, blue, alpha] = redGreenAndBlueNumbers; + const allColorsExists = !!red && !!green && !!blue && !!alpha; + if (!allColorsExists) return null; + + const redNumber = parseInt(red); + const greenNumber = parseInt(green); + const blueNumber = parseInt(blue); + const alphaNumber = parseInt(alpha); + + if ( + !isNumberBetween(redNumber, 0, 255) || + !isNumberBetween(greenNumber, 0, 255) || + !isNumberBetween(blueNumber, 0, 255) || + !isNumberBetween(alphaNumber, 0, 1) + ) { + return null; + } + + const redNumericString = redNumber.toString(16); + const greenNumericString = greenNumber.toString(16); + const blueNumericString = blueNumber.toString(16); + const alphaNumericString = alphaNumber.toString(16).slice(1); - const hexColor = '#' + byteNumbers.toString(16).slice(1).toUpperCase(); + const hexColor = + `#${redNumericString}${greenNumericString}${blueNumericString}${alphaNumericString}`.toUpperCase(); if (!isHexColor(hexColor)) return null; return hexColor; @@ -67,5 +103,5 @@ export function formatHexColor(hexColor: string): string | null { if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; const [firstChar, secondChar, thirdChar] = hexColor.slice(1); - return `#${firstChar}${firstChar}${secondChar}${secondChar}${thirdChar}${thirdChar}`; + return `#${firstChar}${firstChar}${secondChar}${secondChar}${thirdChar}${thirdChar}`.toUpperCase(); } From 7fb78661b6780f8bfc0b250b372c0dbbc1f1bc59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 12:17:14 -0300 Subject: [PATCH 23/43] fix: a small adjusts when rgba color is dark --- src/helpers/colors.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index a6e3df9..5f41b4d 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -42,8 +42,7 @@ export function rgbToHex(rgbColor: string): string | null { const byteNumbers = (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; - const hexCharacters = byteNumbers.toString(16).slice(1).toUpperCase(); - const hexColor = `#${hexCharacters}`; + const hexColor = `#${byteNumbers.toString(16).slice(1).toUpperCase()}`; if (!isHexColor(hexColor)) return null; return hexColor; @@ -78,13 +77,14 @@ export function rgbaToHex(rgbaColor: string): string | null { return null; } - const redNumericString = redNumber.toString(16); - const greenNumericString = greenNumber.toString(16); - const blueNumericString = blueNumber.toString(16); - const alphaNumericString = alphaNumber.toString(16).slice(1); - - const hexColor = - `#${redNumericString}${greenNumericString}${blueNumericString}${alphaNumericString}`.toUpperCase(); + const alphaNumericString = (((alpha as any) * 255) | (1 << 8)) + .toString(16) + .slice(1); + const byteNumbers = + (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; + const hexColor = `#${byteNumbers + .toString(16) + .slice(1)}${alphaNumericString}`.toUpperCase(); if (!isHexColor(hexColor)) return null; return hexColor; From 3ab9697977d012ca859f7e7a1e72023fb401c9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 14:27:38 -0300 Subject: [PATCH 24/43] feat: created convert to hsl color to hexadecimal color helper --- src/helpers/colors.ts | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index 5f41b4d..3558967 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -105,3 +105,50 @@ export function formatHexColor(hexColor: string): string | null { const [firstChar, secondChar, thirdChar] = hexColor.slice(1); return `#${firstChar}${firstChar}${secondChar}${secondChar}${thirdChar}${thirdChar}`.toUpperCase(); } + +export function hslToHex(hslColor: string): string | null { + const LENGTH_OF_HSL_COLOR = 3; + + const regexToRemoveCharacters = /[A-Z()\s%]/gi; + const hueSaturationAndLightnessNumbers = hslColor + .toLowerCase() + .replace(regexToRemoveCharacters, '') + .split(','); + + if (hueSaturationAndLightnessNumbers.length !== LENGTH_OF_HSL_COLOR) + return null; + + const [hue, saturation, lightness] = hueSaturationAndLightnessNumbers; + const allColorsExists = !!hue && !!saturation && !!lightness; + if (!allColorsExists) return null; + + const hueNumber = parseInt(hue); + const saturationNumber = parseInt(saturation); + let lightnessNumber = parseInt(lightness); + + if ( + !isNumberBetween(hueNumber, 0, 360) || + !isNumberBetween(saturationNumber, 0, 100) || + !isNumberBetween(lightnessNumber, 0, 100) + ) { + return null; + } + + lightnessNumber /= 100; + const alpha = + (saturationNumber * Math.min(lightnessNumber, 1 - lightnessNumber)) / 100; + + const calculateHex = (bytes: number) => { + const hueValue = (bytes + hueNumber / 30) % 12; + const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); + const color = lightnessNumber - alpha * maxHueValue; + return Math.round(255 * color) + .toString(16) + .padStart(2, '0'); + }; + + const hexColor = `#${calculateHex(0)}${calculateHex(8)}${calculateHex(4)}`; + + if (!isHexColor(hexColor)) return null; + return hexColor; +} From b21d249afbe471042d90a28bed9604842b8abc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 14:42:38 -0300 Subject: [PATCH 25/43] feat: created convert to hsla color to hexadecimal color helper --- src/helpers/colors.ts | 75 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index 3558967..d994073 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -17,14 +17,14 @@ export function rgbToHex(rgbColor: string): string | null { const LENGTH_OF_RGB_COLOR = 3; const regexToRemoveCharacters = /[A-Z()\s]/gi; - const redGreenAndBlueNumbers = rgbColor + const rgbValues = rgbColor .toLowerCase() .replace(regexToRemoveCharacters, '') .split(','); - if (redGreenAndBlueNumbers.length !== LENGTH_OF_RGB_COLOR) return null; + if (rgbValues.length !== LENGTH_OF_RGB_COLOR) return null; - const [red, green, blue] = redGreenAndBlueNumbers; + const [red, green, blue] = rgbValues; const allColorsExists = !!red && !!green && !!blue; if (!allColorsExists) return null; @@ -52,21 +52,21 @@ export function rgbaToHex(rgbaColor: string): string | null { const LENGTH_OF_RGBA_COLOR = 4; const regexToRemoveCharacters = /[A-Z()\s]/gi; - const redGreenAndBlueNumbers = rgbaColor + const rgbaValues = rgbaColor .toLowerCase() .replace(regexToRemoveCharacters, '') .split(','); - if (redGreenAndBlueNumbers.length !== LENGTH_OF_RGBA_COLOR) return null; + if (rgbaValues.length !== LENGTH_OF_RGBA_COLOR) return null; - const [red, green, blue, alpha] = redGreenAndBlueNumbers; + const [red, green, blue, alpha] = rgbaValues; const allColorsExists = !!red && !!green && !!blue && !!alpha; if (!allColorsExists) return null; const redNumber = parseInt(red); const greenNumber = parseInt(green); const blueNumber = parseInt(blue); - const alphaNumber = parseInt(alpha); + const alphaNumber = Number.parseFloat(alpha); if ( !isNumberBetween(redNumber, 0, 255) || @@ -110,15 +110,14 @@ export function hslToHex(hslColor: string): string | null { const LENGTH_OF_HSL_COLOR = 3; const regexToRemoveCharacters = /[A-Z()\s%]/gi; - const hueSaturationAndLightnessNumbers = hslColor + const hslValues = hslColor .toLowerCase() .replace(regexToRemoveCharacters, '') .split(','); - if (hueSaturationAndLightnessNumbers.length !== LENGTH_OF_HSL_COLOR) - return null; + if (hslValues.length !== LENGTH_OF_HSL_COLOR) return null; - const [hue, saturation, lightness] = hueSaturationAndLightnessNumbers; + const [hue, saturation, lightness] = hslValues; const allColorsExists = !!hue && !!saturation && !!lightness; if (!allColorsExists) return null; @@ -135,13 +134,13 @@ export function hslToHex(hslColor: string): string | null { } lightnessNumber /= 100; - const alpha = + const brightness = (saturationNumber * Math.min(lightnessNumber, 1 - lightnessNumber)) / 100; const calculateHex = (bytes: number) => { const hueValue = (bytes + hueNumber / 30) % 12; const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); - const color = lightnessNumber - alpha * maxHueValue; + const color = lightnessNumber - brightness * maxHueValue; return Math.round(255 * color) .toString(16) .padStart(2, '0'); @@ -152,3 +151,53 @@ export function hslToHex(hslColor: string): string | null { if (!isHexColor(hexColor)) return null; return hexColor; } + +export function hslaToHex(hslaColor: string): string | null { + const LENGTH_OF_HSLA_COLOR = 4; + + const regexToRemoveCharacters = /[A-Z()\s%]/gi; + const hslaValues = hslaColor + .toLowerCase() + .replace(regexToRemoveCharacters, '') + .split(','); + + if (hslaValues.length !== LENGTH_OF_HSLA_COLOR) return null; + + const [hue, saturation, lightness, alpha] = hslaValues; + const allColorsExists = !!hue && !!saturation && !!lightness && !!alpha; + if (!allColorsExists) return null; + + const hueNumber = parseInt(hue); + const saturationNumber = parseInt(saturation); + let lightnessNumber = parseInt(lightness); + const alphaNumber = Number.parseFloat(alpha); + + if ( + !isNumberBetween(hueNumber, 0, 360) || + !isNumberBetween(saturationNumber, 0, 100) || + !isNumberBetween(lightnessNumber, 0, 100) + ) { + return null; + } + + lightnessNumber /= 100; + const brightness = + (saturationNumber * Math.min(lightnessNumber, 1 - lightnessNumber)) / 100; + + const calculateHex = (bytes: number) => { + const hueValue = (bytes + hueNumber / 30) % 12; + const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); + const color = lightnessNumber - brightness * maxHueValue; + return Math.round(255 * color) + .toString(16) + .padStart(2, '0'); + }; + + const alphaValue = Math.round(alphaNumber * 255) + .toString(16) + .padStart(2, '0'); + const hexColor = `#${calculateHex(0)}${calculateHex(8)}${calculateHex(4)}`; + + if (!isHexColor(`${hexColor}${alphaValue}`)) return null; + return `${hexColor}${alphaValue}`; +} From 1e97dc3d29f4fb61185458b47138dd0e87281579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 14:46:21 -0300 Subject: [PATCH 26/43] chore: small refactor in hsl functions --- src/helpers/colors.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index d994073..a782a30 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -146,10 +146,10 @@ export function hslToHex(hslColor: string): string | null { .padStart(2, '0'); }; - const hexColor = `#${calculateHex(0)}${calculateHex(8)}${calculateHex(4)}`; + const hexColor = '#' + calculateHex(0) + calculateHex(8) + calculateHex(4); - if (!isHexColor(hexColor)) return null; - return hexColor; + if (!isHexColor(hexColor.toUpperCase())) return null; + return hexColor.toUpperCase(); } export function hslaToHex(hslaColor: string): string | null { @@ -196,8 +196,10 @@ export function hslaToHex(hslaColor: string): string | null { const alphaValue = Math.round(alphaNumber * 255) .toString(16) .padStart(2, '0'); - const hexColor = `#${calculateHex(0)}${calculateHex(8)}${calculateHex(4)}`; + const hexCharacters = + '#' + calculateHex(0) + calculateHex(8) + calculateHex(4); + const hexColor = `${hexCharacters}${alphaValue}`.toUpperCase(); - if (!isHexColor(`${hexColor}${alphaValue}`)) return null; - return `${hexColor}${alphaValue}`; + if (!isHexColor(hexColor)) return null; + return hexColor; } From ba990adad59b29516bff78ffa9f4d1b1bf80b495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 16:09:35 -0300 Subject: [PATCH 27/43] chore: refactoring convert color functions --- src/helpers/colors.ts | 227 +++++++++++++++++------------------------- 1 file changed, 91 insertions(+), 136 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index a782a30..580f205 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -1,8 +1,3 @@ -function parseInt(value?: string): number { - if (!value || Number.isNaN(value)) return -1; - return Number.parseInt(value, 10); -} - function isHexColor(hexColor: string): boolean { const regexToCheckIfHexColor = /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3})$/; return regexToCheckIfHexColor.test(hexColor); @@ -13,35 +8,73 @@ function isNumberBetween(value: number, min: number, max: number): boolean { return value >= min && value <= max; } -export function rgbToHex(rgbColor: string): string | null { - const LENGTH_OF_RGB_COLOR = 3; +function calculateHslHex( + bytes: number, + hue: number, + lightness: number, + saturation: number +): string { + const lightnessDivide = lightness / 100; + const brightness = + (saturation * Math.min(lightnessDivide, 1 - lightnessDivide)) / 100; + const hueValue = (bytes + hue / 30) % 12; + const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); + const color = lightnessDivide - brightness * maxHueValue; + return Math.round(255 * color) + .toString(16) + .padStart(2, '0'); +} + +type ColorTableType = 'RGB' | 'RGBA' | 'HSL' | 'HSLA'; + +function isBetweenLimits(type: ColorTableType, colors: number[]): boolean { + const hasAlpha = type === 'HSLA' || type === 'RGBA'; + const isRgb = type === 'RGBA' || type === 'RGB'; + + const [firstColor, secondColor, thirdColor, alpha] = colors; + const isValid = + isNumberBetween(firstColor!, 0, isRgb ? 255 : 360) && + isNumberBetween(secondColor!, 0, isRgb ? 255 : 100) && + isNumberBetween(thirdColor!, 0, isRgb ? 255 : 100); + + if (hasAlpha) return isValid && isNumberBetween(alpha!, 0, 1); + return isValid; +} + +function getColorTable(type: ColorTableType, color: string): number[] | null { + const hasAlpha = type === 'HSLA' || type === 'RGBA'; + const COLOR_LENGTH = hasAlpha ? 4 : 3; - const regexToRemoveCharacters = /[A-Z()\s]/gi; - const rgbValues = rgbColor + const regexToRemoveCharacters = hasAlpha ? /[A-Z()\s%]/gi : /[A-Z()\s]/gi; + const tableValues = color .toLowerCase() .replace(regexToRemoveCharacters, '') .split(','); - if (rgbValues.length !== LENGTH_OF_RGB_COLOR) return null; + if (tableValues.length !== COLOR_LENGTH) return null; - const [red, green, blue] = rgbValues; - const allColorsExists = !!red && !!green && !!blue; - if (!allColorsExists) return null; + const [firstColor, secondColor, thirdColor] = tableValues; + if (hasAlpha && tableValues.every((value) => !!value)) { + return tableValues.map((value, index) => { + if (index !== COLOR_LENGTH - 1) return Number.parseFloat(value); + return Number.parseInt(value, 10); + }); + } - const redNumber = parseInt(red); - const greenNumber = parseInt(green); - const blueNumber = parseInt(blue); + const hasEveryColors = !!firstColor && !!secondColor && !!thirdColor; + return hasEveryColors + ? tableValues.map((value) => Number.parseInt(value, 10)) + : null; +} - if ( - !isNumberBetween(redNumber, 0, 255) || - !isNumberBetween(greenNumber, 0, 255) || - !isNumberBetween(blueNumber, 0, 255) - ) { - return null; - } +export function rgbToHex(rgbColor: string): string | null { + const colorTable = getColorTable('RGB', rgbColor); + if (!colorTable) return null; + + if (!isBetweenLimits('RGB', colorTable)) return null; + const [red, green, blue] = colorTable; - const byteNumbers = - (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; + const byteNumbers = (1 << 24) | (red! << 16) | (green! << 8) | blue!; const hexColor = `#${byteNumbers.toString(16).slice(1).toUpperCase()}`; if (!isHexColor(hexColor)) return null; @@ -49,39 +82,16 @@ export function rgbToHex(rgbColor: string): string | null { } export function rgbaToHex(rgbaColor: string): string | null { - const LENGTH_OF_RGBA_COLOR = 4; - - const regexToRemoveCharacters = /[A-Z()\s]/gi; - const rgbaValues = rgbaColor - .toLowerCase() - .replace(regexToRemoveCharacters, '') - .split(','); + const colorTable = getColorTable('RGBA', rgbaColor); + if (!colorTable) return null; - if (rgbaValues.length !== LENGTH_OF_RGBA_COLOR) return null; + if (!isBetweenLimits('RGBA', colorTable)) return null; + const [red, green, blue, alpha] = colorTable; - const [red, green, blue, alpha] = rgbaValues; - const allColorsExists = !!red && !!green && !!blue && !!alpha; - if (!allColorsExists) return null; - - const redNumber = parseInt(red); - const greenNumber = parseInt(green); - const blueNumber = parseInt(blue); - const alphaNumber = Number.parseFloat(alpha); - - if ( - !isNumberBetween(redNumber, 0, 255) || - !isNumberBetween(greenNumber, 0, 255) || - !isNumberBetween(blueNumber, 0, 255) || - !isNumberBetween(alphaNumber, 0, 1) - ) { - return null; - } - - const alphaNumericString = (((alpha as any) * 255) | (1 << 8)) + const alphaNumericString = (((alpha! as any) * 255) | (1 << 8)) .toString(16) .slice(1); - const byteNumbers = - (1 << 24) | (redNumber << 16) | (greenNumber << 8) | blueNumber; + const byteNumbers = (1 << 24) | (red! << 16) | (green! << 8) | blue!; const hexColor = `#${byteNumbers .toString(16) .slice(1)}${alphaNumericString}`.toUpperCase(); @@ -103,102 +113,47 @@ export function formatHexColor(hexColor: string): string | null { if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; const [firstChar, secondChar, thirdChar] = hexColor.slice(1); - return `#${firstChar}${firstChar}${secondChar}${secondChar}${thirdChar}${thirdChar}`.toUpperCase(); + const redHexColor = firstChar!.repeat(2); + const greenHexColor = secondChar!.repeat(2); + const blueHexColor = thirdChar!.repeat(2); + + return `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); } export function hslToHex(hslColor: string): string | null { - const LENGTH_OF_HSL_COLOR = 3; - - const regexToRemoveCharacters = /[A-Z()\s%]/gi; - const hslValues = hslColor - .toLowerCase() - .replace(regexToRemoveCharacters, '') - .split(','); + const colorTable = getColorTable('HSL', hslColor); + if (!colorTable) return null; - if (hslValues.length !== LENGTH_OF_HSL_COLOR) return null; - - const [hue, saturation, lightness] = hslValues; - const allColorsExists = !!hue && !!saturation && !!lightness; - if (!allColorsExists) return null; - - const hueNumber = parseInt(hue); - const saturationNumber = parseInt(saturation); - let lightnessNumber = parseInt(lightness); - - if ( - !isNumberBetween(hueNumber, 0, 360) || - !isNumberBetween(saturationNumber, 0, 100) || - !isNumberBetween(lightnessNumber, 0, 100) - ) { - return null; - } - - lightnessNumber /= 100; - const brightness = - (saturationNumber * Math.min(lightnessNumber, 1 - lightnessNumber)) / 100; + if (!isBetweenLimits('HSL', colorTable)) return null; + const [hue, saturation, lightness] = colorTable; - const calculateHex = (bytes: number) => { - const hueValue = (bytes + hueNumber / 30) % 12; - const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); - const color = lightnessNumber - brightness * maxHueValue; - return Math.round(255 * color) - .toString(16) - .padStart(2, '0'); - }; + const redHexColor = calculateHslHex(0, hue!, lightness!, saturation!); + const greenHexColor = calculateHslHex(8, hue!, lightness!, saturation!); + const blueHexColor = calculateHslHex(4, hue!, lightness!, saturation!); - const hexColor = '#' + calculateHex(0) + calculateHex(8) + calculateHex(4); + const hexColor = + `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); - if (!isHexColor(hexColor.toUpperCase())) return null; - return hexColor.toUpperCase(); + if (!isHexColor(hexColor)) return null; + return hexColor; } export function hslaToHex(hslaColor: string): string | null { - const LENGTH_OF_HSLA_COLOR = 4; - - const regexToRemoveCharacters = /[A-Z()\s%]/gi; - const hslaValues = hslaColor - .toLowerCase() - .replace(regexToRemoveCharacters, '') - .split(','); + const colorTable = getColorTable('HSLA', hslaColor); + if (!colorTable) return null; - if (hslaValues.length !== LENGTH_OF_HSLA_COLOR) return null; + if (!isBetweenLimits('HSLA', colorTable)) return null; + const [hue, saturation, lightness, alpha] = colorTable; - const [hue, saturation, lightness, alpha] = hslaValues; - const allColorsExists = !!hue && !!saturation && !!lightness && !!alpha; - if (!allColorsExists) return null; - - const hueNumber = parseInt(hue); - const saturationNumber = parseInt(saturation); - let lightnessNumber = parseInt(lightness); - const alphaNumber = Number.parseFloat(alpha); - - if ( - !isNumberBetween(hueNumber, 0, 360) || - !isNumberBetween(saturationNumber, 0, 100) || - !isNumberBetween(lightnessNumber, 0, 100) - ) { - return null; - } - - lightnessNumber /= 100; - const brightness = - (saturationNumber * Math.min(lightnessNumber, 1 - lightnessNumber)) / 100; - - const calculateHex = (bytes: number) => { - const hueValue = (bytes + hueNumber / 30) % 12; - const maxHueValue = Math.max(Math.min(hueValue - 3, 9 - hueValue, 1), -1); - const color = lightnessNumber - brightness * maxHueValue; - return Math.round(255 * color) - .toString(16) - .padStart(2, '0'); - }; - - const alphaValue = Math.round(alphaNumber * 255) + const redHexColor = calculateHslHex(0, hue!, lightness!, saturation!); + const greenHexColor = calculateHslHex(8, hue!, lightness!, saturation!); + const blueHexColor = calculateHslHex(4, hue!, lightness!, saturation!); + const alphaValue = Math.round(alpha! * 255) .toString(16) .padStart(2, '0'); - const hexCharacters = - '#' + calculateHex(0) + calculateHex(8) + calculateHex(4); - const hexColor = `${hexCharacters}${alphaValue}`.toUpperCase(); + + const hexColor = + `#${redHexColor}${greenHexColor}${blueHexColor}${alphaValue}`.toUpperCase(); if (!isHexColor(hexColor)) return null; return hexColor; From 386a17fc841240ef16f9235e610724f527d83461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 20:30:06 -0300 Subject: [PATCH 28/43] feat: created `convertToHexColor` function to manager colors --- src/helpers/colors.ts | 116 ++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 49 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index 580f205..b16e01c 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -1,6 +1,15 @@ -function isHexColor(hexColor: string): boolean { - const regexToCheckIfHexColor = /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3})$/; - return regexToCheckIfHexColor.test(hexColor); +type ColorType = 'HEX' | 'RGB' | 'RGBA' | 'HSL' | 'HSLA'; +type ColorTableType = Exclude; + +function isColor(type: ColorType, color: string): boolean { + const regexsColors: Record = { + HEX: /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3})$/, + HSL: /[Hh][Ss][Ll][(](((([\d]{1,3}|[\d%]{2,4})[,]{0,1})[\s]*){3})[)]/gm, + HSLA: /[Hh][Ss][Ll][Aa][(](((([\d]{1,3}|[\d%]{2,4}|[\d.]{1,3})[,]{0,1})[\s]*){4})[)]/gm, + RGB: /[Rr][Gg][Bb][(](((([\d]{1,3})[,]{0,1})[\s]*){3})[)]/gm, + RGBA: /[Rr][Gg][Bb][Aa][(](((([\d]{1,3}|[\d.]{1,3})[,]{0,1})[\s]*){4})[)]/gm, + }; + return regexsColors[type].test(color); } function isNumberBetween(value: number, min: number, max: number): boolean { @@ -25,27 +34,26 @@ function calculateHslHex( .padStart(2, '0'); } -type ColorTableType = 'RGB' | 'RGBA' | 'HSL' | 'HSLA'; - function isBetweenLimits(type: ColorTableType, colors: number[]): boolean { const hasAlpha = type === 'HSLA' || type === 'RGBA'; const isRgb = type === 'RGBA' || type === 'RGB'; const [firstColor, secondColor, thirdColor, alpha] = colors; - const isValid = + const isValidColor = isNumberBetween(firstColor!, 0, isRgb ? 255 : 360) && isNumberBetween(secondColor!, 0, isRgb ? 255 : 100) && isNumberBetween(thirdColor!, 0, isRgb ? 255 : 100); - if (hasAlpha) return isValid && isNumberBetween(alpha!, 0, 1); - return isValid; + if (hasAlpha) return isValidColor && isNumberBetween(alpha!, 0, 1); + return isValidColor; } function getColorTable(type: ColorTableType, color: string): number[] | null { const hasAlpha = type === 'HSLA' || type === 'RGBA'; + const isHsl = type === 'HSL' || type === 'HSLA'; const COLOR_LENGTH = hasAlpha ? 4 : 3; - const regexToRemoveCharacters = hasAlpha ? /[A-Z()\s%]/gi : /[A-Z()\s]/gi; + const regexToRemoveCharacters = isHsl ? /[A-Z()\s%]/gi : /[A-Z()\s]/gi; const tableValues = color .toLowerCase() .replace(regexToRemoveCharacters, '') @@ -53,74 +61,75 @@ function getColorTable(type: ColorTableType, color: string): number[] | null { if (tableValues.length !== COLOR_LENGTH) return null; - const [firstColor, secondColor, thirdColor] = tableValues; + const tableValuesAsNumber = tableValues.map((value, index) => { + if (hasAlpha && index === COLOR_LENGTH - 1) return Number.parseFloat(value); + return Number.parseInt(value, 10); + }); + if (hasAlpha && tableValues.every((value) => !!value)) { - return tableValues.map((value, index) => { - if (index !== COLOR_LENGTH - 1) return Number.parseFloat(value); - return Number.parseInt(value, 10); - }); + return tableValuesAsNumber; } - const hasEveryColors = !!firstColor && !!secondColor && !!thirdColor; - return hasEveryColors - ? tableValues.map((value) => Number.parseInt(value, 10)) - : null; + return tableValues.every((value) => !!value) ? tableValuesAsNumber : null; } -export function rgbToHex(rgbColor: string): string | null { +function formatHexColor(hexColor: string): string | null { + if (!isColor('HEX', hexColor)) return null; + const MIN_LENGTH_HEX_COLOR = 4; + const MIDDLE_LENGTH_HEX_COLOR = 7; + const MAX_LENGTH_HEX_COLOR = 9; + + const isMiddleHexColor = hexColor.length === MIDDLE_LENGTH_HEX_COLOR; + const isMaxHexColor = hexColor.length === MAX_LENGTH_HEX_COLOR; + if (isMiddleHexColor || isMaxHexColor) return hexColor; + + if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; + + const [firstChar, secondChar, thirdChar] = hexColor.slice(1); + const redHexColor = firstChar!.repeat(2); + const greenHexColor = secondChar!.repeat(2); + const blueHexColor = thirdChar!.repeat(2); + + const color = `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); + + if (!isColor('HEX', color)) return null; + return color; +} + +function rgbToHex(rgbColor: string): string | null { const colorTable = getColorTable('RGB', rgbColor); if (!colorTable) return null; if (!isBetweenLimits('RGB', colorTable)) return null; - const [red, green, blue] = colorTable; + const [red, green, blue] = colorTable; const byteNumbers = (1 << 24) | (red! << 16) | (green! << 8) | blue!; const hexColor = `#${byteNumbers.toString(16).slice(1).toUpperCase()}`; - if (!isHexColor(hexColor)) return null; + if (!isColor('HEX', hexColor)) return null; return hexColor; } -export function rgbaToHex(rgbaColor: string): string | null { +function rgbaToHex(rgbaColor: string): string | null { const colorTable = getColorTable('RGBA', rgbaColor); if (!colorTable) return null; if (!isBetweenLimits('RGBA', colorTable)) return null; const [red, green, blue, alpha] = colorTable; - const alphaNumericString = (((alpha! as any) * 255) | (1 << 8)) + const alphaNumeric = (((alpha! as any) * 255) | (1 << 8)) .toString(16) .slice(1); const byteNumbers = (1 << 24) | (red! << 16) | (green! << 8) | blue!; const hexColor = `#${byteNumbers .toString(16) - .slice(1)}${alphaNumericString}`.toUpperCase(); + .slice(1)}${alphaNumeric}`.toUpperCase(); - if (!isHexColor(hexColor)) return null; + if (!isColor('HEX', hexColor)) return null; return hexColor; } -export function formatHexColor(hexColor: string): string | null { - if (!isHexColor(hexColor)) return null; - const MIN_LENGTH_HEX_COLOR = 4; - const MIDDLE_LENGTH_HEX_COLOR = 7; - const MAX_LENGTH_HEX_COLOR = 9; - - const isMiddleHexColor = hexColor.length === MIDDLE_LENGTH_HEX_COLOR; - const isMaxHexColor = hexColor.length === MAX_LENGTH_HEX_COLOR; - if (isMiddleHexColor || isMaxHexColor) return hexColor; - - if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; - - const [firstChar, secondChar, thirdChar] = hexColor.slice(1); - const redHexColor = firstChar!.repeat(2); - const greenHexColor = secondChar!.repeat(2); - const blueHexColor = thirdChar!.repeat(2); - - return `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); -} - -export function hslToHex(hslColor: string): string | null { +function hslToHex(hslColor: string): string | null { const colorTable = getColorTable('HSL', hslColor); if (!colorTable) return null; @@ -134,11 +143,11 @@ export function hslToHex(hslColor: string): string | null { const hexColor = `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); - if (!isHexColor(hexColor)) return null; + if (!isColor('HEX', hexColor)) return null; return hexColor; } -export function hslaToHex(hslaColor: string): string | null { +function hslaToHex(hslaColor: string): string | null { const colorTable = getColorTable('HSLA', hslaColor); if (!colorTable) return null; @@ -155,6 +164,15 @@ export function hslaToHex(hslaColor: string): string | null { const hexColor = `#${redHexColor}${greenHexColor}${blueHexColor}${alphaValue}`.toUpperCase(); - if (!isHexColor(hexColor)) return null; + if (!isColor('HEX', hexColor)) return null; return hexColor; } + +export function convertToHexColor(color: string): string | null { + if (isColor('HEX', color)) return formatHexColor(color); + if (isColor('RGB', color)) return rgbToHex(color); + if (isColor('RGBA', color)) return rgbaToHex(color); + if (isColor('HSL', color)) return hslToHex(color); + if (isColor('HSLA', color)) return hslaToHex(color); + return null; +} From b066959bf2c8bd18257daf1545ac66960472d960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Thu, 14 Sep 2023 21:02:56 -0300 Subject: [PATCH 29/43] chore: added custom comments --- src/helpers/colors.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index b16e01c..e74e4b0 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -168,6 +168,15 @@ function hslaToHex(hslaColor: string): string | null { return hexColor; } +/** + * @description Calculates a hexadecimal, RGB, RGBA, HSL or HSLA color from a + * hexadecimal color provided as a string. + * + * @param color - A color in hexadecimal, RGB, RGBA, HSL or HSLA format to be + * converted to a hexadecimal color string. + * + * @returns {string|null} + */ export function convertToHexColor(color: string): string | null { if (isColor('HEX', color)) return formatHexColor(color); if (isColor('RGB', color)) return rgbToHex(color); From 32c7863a1c3dde90abf42d6b1c0588d9065ca3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 09:28:23 -0300 Subject: [PATCH 30/43] fix: small adjusts in hexadecimal regex --- src/helpers/colors.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index e74e4b0..cd14f19 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -3,7 +3,7 @@ type ColorTableType = Exclude; function isColor(type: ColorType, color: string): boolean { const regexsColors: Record = { - HEX: /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3})$/, + HEX: /^#(([0-9A-Fa-f]{2}){3,4}|[0-9A-Fa-f]{3,4})$/, HSL: /[Hh][Ss][Ll][(](((([\d]{1,3}|[\d%]{2,4})[,]{0,1})[\s]*){3})[)]/gm, HSLA: /[Hh][Ss][Ll][Aa][(](((([\d]{1,3}|[\d%]{2,4}|[\d.]{1,3})[,]{0,1})[\s]*){4})[)]/gm, RGB: /[Rr][Gg][Bb][(](((([\d]{1,3})[,]{0,1})[\s]*){3})[)]/gm, @@ -76,21 +76,27 @@ function getColorTable(type: ColorTableType, color: string): number[] | null { function formatHexColor(hexColor: string): string | null { if (!isColor('HEX', hexColor)) return null; const MIN_LENGTH_HEX_COLOR = 4; - const MIDDLE_LENGTH_HEX_COLOR = 7; - const MAX_LENGTH_HEX_COLOR = 9; + const MIN_LENGTH_HEX_ALPHA_COLOR = 5; + const MAX_LENGTH_HEX_COLOR = 7; + const MAX_LENGTH_HEX_ALPHA_COLOR = 9; - const isMiddleHexColor = hexColor.length === MIDDLE_LENGTH_HEX_COLOR; - const isMaxHexColor = hexColor.length === MAX_LENGTH_HEX_COLOR; - if (isMiddleHexColor || isMaxHexColor) return hexColor; + const isMiddleHexColor = hexColor.length === MAX_LENGTH_HEX_COLOR; + const isMaxHexAlphaColor = hexColor.length === MAX_LENGTH_HEX_ALPHA_COLOR; + if (isMiddleHexColor || isMaxHexAlphaColor) return hexColor; - if (hexColor.length !== MIN_LENGTH_HEX_COLOR) return null; + const isMinHexColor = hexColor.length !== MIN_LENGTH_HEX_COLOR; + const isMinHexAlphaColor = hexColor.length !== MIN_LENGTH_HEX_ALPHA_COLOR; + if (isMinHexColor && isMinHexAlphaColor) return null; - const [firstChar, secondChar, thirdChar] = hexColor.slice(1); + const [firstChar, secondChar, thirdChar, alpha] = hexColor.slice(1); const redHexColor = firstChar!.repeat(2); const greenHexColor = secondChar!.repeat(2); const blueHexColor = thirdChar!.repeat(2); + const alphaHexColor = alpha?.repeat(2); - const color = `#${redHexColor}${greenHexColor}${blueHexColor}`.toUpperCase(); + const color = `#${redHexColor}${greenHexColor}${blueHexColor}${ + alphaHexColor || '' + }`.toUpperCase(); if (!isColor('HEX', color)) return null; return color; From 3c558a14e6aa35e6605244bc2879eb83c8c89092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 10:28:27 -0300 Subject: [PATCH 31/43] chore: created unit test to colors helpers --- src/helpers/colors.test.ts | 197 +++++++++++++++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 src/helpers/colors.test.ts diff --git a/src/helpers/colors.test.ts b/src/helpers/colors.test.ts new file mode 100644 index 0000000..85f8c4b --- /dev/null +++ b/src/helpers/colors.test.ts @@ -0,0 +1,197 @@ +import { convertToHexColor } from '.'; + +const MAX_HEX_ALPHA_COLOR = '#00000000'; +const MAX_HEX_COLOR = '#000000'; +const MIN_HEX_ALPHA_COLOR = '#0000'; +const MIN_HEX_COLOR = '#000'; + +describe('Colors Helper', () => { + describe('Ensure convertToHexColor function should', () => { + describe('Works general', () => { + it('Should be call with correct values', () => { + const fn = { method: convertToHexColor }; + jest.spyOn(fn, 'method'); + fn.method(MAX_HEX_COLOR); + expect(fn.method).toHaveBeenCalledTimes(1); + expect(fn.method).toHaveBeenCalledWith(MAX_HEX_COLOR); + }); + + it('Should return null if invalid values provided', () => { + expect(convertToHexColor('')).toBeNull(); + expect(convertToHexColor(' ')).toBeNull(); + expect(convertToHexColor('invalid')).toBeNull(); + expect(convertToHexColor('1234567890')).toBeNull(); + expect(convertToHexColor('ABCDEFGHIJKLMNOPQRSTUVWXYZ')).toBeNull(); + expect(convertToHexColor('˜!@#$%Λ†&*()_+`-={}][;:"<>,./?')).toBeNull(); + }); + }); + + describe('Works with hexadecimal colors', () => { + it('Should a return hexadecimal color if a hexadecimal color is provided', () => { + const maxHexCharacters = convertToHexColor(MAX_HEX_COLOR); + const minHexCharacters = convertToHexColor(MIN_HEX_COLOR); + const minHexAlphaCharacters = convertToHexColor(MIN_HEX_ALPHA_COLOR); + const maxHexAlphaCharacters = convertToHexColor(MAX_HEX_ALPHA_COLOR); + + expect(maxHexCharacters).toBe(MAX_HEX_COLOR); + expect(minHexCharacters).toBe(MAX_HEX_COLOR); + expect(minHexAlphaCharacters).toBe(MAX_HEX_ALPHA_COLOR); + expect(maxHexAlphaCharacters).toBe(MAX_HEX_ALPHA_COLOR); + }); + + it('Should return null if an invalid hexadecimal colors is provided', () => { + expect(convertToHexColor('#')).toBeNull(); + expect(convertToHexColor('#0')).toBeNull(); + expect(convertToHexColor('#0')).toBeNull(); + expect(convertToHexColor('000')).toBeNull(); + expect(convertToHexColor('#XYZ')).toBeNull(); + expect(convertToHexColor('#XYZX')).toBeNull(); + expect(convertToHexColor('#00000')).toBeNull(); + expect(convertToHexColor('000000')).toBeNull(); + expect(convertToHexColor('#XYZXYZ')).toBeNull(); + expect(convertToHexColor('#0000000')).toBeNull(); + expect(convertToHexColor('00000000')).toBeNull(); + expect(convertToHexColor('#XYZXYZ00')).toBeNull(); + expect(convertToHexColor('#0000000000')).toBeNull(); + expect(convertToHexColor('#00000000000000000000000')).toBeNull(); + }); + }); + + describe('Works with RGB colors', () => { + it('Should a return RGB color if a hexadecimal color is provided', () => { + const hexColor = convertToHexColor('rgb(0, 0, 0)'); + expect(hexColor).toBe(MAX_HEX_COLOR); + }); + + it('Should return null if an invalid RGB colors is provided', () => { + expect(convertToHexColor('rgb')).toBeNull(); + expect(convertToHexColor('rgb()')).toBeNull(); + expect(convertToHexColor('rgb(0)')).toBeNull(); + expect(convertToHexColor('rgb(0,)')).toBeNull(); + expect(convertToHexColor('rgb(,,,)')).toBeNull(); + expect(convertToHexColor('rgb(0 0)')).toBeNull(); + expect(convertToHexColor('rgb(0-0)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0,)')).toBeNull(); + expect(convertToHexColor('rgb(0 0 0)')).toBeNull(); + expect(convertToHexColor('rgb(0-0-0)')).toBeNull(); + expect(convertToHexColor('rgb(=, +, -)')).toBeNull(); + expect(convertToHexColor('rgb(X, Y, Z)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0, -1)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0, 0,)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0, 256)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0, 0, 0)')).toBeNull(); + expect(convertToHexColor('rgb(-1, -1, -1)')).toBeNull(); + expect(convertToHexColor('rgb(256, 256, 256)')).toBeNull(); + expect(convertToHexColor('rgb(0, 0, 0, 0, 0)')).toBeNull(); + }); + }); + + describe('Works with RGBA colors', () => { + it('Should a return RGBA color if a hexadecimal color is provided', () => { + const hexColor = convertToHexColor('rgba(0, 0, 0, 0)'); + expect(hexColor).toBe(MAX_HEX_ALPHA_COLOR); + }); + + it('Should return null if an invalid RGBA colors is provided', () => { + expect(convertToHexColor('rgba')).toBeNull(); + expect(convertToHexColor('rgba()')).toBeNull(); + expect(convertToHexColor('rgba(0)')).toBeNull(); + expect(convertToHexColor('rgba(0,)')).toBeNull(); + expect(convertToHexColor('rgba(0 0)')).toBeNull(); + expect(convertToHexColor('rgba(0-0)')).toBeNull(); + expect(convertToHexColor('rgba(,,,)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0,)')).toBeNull(); + expect(convertToHexColor('rgba(0 0 0)')).toBeNull(); + expect(convertToHexColor('rgba(0-0-0)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, -1)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, 0,)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, 256)')).toBeNull(); + expect(convertToHexColor('rgba(+, -, *, /)')).toBeNull(); + expect(convertToHexColor('rgba(X, Y, Z, A)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, 0, 2)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, 0, -1)')).toBeNull(); + expect(convertToHexColor('rgba(256, 256, 256)')).toBeNull(); + expect(convertToHexColor('rgba(0, 0, 0, 1, 0)')).toBeNull(); + expect(convertToHexColor('rgba(-1, -1, -1, -1)')).toBeNull(); + }); + }); + + describe('Works with HSL colors', () => { + it('Should a return HSL color if a hexadecimal color is provided', () => { + expect(convertToHexColor('hsl(0, 0, 0)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(0, 0, 0%)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(0, 0%, 0)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(0, 0%, 0%)')).toBe(MAX_HEX_COLOR); + }); + + it('Should return null if an invalid HSL colors is provided', () => { + expect(convertToHexColor('hsl')).toBeNull(); + expect(convertToHexColor('hsl()')).toBeNull(); + expect(convertToHexColor('hsl(0)')).toBeNull(); + expect(convertToHexColor('hsl(0,)')).toBeNull(); + expect(convertToHexColor('hsl(,,,)')).toBeNull(); + expect(convertToHexColor('hsl(0 0)')).toBeNull(); + expect(convertToHexColor('hsl(0-0)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%)')).toBeNull(); + expect(convertToHexColor('hsl(0-0-0)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%,)')).toBeNull(); + expect(convertToHexColor('hsl(=, +, -)')).toBeNull(); + expect(convertToHexColor('hsl(X, Y, Z)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%, -1)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%, 0%,)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%, -0%)')).toBeNull(); + expect(convertToHexColor('hsl(0, 101%, 0%)')).toBeNull(); + expect(convertToHexColor('hsl(-1, -1%, -1%)')).toBeNull(); + expect(convertToHexColor('hsl(0, 0%, 0%, 1, 0%)')).toBeNull(); + }); + }); + + describe('Works with HSLA colors', () => { + it('Should a return HSLA color if a hexadecimal color is provided', () => { + expect(convertToHexColor('hsla(0, 0, 0, 0)')).toBe(MAX_HEX_ALPHA_COLOR); + expect(convertToHexColor('hsla(0, 0%, 0%, 0)')).toBe( + MAX_HEX_ALPHA_COLOR + ); + expect(convertToHexColor('hsla(0, 0, 0%, 0)')).toBe( + MAX_HEX_ALPHA_COLOR + ); + expect(convertToHexColor('hsla(0, 0%, 0, 0)')).toBe( + MAX_HEX_ALPHA_COLOR + ); + }); + + it('Should return null if an invalid HSLA colors is provided', () => { + expect(convertToHexColor('hsla')).toBeNull(); + expect(convertToHexColor('hsla()')).toBeNull(); + expect(convertToHexColor('hsla(0)')).toBeNull(); + expect(convertToHexColor('hsla(0,)')).toBeNull(); + expect(convertToHexColor('hsla(,,,)')).toBeNull(); + expect(convertToHexColor('hsla(0 0)')).toBeNull(); + expect(convertToHexColor('hsla(0-0)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%)')).toBeNull(); + expect(convertToHexColor('hsla(0-0-0)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%,)')).toBeNull(); + expect(convertToHexColor('hsla(0-0-0-0)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, -1)')).toBeNull(); + expect(convertToHexColor('hsla(+, -, *, /)')).toBeNull(); + expect(convertToHexColor('hsla(X, Y, Z, A)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, -0%)')).toBeNull(); + expect(convertToHexColor('hsla(0, 101%, 0%)')).toBeNull(); + expect(convertToHexColor('hsla(-1, -1%, -1%)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, 101%,)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, 0%, 2)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, -0%, 1)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, 0%, -1)')).toBeNull(); + expect(convertToHexColor('hsla(0, 101%, 0%, 1)')).toBeNull(); + expect(convertToHexColor('hsla(0, 0%, 0%, 1, 0%)')).toBeNull(); + expect(convertToHexColor('hsla(-1, -1%, -1%, -1%)')).toBeNull(); + }); + }); + }); +}); From 409d9f7b94cba8e0bdf4b966d6e5ef515296f2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 10:30:02 -0300 Subject: [PATCH 32/43] chore: added jest clear cache command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4272c73..c0c64a4 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,8 @@ "build:ios": "cd example/ios && xcodebuild -workspace ReactNativeCapfaceSdkExample.xcworkspace -scheme ReactNativeCapfaceSdkExample -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO", "bootstrap": "npm i example && npm install && npm i example pods", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build", - "podspec": "pod ipc spec capitual-react-native-capface-sdk.podspec" + "podspec": "pod ipc spec capitual-react-native-capface-sdk.podspec", + "test:clean": "jest --clearCache" }, "keywords": [ "react-native", From a678a2f134e37063b904febe5fd095f9abc61c73 Mon Sep 17 00:00:00 2001 From: Bruno Fialho Date: Fri, 15 Sep 2023 10:38:25 -0300 Subject: [PATCH 33/43] fix: types and exports --- README.md | 153 +++++++++-------- .../project.pbxproj | 110 ++++++------ example/package-lock.json | 119 ++++++------- example/types/index.d.ts | 1 - package-lock.json | 157 +++++++++--------- src/constants/index.ts | 6 +- src/index.tsx | 72 +++++--- src/types/index.ts | 45 +---- 8 files changed, 331 insertions(+), 332 deletions(-) delete mode 100644 example/types/index.d.ts diff --git a/README.md b/README.md index cba945a..fd4c562 100644 --- a/README.md +++ b/README.md @@ -5,23 +5,23 @@ Capface sdk adapter to react native. πŸ“± - [Installation](#installation) - [Usage](#usage) - [API](#api) - - [`initialize(init: CapfaceSdk.Initialize)`](#initializeinit-capfacesdkinitialize) - - [`faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData)`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) + - [`initialize(init: CapfaceSdkProps.Initialize)`](#initializeinit-capfacesdkinitialize) + - [`faceMatch(type: CapfaceSdkProps.MatchType, data?: CapfaceSdkProps.MatchData)`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) - [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) - - [`setTheme(options?: CapfaceSdk.Theme)`](#setthemeoptions-capfacesdktheme) + - [`setTheme(options?: CapfaceSdkProps.Theme)`](#setthemeoptions-capfacesdktheme) - [Types](#types) - - [`CapfaceSdk.Params`](#capfacesdkparams) - - [`CapfaceSdk.Headers`](#capfacesdkheaders) - - [`CapfaceSdk.Theme`](#capfacesdktheme) - - [`CapfaceSdk.ButtonLocation`](#capfacesdkbuttonlocation) - - [`CapfaceSdk.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) - - [`CapfaceSdk.FeedbackBackgroundColor`](#capfacesdkfeedbackbackgroundcolor-ios-only) - - [`CapfaceSdk.Point`](#capfacesdkpoint-ios-only) - - [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) - - [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) - - [`CapfaceSdk.Errors`](#capfacesdkerrors) - - [`CapfaceSdk.MatchType`](#capfacesdkmatchtype) - - [`CapfaceSdk.MatchData`](#capfacesdkmatchdata) + - [`CapfaceSdkProps.Params`](#capfacesdkparams) + - [`CapfaceSdkProps.Headers`](#capfacesdkheaders) + - [`CapfaceSdkProps.Theme`](#capfacesdktheme) + - [`CapfaceSdkProps.ButtonLocation`](#capfacesdkbuttonlocation) + - [`CapfaceSdkProps.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) + - [`CapfaceSdkProps.FeedbackBackgroundColor`](#capfacesdkfeedbackbackgroundcolor-ios-only) + - [`CapfaceSdkProps.Point`](#capfacesdkpoint-ios-only) + - [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) + - [`CapfaceSdkProps.DefaultScanMessage`](#capfacesdkdefaultscanmessage) + - [`CapfaceSdkProps.Errors`](#capfacesdkerrors) + - [`CapfaceSdkProps.MatchType`](#capfacesdkmatchtype) + - [`CapfaceSdkProps.MatchData`](#capfacesdkmatchdata) - [Native Events](#native-events) - [`Event Types`](#event-types) - [How to add images in CapfaceSDK module?](#how-to-add-images-in-capfacesdk-module) @@ -55,9 +55,8 @@ import { ScrollView, NativeEventEmitter, } from 'react-native'; -import { - CapfaceSdk, - ReactNativeCapfaceSdk, +import CapfaceSdk, { + CapfaceSdkProps, initialize, faceMatch, photoMatch, @@ -96,7 +95,7 @@ export default function App() { console.log(isInitialized); }; - const emitter = new NativeEventEmitter(ReactNativeCapfaceSdk); + const emitter = new NativeEventEmitter(CapfaceSdk); emitter.addListener('onCloseModal', (event: boolean) => console.log('onCloseModal', event) ); @@ -111,8 +110,8 @@ export default function App() { }; const onPressFaceMatch = async ( - type: CapfaceSdk.MatchType, - data?: CapfaceSdk.MatchData + type: CapfaceSdkProps.MatchType, + data?: CapfaceSdkProps.MatchData ) => { try { const isSuccess = await faceMatch(type, data); @@ -189,21 +188,21 @@ const styles = StyleSheet.create({ | Methods | Return Type | iOS | Android | | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ | --- | ------- | -| [`initialize(init: CapfaceSdk.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | -| [`faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) | `Promise` | βœ… | βœ… | +| [`initialize(init: CapfaceSdkProps.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | +| [`faceMatch(type: CapfaceSdkProps.MatchType, data?: CapfaceSdkProps.MatchData`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) | `Promise` | βœ… | βœ… | | [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) | `Promise` | βœ… | βœ… | -| [`setTheme(options?: CapfaceSdk.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | +| [`setTheme(options?: CapfaceSdkProps.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | -### `initialize(init: CapfaceSdk.Initialize)` +### `initialize(init: CapfaceSdkProps.Initialize)` This is the **principal** method to be called, he must be **called first** to initialize the Capface SDK. If he doens't be called the other methods **don't works!** -| `CapfaceSdk.Initialize` | type | Required | Default | +| `CapfaceSdkProps.Initialize` | type | Required | Default | | ----------------------- | ------------------------------------------ | -------- | ----------- | -| `params` | [`CapfaceSdk.Params`](#capfacesdkparams) | βœ… | - | -| `headers` | [`CapfaceSdk.Headers`](#capfacesdkheaders) | ❌ | `undefined` | +| `params` | [`CapfaceSdkProps.Params`](#capfacesdkparams) | βœ… | - | +| `headers` | [`CapfaceSdkProps.Headers`](#capfacesdkheaders) | ❌ | `undefined` | -### `faceMatch(type: CapfaceSdk.MatchType, data?: CapfaceSdk.MatchData)` +### `faceMatch(type: CapfaceSdkProps.MatchType, data?: CapfaceSdkProps.MatchData)` This method is called to make enrollment, authenticate and liveness available. The type is required and it must provided to select which flow you are interested. @@ -213,8 +212,8 @@ This method is called to make enrollment, authenticate and liveness available. T | `Object` | type | Required | Default | | -------- | ---------------------------------------------- | -------- | ----------- | -| `type` | [`CapfaceSdk.MatchType`](#capfacesdkmatchtype) | βœ… | - | -| `data` | [`CapfaceSdk.MatchData`](#capfacesdkmatchdata) | ❌ | `undefined` | +| `type` | [`CapfaceSdkProps.MatchType`](#capfacesdkmatchtype) | βœ… | - | +| `data` | [`CapfaceSdkProps.MatchData`](#capfacesdkmatchdata) | ❌ | `undefined` | ### `photoMatch(data?: Object)` @@ -224,37 +223,37 @@ This method make to read from face and documents for user, after comparate face | -------- | -------- | -------- | ----------- | | `data` | `Object` | ❌ | `undefined` | -### `setTheme(options?: CapfaceSdk.Theme)` +### `setTheme(options?: CapfaceSdkProps.Theme)` This method must be used to **set** the **theme** of the Capface SDK screen. -| `CapfaceSdk.Theme` | type | Required | Default | +| `CapfaceSdkProps.Theme` | type | Required | Default | | ------------------ | -------------------------------------- | -------- | ----------- | -| `options` | [`CapfaceSdk.Theme`](#capfacesdktheme) | ❌ | `undefined` | +| `options` | [`CapfaceSdkProps.Theme`](#capfacesdktheme) | ❌ | `undefined` |
## Types -| `CapfaceSdk` - Types | iOS | Android | +| `CapfaceSdkProps` - Types | iOS | Android | | ----------------------------------------------------------------------------------- | --- | ------- | -| [`CapfaceSdk.Params`](#capfacesdkparams) | βœ… | βœ… | -| [`CapfaceSdk.Headers`](#capfacesdkheaders) | βœ… | βœ… | -| [`CapfaceSdk.Theme`](#capfacesdktheme) | βœ… | βœ… | -| [`CapfaceSdk.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | -| [`CapfaceSdk.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | -| [`CapfaceSdk.FeedbackBackgroundColor`](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | -| [`CapfaceSdk.Point`](#capfacesdkpoint-ios-only) | βœ… | ❌ | -| [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | -| [`CapfaceSdk.Errors`](#capfacesdkerrors) | βœ… | βœ… | -| [`CapfaceSdk.MatchType`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | -| [`CapfaceSdk.MatchData`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | - -### `CapfaceSdk.Params` +| [`CapfaceSdkProps.Params`](#capfacesdkparams) | βœ… | βœ… | +| [`CapfaceSdkProps.Headers`](#capfacesdkheaders) | βœ… | βœ… | +| [`CapfaceSdkProps.Theme`](#capfacesdktheme) | βœ… | βœ… | +| [`CapfaceSdkProps.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | +| [`CapfaceSdkProps.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | +| [`CapfaceSdkProps.FeedbackBackgroundColor`](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | +| [`CapfaceSdkProps.Point`](#capfacesdkpoint-ios-only) | βœ… | ❌ | +| [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | +| [`CapfaceSdkProps.Errors`](#capfacesdkerrors) | βœ… | βœ… | +| [`CapfaceSdkProps.MatchType`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | +| [`CapfaceSdkProps.MatchData`](#capfacesdkdefaultscanmessage) | βœ… | βœ… | + +### `CapfaceSdkProps.Params` Here must be passed to initialize the Capface SDK! Case the parameters isn't provided the Capface SDK goes to be not initialized. -| `CapfaceSdk.Params` | type | Required | +| `CapfaceSdkProps.Params` | type | Required | | ------------------- | --------- | -------- | | `device` | `string` | βœ… | | `url` | `string` | βœ… | @@ -262,24 +261,24 @@ Here must be passed to initialize the Capface SDK! Case the parameters isn't pro | `productionKey` | `string` | βœ… | | `isDeveloperMode` | `boolean` | ❌ | -### `CapfaceSdk.Headers` +### `CapfaceSdkProps.Headers` Here you can add your headers to send request when some method is called. Only values from type **string**, **null** or **undefined** are accepts! -| `CapfaceSdk.Headers` | type | Required | Default | +| `CapfaceSdkProps.Headers` | type | Required | Default | | -------------------- | ------------------------------- | -------- | ----------- | | `[key: string]` | `string`, `null` or `undefined` | ❌ | `undefined` | -### `CapfaceSdk.Theme` +### `CapfaceSdkProps.Theme` This is a list of theme properties that can be used to styling. Note, we recommend that you use **only** hexadecimal values to colors, between six and eight characters, because still we don't supported others color type. -| `CapfaceSdk.Theme` | type | iOS | Android | Required | Default | +| `CapfaceSdkProps.Theme` | type | iOS | Android | Required | Default | | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --- | ------- | -------- | ------------------------------------------------------------------------------------------------------- | | `logoImage` | `string` | βœ… | βœ… | ❌ | `facetec_your_app_logo.png` | | `cancelImage` | `string` | βœ… | βœ… | ❌ | `facetec_cancel.png` | -| `cancelButtonLocation` | [`CapfaceSdk.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | ❌ | `TOP_RIGHT` | -| `defaultStatusBarColorIos` | [`CapfaceSdk.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | ❌ | `DARK_CONTENT` | +| `cancelButtonLocation` | [`CapfaceSdkProps.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | ❌ | `TOP_RIGHT` | +| `defaultStatusBarColorIos` | [`CapfaceSdkProps.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | ❌ | `DARK_CONTENT` | | `frameCornerRadius` | `number` | βœ… | βœ… | ❌ | `10` (iOS) and `20` (Android) | | `frameBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `frameBorderColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | @@ -299,7 +298,7 @@ This is a list of theme properties that can be used to styling. Note, we recomme | `ovalFirstProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | | `ovalSecondProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | | `feedbackBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#026FF4` | -| `feedbackBackgroundColorsIos` | [`CapfaceSdk.FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | ❌ | [`FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | +| `feedbackBackgroundColorsIos` | [`CapfaceSdkProps.FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | ❌ | [`FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | | `feedbackTextColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `resultScreenBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | | `resultScreenBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | @@ -323,64 +322,64 @@ This is a list of theme properties that can be used to styling. Note, we recomme | `idScanButtonTextHighlightColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `idScanCaptureScreenBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `idScanCaptureFrameStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `autheticanteMessage` | [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | -| `enrollMessage` | [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | -| `photoIdMatchMessage` | [`CapfaceSdk.DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`CapfaceSdk.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`DefaultMessage`](#capfacesdkdefaultmessage) | +| `autheticanteMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | +| `enrollMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | +| `photoIdMatchMessage` | [`CapfaceSdkProps.DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`DefaultMessage`](#capfacesdkdefaultmessage) | -### `CapfaceSdk.ButtonLocation` +### `CapfaceSdkProps.ButtonLocation` This type must be used to position of the cancel button on screen. -| `CapfaceSdk.ButtonLocation` | Description | +| `CapfaceSdkProps.ButtonLocation` | Description | | --------------------------- | --------------------------------------------------------------- | | `DISABLED` | Disable cancel button and doesn't show it. | | `TOP_LEFT` | Position cancel button in top right. | | `TOP_RIGHT` | Position cancel button in top right. It's **default** position. | -### `CapfaceSdk.StatusBarColor` (`iOS` only) +### `CapfaceSdkProps.StatusBarColor` (`iOS` only) This type must be used to status bar color. -| `CapfaceSdk.StatusBarColor` | Description | +| `CapfaceSdkProps.StatusBarColor` | Description | | --------------------------- | -------------------------------------------- | | `DARK_CONTENT` | **Default** color to status bar. | | `DEFAULT` | Status bar color that's set from the device. | | `LIGHT_CONTENT` | Light color to status bar. | -### `CapfaceSdk.FeedbackBackgroundColor` (`iOS` only) +### `CapfaceSdkProps.FeedbackBackgroundColor` (`iOS` only) This type must be used to **set** the **theme** of the feedback box. -| `CapfaceSdk.FeedbackBackgroundColor` | Description | type | Required | Default | +| `CapfaceSdkProps.FeedbackBackgroundColor` | Description | type | Required | Default | | ------------------------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------ | -------- | ------------------------ | | `colors` | An array of colors defining the color of each gradient stop. | `string[]` | ❌ | `["#026FF4", "#026FF4"]` | | `locations` | It's accepts only two values between 0 and 1 that defining the location of each gradient stop. | `[number, number]` | ❌ | `[0, 1]` | | `startPoint` | The start point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 0` and `y: 0` | | `endPoint` | The end point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 1` and `y: 0` | -### `CapfaceSdk.Point` (`iOS` only) +### `CapfaceSdkProps.Point` (`iOS` only) This interface defines the drawn in the layer's coordinate space. -| `CapfaceSdk.Point` | type | Required | Default | +| `CapfaceSdkProps.Point` | type | Required | Default | | ------------------ | -------- | -------- | ----------- | | `x` | `number` | ❌ | `undefined` | | `y` | `number` | ❌ | `undefined` | -### `CapfaceSdk.DefaultMessage` +### `CapfaceSdkProps.DefaultMessage` This interface represents the success message and loading data message during to CapfaceSDK flow. It interface is used **more** by processors's [authenticate](#authenticatedata-capfacesdkdata) and [enroll](#enrolldata-capfacesdkdata) processors. -| `CapfaceSdk.DefaultMessage` | type | iOS | Android | Required | Default | +| `CapfaceSdkProps.DefaultMessage` | type | iOS | Android | Required | Default | | --------------------------- | -------- | --- | ------- | -------- | ----------------------------------------------------------------------- | | `successMessage` | `string` | βœ… | βœ… | ❌ | `Liveness Confirmed` (Exception to authenticate method: `Autheticated`) | | `uploadMessageIos` | `string` | βœ… | ❌ | ❌ | `Still Uploading...` | -### `CapfaceSdk.DefaultScanMessage` +### `CapfaceSdkProps.DefaultScanMessage` This interface represents the all scan messages during to CapfaceSDK flow. It interface is used by [photoMatch](#photomatchdata-capfacesdkdata) processors. -| `CapfaceSdk.DefaultScanMessage` | type | iOS | Android | Required | Default | +| `CapfaceSdkProps.DefaultScanMessage` | type | iOS | Android | Required | Default | | --------------------------------------------------- | -------- | --- | ------- | -------- | ------------------------------------ | | `frontSideUploadStarted` | `string` | βœ… | βœ… | ❌ | `Uploading Encrypted ID Scan` | | `frontSideStillUploading` | `string` | βœ… | βœ… | ❌ | `Still Uploading... Slow Connection` | @@ -417,11 +416,11 @@ This interface represents the all scan messages during to CapfaceSDK flow. It in | `retryIDTypeNotSupported` | `string` | βœ… | βœ… | ❌ | `ID Type Mismatch Please Try Again` | | `skipOrErrorNFC` | `string` | βœ… | βœ… | ❌ | `ID Details Uploaded` | -### `CapfaceSdk.Errors` +### `CapfaceSdkProps.Errors` This enum represents all errors that are encountered on the CapFace SDK. -| `CapfaceSdk.Errors` | Description | iOS | Android | +| `CapfaceSdkProps.Errors` | Description | iOS | Android | | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --- | ------- | | `CapFaceHasNotBeenInitialized` | When some processors method is runned, but CapfaceSDK **has not been initialized**. | βœ… | βœ… | | `CapFaceValuesWereNotProcessed` | When the image sent to the processors cannot be processed due to inconsistency. | βœ… | βœ… | @@ -432,11 +431,11 @@ This enum represents all errors that are encountered on the CapFace SDK. | `CapFaceLivenessWasntProcessed` | When the image user sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | | `CapFaceScanWasntProcessed` | When the image ID sent to the processors cannot be processed due to inconsistency. | ❌ | βœ… | -### `CapfaceSdk.MatchType` +### `CapfaceSdkProps.MatchType` This enum represents all the possible types of flow that can be used on the [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) method. -| `CapfaceSdk.MatchType` | Description | iOS | Android | +| `CapfaceSdkProps.MatchType` | Description | iOS | Android | | ---------------------- | ---------------------------------------- | --- | ------- | | `authenticate` | When you want to make authenticate flow. | βœ… | βœ… | | `enroll` | When you want to make enrollment flow. | βœ… | βœ… | @@ -444,11 +443,11 @@ This enum represents all the possible types of flow that can be used on the [`fa > The **authenticate flow** depends on to enrollment flow to **work** because the authenticate flow is done using an **UUID** that's was created by enrollment flow. -### `CapfaceSdk.MatchData` +### `CapfaceSdkProps.MatchData` The object with properties that will be sent to native modules to make the requests, change text labels and sent parameters via headers. -| `CapfaceSdk.MatchData` | type | iOS | Android | Required | Default | +| `CapfaceSdkProps.MatchData` | type | iOS | Android | Required | Default | | ---------------------- | ------------------ | --- | ------- | -------- | ------------------------------------------------------------------------------------------- | | `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enrollment and liveness) | | `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | diff --git a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj index 3f75430..a69ced3 100644 --- a/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj +++ b/example/ios/ReactNativeCapfaceSdkExample.xcodeproj/project.pbxproj @@ -11,9 +11,9 @@ 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 22D0CFF7FEC440F271506AA9 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */; }; + 247F089AB22530C1DB46BC5E /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADC4772197DCED03368D4E9E /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; + 7EBB414F5B4443B5D27B40CB /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F83D6D7BA19CA446A61F40F /* libPods-ReactNativeCapfaceSdkExample.a */; }; 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; - C91F24D5EF32BD1F390D174B /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -27,22 +27,22 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 00CEB308EFD90EB634406C74 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; 00E356EE1AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeCapfaceSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* ReactNativeCapfaceSdkExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeCapfaceSdkExampleTests.m; sourceTree = ""; }; - 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07F961A680F5B00A75B9A /* ReactNativeCapfaceSdkExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeCapfaceSdkExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = ReactNativeCapfaceSdkExample/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = ReactNativeCapfaceSdkExample/AppDelegate.mm; sourceTree = ""; }; 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeCapfaceSdkExample/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeCapfaceSdkExample/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeCapfaceSdkExample/main.m; sourceTree = ""; }; - 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; + 1F83D6D7BA19CA446A61F40F /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 69AA8473C7F1550B80E8D0F3 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; + 74BD28E6D2B4F2D1FB2E723A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig"; sourceTree = ""; }; 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeCapfaceSdkExample/LaunchScreen.storyboard; sourceTree = ""; }; - 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; - 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig"; sourceTree = ""; }; - AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.debug.xcconfig"; sourceTree = ""; }; - C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + ADC4772197DCED03368D4E9E /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + C705CB4038A1FF10A88C5C9D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample.release.xcconfig"; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; /* End PBXFileReference section */ @@ -51,7 +51,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C91F24D5EF32BD1F390D174B /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, + 247F089AB22530C1DB46BC5E /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -59,7 +59,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 22D0CFF7FEC440F271506AA9 /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, + 7EBB414F5B4443B5D27B40CB /* libPods-ReactNativeCapfaceSdkExample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -100,8 +100,8 @@ isa = PBXGroup; children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - C823DE56C47EA65778AB28A4 /* libPods-ReactNativeCapfaceSdkExample.a */, - 0808837B5851ECA9EC65C64C /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, + 1F83D6D7BA19CA446A61F40F /* libPods-ReactNativeCapfaceSdkExample.a */, + ADC4772197DCED03368D4E9E /* libPods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.a */, ); name = Frameworks; sourceTree = ""; @@ -140,10 +140,10 @@ BBD78D7AC51CEA395F1C20DB /* Pods */ = { isa = PBXGroup; children = ( - AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, - 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, - 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, - 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, + 00CEB308EFD90EB634406C74 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */, + C705CB4038A1FF10A88C5C9D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */, + 69AA8473C7F1550B80E8D0F3 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */, + 74BD28E6D2B4F2D1FB2E723A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -155,12 +155,12 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExampleTests" */; buildPhases = ( - C996117FAE27CC09311295E2 /* [CP] Check Pods Manifest.lock */, + 0AD25F458B8F503320F9FC49 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 865C50E22E6C7C2E8DF1AF32 /* [CP] Embed Pods Frameworks */, - 3D0B7ADB0D87A0928F4CCFF3 /* [CP] Copy Pods Resources */, + E000661927B249290E520171 /* [CP] Embed Pods Frameworks */, + 06FBC355CA314BEA65598583 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -176,14 +176,14 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeCapfaceSdkExample" */; buildPhases = ( - 5D1D2A32F60AC8D524AB6C52 /* [CP] Check Pods Manifest.lock */, + 9265056B7603D4FE81DCE93B /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - FC65C77F5CDAB55C15DE1FFE /* [CP] Embed Pods Frameworks */, - 3C4B398EA6C5E7DC3EA9AA19 /* [CP] Copy Pods Resources */, + 2A1B014C431F06DC2776A7EA /* [CP] Embed Pods Frameworks */, + 1FA3CEB0278C7BB8FCFBA2E0 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -266,80 +266,80 @@ shellPath = /bin/sh; shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; }; - 3C4B398EA6C5E7DC3EA9AA19 /* [CP] Copy Pods Resources */ = { + 06FBC355CA314BEA65598583 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 3D0B7ADB0D87A0928F4CCFF3 /* [CP] Copy Pods Resources */ = { + 0AD25F458B8F503320F9FC49 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Copy Pods Resources"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-resources.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 5D1D2A32F60AC8D524AB6C52 /* [CP] Check Pods Manifest.lock */ = { + 1FA3CEB0278C7BB8FCFBA2E0 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Copy Pods Resources"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 865C50E22E6C7C2E8DF1AF32 /* [CP] Embed Pods Frameworks */ = { + 2A1B014C431F06DC2776A7EA /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - C996117FAE27CC09311295E2 /* [CP] Check Pods Manifest.lock */ = { + 9265056B7603D4FE81DCE93B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -354,28 +354,28 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeCapfaceSdkExample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - FC65C77F5CDAB55C15DE1FFE /* [CP] Embed Pods Frameworks */ = { + E000661927B249290E520171 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample/Pods-ReactNativeCapfaceSdkExample-frameworks.sh\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests/Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FD10A7F022414F080027D42C /* Start Packager */ = { @@ -430,7 +430,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9ADBF0E6618304AA1F86BC93 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; + baseConfigurationReference = 69AA8473C7F1550B80E8D0F3 /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -457,7 +457,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6069289BA0E4E8DA1288AC2A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; + baseConfigurationReference = 74BD28E6D2B4F2D1FB2E723A /* Pods-ReactNativeCapfaceSdkExample-ReactNativeCapfaceSdkExampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -481,7 +481,7 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = AD50B0CE6663C59E5BBBEADB /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; + baseConfigurationReference = 00CEB308EFD90EB634406C74 /* Pods-ReactNativeCapfaceSdkExample.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; @@ -509,7 +509,7 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 81DAF9E5BDC90EBF7AC35C88 /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; + baseConfigurationReference = C705CB4038A1FF10A88C5C9D /* Pods-ReactNativeCapfaceSdkExample.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; diff --git a/example/package-lock.json b/example/package-lock.json index 9163894..1d6b5c8 100644 --- a/example/package-lock.json +++ b/example/package-lock.json @@ -70,20 +70,20 @@ } }, "node_modules/@babel/core": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz", - "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.19.tgz", + "integrity": "sha512-Q8Yj5X4LHVYTbLCKVz0//2D2aDmHF4xzCdEttYvKOnWvErGsa6geHXD6w46x64n5tP69VfeH+IfSrdyH3MLhwA==", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.17", + "@babel/helper-module-transforms": "^7.22.19", "@babel/helpers": "^7.22.15", "@babel/parser": "^7.22.16", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.17", - "@babel/types": "^7.22.17", + "@babel/traverse": "^7.22.19", + "@babel/types": "^7.22.19", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -274,15 +274,15 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", - "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.19.tgz", + "integrity": "sha512-m6h1cJvn+OJ+R3jOHp30faq5xKJ7VbjwDj5RGgHuRlU9hrMeKsGC+JpihkR5w1g7IfseCPPtZ0r7/hB4UKaYlA==", "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.19" }, "engines": { "node": ">=6.9.0" @@ -384,9 +384,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.19.tgz", + "integrity": "sha512-Tinq7ybnEPFFXhlYOYFiSjespWQk0dq2dRNAiMdRTOYQzEGqnnNyrTxPYHP5r6wGjlF1rFgABdDV0g8EwD6Qbg==", "engines": { "node": ">=6.9.0" } @@ -1919,9 +1919,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", - "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.19.tgz", + "integrity": "sha512-ZCcpVPK64krfdScRbpxF6xA5fz7IOsfMwx1tcACvCzt6JY+0aHkBk7eIU8FRDSZRU5Zei6Z4JfgAxN1bqXGECg==", "dependencies": { "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", @@ -1930,7 +1930,7 @@ "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.17", + "@babel/types": "^7.22.19", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1939,12 +1939,12 @@ } }, "node_modules/@babel/types": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", - "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-validator-identifier": "^7.22.19", "to-fast-properties": "^2.0.0" }, "engines": { @@ -4034,14 +4034,14 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.6.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.0.tgz", - "integrity": "sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==" + "version": "20.6.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.1.tgz", + "integrity": "sha512-4LcJvuXQlv4lTHnxwyHQZ3uR9Zw2j7m1C9DfuwoTFQQP4Pmu04O6IfLYgMmHoOCt0nosItLLZAH+sOrRE0Bo8g==" }, "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -5424,9 +5424,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.4.519", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz", - "integrity": "sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==" + "version": "1.4.522", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.522.tgz", + "integrity": "sha512-KGKjcafTpOxda0kqwQ72M0tDmX6RsGhUJTy0Hr7slt0+CgHh9Oex8JdjY9Og68dUkTLUlBOJC0A5W5Mw3QSGCg==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -5481,18 +5481,18 @@ } }, "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", + "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.1", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", @@ -5508,23 +5508,23 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.0", "typed-array-byte-length": "^1.0.0", "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -5534,14 +5534,14 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", - "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", "dev": true, "dependencies": { "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.2", - "define-properties": "^1.2.0", + "define-properties": "^1.2.1", "es-abstract": "^1.22.1", "es-set-tostringtag": "^2.0.1", "function-bind": "^1.1.1", @@ -5551,8 +5551,8 @@ "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.0", - "safe-array-concat": "^1.0.0" + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" } }, "node_modules/es-set-tostringtag": { @@ -7293,15 +7293,16 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz", - "integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", "dev": true, "dependencies": { - "define-properties": "^1.2.0", + "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.3" + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" } }, "node_modules/jest-environment-node": { @@ -10127,9 +10128,9 @@ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dependencies": { "regenerate": "^1.4.2" }, @@ -10222,9 +10223,9 @@ "dev": true }, "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", diff --git a/example/types/index.d.ts b/example/types/index.d.ts deleted file mode 100644 index 343b4c9..0000000 --- a/example/types/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module '@capitual/react-native-capface-sdk'; diff --git a/package-lock.json b/package-lock.json index b2b233c..0a26b11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,21 +92,21 @@ } }, "node_modules/@babel/core": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.17.tgz", - "integrity": "sha512-2EENLmhpwplDux5PSsZnSbnSkB3tZ6QTksgO25xwEL7pIDcNOMhF5v/s6RzwjMZzZzw9Ofc30gHv5ChCC8pifQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.19.tgz", + "integrity": "sha512-Q8Yj5X4LHVYTbLCKVz0//2D2aDmHF4xzCdEttYvKOnWvErGsa6geHXD6w46x64n5tP69VfeH+IfSrdyH3MLhwA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.22.13", "@babel/generator": "^7.22.15", "@babel/helper-compilation-targets": "^7.22.15", - "@babel/helper-module-transforms": "^7.22.17", + "@babel/helper-module-transforms": "^7.22.19", "@babel/helpers": "^7.22.15", "@babel/parser": "^7.22.16", "@babel/template": "^7.22.15", - "@babel/traverse": "^7.22.17", - "@babel/types": "^7.22.17", + "@babel/traverse": "^7.22.19", + "@babel/types": "^7.22.19", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -251,9 +251,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider/node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -326,16 +326,16 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.17.tgz", - "integrity": "sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.19.tgz", + "integrity": "sha512-m6h1cJvn+OJ+R3jOHp30faq5xKJ7VbjwDj5RGgHuRlU9hrMeKsGC+JpihkR5w1g7IfseCPPtZ0r7/hB4UKaYlA==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", "@babel/helper-simple-access": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.15" + "@babel/helper-validator-identifier": "^7.22.19" }, "engines": { "node": ">=6.9.0" @@ -445,9 +445,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.15.tgz", - "integrity": "sha512-4E/F9IIEi8WR94324mbDUMo074YTheJmd7eZF5vITTeYchqAi6sYXRLHUVsmkdmY4QjfKTcB2jB7dVP3NaBElQ==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.19.tgz", + "integrity": "sha512-Tinq7ybnEPFFXhlYOYFiSjespWQk0dq2dRNAiMdRTOYQzEGqnnNyrTxPYHP5r6wGjlF1rFgABdDV0g8EwD6Qbg==", "dev": true, "engines": { "node": ">=6.9.0" @@ -2192,9 +2192,9 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.17.tgz", - "integrity": "sha512-xK4Uwm0JnAMvxYZxOVecss85WxTEIbTa7bnGyf/+EgCL5Zt3U7htUpEOWv9detPlamGKuRzCqw74xVglDWpPdg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.19.tgz", + "integrity": "sha512-ZCcpVPK64krfdScRbpxF6xA5fz7IOsfMwx1tcACvCzt6JY+0aHkBk7eIU8FRDSZRU5Zei6Z4JfgAxN1bqXGECg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.22.13", @@ -2204,7 +2204,7 @@ "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.17", + "@babel/types": "^7.22.19", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -2213,13 +2213,13 @@ } }, "node_modules/@babel/types": { - "version": "7.22.17", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.17.tgz", - "integrity": "sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==", + "version": "7.22.19", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", + "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.15", + "@babel/helper-validator-identifier": "^7.22.19", "to-fast-properties": "^2.0.0" }, "engines": { @@ -5570,9 +5570,9 @@ } }, "node_modules/@semantic-release/github": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.0.5.tgz", - "integrity": "sha512-d1ZZjMvXpSa4E1L3XjdNOqgUy00o9QZX55L75pMsb/w+1NV6CCfDYOvH8qwKygHS/rKzI3FkBTcR40ahOodsgg==", + "version": "9.0.6", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.0.6.tgz", + "integrity": "sha512-GBGt9c3c2UdSvso4jcyQQSUpZA9hbfHqGQerZKN9WvVzCIkaBy8xkhOyiFVX08LjRHHT/H221SJNBLtuihX5iw==", "dev": true, "peer": true, "dependencies": { @@ -5581,7 +5581,7 @@ "@octokit/plugin-retry": "^6.0.0", "@octokit/plugin-throttling": "^7.0.0", "@semantic-release/error": "^4.0.0", - "aggregate-error": "^4.0.1", + "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", "globby": "^13.1.4", @@ -5763,33 +5763,33 @@ } }, "node_modules/@semantic-release/github/node_modules/aggregate-error": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", - "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", + "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==", "dev": true, "peer": true, "dependencies": { - "clean-stack": "^4.0.0", + "clean-stack": "^5.2.0", "indent-string": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@semantic-release/github/node_modules/clean-stack": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", - "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz", + "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==", "dev": true, "peer": true, "dependencies": { "escape-string-regexp": "5.0.0" }, "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -6386,9 +6386,9 @@ "dev": true }, "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-7aqorHYgdNO4DM36stTiGO3DvKoex9TQRwsJU6vMaFGyqpBA1MNZkz+PG3gaNUPpTAOYhT1WR7M1JyA3fbS9Cw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -9336,9 +9336,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.519", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz", - "integrity": "sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==", + "version": "1.4.522", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.522.tgz", + "integrity": "sha512-KGKjcafTpOxda0kqwQ72M0tDmX6RsGhUJTy0Hr7slt0+CgHh9Oex8JdjY9Og68dUkTLUlBOJC0A5W5Mw3QSGCg==", "dev": true }, "node_modules/emittery": { @@ -9566,18 +9566,18 @@ } }, "node_modules/es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", + "integrity": "sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA==", "dev": true, "dependencies": { "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.2", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", + "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.1", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", @@ -9593,23 +9593,23 @@ "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.12", "is-weakref": "^1.0.2", "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", "typed-array-buffer": "^1.0.0", "typed-array-byte-length": "^1.0.0", "typed-array-byte-offset": "^1.0.0", "typed-array-length": "^1.0.4", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -9651,14 +9651,14 @@ "dev": true }, "node_modules/es-iterator-helpers": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.14.tgz", - "integrity": "sha512-JgtVnwiuoRuzLvqelrvN3Xu7H9bu2ap/kQ2CrM62iidP8SKuD99rWU3CJy++s7IVL2qb/AjXPGR/E7i9ngd/Cw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz", + "integrity": "sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g==", "dev": true, "dependencies": { "asynciterator.prototype": "^1.0.0", "call-bind": "^1.0.2", - "define-properties": "^1.2.0", + "define-properties": "^1.2.1", "es-abstract": "^1.22.1", "es-set-tostringtag": "^2.0.1", "function-bind": "^1.1.1", @@ -9668,8 +9668,8 @@ "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.0", - "safe-array-concat": "^1.0.0" + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" } }, "node_modules/es-set-tostringtag": { @@ -12745,15 +12745,16 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.1.tgz", - "integrity": "sha512-9E+nePc8C9cnQldmNl6bgpTY6zI4OPRZd97fhJ/iVZ1GifIUDVV5F6x1nEDqpe8KaMEZGT4xgrwKQDxXnjOIZQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz", + "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==", "dev": true, "dependencies": { - "define-properties": "^1.2.0", + "define-properties": "^1.2.1", "get-intrinsic": "^1.2.1", "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.3" + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" } }, "node_modules/java-properties": { @@ -13704,9 +13705,9 @@ } }, "node_modules/jest-resolve/node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -15477,9 +15478,9 @@ } }, "node_modules/meow/node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -22247,9 +22248,9 @@ } }, "node_modules/rechoir/node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", + "version": "1.22.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", + "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, "dependencies": { "is-core-module": "^2.13.0", @@ -22313,9 +22314,9 @@ "dev": true }, "node_modules/regenerate-unicode-properties": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz", - "integrity": "sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", + "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", "dev": true, "dependencies": { "regenerate": "^1.4.2" diff --git a/src/constants/index.ts b/src/constants/index.ts index 9028f78..4b95e21 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,8 +1,8 @@ -import type { CapfaceSdk } from '..'; +import type { CapfaceSdkProps } from '..'; export const NATIVE_CONSTANTS = ( - data?: CapfaceSdk.MatchData -): Record => ({ + data?: CapfaceSdkProps.MatchData +): Record => ({ authenticate: { key: 'authenticateMessage', hasExternalDatabaseRefID: true, diff --git a/src/index.tsx b/src/index.tsx index b8d5566..735b0b0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,12 +1,46 @@ +import { NativeModules, Platform } from 'react-native'; + import { NATIVE_CONSTANTS } from './constants'; -import { CapfaceSdk, ReactNativeCapfaceSdk } from './types'; +import { CapfaceSdkProps } from './types'; + +import type { NativeModule } from 'react-native'; + +const LINKING_ERROR = + `The package '@capitual/react-native-capface-sdk' doesn't seem to be linked. Make sure: \n\n` + + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + + '- You rebuilt the app after installing the package\n' + + '- You are not using Expo Go\n'; + +/** + * @description Native module CapfaceSDK, it's recommended use it with event + * types. + * + * @example + * import { NativeEventEmitter } from 'react-native'; + * import ReactNativeCapfaceSdk from '@capitual/react-native-capface-sdk'; + * + * const emitter = new NativeEventEmitter(ReactNativeCapfaceSdk); + * emitter.addListener('onCloseModal', (event: boolean) => console.log('onCloseModal', event)); + */ +const CapfaceSdk = NativeModules.ReactNativeCapfaceSdk + ? NativeModules.ReactNativeCapfaceSdk + : new Proxy( + {}, + { + get() { + throw new Error(LINKING_ERROR); + }, + } + ); + +export default CapfaceSdk as NativeModule; /** * @description This is the **principal** method to be called, he must be * **called first** to initialize the Capface SDK. If he doens't be called the * other methods **don't works!** * - * @param {CapfaceSdk.Initialize} initialize - Initialize the Capface SDK with + * @param {CapfaceSdkProps.Initialize} initialize - Initialize the Capface SDK with * especific parameters and an optional headers. * * @return {Promise} Represents if Capface SDK initialized with @@ -15,16 +49,12 @@ import { CapfaceSdk, ReactNativeCapfaceSdk } from './types'; export function initialize({ params, headers, -}: CapfaceSdk.Initialize): Promise { +}: CapfaceSdkProps.Initialize): Promise { return new Promise((resolve, reject) => { - ReactNativeCapfaceSdk.initializeSdk( - params, - headers, - (successful: boolean) => { - if (successful) resolve(true); - else reject(false); - } - ); + CapfaceSdk.initializeSdk(params, headers, (successful: boolean) => { + if (successful) resolve(true); + else reject(false); + }); }); } @@ -37,8 +67,8 @@ export function initialize({ * your server. Finally, the **liveness** method makes a 3D reading of the * user's face. * - * @param {CapfaceSdk.MatchType} type - The type of flow to be called. - * @param {CapfaceSdk.MatchData|undefined} data - The object with properties + * @param {CapfaceSdkProps.MatchType} type - The type of flow to be called. + * @param {CapfaceSdkProps.MatchData|undefined} data - The object with properties * that will be sent to native modules to make the requests, change text labels * and sent parameters via headers. * @@ -46,12 +76,10 @@ export function initialize({ * @throws If was a unsuccessful or occurred some interference. */ export async function faceMatch( - type: CapfaceSdk.MatchType, - data?: CapfaceSdk.MatchData + type: CapfaceSdkProps.MatchType, + data?: CapfaceSdkProps.MatchData ): Promise { - return await ReactNativeCapfaceSdk.handleFaceUser( - NATIVE_CONSTANTS(data)[type] - ) + return await CapfaceSdk.handleFaceUser(NATIVE_CONSTANTS(data)[type]) .then((successful: boolean) => successful) .catch((error: Error) => { throw new Error(error.message); @@ -69,7 +97,7 @@ export async function faceMatch( * @throws If photo ID match was a unsuccessful or occurred some interference. */ export async function photoMatch(data?: Object): Promise { - return await ReactNativeCapfaceSdk.handlePhotoIDMatch(data) + return await CapfaceSdk.handlePhotoIDMatch(data) .then((successful: boolean) => successful) .catch((error: Error) => { throw new Error(error.message); @@ -80,13 +108,13 @@ export async function photoMatch(data?: Object): Promise { * @description This method must be used to **set** the **theme** of the Capface * SDK screen. * - * @param {CapfaceSdk.Theme|undefined} options - The object theme options. All + * @param {CapfaceSdkProps.Theme|undefined} options - The object theme options. All * options are optional. * * @return {void} */ -export function setTheme(options?: CapfaceSdk.Theme): void { - ReactNativeCapfaceSdk.handleTheme(options); +export function setTheme(options?: CapfaceSdkProps.Theme): void { + CapfaceSdk.handleTheme(options); } export * from './types'; diff --git a/src/types/index.ts b/src/types/index.ts index 3b983ff..99029ff 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,17 +1,9 @@ -import { NativeModules, Platform } from 'react-native'; - -const LINKING_ERROR = - `The package '@capitual/react-native-capface-sdk' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo Go\n'; - /** * @namespace * * @description The principal namespace of the Capface SDK. */ -export declare namespace CapfaceSdk { +export declare namespace CapfaceSdkProps { /** * @type * @@ -892,8 +884,8 @@ export declare namespace CapfaceSdk { * **called first** to initialize the Capface SDK. If he doens't be called * the other methods **don't works!** * - * @param {CapfaceSdk.Params} params - Initialization SDK parameters. - * @param {CapfaceSdk.Headers} headers - Headers your requests, to each + * @param {CapfaceSdkProps.Params} params - Initialization SDK parameters. + * @param {CapfaceSdkProps.Headers} headers - Headers your requests, to each * request it's sent. The headers is optional. * @param {Function} callback - Callback function to be called after with * the response of the successfully. The callback is optional. @@ -927,19 +919,21 @@ export declare namespace CapfaceSdk { * your server. Finally, the **liveness** method makes a 3D reading of the * user's face. * - * @param {CapfaceSdk.MatchData|undefined} data - The object with data to + * @param {CapfaceSdkProps.MatchData|undefined} data - The object with data to * be will send by headers on the requests. The data is optional. * * @return {Promise} Represents if flow was a successful. * @throws If was a unsuccessful or occurred some interference. */ - handleFaceUser(data?: CapfaceSdk.MatchData | undefined): Promise; + handleFaceUser( + data?: CapfaceSdkProps.MatchData | undefined + ): Promise; /** * @description This method must be used to **set** the **theme** of the * Capface SDK screen. * - * @param {CapfaceSdk.Theme|undefined} options - The object theme options. + * @param {CapfaceSdkProps.Theme|undefined} options - The object theme options. * All options are optional. * * @return {void} @@ -947,26 +941,3 @@ export declare namespace CapfaceSdk { handleTheme(options?: Theme): void; } } - -/** - * @description Native module CapfaceSDK, it's recommended use it with event - * types. - * - * @example - * import { NativeEventEmitter } from 'react-native'; - * import ReactNativeCapfaceSdk from '@capitual/react-native-capface-sdk'; - * - * const emitter = new NativeEventEmitter(ReactNativeCapfaceSdk); - * emitter.addListener('onCloseModal', (event: boolean) => console.log('onCloseModal', event)); - */ -export const ReactNativeCapfaceSdk: CapfaceSdk.Methods = - NativeModules.ReactNativeCapfaceSdk - ? NativeModules.ReactNativeCapfaceSdk - : new Proxy( - {}, - { - get() { - throw new Error(LINKING_ERROR); - }, - } - ); From 5b434129565959333619d56bbd9669d7f353ed49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 10:45:06 -0300 Subject: [PATCH 34/43] fix: small adjusts in hexadecimal colors in documentation --- NATIVE_IMPLEMENTATION.md | 11 -- README.md | 212 +++++++++++++++++++-------------------- 2 files changed, 106 insertions(+), 117 deletions(-) diff --git a/NATIVE_IMPLEMENTATION.md b/NATIVE_IMPLEMENTATION.md index 9e47bcb..b4d0a73 100644 --- a/NATIVE_IMPLEMENTATION.md +++ b/NATIVE_IMPLEMENTATION.md @@ -6,23 +6,12 @@ ## Introduction -- [Let's go talk about colors](#lets-go-talk-about-colors-πŸ§‘β€πŸŽ¨) - [Enabling Camera](#enabling-camera-ios-only) - [Contributing](#contributing) - [License](#license)
-## Let's go talk about colors πŸ§‘β€πŸŽ¨ - -Our SDK has support for some format of the hexadecimal colors and some colors name, but not all. - -- **Android**: Support for some hexadecimal colors between **six** and **eight** characters and some colors name. We have support only these colors because we use `parseColor` method in our native module Java. It doesn't support others colors types like RGB, RGBA, HSL and HSLA, [click here to learn more about `parseColor`](). If you have some suggestions to improve it, thank you very much. - -- **iOS**: Support for hexadecimal colors only. We have support for this color because we use `UIColor` method in our native module Swift, when we call it in your constructor we provided only hexadecimal `strings`. We didn't find another way per hour to support others colors. If you have some suggestions to improve it, thank you very much. - -
- ## Enabling Camera (iOS only) If you want to enable the camera, you need to add the following instructions in your `Info.plist` file: diff --git a/README.md b/README.md index fd4c562..6d26a1a 100644 --- a/README.md +++ b/README.md @@ -186,21 +186,21 @@ const styles = StyleSheet.create({ ## API -| Methods | Return Type | iOS | Android | -| ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ | --- | ------- | -| [`initialize(init: CapfaceSdkProps.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | +| Methods | Return Type | iOS | Android | +| -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | --- | ------- | +| [`initialize(init: CapfaceSdkProps.Initialize)`](#initializeinit-capfacesdkinitialize) | `Promise` | βœ… | βœ… | | [`faceMatch(type: CapfaceSdkProps.MatchType, data?: CapfaceSdkProps.MatchData`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) | `Promise` | βœ… | βœ… | -| [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) | `Promise` | βœ… | βœ… | -| [`setTheme(options?: CapfaceSdkProps.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | +| [`photoMatch(data?: Object)`](#photomatchdata-capfacesdkdata) | `Promise` | βœ… | βœ… | +| [`setTheme(options?: CapfaceSdkProps.Theme)`](#setthemeoptions-capfacesdktheme) | `void` | βœ… | βœ… | ### `initialize(init: CapfaceSdkProps.Initialize)` This is the **principal** method to be called, he must be **called first** to initialize the Capface SDK. If he doens't be called the other methods **don't works!** -| `CapfaceSdkProps.Initialize` | type | Required | Default | -| ----------------------- | ------------------------------------------ | -------- | ----------- | -| `params` | [`CapfaceSdkProps.Params`](#capfacesdkparams) | βœ… | - | -| `headers` | [`CapfaceSdkProps.Headers`](#capfacesdkheaders) | ❌ | `undefined` | +| `CapfaceSdkProps.Initialize` | type | Required | Default | +| ---------------------------- | ----------------------------------------------- | -------- | ----------- | +| `params` | [`CapfaceSdkProps.Params`](#capfacesdkparams) | βœ… | - | +| `headers` | [`CapfaceSdkProps.Headers`](#capfacesdkheaders) | ❌ | `undefined` | ### `faceMatch(type: CapfaceSdkProps.MatchType, data?: CapfaceSdkProps.MatchData)` @@ -210,8 +210,8 @@ This method is called to make enrollment, authenticate and liveness available. T - **Authenticate**: This method makes a 3D reading of the user's face. But, you must use to **authenticate** user in Capface SDK or in your server. - **Liveness**: This method makes a 3D reading of the user's face. -| `Object` | type | Required | Default | -| -------- | ---------------------------------------------- | -------- | ----------- | +| `Object` | type | Required | Default | +| -------- | --------------------------------------------------- | -------- | ----------- | | `type` | [`CapfaceSdkProps.MatchType`](#capfacesdkmatchtype) | βœ… | - | | `data` | [`CapfaceSdkProps.MatchData`](#capfacesdkmatchdata) | ❌ | `undefined` | @@ -227,16 +227,16 @@ This method make to read from face and documents for user, after comparate face This method must be used to **set** the **theme** of the Capface SDK screen. -| `CapfaceSdkProps.Theme` | type | Required | Default | -| ------------------ | -------------------------------------- | -------- | ----------- | -| `options` | [`CapfaceSdkProps.Theme`](#capfacesdktheme) | ❌ | `undefined` | +| `CapfaceSdkProps.Theme` | type | Required | Default | +| ----------------------- | ------------------------------------------- | -------- | ----------- | +| `options` | [`CapfaceSdkProps.Theme`](#capfacesdktheme) | ❌ | `undefined` |
## Types | `CapfaceSdkProps` - Types | iOS | Android | -| ----------------------------------------------------------------------------------- | --- | ------- | +| ---------------------------------------------------------------------------------------- | --- | ------- | | [`CapfaceSdkProps.Params`](#capfacesdkparams) | βœ… | βœ… | | [`CapfaceSdkProps.Headers`](#capfacesdkheaders) | βœ… | βœ… | | [`CapfaceSdkProps.Theme`](#capfacesdktheme) | βœ… | βœ… | @@ -254,76 +254,76 @@ This method must be used to **set** the **theme** of the Capface SDK screen. Here must be passed to initialize the Capface SDK! Case the parameters isn't provided the Capface SDK goes to be not initialized. | `CapfaceSdkProps.Params` | type | Required | -| ------------------- | --------- | -------- | -| `device` | `string` | βœ… | -| `url` | `string` | βœ… | -| `key` | `string` | βœ… | -| `productionKey` | `string` | βœ… | -| `isDeveloperMode` | `boolean` | ❌ | +| ------------------------ | --------- | -------- | +| `device` | `string` | βœ… | +| `url` | `string` | βœ… | +| `key` | `string` | βœ… | +| `productionKey` | `string` | βœ… | +| `isDeveloperMode` | `boolean` | ❌ | ### `CapfaceSdkProps.Headers` Here you can add your headers to send request when some method is called. Only values from type **string**, **null** or **undefined** are accepts! | `CapfaceSdkProps.Headers` | type | Required | Default | -| -------------------- | ------------------------------- | -------- | ----------- | -| `[key: string]` | `string`, `null` or `undefined` | ❌ | `undefined` | +| ------------------------- | ------------------------------- | -------- | ----------- | +| `[key: string]` | `string`, `null` or `undefined` | ❌ | `undefined` | ### `CapfaceSdkProps.Theme` -This is a list of theme properties that can be used to styling. Note, we recommend that you use **only** hexadecimal values to colors, between six and eight characters, because still we don't supported others color type. - -| `CapfaceSdkProps.Theme` | type | iOS | Android | Required | Default | -| ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | --- | ------- | -------- | ------------------------------------------------------------------------------------------------------- | -| `logoImage` | `string` | βœ… | βœ… | ❌ | `facetec_your_app_logo.png` | -| `cancelImage` | `string` | βœ… | βœ… | ❌ | `facetec_cancel.png` | -| `cancelButtonLocation` | [`CapfaceSdkProps.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | ❌ | `TOP_RIGHT` | -| `defaultStatusBarColorIos` | [`CapfaceSdkProps.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | ❌ | `DARK_CONTENT` | -| `frameCornerRadius` | `number` | βœ… | βœ… | ❌ | `10` (iOS) and `20` (Android) | -| `frameBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `frameBorderColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `overlayBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `guidanceBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | -| `guidanceBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | -| `guidanceForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | -| `guidanceButtonBackgroundNormalColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `guidanceButtonBackgroundDisabledColor` | `string` | βœ… | βœ… | ❌ | `#B3D4FC` | -| `guidanceButtonBackgroundHighlightColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | -| `guidanceButtonTextNormalColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `guidanceButtonTextDisabledColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `guidanceButtonTextHighlightColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `guidanceRetryScreenImageBorderColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `guidanceRetryScreenOvalStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `ovalStrokeColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `ovalFirstProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | -| `ovalSecondProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | -| `feedbackBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#026FF4` | -| `feedbackBackgroundColorsIos` | [`CapfaceSdkProps.FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | ❌ | [`FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | -| `feedbackTextColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `resultScreenBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | -| `resultScreenBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | -| `resultScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | -| `resultScreenActivityIndicatorColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `resultScreenResultAnimationBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `resultScreenResultAnimationForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `resultScreenUploadProgressFillColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `idScanSelectionScreenBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | -| `idScanSelectionScreenBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | -| `idScanSelectionScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | -| `idScanReviewScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanReviewScreenTextBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `idScanCaptureScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanCaptureScreenTextBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `idScanButtonBackgroundNormalColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | -| `idScanButtonBackgroundDisabledColor` | `string` | βœ… | βœ… | ❌ | `#B3D4FC` | -| `idScanButtonBackgroundHighlightColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | -| `idScanButtonTextNormalColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanButtonTextDisabledColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanButtonTextHighlightColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanCaptureScreenBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `idScanCaptureFrameStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | -| `autheticanteMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | -| `enrollMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | +This is a list of theme properties that can be used to styling. We recommend that you use hexadecimal values for colors. RGB, RGBA, HSL and HSLA colors are also supported. + +| `CapfaceSdkProps.Theme` | type | iOS | Android | Required | Default | +| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --- | ------- | -------- | ------------------------------------------------------------------------------------------------------- | +| `logoImage` | `string` | βœ… | βœ… | ❌ | `facetec_your_app_logo.png` | +| `cancelImage` | `string` | βœ… | βœ… | ❌ | `facetec_cancel.png` | +| `cancelButtonLocation` | [`CapfaceSdkProps.ButtonLocation`](#capfacesdkbuttonlocation) | βœ… | βœ… | ❌ | `TOP_RIGHT` | +| `defaultStatusBarColorIos` | [`CapfaceSdkProps.StatusBarColor`](#capfacesdkstatusbarcolor-ios-only) | βœ… | ❌ | ❌ | `DARK_CONTENT` | +| `frameCornerRadius` | `number` | βœ… | βœ… | ❌ | `10` (iOS) and `20` (Android) | +| `frameBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `frameBorderColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `overlayBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `guidanceBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | +| `guidanceBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | +| `guidanceForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | +| `guidanceButtonBackgroundNormalColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `guidanceButtonBackgroundDisabledColor` | `string` | βœ… | βœ… | ❌ | `#B3D4FC` | +| `guidanceButtonBackgroundHighlightColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | +| `guidanceButtonTextNormalColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `guidanceButtonTextDisabledColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `guidanceButtonTextHighlightColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `guidanceRetryScreenImageBorderColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `guidanceRetryScreenOvalStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `ovalStrokeColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `ovalFirstProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | +| `ovalSecondProgressColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | +| `feedbackBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#026FF4` | +| `feedbackBackgroundColorsIos` | [`CapfaceSdkProps.FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | βœ… | ❌ | ❌ | [`FeedbackBackgroundColor` ](#capfacesdkfeedbackbackgroundcolor-ios-only) | +| `feedbackTextColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `resultScreenBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | +| `resultScreenBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | +| `resultScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | +| `resultScreenActivityIndicatorColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `resultScreenResultAnimationBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `resultScreenResultAnimationForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `resultScreenUploadProgressFillColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `idScanSelectionScreenBackgroundColorsAndroid` | `string` | ❌ | βœ… | ❌ | `#FFFFFF` | +| `idScanSelectionScreenBackgroundColorsIos` | `string[]` | βœ… | ❌ | ❌ | `["#FFFFFF", "#FFFFFF"]` | +| `idScanSelectionScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#272937` | +| `idScanReviewScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanReviewScreenTextBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `idScanCaptureScreenForegroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanCaptureScreenTextBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `idScanButtonBackgroundNormalColor` | `string` | βœ… | βœ… | ❌ | `#026FF4` | +| `idScanButtonBackgroundDisabledColor` | `string` | βœ… | βœ… | ❌ | `#B3D4FC` | +| `idScanButtonBackgroundHighlightColor` | `string` | βœ… | βœ… | ❌ | `#0264DC` | +| `idScanButtonTextNormalColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanButtonTextDisabledColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanButtonTextHighlightColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanCaptureScreenBackgroundColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `idScanCaptureFrameStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | +| `autheticanteMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | +| `enrollMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | | `photoIdMatchMessage` | [`CapfaceSdkProps.DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`DefaultMessage`](#capfacesdkdefaultmessage) | ### `CapfaceSdkProps.ButtonLocation` @@ -331,55 +331,55 @@ This is a list of theme properties that can be used to styling. Note, we recomme This type must be used to position of the cancel button on screen. | `CapfaceSdkProps.ButtonLocation` | Description | -| --------------------------- | --------------------------------------------------------------- | -| `DISABLED` | Disable cancel button and doesn't show it. | -| `TOP_LEFT` | Position cancel button in top right. | -| `TOP_RIGHT` | Position cancel button in top right. It's **default** position. | +| -------------------------------- | --------------------------------------------------------------- | +| `DISABLED` | Disable cancel button and doesn't show it. | +| `TOP_LEFT` | Position cancel button in top right. | +| `TOP_RIGHT` | Position cancel button in top right. It's **default** position. | ### `CapfaceSdkProps.StatusBarColor` (`iOS` only) This type must be used to status bar color. | `CapfaceSdkProps.StatusBarColor` | Description | -| --------------------------- | -------------------------------------------- | -| `DARK_CONTENT` | **Default** color to status bar. | -| `DEFAULT` | Status bar color that's set from the device. | -| `LIGHT_CONTENT` | Light color to status bar. | +| -------------------------------- | -------------------------------------------- | +| `DARK_CONTENT` | **Default** color to status bar. | +| `DEFAULT` | Status bar color that's set from the device. | +| `LIGHT_CONTENT` | Light color to status bar. | ### `CapfaceSdkProps.FeedbackBackgroundColor` (`iOS` only) This type must be used to **set** the **theme** of the feedback box. | `CapfaceSdkProps.FeedbackBackgroundColor` | Description | type | Required | Default | -| ------------------------------------ | ---------------------------------------------------------------------------------------------- | ------------------------------------ | -------- | ------------------------ | -| `colors` | An array of colors defining the color of each gradient stop. | `string[]` | ❌ | `["#026FF4", "#026FF4"]` | -| `locations` | It's accepts only two values between 0 and 1 that defining the location of each gradient stop. | `[number, number]` | ❌ | `[0, 1]` | -| `startPoint` | The start point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 0` and `y: 0` | -| `endPoint` | The end point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 1` and `y: 0` | +| ----------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------ | -------- | ------------------------ | +| `colors` | An array of colors defining the color of each gradient stop. | `string[]` | ❌ | `["#026FF4", "#026FF4"]` | +| `locations` | It's accepts only two values between 0 and 1 that defining the location of each gradient stop. | `[number, number]` | ❌ | `[0, 1]` | +| `startPoint` | The start point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 0` and `y: 0` | +| `endPoint` | The end point of the gradient when drawn in the layer’s coordinate space. | [`Point`](#capfacesdkpoint-ios-only) | ❌ | `x: 1` and `y: 0` | ### `CapfaceSdkProps.Point` (`iOS` only) This interface defines the drawn in the layer's coordinate space. | `CapfaceSdkProps.Point` | type | Required | Default | -| ------------------ | -------- | -------- | ----------- | -| `x` | `number` | ❌ | `undefined` | -| `y` | `number` | ❌ | `undefined` | +| ----------------------- | -------- | -------- | ----------- | +| `x` | `number` | ❌ | `undefined` | +| `y` | `number` | ❌ | `undefined` | ### `CapfaceSdkProps.DefaultMessage` This interface represents the success message and loading data message during to CapfaceSDK flow. It interface is used **more** by processors's [authenticate](#authenticatedata-capfacesdkdata) and [enroll](#enrolldata-capfacesdkdata) processors. | `CapfaceSdkProps.DefaultMessage` | type | iOS | Android | Required | Default | -| --------------------------- | -------- | --- | ------- | -------- | ----------------------------------------------------------------------- | -| `successMessage` | `string` | βœ… | βœ… | ❌ | `Liveness Confirmed` (Exception to authenticate method: `Autheticated`) | -| `uploadMessageIos` | `string` | βœ… | ❌ | ❌ | `Still Uploading...` | +| -------------------------------- | -------- | --- | ------- | -------- | ----------------------------------------------------------------------- | +| `successMessage` | `string` | βœ… | βœ… | ❌ | `Liveness Confirmed` (Exception to authenticate method: `Autheticated`) | +| `uploadMessageIos` | `string` | βœ… | ❌ | ❌ | `Still Uploading...` | ### `CapfaceSdkProps.DefaultScanMessage` This interface represents the all scan messages during to CapfaceSDK flow. It interface is used by [photoMatch](#photomatchdata-capfacesdkdata) processors. -| `CapfaceSdkProps.DefaultScanMessage` | type | iOS | Android | Required | Default | +| `CapfaceSdkProps.DefaultScanMessage` | type | iOS | Android | Required | Default | | --------------------------------------------------- | -------- | --- | ------- | -------- | ------------------------------------ | | `frontSideUploadStarted` | `string` | βœ… | βœ… | ❌ | `Uploading Encrypted ID Scan` | | `frontSideStillUploading` | `string` | βœ… | βœ… | ❌ | `Still Uploading... Slow Connection` | @@ -420,7 +420,7 @@ This interface represents the all scan messages during to CapfaceSDK flow. It in This enum represents all errors that are encountered on the CapFace SDK. -| `CapfaceSdkProps.Errors` | Description | iOS | Android | +| `CapfaceSdkProps.Errors` | Description | iOS | Android | | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- | --- | ------- | | `CapFaceHasNotBeenInitialized` | When some processors method is runned, but CapfaceSDK **has not been initialized**. | βœ… | βœ… | | `CapFaceValuesWereNotProcessed` | When the image sent to the processors cannot be processed due to inconsistency. | βœ… | βœ… | @@ -436,10 +436,10 @@ This enum represents all errors that are encountered on the CapFace SDK. This enum represents all the possible types of flow that can be used on the [`faceMatch`](#facematchtype-capfacesdkmatchtype-data-capfacesdkmatchdata) method. | `CapfaceSdkProps.MatchType` | Description | iOS | Android | -| ---------------------- | ---------------------------------------- | --- | ------- | -| `authenticate` | When you want to make authenticate flow. | βœ… | βœ… | -| `enroll` | When you want to make enrollment flow. | βœ… | βœ… | -| `liveness` | When you want to make liveness flow. | βœ… | βœ… | +| --------------------------- | ---------------------------------------- | --- | ------- | +| `authenticate` | When you want to make authenticate flow. | βœ… | βœ… | +| `enroll` | When you want to make enrollment flow. | βœ… | βœ… | +| `liveness` | When you want to make liveness flow. | βœ… | βœ… | > The **authenticate flow** depends on to enrollment flow to **work** because the authenticate flow is done using an **UUID** that's was created by enrollment flow. @@ -448,11 +448,11 @@ This enum represents all the possible types of flow that can be used on the [`fa The object with properties that will be sent to native modules to make the requests, change text labels and sent parameters via headers. | `CapfaceSdkProps.MatchData` | type | iOS | Android | Required | Default | -| ---------------------- | ------------------ | --- | ------- | -------- | ------------------------------------------------------------------------------------------- | -| `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enrollment and liveness) | -| `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | -| `successMessage` | `string` or `null` | βœ… | βœ… | ❌ | `/match-3d-3d` (authenticate) or `/enrollment-3d` (enrollment) or `/liveness-3d` (liveness) | -| `uploadMessageIos` | `string` or `null` | βœ… | βœ… | ❌ | `Still Uploading...` | +| --------------------------- | ------------------ | --- | ------- | -------- | ------------------------------------------------------------------------------------------- | +| `endpoint` | `string` or `null` | βœ… | βœ… | ❌ | `Authenticated` (authenticate) or `Liveness\nConfirmed` (enrollment and liveness) | +| `parameters` | `string` or `null` | βœ… | βœ… | ❌ | `null` | +| `successMessage` | `string` or `null` | βœ… | βœ… | ❌ | `/match-3d-3d` (authenticate) or `/enrollment-3d` (enrollment) or `/liveness-3d` (liveness) | +| `uploadMessageIos` | `string` or `null` | βœ… | βœ… | ❌ | `Still Uploading...` |
From 8afc406a3c6f8d83f9279e3c4f61c1a078c5b48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 14:02:39 -0300 Subject: [PATCH 35/43] feat: added `convertToHexColor` to `setTheme` method --- README.md | 1 + src/index.tsx | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d26a1a..9427368 100644 --- a/README.md +++ b/README.md @@ -324,6 +324,7 @@ This is a list of theme properties that can be used to styling. We recommend tha | `idScanCaptureFrameStrokeColor` | `string` | βœ… | βœ… | ❌ | `#FFFFFF` | | `autheticanteMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | | `enrollMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | +| `livenessMessage` | [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultMessage`](#capfacesdkdefaultmessage) | | `photoIdMatchMessage` | [`CapfaceSdkProps.DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`CapfaceSdkProps.DefaultMessage`](#capfacesdkdefaultmessage) | βœ… | βœ… | ❌ | [`DefaultScanMessage`](#capfacesdkdefaultscanmessage) and [`DefaultMessage`](#capfacesdkdefaultmessage) | ### `CapfaceSdkProps.ButtonLocation` diff --git a/src/index.tsx b/src/index.tsx index 735b0b0..5dd9bd7 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,6 +4,7 @@ import { NATIVE_CONSTANTS } from './constants'; import { CapfaceSdkProps } from './types'; import type { NativeModule } from 'react-native'; +import { convertToHexColor } from './helpers'; const LINKING_ERROR = `The package '@capitual/react-native-capface-sdk' doesn't seem to be linked. Make sure: \n\n` + @@ -108,12 +109,43 @@ export async function photoMatch(data?: Object): Promise { * @description This method must be used to **set** the **theme** of the Capface * SDK screen. * - * @param {CapfaceSdkProps.Theme|undefined} options - The object theme options. All - * options are optional. + * @param {CapfaceSdkProps.Theme|undefined} options - The object theme options. + * All options are optional. * * @return {void} */ export function setTheme(options?: CapfaceSdkProps.Theme): void { + if (options) { + if (options?.feedbackBackgroundColorsIos) { + if (Array.isArray(options.feedbackBackgroundColorsIos?.colors)) { + const colors = options.feedbackBackgroundColorsIos.colors.map( + (color) => convertToHexColor(color) || '' + ); + const everyColorsExists = colors.every((color) => !!color); + options.feedbackBackgroundColorsIos.colors = everyColorsExists + ? colors + : undefined; + } + } + + for (const property in options) { + const option = property as keyof CapfaceSdkProps.Theme; + if (typeof options[option] === 'string') { + const color = convertToHexColor(options[option] as string); + options = Object.assign(options, { [option]: color || undefined }); + } + if (Array.isArray(options[option])) { + const hexColors: string[] = (options[option] as string[]).map( + (color) => convertToHexColor(color) || '' + ); + const everyColorsExists = hexColors.every((color) => !!color); + options = Object.assign(options, { + [option]: everyColorsExists ? hexColors : undefined, + }); + } + } + } + CapfaceSdk.handleTheme(options); } From e4968bda12fe0caa473b0cc13e8c9ec1dcf9ae1d Mon Sep 17 00:00:00 2001 From: Bruno Fialho Date: Fri, 15 Sep 2023 14:09:10 -0300 Subject: [PATCH 36/43] fix: update app.tsx --- example/src/App.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/example/src/App.tsx b/example/src/App.tsx index 71b32a1..c89ff7c 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -8,9 +8,8 @@ import { ScrollView, NativeEventEmitter, } from 'react-native'; -import { - ReactNativeCapfaceSdk, - CapfaceSdk, +import CapfaceSdk, { + CapfaceSdkProps, initialize, faceMatch, photoMatch, @@ -49,7 +48,7 @@ export default function App() { console.log(isInitialized); }; - const emitter = new NativeEventEmitter(ReactNativeCapfaceSdk); + const emitter = new NativeEventEmitter(CapfaceSdk); emitter.addListener('onCloseModal', (event: boolean) => console.log('onCloseModal', event) ); @@ -64,8 +63,8 @@ export default function App() { }; const onPressFaceMatch = async ( - type: CapfaceSdk.MatchType, - data?: CapfaceSdk.MatchData + type: CapfaceSdkProps.MatchType, + data?: CapfaceSdkProps.MatchData ) => { try { const isSuccess = await faceMatch(type, data); From f197674d59d0b211c0bd194a192d69280e670d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 15:20:50 -0300 Subject: [PATCH 37/43] fix: added convert theme properties to hexadecimal colores and small adjusts in alpha rgba color --- src/helpers/colors.ts | 4 +-- src/helpers/index.ts | 1 + src/helpers/theme.test.ts | 66 +++++++++++++++++++++++++++++++++++++++ src/helpers/theme.ts | 60 +++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/helpers/theme.test.ts create mode 100644 src/helpers/theme.ts diff --git a/src/helpers/colors.ts b/src/helpers/colors.ts index cd14f19..5afb75d 100644 --- a/src/helpers/colors.ts +++ b/src/helpers/colors.ts @@ -123,9 +123,9 @@ function rgbaToHex(rgbaColor: string): string | null { if (!isBetweenLimits('RGBA', colorTable)) return null; const [red, green, blue, alpha] = colorTable; - const alphaNumeric = (((alpha! as any) * 255) | (1 << 8)) + const alphaNumeric = Math.round(alpha! * 255) .toString(16) - .slice(1); + .padStart(2, '0'); const byteNumbers = (1 << 24) | (red! << 16) | (green! << 8) | blue!; const hexColor = `#${byteNumbers .toString(16) diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 1bae1c0..3579e08 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1 +1,2 @@ export * from './colors'; +export * from './theme'; diff --git a/src/helpers/theme.test.ts b/src/helpers/theme.test.ts new file mode 100644 index 0000000..1d900b3 --- /dev/null +++ b/src/helpers/theme.test.ts @@ -0,0 +1,66 @@ +import { convertThemePropsToHexColor } from '.'; +import { CapfaceSdkProps } from '..'; + +const HEX_COLOR = '#00FFC8'; +const HEX_ALPHA_COLOR = '#00FFC8B3'; +const RGB_COLOR = 'rgb(0,255,200)'; +const RGBA_COLOR = 'rgba(0,255,200,0.7)'; +const HSL_COLOR = 'hsl(167, 100%, 50%)'; +const HSLA_COLOR = 'hsla(167, 100%, 50%, 0.7)'; + +const createTestTheme = (color: string): CapfaceSdkProps.Theme => ({ + feedbackTextColor: color, + feedbackBackgroundColorsIos: { + colors: [color, color], + }, + guidanceBackgroundColorsIos: [color, color], +}); + +describe('Themme Helper', () => { + describe('Ensure convertThemePropsToHexColor function should', () => { + describe('Works general', () => { + it('Should be call with correct values', () => { + const fn = { method: convertThemePropsToHexColor }; + jest.spyOn(fn, 'method'); + fn.method({}); + expect(fn.method).toHaveBeenCalledTimes(1); + expect(fn.method).toHaveBeenCalledWith({}); + }); + }); + + describe('Works with hexadecimal colors', () => { + it('Should a return hexadecimal color if a object with hexadecimal colors is provided', () => { + const theme = convertThemePropsToHexColor(createTestTheme(HEX_COLOR)); + expect(theme).toEqual(createTestTheme(HEX_COLOR)); + }); + }); + + describe('Works with RGB colors', () => { + it('Should a return RGB color if a object with RGB colors is provided', () => { + const theme = convertThemePropsToHexColor(createTestTheme(RGB_COLOR)); + expect(theme).toEqual(createTestTheme(HEX_COLOR)); + }); + }); + + describe('Works with RGBA colors', () => { + it('Should a return RGBA color if a object with RGBA colors is provided', () => { + const theme = convertThemePropsToHexColor(createTestTheme(RGBA_COLOR)); + expect(theme).toEqual(createTestTheme(HEX_ALPHA_COLOR)); + }); + }); + + describe('Works with HSL colors', () => { + it('Should a return HSL color if a object with HSL colors is provided', () => { + const theme = convertThemePropsToHexColor(createTestTheme(HSL_COLOR)); + expect(theme).toEqual(createTestTheme(HEX_COLOR)); + }); + }); + + describe('Works with HSLA colors', () => { + it('Should a return HSLA color if a object with HSLA colors is provided', () => { + const theme = convertThemePropsToHexColor(createTestTheme(HSLA_COLOR)); + expect(theme).toEqual(createTestTheme(HEX_ALPHA_COLOR)); + }); + }); + }); +}); diff --git a/src/helpers/theme.ts b/src/helpers/theme.ts new file mode 100644 index 0000000..4c6d774 --- /dev/null +++ b/src/helpers/theme.ts @@ -0,0 +1,60 @@ +import { CapfaceSdkProps } from '..'; +import { convertToHexColor } from './colors'; + +function formatColorToHexColor(color?: any): string | undefined { + if (typeof color === 'string') { + const hexColor = convertToHexColor(color); + if (hexColor) return hexColor; + } + return undefined; +} + +function formatColorsToHexColors(colors?: any[]): string[] | undefined { + if (Array.isArray(colors)) { + const hexColors = colors.map((color) => convertToHexColor(color) || ''); + const everyColorsExists = hexColors.every((color) => !!color); + if (everyColorsExists) return hexColors; + } + return undefined; +} + +function formatFeedbackBackgroundIos( + background: CapfaceSdkProps.FeedbackBackgroundColor +): CapfaceSdkProps.FeedbackBackgroundColor | undefined { + if (background) { + background.colors = formatColorsToHexColors(background.colors); + } + return background; +} + +export function convertThemePropsToHexColor( + theme?: CapfaceSdkProps.Theme +): CapfaceSdkProps.Theme | undefined { + if (theme) { + if (theme?.feedbackBackgroundColorsIos) { + theme.feedbackBackgroundColorsIos = formatFeedbackBackgroundIos( + theme.feedbackBackgroundColorsIos + ); + } + + for (const property in theme) { + const option = property as keyof CapfaceSdkProps.Theme; + const isImageProperty = + option === 'cancelImage' || option === 'logoImage'; + if (typeof theme[option] === 'string' && !isImageProperty) { + theme = Object.assign(theme, { + [option]: formatColorToHexColor(theme[option]), + }); + } + if (Array.isArray(theme[option])) { + theme = Object.assign(theme, { + [option]: formatColorsToHexColors(theme[option] as any[]), + }); + } + } + + return theme; + } + + return undefined; +} From 48115cda7f6441e3e99c3470de57b01d1efe55db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 15:48:00 -0300 Subject: [PATCH 38/43] chore: remove unnecessaries code block in `setTheme` method --- src/index.tsx | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 5dd9bd7..40f32e0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import { NATIVE_CONSTANTS } from './constants'; import { CapfaceSdkProps } from './types'; import type { NativeModule } from 'react-native'; -import { convertToHexColor } from './helpers'; +import { convertThemePropsToHexColor } from './helpers'; const LINKING_ERROR = `The package '@capitual/react-native-capface-sdk' doesn't seem to be linked. Make sure: \n\n` + @@ -115,38 +115,7 @@ export async function photoMatch(data?: Object): Promise { * @return {void} */ export function setTheme(options?: CapfaceSdkProps.Theme): void { - if (options) { - if (options?.feedbackBackgroundColorsIos) { - if (Array.isArray(options.feedbackBackgroundColorsIos?.colors)) { - const colors = options.feedbackBackgroundColorsIos.colors.map( - (color) => convertToHexColor(color) || '' - ); - const everyColorsExists = colors.every((color) => !!color); - options.feedbackBackgroundColorsIos.colors = everyColorsExists - ? colors - : undefined; - } - } - - for (const property in options) { - const option = property as keyof CapfaceSdkProps.Theme; - if (typeof options[option] === 'string') { - const color = convertToHexColor(options[option] as string); - options = Object.assign(options, { [option]: color || undefined }); - } - if (Array.isArray(options[option])) { - const hexColors: string[] = (options[option] as string[]).map( - (color) => convertToHexColor(color) || '' - ); - const everyColorsExists = hexColors.every((color) => !!color); - options = Object.assign(options, { - [option]: everyColorsExists ? hexColors : undefined, - }); - } - } - } - - CapfaceSdk.handleTheme(options); + CapfaceSdk.handleTheme(convertThemePropsToHexColor(options)); } export * from './types'; From 01f9cf1880cd174eaf5da301cf241aff16ff0ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 16:21:48 -0300 Subject: [PATCH 39/43] fix: resolving format problem with hexadecimal color with alpha value it --- .../java/com/capitual/processors/helpers/ThemeUtils.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java b/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java index 751d7fe..787972a 100644 --- a/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java +++ b/android/src/main/java/com/capitual/processors/helpers/ThemeUtils.java @@ -19,7 +19,11 @@ private Boolean themeAndKeyIsntExists(String key) { } private int parseColor(String key, int defaultColor) { - final String color = Config.Theme.getString(key); + final int hasAlpha = 9; + String color = Config.Theme.getString(key); + if (color.length() == hasAlpha) { + color = "#" + color.substring(hasAlpha - 2) + color.substring(1, hasAlpha - 2); + } return color.isEmpty() ? defaultColor : Color.parseColor(color); } From fbb32776d0163c02e8a47e63115ed396a815b1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 19:50:46 -0300 Subject: [PATCH 40/43] chore: move `handleTheme` method to end of the `initilizeSdk` --- ios/ReactNativeCapfaceSdk.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/ReactNativeCapfaceSdk.swift b/ios/ReactNativeCapfaceSdk.swift index 9d218a9..d2a5c73 100644 --- a/ios/ReactNativeCapfaceSdk.swift +++ b/ios/ReactNativeCapfaceSdk.swift @@ -42,7 +42,6 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { @objc func initializeSdk(_ params: NSDictionary, headers: NSDictionary, callback: @escaping RCTResponseSenderBlock) -> Void { DispatchQueue.main.async { self.capFaceViewController = CapFaceViewController(); - self.handleTheme(Config.Theme); if params.count == 0 { self.isInitialized = false; @@ -61,6 +60,8 @@ class ReactNativeCapfaceSdk: RCTEventEmitter, URLSessionDelegate { self.isInitialized = false; callback([false]); } + + self.handleTheme(Config.Theme); } } From ae4e22b57582b34d05b9a631c549e487537b9d89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 19:53:38 -0300 Subject: [PATCH 41/43] chore: changed `equals` to `equalsIgnoreCase` in conditions --- android/src/main/java/com/capitual/processors/Config.java | 2 +- .../reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/android/src/main/java/com/capitual/processors/Config.java b/android/src/main/java/com/capitual/processors/Config.java index 956ae99..0c50f46 100644 --- a/android/src/main/java/com/capitual/processors/Config.java +++ b/android/src/main/java/com/capitual/processors/Config.java @@ -42,7 +42,7 @@ private static Headers parseHeadersMapToHeaders(Map headersMap, .header("X-Device-Key", DeviceKeyIdentifier) .header("X-User-Agent", FaceTecSDK.createFaceTecAPIUserAgentString("")); - if (!httpMethod.equals("GET")) { + if (!httpMethod.equalsIgnoreCase("GET")) { buildHeader = buildHeader.header("Content-Type", "application/json"); } diff --git a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java index e9b5b00..27d184a 100644 --- a/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java +++ b/android/src/main/java/com/capitual/reactnativecapfacesdk/ReactNativeCapfaceSdkModule.java @@ -56,7 +56,7 @@ public String getName() { private boolean isDeveloperMode(Map params) { if (params.containsKey("isDeveloperMode")) { - return params.get("isDeveloperMode").toString().equals("true"); + return params.get("isDeveloperMode").toString().equalsIgnoreCase("true"); } return false; } From 76c306fafbc05d6dfa7341ac4cee54c2295b1383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Fri, 15 Sep 2023 19:54:01 -0300 Subject: [PATCH 42/43] chore: added real values in test colors --- src/helpers/colors.test.ts | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/helpers/colors.test.ts b/src/helpers/colors.test.ts index 85f8c4b..9cf4998 100644 --- a/src/helpers/colors.test.ts +++ b/src/helpers/colors.test.ts @@ -1,9 +1,9 @@ import { convertToHexColor } from '.'; -const MAX_HEX_ALPHA_COLOR = '#00000000'; -const MAX_HEX_COLOR = '#000000'; -const MIN_HEX_ALPHA_COLOR = '#0000'; -const MIN_HEX_COLOR = '#000'; +const MAX_HEX_ALPHA_COLOR = '#00FFC8B3'; +const MAX_HEX_COLOR = '#00FFC8'; +const MIN_HEX_ALPHA_COLOR = '#0FCB'; +const MIN_HEX_COLOR = '#0FC'; describe('Colors Helper', () => { describe('Ensure convertToHexColor function should', () => { @@ -33,9 +33,9 @@ describe('Colors Helper', () => { const minHexAlphaCharacters = convertToHexColor(MIN_HEX_ALPHA_COLOR); const maxHexAlphaCharacters = convertToHexColor(MAX_HEX_ALPHA_COLOR); + expect(minHexCharacters).toBe('#00FFCC'); expect(maxHexCharacters).toBe(MAX_HEX_COLOR); - expect(minHexCharacters).toBe(MAX_HEX_COLOR); - expect(minHexAlphaCharacters).toBe(MAX_HEX_ALPHA_COLOR); + expect(minHexAlphaCharacters).toBe('#00FFCCBB'); expect(maxHexAlphaCharacters).toBe(MAX_HEX_ALPHA_COLOR); }); @@ -59,7 +59,7 @@ describe('Colors Helper', () => { describe('Works with RGB colors', () => { it('Should a return RGB color if a hexadecimal color is provided', () => { - const hexColor = convertToHexColor('rgb(0, 0, 0)'); + const hexColor = convertToHexColor('rgb(0,255,200)'); expect(hexColor).toBe(MAX_HEX_COLOR); }); @@ -90,7 +90,7 @@ describe('Colors Helper', () => { describe('Works with RGBA colors', () => { it('Should a return RGBA color if a hexadecimal color is provided', () => { - const hexColor = convertToHexColor('rgba(0, 0, 0, 0)'); + const hexColor = convertToHexColor('rgba(0,255,200,0.7)'); expect(hexColor).toBe(MAX_HEX_ALPHA_COLOR); }); @@ -122,10 +122,10 @@ describe('Colors Helper', () => { describe('Works with HSL colors', () => { it('Should a return HSL color if a hexadecimal color is provided', () => { - expect(convertToHexColor('hsl(0, 0, 0)')).toBe(MAX_HEX_COLOR); - expect(convertToHexColor('hsl(0, 0, 0%)')).toBe(MAX_HEX_COLOR); - expect(convertToHexColor('hsl(0, 0%, 0)')).toBe(MAX_HEX_COLOR); - expect(convertToHexColor('hsl(0, 0%, 0%)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(167, 100, 50)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(167, 100, 50%)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(167, 100%, 50)')).toBe(MAX_HEX_COLOR); + expect(convertToHexColor('hsl(167, 100%, 50%)')).toBe(MAX_HEX_COLOR); }); it('Should return null if an invalid HSL colors is provided', () => { @@ -153,14 +153,16 @@ describe('Colors Helper', () => { describe('Works with HSLA colors', () => { it('Should a return HSLA color if a hexadecimal color is provided', () => { - expect(convertToHexColor('hsla(0, 0, 0, 0)')).toBe(MAX_HEX_ALPHA_COLOR); - expect(convertToHexColor('hsla(0, 0%, 0%, 0)')).toBe( + expect(convertToHexColor('hsla(167, 100, 50, 0.7)')).toBe( MAX_HEX_ALPHA_COLOR ); - expect(convertToHexColor('hsla(0, 0, 0%, 0)')).toBe( + expect(convertToHexColor('hsla(167, 100%, 50%, 0.7)')).toBe( MAX_HEX_ALPHA_COLOR ); - expect(convertToHexColor('hsla(0, 0%, 0, 0)')).toBe( + expect(convertToHexColor('hsla(167, 100, 50%, 0.7)')).toBe( + MAX_HEX_ALPHA_COLOR + ); + expect(convertToHexColor('hsla(167, 100%, 50, 0.7)')).toBe( MAX_HEX_ALPHA_COLOR ); }); From 80c3e48de02a08007e8019e222d9bd0c8bc41abe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sans=C3=A3o=20Araldi?= Date: Mon, 18 Sep 2023 11:33:31 -0300 Subject: [PATCH 43/43] fix: adjusts on alpha value of the color in iOS --- ios/Processors/Helpers/ThemeHelpers.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/Processors/Helpers/ThemeHelpers.swift b/ios/Processors/Helpers/ThemeHelpers.swift index 68bc87c..a537aab 100644 --- a/ios/Processors/Helpers/ThemeHelpers.swift +++ b/ios/Processors/Helpers/ThemeHelpers.swift @@ -62,7 +62,7 @@ extension UIColor { case 6: // RGB (24-bit) (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) case 8: // ARGB (32-bit) - (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) + (a, r, g, b) = (int & 0xFF, int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF) default: (a, r, g, b) = (255, 0, 0, 0) }