tethysfaceid
Version:
1 lines • 24.2 kB
JSON
{"ast":null,"code":"function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n//\n// Welcome to the annotated FaceTec Device SDK core code for performing secure Liveness Checks!\n//\nimport { Config } from \"common/Config\";\nimport { FaceTecSDK } from \"core-sdk/FaceTecSDK.js/FaceTecSDK\";\nimport { message } from \"antd\";\nimport { FACE_COMPARE } from \"common/apiConstants\"; //\n// This is an example self-contained class to perform Liveness Checks with the FaceTec SDK.\n// You may choose to further componentize parts of this in your own Apps based on your specific requirements.\n//\n\nexport class LivenessCheckProcessor {\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n constructor(sessionToken, sampleAppControllerReference, data) {\n _defineProperty(this, \"latestNetworkRequest\", new XMLHttpRequest());\n\n _defineProperty(this, \"success\", void 0);\n\n _defineProperty(this, \"sampleAppControllerReference\", void 0);\n\n _defineProperty(this, \"data\", void 0);\n\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.success = false;\n this.sampleAppControllerReference = sampleAppControllerReference;\n this.data = data; //\n // Part 1: Starting the FaceTec Session\n //\n // Required parameters:\n // - FaceTecFaceScanProcessor: A class that implements FaceTecFaceScanProcessor, which handles the FaceScan when the User completes a Session. In this example, \"this\" implements the class.\n // - sessionToken: A valid Session Token you just created by calling your API to get a Session Token from the Server SDK.\n //\n\n new FaceTecSDK.FaceTecSession(this, sessionToken);\n } //\n // Part 2: Handling the Result of a FaceScan\n //\n\n\n processSessionResultWhileFaceTecSDKWaits(sessionResult, faceScanResultCallback) {\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.sampleAppControllerReference.setLatestSessionResult(sessionResult); //\n // Part 3: Handles early exit scenarios where there is no FaceScan to handle -- i.e. User Cancellation, Timeouts, etc.\n //\n\n if (sessionResult.status !== FaceTecSDK.FaceTecSessionStatus.SessionCompletedSuccessfully) {\n message.error(\"Session was not completed successfully, cancelling. Status: \" + sessionResult.status, 3);\n this.latestNetworkRequest.abort();\n faceScanResultCallback.cancel();\n return;\n } // IMPORTANT: FaceTecSDK.FaceTecSessionStatus.SessionCompletedSuccessfully DOES NOT mean the Liveness Check was Successful.\n // It simply means the User completed the Session and a 3D FaceScan was created. You still need to perform the Liveness Check on your Servers.\n //\n // Part 4: Get essential data off the FaceTecSessionResult\n //\n\n\n const {\n id,\n username\n } = this.data;\n var parameters = {\n faceScan: sessionResult.faceScan,\n // auditTrailImage: sessionResult.auditTrail[0],\n pic: sessionResult.lowQualityAuditTrail[0],\n sessionId: sessionResult.sessionId,\n id,\n username,\n licence: \"001-593-3147\",\n access_key: \"9a23ad06e00c048f4aebfbcf7d1928acc\"\n }; //\n // Part 5: Make the Networking Call to Your Servers. Below is just example code, you are free to customize based on how your own API works.\n //\n\n this.latestNetworkRequest = new XMLHttpRequest();\n this.latestNetworkRequest.open(\"POST\", FACE_COMPARE);\n this.latestNetworkRequest.setRequestHeader(\"Content-Type\", \"application/json\"); // TODO: Make this prettier and more consolidated and perhaps less things to do here.\n\n this.latestNetworkRequest.setRequestHeader(\"X-Device-Key\", Config.DeviceKeyIdentifier);\n this.latestNetworkRequest.setRequestHeader(\"X-User-Agent\", FaceTecSDK.createFaceTecAPIUserAgentString(sessionResult.sessionId));\n\n this.latestNetworkRequest.onreadystatechange = () => {\n //\n // Part 6: In our Sample, we evaluate a boolean response and treat true as success, false as \"User Needs to Retry\",\n // and handle all other non-nominal responses by cancelling out. You may have different paradigms in your own API and are free to customize based on these.\n //\n if (this.latestNetworkRequest.readyState === XMLHttpRequest.DONE) {\n try {\n var responseJSON = JSON.parse(this.latestNetworkRequest.responseText); //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n\n this.sampleAppControllerReference.setLatestServerResult(responseJSON);\n\n if (responseJSON.Similarity === true) {\n // CASE: Success! The Liveness Check was performed and the User Proved Liveness.\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.success = true; // Demonstrates dynamically setting the Success Screen Message.\n\n FaceTecSDK.FaceTecCustomization.setOverrideResultScreenSuccessMessage(\"Liveness\\nConfirmed\");\n faceScanResultCallback.succeed();\n } else if (responseJSON.Similarity === false) {\n // CASE: In our Sample code, \"success\" being present and false means that the User Needs to Retry.\n // Real Users will likely succeed on subsequent attempts after following on-screen guidance.\n // Attackers/Fraudsters will continue to get rejected.\n faceScanResultCallback.cancel();\n } else {\n message.info(\"User needs to retry, invoking retry.\", 3);\n faceScanResultCallback.retry();\n } // else {\n // // CASE: UNEXPECTED response from API. Our Sample Code keys of a success boolean on the root of the JSON object --> You define your own API contracts with yourself and may choose to do something different here based on the error.\n // message.info(\"Unexpected API response, cancelling out.\", 3);\n // faceScanResultCallback.cancel();\n // }\n\n } catch {\n // CASE: Parsing the response into JSON failed --> You define your own API contracts with yourself and may choose to do something different here based on the error. Solid server-side code should ensure you don't get to this case.\n message.error(\"Exception while handling API response, cancelling out.\", 3);\n faceScanResultCallback.cancel();\n }\n }\n };\n\n this.latestNetworkRequest.onerror = function () {\n // CASE: Network Request itself is erroring --> You define your own API contracts with yourself and may choose to do something different here based on the error.\n console.log(\"XHR error, cancelling.\");\n faceScanResultCallback.cancel();\n }; //\n // Part 7: Demonstrates updating the Progress Bar based on the progress event.\n //\n\n\n this.latestNetworkRequest.upload.onprogress = function name(event) {\n var progress = event.loaded / event.total;\n faceScanResultCallback.uploadProgress(progress);\n }; //\n // Part 8: Actually send the request.\n //\n\n\n var jsonStringToUpload = JSON.stringify(parameters);\n this.latestNetworkRequest.send(jsonStringToUpload); //\n // Part 9: For better UX, update the User if the upload is taking a while. You are free to customize and enhance this behavior to your liking.\n //\n\n setTimeout(() => {\n if (this.latestNetworkRequest.readyState === XMLHttpRequest.DONE) {\n return;\n }\n\n faceScanResultCallback.uploadMessageOverride(\"Still Uploading...\");\n }, 6000);\n } //\n // Part 10: This function gets called after the FaceTec SDK is completely done. There are no parameters because you have already been passed all data in the processSessionWhileFaceTecSDKWaits function and have already handled all of your own results.\n //\n\n\n onFaceTecSDKCompletelyDone() {\n //\n // DEVELOPER NOTE: onFaceTecSDKCompletelyDone() is called after you signal the FaceTec SDK with success() or cancel().\n // Calling a custom function on the Sample App Controller is done for demonstration purposes to show you that here is where you get control back from the FaceTec SDK.\n //\n this.sampleAppControllerReference.onComplete();\n } //\n // DEVELOPER NOTE: This public convenience method is for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In your code, you may not even want or need to do this.\n //\n\n\n isSuccess() {\n return this.success;\n }\n\n}","map":{"version":3,"sources":["/Users/dhrumil1/Documents/Tethy/online-verification/components/LivenessCheck/processors/LivenessCheckProcessor.js"],"names":["Config","FaceTecSDK","message","FACE_COMPARE","LivenessCheckProcessor","constructor","sessionToken","sampleAppControllerReference","data","XMLHttpRequest","success","FaceTecSession","processSessionResultWhileFaceTecSDKWaits","sessionResult","faceScanResultCallback","setLatestSessionResult","status","FaceTecSessionStatus","SessionCompletedSuccessfully","error","latestNetworkRequest","abort","cancel","id","username","parameters","faceScan","pic","lowQualityAuditTrail","sessionId","licence","access_key","open","setRequestHeader","DeviceKeyIdentifier","createFaceTecAPIUserAgentString","onreadystatechange","readyState","DONE","responseJSON","JSON","parse","responseText","setLatestServerResult","Similarity","FaceTecCustomization","setOverrideResultScreenSuccessMessage","succeed","info","retry","onerror","console","log","upload","onprogress","name","event","progress","loaded","total","uploadProgress","jsonStringToUpload","stringify","send","setTimeout","uploadMessageOverride","onFaceTecSDKCompletelyDone","onComplete","isSuccess"],"mappings":"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","sourcesContent":["//\n// Welcome to the annotated FaceTec Device SDK core code for performing secure Liveness Checks!\n//\n\nimport { Config } from \"common/Config\";\nimport { FaceTecSDK } from \"core-sdk/FaceTecSDK.js/FaceTecSDK\";\nimport { message } from \"antd\";\nimport { FACE_COMPARE } from \"common/apiConstants\";\n//\n// This is an example self-contained class to perform Liveness Checks with the FaceTec SDK.\n// You may choose to further componentize parts of this in your own Apps based on your specific requirements.\n//\nexport class LivenessCheckProcessor {\n latestNetworkRequest = new XMLHttpRequest();\n\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n success;\n sampleAppControllerReference;\n data;\n\n constructor(sessionToken, sampleAppControllerReference, data) {\n\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.success = false;\n this.sampleAppControllerReference = sampleAppControllerReference;\n this.data = data;\n //\n // Part 1: Starting the FaceTec Session\n //\n // Required parameters:\n // - FaceTecFaceScanProcessor: A class that implements FaceTecFaceScanProcessor, which handles the FaceScan when the User completes a Session. In this example, \"this\" implements the class.\n // - sessionToken: A valid Session Token you just created by calling your API to get a Session Token from the Server SDK.\n //\n new FaceTecSDK.FaceTecSession(\n this,\n sessionToken\n );\n }\n\n //\n // Part 2: Handling the Result of a FaceScan\n //\n processSessionResultWhileFaceTecSDKWaits(sessionResult, faceScanResultCallback) {\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.sampleAppControllerReference.setLatestSessionResult(sessionResult);\n\n //\n // Part 3: Handles early exit scenarios where there is no FaceScan to handle -- i.e. User Cancellation, Timeouts, etc.\n //\n if (sessionResult.status !== FaceTecSDK.FaceTecSessionStatus.SessionCompletedSuccessfully) {\n message.error(\"Session was not completed successfully, cancelling. Status: \" + sessionResult.status, 3);\n this.latestNetworkRequest.abort();\n faceScanResultCallback.cancel();\n return;\n }\n\n // IMPORTANT: FaceTecSDK.FaceTecSessionStatus.SessionCompletedSuccessfully DOES NOT mean the Liveness Check was Successful.\n // It simply means the User completed the Session and a 3D FaceScan was created. You still need to perform the Liveness Check on your Servers.\n\n //\n // Part 4: Get essential data off the FaceTecSessionResult\n //\n const { id, username } = this.data;\n var parameters = {\n faceScan: sessionResult.faceScan,\n // auditTrailImage: sessionResult.auditTrail[0],\n pic: sessionResult.lowQualityAuditTrail[0],\n sessionId: sessionResult.sessionId,\n id,\n username,\n licence: \"001-593-3147\",\n access_key: \"9a23ad06e00c048f4aebfbcf7d1928acc\",\n };\n\n //\n // Part 5: Make the Networking Call to Your Servers. Below is just example code, you are free to customize based on how your own API works.\n //\n this.latestNetworkRequest = new XMLHttpRequest();\n this.latestNetworkRequest.open(\"POST\", FACE_COMPARE);\n this.latestNetworkRequest.setRequestHeader(\"Content-Type\", \"application/json\");\n\n // TODO: Make this prettier and more consolidated and perhaps less things to do here.\n this.latestNetworkRequest.setRequestHeader(\"X-Device-Key\", Config.DeviceKeyIdentifier);\n this.latestNetworkRequest.setRequestHeader(\"X-User-Agent\", FaceTecSDK.createFaceTecAPIUserAgentString(sessionResult.sessionId));\n\n this.latestNetworkRequest.onreadystatechange = () => {\n\n //\n // Part 6: In our Sample, we evaluate a boolean response and treat true as success, false as \"User Needs to Retry\",\n // and handle all other non-nominal responses by cancelling out. You may have different paradigms in your own API and are free to customize based on these.\n //\n\n if (this.latestNetworkRequest.readyState === XMLHttpRequest.DONE) {\n try {\n var responseJSON = JSON.parse(this.latestNetworkRequest.responseText);\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.sampleAppControllerReference.setLatestServerResult(responseJSON);\n\n if (responseJSON.Similarity === true) {\n // CASE: Success! The Liveness Check was performed and the User Proved Liveness.\n\n //\n // DEVELOPER NOTE: These properties are for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In the code in your own App, you can pass around signals, flags, intermediates, and results however you would like.\n //\n this.success = true;\n\n // Demonstrates dynamically setting the Success Screen Message.\n FaceTecSDK.FaceTecCustomization.setOverrideResultScreenSuccessMessage(\"Liveness\\nConfirmed\");\n faceScanResultCallback.succeed();\n }\n else if (responseJSON.Similarity === false) {\n // CASE: In our Sample code, \"success\" being present and false means that the User Needs to Retry.\n // Real Users will likely succeed on subsequent attempts after following on-screen guidance.\n // Attackers/Fraudsters will continue to get rejected.\n faceScanResultCallback.cancel();\n\n }\n else {\n message.info(\"User needs to retry, invoking retry.\", 3);\n faceScanResultCallback.retry();\n }\n // else {\n // // CASE: UNEXPECTED response from API. Our Sample Code keys of a success boolean on the root of the JSON object --> You define your own API contracts with yourself and may choose to do something different here based on the error.\n // message.info(\"Unexpected API response, cancelling out.\", 3);\n // faceScanResultCallback.cancel();\n // }\n }\n catch {\n // CASE: Parsing the response into JSON failed --> You define your own API contracts with yourself and may choose to do something different here based on the error. Solid server-side code should ensure you don't get to this case.\n message.error(\"Exception while handling API response, cancelling out.\", 3);\n faceScanResultCallback.cancel();\n }\n }\n };\n\n this.latestNetworkRequest.onerror = function () {\n\n // CASE: Network Request itself is erroring --> You define your own API contracts with yourself and may choose to do something different here based on the error.\n console.log(\"XHR error, cancelling.\");\n faceScanResultCallback.cancel();\n };\n\n //\n // Part 7: Demonstrates updating the Progress Bar based on the progress event.\n //\n this.latestNetworkRequest.upload.onprogress = function name(event) {\n\n var progress = event.loaded / event.total;\n faceScanResultCallback.uploadProgress(progress);\n };\n\n //\n // Part 8: Actually send the request.\n //\n var jsonStringToUpload = JSON.stringify(parameters);\n this.latestNetworkRequest.send(jsonStringToUpload);\n\n //\n // Part 9: For better UX, update the User if the upload is taking a while. You are free to customize and enhance this behavior to your liking.\n //\n setTimeout(() => {\n\n if (this.latestNetworkRequest.readyState === XMLHttpRequest.DONE) {\n return;\n }\n faceScanResultCallback.uploadMessageOverride(\"Still Uploading...\");\n }, 6000);\n }\n\n //\n // Part 10: This function gets called after the FaceTec SDK is completely done. There are no parameters because you have already been passed all data in the processSessionWhileFaceTecSDKWaits function and have already handled all of your own results.\n //\n onFaceTecSDKCompletelyDone() {\n\n //\n // DEVELOPER NOTE: onFaceTecSDKCompletelyDone() is called after you signal the FaceTec SDK with success() or cancel().\n // Calling a custom function on the Sample App Controller is done for demonstration purposes to show you that here is where you get control back from the FaceTec SDK.\n //\n this.sampleAppControllerReference.onComplete();\n }\n\n //\n // DEVELOPER NOTE: This public convenience method is for demonstration purposes only so the Sample App can get information about what is happening in the processor.\n // In your code, you may not even want or need to do this.\n //\n isSuccess() {\n return this.success;\n }\n}\n"]},"metadata":{},"sourceType":"module"}