diff --git a/.travis.yml b/.travis.yml index 4f856616..87099880 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,10 @@ jobs: node_js: "11" - <<: *test-compatibility node_js: "12" + - <<: *test-compatibility + node_js: "13" + - <<: *test-compatibility + node_js: "14" - &test-compatibility-osx <<: *test-compatibility os: osx diff --git a/examples/aml-check/package-lock.json b/examples/aml-check/package-lock.json index 631c9bc8..14f7dd32 100644 --- a/examples/aml-check/package-lock.json +++ b/examples/aml-check/package-lock.json @@ -848,9 +848,9 @@ } }, "lodash": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.17.tgz", - "integrity": "sha512-/B2DjOphAoqi5BX4Gg2oh4UR0Gy/A7xYAMh3aSECEKzwS3eCDEpS0Cals1Ktvxwlal3bBJNc+5W9kNIcADdw5Q==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lru-cache": { diff --git a/examples/doc-scan/package.json b/examples/doc-scan/package.json index 0ae40f7d..15b18577 100755 --- a/examples/doc-scan/package.json +++ b/examples/doc-scan/package.json @@ -16,7 +16,6 @@ "ejs": "^3.0.1", "express": "^4.17.1", "express-session": "^1.17.0", - "file-type": "^14.1.4", "yoti": "file:../.." }, "devDependencies": { diff --git a/examples/doc-scan/src/controllers/index.controller.js b/examples/doc-scan/src/controllers/index.controller.js index 3e4eb816..d8b52d2c 100644 --- a/examples/doc-scan/src/controllers/index.controller.js +++ b/examples/doc-scan/src/controllers/index.controller.js @@ -8,6 +8,9 @@ const { RequestedTextExtractionTaskBuilder, RequestedFaceMatchCheckBuilder, SdkConfigBuilder, + RequiredIdDocumentBuilder, + OrthogonalRestrictionsFilterBuilder, + RequestedIdDocumentComparisonCheckBuilder, } = require('yoti'); /** @@ -37,6 +40,10 @@ async function createSession() { .withManualCheckNever() .build() ) + .withRequestedCheck( + new RequestedIdDocumentComparisonCheckBuilder() + .build() + ) .withRequestedTask( new RequestedTextExtractionTaskBuilder() .withManualCheckNever() @@ -55,6 +62,24 @@ async function createSession() { .withErrorUrl(`${config.YOTI_APP_BASE_URL}/error`) .build() ) + .withRequiredDocument( + (new RequiredIdDocumentBuilder()) + .withFilter( + (new OrthogonalRestrictionsFilterBuilder()) + .withWhitelistedDocumentTypes(['PASSPORT']) + .build() + ) + .build() + ) + .withRequiredDocument( + (new RequiredIdDocumentBuilder()) + .withFilter( + (new OrthogonalRestrictionsFilterBuilder()) + .withWhitelistedDocumentTypes(['DRIVING_LICENCE']) + .build() + ) + .build() + ) .build(); return docScanClient.createSession(sessionSpec); diff --git a/examples/doc-scan/src/controllers/media.controller.js b/examples/doc-scan/src/controllers/media.controller.js index 690f9e9e..da51aa1a 100644 --- a/examples/doc-scan/src/controllers/media.controller.js +++ b/examples/doc-scan/src/controllers/media.controller.js @@ -1,5 +1,4 @@ const config = require('../../config'); -const FileType = require('file-type'); const { DocScanClient, @@ -17,18 +16,8 @@ module.exports = async (req, res) => { req.query.mediaId ); - let contentType = media.getMimeType(); - let buffer = media.getContent().toBuffer(); - - // If the media is base64 encoded, decode and detect the mime type. - if (req.query.base64 === '1' && contentType === 'application/octet-stream') { - buffer = Buffer.from(buffer.toString('utf8'), 'base64'); - const fileInfo = await FileType.fromBuffer(buffer); - contentType = fileInfo.mime || contentType; - } - - res.set('Content-Type', contentType); - res.status(200).end(buffer); + res.set('Content-Type', media.getMimeType()); + res.status(200).end(media.getContent().toBuffer()); } catch (error) { res.render('pages/error', { error }); } diff --git a/examples/doc-scan/views/pages/success.ejs b/examples/doc-scan/views/pages/success.ejs index a14b38ff..aa294fc3 100644 --- a/examples/doc-scan/views/pages/success.ejs +++ b/examples/doc-scan/views/pages/success.ejs @@ -35,6 +35,14 @@ User Tracking ID <%= sessionResult.getUserTrackingId() %> + <% if (sessionResult.getBiometricConsentTimestamp()) { %> + + Biometric Consent Timestamp + + <%= sessionResult.getBiometricConsentTimestamp() %> + + + <% } %> @@ -138,6 +146,28 @@ <% } %> + + <% if (sessionResult.getIdDocumentComparisonChecks().length > 0) { %> +
+
+

+ +

+
+ +
+
+ <% sessionResult.getIdDocumentComparisonChecks().forEach(function(check){ %> + <%- include('partials/check', { check }); %> + <% }); %> +
+
+
+ <% } %> @@ -339,39 +369,6 @@
- <% if (livenessResource.getFaceMap()) { %> -
-
-

- -

-
-
-
- <% if (livenessResource.getFaceMap().getMedia()) { %> -

Media

- - - - - - - -
ID - - <%= livenessResource.getFaceMap().getMedia().getId() %> - -
- <% } %> -
-
-
- <% } %> - <% if (livenessResource.getFrames().length > 0){ %>
diff --git a/examples/profile/package-lock.json b/examples/profile/package-lock.json index fa0368e8..6015c8d8 100644 --- a/examples/profile/package-lock.json +++ b/examples/profile/package-lock.json @@ -1100,9 +1100,9 @@ } }, "lodash": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.17.tgz", - "integrity": "sha512-/B2DjOphAoqi5BX4Gg2oh4UR0Gy/A7xYAMh3aSECEKzwS3eCDEpS0Cals1Ktvxwlal3bBJNc+5W9kNIcADdw5Q==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lru-cache": { diff --git a/index.js b/index.js index 2eb2a73a..6c2a03ad 100644 --- a/index.js +++ b/index.js @@ -25,6 +25,7 @@ const { NotificationConfigBuilder, SdkConfigBuilder, RequestedDocumentAuthenticityCheckBuilder, + RequestedIdDocumentComparisonCheckBuilder, RequestedFaceMatchCheckBuilder, RequestedLivenessCheckBuilder, RequestedTextExtractionTaskBuilder, @@ -59,6 +60,7 @@ module.exports = { NotificationConfigBuilder, SdkConfigBuilder, RequestedDocumentAuthenticityCheckBuilder, + RequestedIdDocumentComparisonCheckBuilder, RequestedFaceMatchCheckBuilder, RequestedLivenessCheckBuilder, RequestedTextExtractionTaskBuilder, diff --git a/package-lock.json b/package-lock.json index 4a3a9273..f69c9abe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "yoti", - "version": "3.11.0", + "version": "3.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,24 +14,24 @@ } }, "@babel/core": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.4.tgz", - "integrity": "sha512-3A0tS0HWpy4XujGc7QtOIHTeNwUgWaZc/WuS5YQrfhU67jnVmsD6OGPc1AKHH0LJHQICGncy3+YUjIhVlfDdcA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.5.tgz", + "integrity": "sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", "@babel/helpers": "^7.10.4", - "@babel/parser": "^7.10.4", + "@babel/parser": "^7.10.5", "@babel/template": "^7.10.4", - "@babel/traverse": "^7.10.4", - "@babel/types": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.2", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" @@ -55,14 +55,13 @@ } }, "@babel/generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.4.tgz", - "integrity": "sha512-toLIHUIAgcQygFZRAQcsLQV3CBuX6yOIru1kJk/qqqvcRmZrYe6WavZTSG+bB8MxhnL9YPf+pKQfuiP161q7ng==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.5.tgz", + "integrity": "sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig==", "dev": true, "requires": { - "@babel/types": "^7.10.4", + "@babel/types": "^7.10.5", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { @@ -95,12 +94,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz", - "integrity": "sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.5.tgz", + "integrity": "sha512-HiqJpYD5+WopCXIAbQDG0zye5XYVvcO9w/DHp5GsaGkRUaamLj2bEtu6i8rnGGprAhHM3qidCMgp71HF4endhA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.10.5" } }, "@babel/helper-module-imports": { @@ -113,9 +112,9 @@ } }, "@babel/helper-module-transforms": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.4.tgz", - "integrity": "sha512-Er2FQX0oa3nV7eM1o0tNCTx7izmQtwAQsIiaLRWtavAAEcskb0XJ5OjJbVrYXWOTr8om921Scabn4/tzlx7j1Q==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz", + "integrity": "sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.10.4", @@ -123,8 +122,8 @@ "@babel/helper-simple-access": "^7.10.4", "@babel/helper-split-export-declaration": "^7.10.4", "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4", - "lodash": "^4.17.13" + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" } }, "@babel/helper-optimise-call-expression": { @@ -202,9 +201,9 @@ } }, "@babel/parser": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.4.tgz", - "integrity": "sha512-8jHII4hf+YVDsskTF6WuMB3X4Eh+PsUkC2ljq22so5rHvH+T8BzyL94VOdyFLNR8tBSVXOTbNHOKpR4TfRxVtA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.5.tgz", + "integrity": "sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==", "dev": true }, "@babel/plugin-syntax-object-rest-spread": { @@ -228,30 +227,30 @@ } }, "@babel/traverse": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.4.tgz", - "integrity": "sha512-aSy7p5THgSYm4YyxNGz6jZpXf+Ok40QF3aA2LyIONkDHpAcJzDUqlCKXv6peqYUs2gmic849C/t2HKw2a2K20Q==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.5.tgz", + "integrity": "sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.10.4", + "@babel/generator": "^7.10.5", "@babel/helper-function-name": "^7.10.4", "@babel/helper-split-export-declaration": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.13" + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.4.tgz", - "integrity": "sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.5.tgz", + "integrity": "sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.13", + "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } }, @@ -513,9 +512,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", - "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", + "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -655,9 +654,9 @@ "dev": true }, "ajv": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", - "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -1339,27 +1338,27 @@ "dev": true }, "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", + "import-fresh": "^3.2.1", "parse-json": "^5.0.0", "path-type": "^4.0.0", - "yaml": "^1.7.2" + "yaml": "^1.10.0" }, "dependencies": { "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -2492,15 +2491,15 @@ } }, "husky": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", - "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.0.tgz", + "integrity": "sha512-tTMeLCLqSBqnflBZnlVDhpaIMucSGaYyX6855jM4AguGeWCeSzNdb1mfyWduTZ3pe3SJVvVWGL0jO1iKZVPfTA==", "dev": true, "requires": { "chalk": "^4.0.0", "ci-info": "^2.0.0", "compare-versions": "^3.6.0", - "cosmiconfig": "^6.0.0", + "cosmiconfig": "^7.0.0", "find-versions": "^3.2.0", "opencollective-postinstall": "^2.0.2", "pkg-dir": "^4.2.0", @@ -2609,9 +2608,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3883,6 +3882,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -3999,9 +4004,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "lodash.sortby": { @@ -4250,9 +4255,9 @@ } }, "node-forge": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", - "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, "node-int64": { "version": "0.4.0", @@ -4280,9 +4285,9 @@ } }, "node-rsa": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.0.8.tgz", - "integrity": "sha512-q8knkMHEqViIX/fshOltCHTtlt4Nw5wpBpu0//LB1tkxqYZB/001dYMwbPvTPiENwKvPqVDkhxK6J4fV09oa7w==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/node-rsa/-/node-rsa-1.1.1.tgz", + "integrity": "sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==", "requires": { "asn1": "^0.2.4" } @@ -5950,9 +5955,9 @@ } }, "uuid": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", - "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", + "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" }, "validate-npm-package-license": { "version": "3.0.4", diff --git a/package.json b/package.json index d45bed0d..aa5b75cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yoti", - "version": "3.11.0", + "version": "3.12.0", "description": "Yoti NodeJS SDK for back-end integration", "author": "Yoti LTD (https://www.yoti.com/developers)", "license": "MIT", @@ -36,7 +36,7 @@ "dependencies": { "base64-url": "^2.2.1", "bytebuffer": "^5.0.1", - "node-forge": "^0.9.1", + "node-forge": "^0.10.0", "node-rsa": "^1.0.3", "protobufjs": "^5.0.3", "safe-buffer": "^5.1.2", diff --git a/sonar-project.properties b/sonar-project.properties index b89116ff..68554315 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -3,7 +3,7 @@ sonar.organization = getyoti sonar.projectKey = getyoti:node sonar.projectName = Node SDK -sonar.projectVersion = 3.11.0 +sonar.projectVersion = 3.12.0 sonar.exclusions=tests/**,examples/**,node_modules/**,coverage/** sonar.javascript.lcov.reportPaths=coverage/lcov.info sonar.verbose = true diff --git a/src/doc_scan_service/doc.scan.constants.js b/src/doc_scan_service/doc.scan.constants.js index d135371b..fa4eef16 100644 --- a/src/doc_scan_service/doc.scan.constants.js +++ b/src/doc_scan_service/doc.scan.constants.js @@ -9,6 +9,7 @@ module.exports = Object.freeze({ ID_DOCUMENT_TEXT_DATA_CHECK: 'ID_DOCUMENT_TEXT_DATA_CHECK', ID_DOCUMENT_TEXT_DATA_EXTRACTION: 'ID_DOCUMENT_TEXT_DATA_EXTRACTION', ID_DOCUMENT_FACE_MATCH: 'ID_DOCUMENT_FACE_MATCH', + ID_DOCUMENT_COMPARISON: 'ID_DOCUMENT_COMPARISON', LIVENESS: 'LIVENESS', ZOOM: 'ZOOM', CAMERA: 'CAMERA', diff --git a/src/doc_scan_service/index.js b/src/doc_scan_service/index.js index 89cf23f9..c166f7fc 100644 --- a/src/doc_scan_service/index.js +++ b/src/doc_scan_service/index.js @@ -6,6 +6,7 @@ const SessionSpecificationBuilder = require('./session/create/session.specificat const NotificationConfigBuilder = require('./session/create/notification.config.builder'); const SdkConfigBuilder = require('./session/create/sdk.config.builder'); const RequestedDocumentAuthenticityCheckBuilder = require('./session/create/check/requested.document.authenticity.check.builder'); +const RequestedIdDocumentComparisonCheckBuilder = require('./session/create/check/requested.id.document.comparison.check.builder'); const RequestedFaceMatchCheckBuilder = require('./session/create/check/requested.face.match.check.builder'); const RequestedLivenessCheckBuilder = require('./session/create/check/requested.liveness.check.builder'); const RequestedTextExtractionTaskBuilder = require('./session/create/task/requested.text.extraction.task.builder'); @@ -21,6 +22,7 @@ module.exports = { NotificationConfigBuilder, SdkConfigBuilder, RequestedDocumentAuthenticityCheckBuilder, + RequestedIdDocumentComparisonCheckBuilder, RequestedFaceMatchCheckBuilder, RequestedLivenessCheckBuilder, RequestedTextExtractionTaskBuilder, diff --git a/src/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.js b/src/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.js index a171d532..39732f2a 100644 --- a/src/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.js +++ b/src/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.js @@ -2,16 +2,54 @@ const RequestedDocumentAuthenticityCheck = require('./requested.document.authenticity.check'); const RequestedDocumentAuthenticityConfig = require('./requested.document.authenticity.config'); +const DocScanConstants = require('../../../doc.scan.constants'); /** * Builder to assist the creation of {@link RequestedDocumentAuthenticityCheck}. * * @class RequestedDocumentAuthenticityCheckBuilder */ -/* eslint class-methods-use-this: ["error", { "exceptMethods": ["build"] }] */ class RequestedDocumentAuthenticityCheckBuilder { + /** + * Requires that a manual follow-up check is always performed + * + * @returns {this} + */ + withManualCheckAlways() { + this.manualCheck = DocScanConstants.ALWAYS; + return this; + } + + /** + * Requires that a manual follow-up check is performed only on failed Checks, + * and those with a low level of confidence + * + * @returns {this} + */ + withManualCheckFallback() { + this.manualCheck = DocScanConstants.FALLBACK; + return this; + } + + /** + * Requires that only an automated Check is performed. No manual follow-up + * Check will ever be initiated + * + * @returns {this} + */ + withManualCheckNever() { + this.manualCheck = DocScanConstants.NEVER; + return this; + } + + /** + * Build a {@link RequestedDocumentAuthenticityCheck} using the values supplied to the builder + * + * @returns {RequestedDocumentAuthenticityCheck} + */ build() { - return new RequestedDocumentAuthenticityCheck(new RequestedDocumentAuthenticityConfig()); + const config = new RequestedDocumentAuthenticityConfig(this.manualCheck); + return new RequestedDocumentAuthenticityCheck(config); } } diff --git a/src/doc_scan_service/session/create/check/requested.document.authenticity.config.js b/src/doc_scan_service/session/create/check/requested.document.authenticity.config.js index 4c3cbe58..2372716b 100644 --- a/src/doc_scan_service/session/create/check/requested.document.authenticity.config.js +++ b/src/doc_scan_service/session/create/check/requested.document.authenticity.config.js @@ -1,17 +1,28 @@ 'use strict'; +const Validation = require('../../../../yoti_common/validation'); + /** * The configuration applied when creating a DocumentAuthenticityCheck * * @class RequestedDocumentAuthenticityConfig */ class RequestedDocumentAuthenticityConfig { + /** + * @param {string} manualCheck + */ + constructor(manualCheck) { + Validation.isString(manualCheck, 'manualCheck', true); + this.manualCheck = manualCheck; + } + /** * @returns {Object} data for JSON.stringify() */ - // eslint-disable-next-line class-methods-use-this toJSON() { - return {}; + return { + manual_check: this.manualCheck, + }; } } diff --git a/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.js b/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.js new file mode 100644 index 00000000..b4f07cd9 --- /dev/null +++ b/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.js @@ -0,0 +1,18 @@ +'use strict'; + +const RequestedIdDocumentComparisonCheck = require('./requested.id.document.comparison.check'); +const RequestedIdDocumentComparisonConfig = require('./requested.id.document.comparison.config'); + +/** + * Builder to assist the creation of {@link RequestedIdDocumentComparisonCheck}. + * + * @class RequestedIdDocumentComparisonCheckBuilder + */ +/* eslint class-methods-use-this: ["error", { "exceptMethods": ["build"] }] */ +class RequestedIdDocumentComparisonCheckBuilder { + build() { + return new RequestedIdDocumentComparisonCheck(new RequestedIdDocumentComparisonConfig()); + } +} + +module.exports = RequestedIdDocumentComparisonCheckBuilder; diff --git a/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.js b/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.js new file mode 100644 index 00000000..c6c1b0c5 --- /dev/null +++ b/src/doc_scan_service/session/create/check/requested.id.document.comparison.check.js @@ -0,0 +1,21 @@ +'use strict'; + +const RequestedCheck = require('./requested.check'); +const DocScanConstants = require('../../../doc.scan.constants'); +const Validation = require('../../../../yoti_common/validation'); +const RequestedIdDocumentComparisonConfig = require('./requested.id.document.comparison.config'); + +/** + * @class RequestedIdDocumentComparisonCheck + */ +class RequestedIdDocumentComparisonCheck extends RequestedCheck { + /** + * @param {RequestedIdDocumentComparisonConfig} config + */ + constructor(config) { + Validation.instanceOf(config, RequestedIdDocumentComparisonConfig, 'config'); + super(DocScanConstants.ID_DOCUMENT_COMPARISON, config); + } +} + +module.exports = RequestedIdDocumentComparisonCheck; diff --git a/src/doc_scan_service/session/create/check/requested.id.document.comparison.config.js b/src/doc_scan_service/session/create/check/requested.id.document.comparison.config.js new file mode 100644 index 00000000..08a471a3 --- /dev/null +++ b/src/doc_scan_service/session/create/check/requested.id.document.comparison.config.js @@ -0,0 +1,18 @@ +'use strict'; + +/** + * The configuration applied when creating a RequestedIdDocumentComparisonCheck + * + * @class RequestedIdDocumentComparisonConfig + */ +class RequestedIdDocumentComparisonConfig { + /** + * @returns {Object} data for JSON.stringify() + */ + // eslint-disable-next-line class-methods-use-this + toJSON() { + return {}; + } +} + +module.exports = RequestedIdDocumentComparisonConfig; diff --git a/src/doc_scan_service/session/create/session.specification.builder.js b/src/doc_scan_service/session/create/session.specification.builder.js index 8896ba0b..3062c7de 100644 --- a/src/doc_scan_service/session/create/session.specification.builder.js +++ b/src/doc_scan_service/session/create/session.specification.builder.js @@ -127,6 +127,19 @@ class SessionSpecificationBuilder { return this; } + /** + * Sets whether or not to block the collection of biometric consent + * + * @param {bool} blockBiometricConsent + * + * @return {this} + */ + withBlockBiometricConsent(blockBiometricConsent) { + Validation.isBoolean(blockBiometricConsent, 'blockBiometricConsent'); + this.blockBiometricConsent = blockBiometricConsent; + return this; + } + /** * Builds the {@link SessionSpec} based on the values supplied to the builder * @@ -141,7 +154,8 @@ class SessionSpecificationBuilder { this.requestedChecks, this.requestedTasks, this.sdkConfig, - this.requiredDocuments + this.requiredDocuments, + this.blockBiometricConsent ); } } diff --git a/src/doc_scan_service/session/create/session.specification.js b/src/doc_scan_service/session/create/session.specification.js index f30d8c14..4f58058c 100644 --- a/src/doc_scan_service/session/create/session.specification.js +++ b/src/doc_scan_service/session/create/session.specification.js @@ -30,6 +30,8 @@ class SessionSpecification { * The SDK configuration set on the session specification * @param {RequiredDocument[]} requiredDocuments * List of RequiredDocument defining the documents required from the client + * @param {bool} blockBiometricConsent + * Sets whether or not to block the collection of biometric consent */ constructor( clientSessionTokenTtl, @@ -39,7 +41,8 @@ class SessionSpecification { requestedChecks, requestedTasks, sdkConfig, - requiredDocuments + requiredDocuments, + blockBiometricConsent ) { Validation.isInteger(clientSessionTokenTtl, 'clientSessionTokenTtl', true); this.clientSessionTokenTtl = clientSessionTokenTtl; @@ -70,6 +73,9 @@ class SessionSpecification { Validation.isArrayOfType(requiredDocuments, RequiredDocument, 'requiredDocuments'); this.requiredDocuments = requiredDocuments; } + + Validation.isBoolean(blockBiometricConsent, 'blockBiometricConsent', true); + this.blockBiometricConsent = blockBiometricConsent; } /** @@ -85,6 +91,7 @@ class SessionSpecification { requested_tasks: this.requestedTasks, sdk_config: this.sdkConfig, required_documents: this.requiredDocuments, + block_biometric_consent: this.blockBiometricConsent, }; } } diff --git a/src/doc_scan_service/session/retrieve/get.session.result.js b/src/doc_scan_service/session/retrieve/get.session.result.js index d5c49e06..e5c0f232 100644 --- a/src/doc_scan_service/session/retrieve/get.session.result.js +++ b/src/doc_scan_service/session/retrieve/get.session.result.js @@ -7,7 +7,9 @@ const AuthenticityCheckResponse = require('./authenticity.check.response'); const FaceMatchCheckResponse = require('./face.match.check.response'); const TextDataCheckResponse = require('./text.data.check.response'); const LivenessCheckResponse = require('./liveness.check.response'); +const IdDocumentComparisonCheckResponse = require('./id.document.comparison.check.response'); const DocScanConstants = require('../../doc.scan.constants'); +const { YotiDate } = require('../../../data_type/date'); class GetSessionResult { constructor(response) { @@ -34,6 +36,8 @@ class GetSessionResult { switch (check.type) { case DocScanConstants.ID_DOCUMENT_AUTHENTICITY: return new AuthenticityCheckResponse(check); + case DocScanConstants.ID_DOCUMENT_COMPARISON: + return new IdDocumentComparisonCheckResponse(check); case DocScanConstants.ID_DOCUMENT_FACE_MATCH: return new FaceMatchCheckResponse(check); case DocScanConstants.ID_DOCUMENT_TEXT_DATA_CHECK: @@ -52,6 +56,10 @@ class GetSessionResult { Validation.instanceOf(response.resources, Object); this.resources = new ResourceContainer(response.resources); } + + if (response.biometric_consent) { + this.biometricConsent = YotiDate.fromDateString(response.biometric_consent); + } } /** @@ -117,6 +125,13 @@ class GetSessionResult { return this.getChecks().filter((check) => check instanceof LivenessCheckResponse); } + /** + * @returns {IdDocumentComparisonCheckResponse[]} + */ + getIdDocumentComparisonChecks() { + return this.getChecks().filter((check) => check instanceof IdDocumentComparisonCheckResponse); + } + /** * @returns {ResourceContainer} */ @@ -130,6 +145,13 @@ class GetSessionResult { getUserTrackingId() { return this.userTrackingId; } + + /** + * @returns {YotiDate} + */ + getBiometricConsentTimestamp() { + return this.biometricConsent; + } } module.exports = GetSessionResult; diff --git a/src/doc_scan_service/session/retrieve/id.document.comparison.check.response.js b/src/doc_scan_service/session/retrieve/id.document.comparison.check.response.js new file mode 100644 index 00000000..c01a60f7 --- /dev/null +++ b/src/doc_scan_service/session/retrieve/id.document.comparison.check.response.js @@ -0,0 +1,8 @@ +'use strict'; + +const CheckResponse = require('./check.response'); + +class IdDocumentComparisonCheckResponse extends CheckResponse { +} + +module.exports = IdDocumentComparisonCheckResponse; diff --git a/src/yoti_common/validation.js b/src/yoti_common/validation.js index dcf0ca22..2ceae8de 100644 --- a/src/yoti_common/validation.js +++ b/src/yoti_common/validation.js @@ -33,10 +33,14 @@ module.exports = class Validation { /** * @param {*} value * @param {string} name + * @param {bool} optional the value can be undefined * * @throws {TypeError} */ - static isBoolean(value, name) { + static isBoolean(value, name, optional = false) { + if ((typeof value) === 'undefined' && optional) { + return; + } if ((typeof value) !== 'boolean') { throw TypeError(`${name} must be a boolean`); } diff --git a/tests/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.spec.js b/tests/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.spec.js index 331c1c39..800fe636 100644 --- a/tests/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.spec.js +++ b/tests/doc_scan_service/session/create/check/requested.document.authenticity.check.builder.spec.js @@ -11,4 +11,49 @@ describe('RequestedDocumentAuthenticityCheckBuilder', () => { expect(JSON.stringify(check)).toBe(expectedJson); }); + + it('should build RequestedDocumentAuthenticityCheck with manual check always', () => { + const expectedJson = JSON.stringify({ + type: 'ID_DOCUMENT_AUTHENTICITY', + config: { + manual_check: 'ALWAYS', + }, + }); + + const check = new RequestedDocumentAuthenticityCheckBuilder() + .withManualCheckAlways() + .build(); + + expect(JSON.stringify(check)).toBe(expectedJson); + }); + + it('should build RequestedDocumentAuthenticityCheck with manual check fallback', () => { + const expectedJson = JSON.stringify({ + type: 'ID_DOCUMENT_AUTHENTICITY', + config: { + manual_check: 'FALLBACK', + }, + }); + + const check = new RequestedDocumentAuthenticityCheckBuilder() + .withManualCheckFallback() + .build(); + + expect(JSON.stringify(check)).toBe(expectedJson); + }); + + it('should build RequestedDocumentAuthenticityCheck with manual check never', () => { + const expectedJson = JSON.stringify({ + type: 'ID_DOCUMENT_AUTHENTICITY', + config: { + manual_check: 'NEVER', + }, + }); + + const check = new RequestedDocumentAuthenticityCheckBuilder() + .withManualCheckNever() + .build(); + + expect(JSON.stringify(check)).toBe(expectedJson); + }); }); diff --git a/tests/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.spec.js b/tests/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.spec.js new file mode 100644 index 00000000..8f728012 --- /dev/null +++ b/tests/doc_scan_service/session/create/check/requested.id.document.comparison.check.builder.spec.js @@ -0,0 +1,14 @@ +const { RequestedIdDocumentComparisonCheckBuilder } = require('../../../../..'); + +describe('RequestedIdDocumentComparisonCheckBuilder', () => { + it('should build RequestedIdDocumentComparisonCheck', () => { + const expectedJson = JSON.stringify({ + type: 'ID_DOCUMENT_COMPARISON', + config: {}, + }); + + const check = new RequestedIdDocumentComparisonCheckBuilder().build(); + + expect(JSON.stringify(check)).toBe(expectedJson); + }); +}); diff --git a/tests/doc_scan_service/session/create/notification.config.builder.test.js b/tests/doc_scan_service/session/create/notification.config.builder.test.js index fba99dbf..ee2bea76 100644 --- a/tests/doc_scan_service/session/create/notification.config.builder.test.js +++ b/tests/doc_scan_service/session/create/notification.config.builder.test.js @@ -93,4 +93,14 @@ describe('NotificationConfigBuilder', () => { expect(JSON.stringify(notificationConfig)).toBe(expectedJson); }); + + it('should build NotificationConfig without topics', () => { + const notificationConfig = new NotificationConfigBuilder().build(); + + const expectedJson = JSON.stringify({ + topics: [], + }); + + expect(JSON.stringify(notificationConfig)).toBe(expectedJson); + }); }); diff --git a/tests/doc_scan_service/session/create/notification.config.test.js b/tests/doc_scan_service/session/create/notification.config.test.js new file mode 100644 index 00000000..e24e67e1 --- /dev/null +++ b/tests/doc_scan_service/session/create/notification.config.test.js @@ -0,0 +1,17 @@ +const NotificationConfig = require('../../../../src/doc_scan_service/session/create/notification.config'); + +const SOME_AUTH_TOKEN = 'some-auth-token'; +const SOME_ENDPOINT = 'some-endpoint'; + +describe('NotificationConfig', () => { + it('should serialize without topics', () => { + const notificationConfig = new NotificationConfig(SOME_AUTH_TOKEN, SOME_ENDPOINT); + + const expectedJson = JSON.stringify({ + auth_token: SOME_AUTH_TOKEN, + endpoint: SOME_ENDPOINT, + }); + + expect(JSON.stringify(notificationConfig)).toBe(expectedJson); + }); +}); diff --git a/tests/doc_scan_service/session/create/session.specification.builder.test.js b/tests/doc_scan_service/session/create/session.specification.builder.test.js index c0be0507..fa9d4523 100644 --- a/tests/doc_scan_service/session/create/session.specification.builder.test.js +++ b/tests/doc_scan_service/session/create/session.specification.builder.test.js @@ -65,47 +65,51 @@ describe('SessionSpecificationBuilder', () => { topics: [], }, requested_checks: [ - { - type: 'ID_DOCUMENT_FACE_MATCH', - config: { - manual_check: 'NEVER', - }, - }, - { - type: 'LIVENESS', - config: { - max_retries: 1, - liveness_type: 'ZOOM', - }, - }, - { - type: 'ID_DOCUMENT_AUTHENTICITY', - config: {}, - }, + faceMatchCheck, + livenessCheck, + docAuthenticityCheck, ], requested_tasks: [ - { - type: 'ID_DOCUMENT_TEXT_DATA_EXTRACTION', - config: { - manual_check: 'FALLBACK', - }, - }, + textExtractionTask, ], sdk_config: { allowed_capture_methods: 'CAMERA', }, required_documents: [ - { - type: 'ID_DOCUMENT', - filter: { - type: 'DOCUMENT_RESTRICTIONS', - inclusion: 'WHITELIST', - documents: [], - }, - }, + requiredDocument, ], }); expect(JSON.stringify(sessionSpec)).toBe(expectedJson); }); + + it('should build SessionSpecification with block biometric consent true', () => { + const sessionSpec = new SessionSpecificationBuilder() + .withBlockBiometricConsent(true) + .build(); + + const expectedJson = JSON.stringify({ + requested_checks: [], + requested_tasks: [], + required_documents: [], + block_biometric_consent: true, + }); + + expect(JSON.stringify(sessionSpec)).toBe(expectedJson); + }); + + it('should build SessionSpecification with block biometric consent false', () => { + const sessionSpec = new SessionSpecificationBuilder() + .withBlockBiometricConsent(false) + .build(); + + const expectedJson = JSON.stringify({ + requested_checks: [], + requested_tasks: [], + required_documents: [], + block_biometric_consent: false, + }); + + expect(JSON.stringify(sessionSpec)).toBe(expectedJson); + }); }); diff --git a/tests/doc_scan_service/session/retrieve/get.session.result.spec.js b/tests/doc_scan_service/session/retrieve/get.session.result.spec.js index 2c204f6f..c0ffeaf3 100644 --- a/tests/doc_scan_service/session/retrieve/get.session.result.spec.js +++ b/tests/doc_scan_service/session/retrieve/get.session.result.spec.js @@ -5,12 +5,16 @@ const FaceMatchCheckResponse = require('../../../../src/doc_scan_service/session const TextDataCheckResponse = require('../../../../src/doc_scan_service/session/retrieve/text.data.check.response'); const LivenessCheckResponse = require('../../../../src/doc_scan_service/session/retrieve/liveness.check.response'); const ResourceContainer = require('../../../../src/doc_scan_service/session/retrieve/resource.container'); +const IdDocumentComparisonCheckResponse = require('../../../../src/doc_scan_service/session/retrieve/id.document.comparison.check.response'); +const { YotiDate } = require('../../../..'); const ID_DOCUMENT_AUTHENTICITY = 'ID_DOCUMENT_AUTHENTICITY'; const ID_DOCUMENT_FACE_MATCH = 'ID_DOCUMENT_FACE_MATCH'; const ID_DOCUMENT_TEXT_DATA_CHECK = 'ID_DOCUMENT_TEXT_DATA_CHECK'; const LIVENESS = 'LIVENESS'; +const ID_DOCUMENT_COMPARISON = 'ID_DOCUMENT_COMPARISON'; const SOME_UNKNOWN_CHECK = 'SOME_UNKNOWN_CHECK'; +const SOME_DATE_STRING = '2019-12-02T12:00:00.123Z'; describe('GetSessionResult', () => { let session; @@ -39,7 +43,11 @@ describe('GetSessionResult', () => { { type: ID_DOCUMENT_TEXT_DATA_CHECK, }, + { + type: ID_DOCUMENT_COMPARISON, + }, ], + biometric_consent: SOME_DATE_STRING, }); }); @@ -77,11 +85,12 @@ describe('GetSessionResult', () => { describe('when checks are available', () => { it('should return array of checks', () => { const checks = session.getChecks(); - expect(checks.length).toBe(4); + expect(checks.length).toBe(5); expect(checks[0]).toBeInstanceOf(AuthenticityCheckResponse); expect(checks[1]).toBeInstanceOf(LivenessCheckResponse); expect(checks[2]).toBeInstanceOf(FaceMatchCheckResponse); expect(checks[3]).toBeInstanceOf(TextDataCheckResponse); + expect(checks[4]).toBeInstanceOf(IdDocumentComparisonCheckResponse); checks.forEach((check) => expect(check).toBeInstanceOf(CheckResponse)); }); }); @@ -104,6 +113,15 @@ describe('GetSessionResult', () => { }); }); + describe('#getAuthenticityChecks', () => { + it('should return array of AuthenticityCheckResponse', () => { + const checks = session.getIdDocumentComparisonChecks(); + expect(checks.length).toBe(1); + expect(checks[0]).toBeInstanceOf(IdDocumentComparisonCheckResponse); + expect(checks[0].getType()).toBe(ID_DOCUMENT_COMPARISON); + }); + }); + describe('#getLivenessChecks', () => { it('should return array of ZoomLivenessCheckResponse', () => { const checks = session.getLivenessChecks(); @@ -154,4 +172,13 @@ describe('GetSessionResult', () => { expect(checks[0].getType()).toBe(SOME_UNKNOWN_CHECK); }); }); + + describe('#getBiometricConsentTimestamp', () => { + it('should return biometric consent timestamp container', () => { + const biometricConsent = session.getBiometricConsentTimestamp(); + expect(biometricConsent).toBeInstanceOf(YotiDate); + expect(biometricConsent).toBeInstanceOf(Date); + expect(biometricConsent.toISOString()).toBe(SOME_DATE_STRING); + }); + }); });