diff --git a/README.md b/README.md index 6f35b579..e6dadebc 100755 --- a/README.md +++ b/README.md @@ -42,13 +42,13 @@ Add the Yoti SDK dependency: ```json "require": { - "yoti/yoti-php-sdk" : "^4.3.0" + "yoti/yoti-php-sdk" : "^4.4.0" } ``` Or run this Composer command ```console -$ composer require yoti/yoti-php-sdk "^4.3.0" +$ composer require yoti/yoti-php-sdk "^4.4.0" ``` ## Setup diff --git a/composer.json b/composer.json index 95ef8a52..4879618b 100755 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "yoti/yoti-php-sdk", "description": "Yoti SDK for quickly integrating your PHP backend with Yoti", - "version": "4.3.0", + "version": "4.4.0", "keywords": [ "yoti", "sdk" diff --git a/examples/digitalidentity/.env.example b/examples/digitalidentity/.env.example index 72022df2..58bc3f2e 100644 --- a/examples/digitalidentity/.env.example +++ b/examples/digitalidentity/.env.example @@ -1,4 +1,4 @@ -# This file is a template for defining the environment variables +0# This file is a template for defining the environment variables # Set the application config values here YOTI_SDK_ID=xxxxxxxxxxxxxxxxxxxxx diff --git a/examples/digitalidentity/README.md b/examples/digitalidentity/README.md index 3673b72a..9bf2d1b3 100644 --- a/examples/digitalidentity/README.md +++ b/examples/digitalidentity/README.md @@ -24,4 +24,4 @@ This example requires [Docker](https://docs.docker.com/) ## Digital Identity(Advanced) Share Example * Visit [/generate-advanced-identity-share](https://localhost:4002/generate-advanced-identity-share) * ## Digital Identity DBS Example -* Visit [/generate-dbs-share](https://localhost:4002/generate-dbs-share) \ No newline at end of file +* Visit [/generate-dbs-share](https://localhost:4002/generate-dbs-share) diff --git a/examples/digitalidentity/resources/views/dbs.blade.php b/examples/digitalidentity/resources/views/dbs.blade.php index 1359cc7c..9f325177 100644 --- a/examples/digitalidentity/resources/views/dbs.blade.php +++ b/examples/digitalidentity/resources/views/dbs.blade.php @@ -85,5 +85,6 @@ function onErrorListener(...data) { await onReadyToStart() } + diff --git a/examples/doc-scan/app/Http/Controllers/HomeController.php b/examples/doc-scan/app/Http/Controllers/HomeController.php index 299fa6b1..f116e776 100644 --- a/examples/doc-scan/app/Http/Controllers/HomeController.php +++ b/examples/doc-scan/app/Http/Controllers/HomeController.php @@ -103,11 +103,12 @@ public function show(Request $request, DocScanClient $client) ->withMaxRetries(3) ->build() ) + /* ->withRequestedCheck( (new RequestedWatchlistAdvancedCaCheckBuilder()) ->withConfig($customConfig) ->build() - ) + )*/ ->withRequestedCheck( (new RequestedFaceMatchCheckBuilder()) ->withManualCheckFallback() @@ -150,6 +151,7 @@ public function show(Request $request, DocScanClient $client) ->withErrorUrl(config('app.url') . '/error') ->withPrivacyPolicyUrl(config('app.url') . '/privacy-policy') ->withBiometricConsentFlow('EARLY') + ->withBrandId('brand_id') ->build() ) ->withRequiredDocument( diff --git a/src/Constants.php b/src/Constants.php index b1cb4499..67486d3d 100644 --- a/src/Constants.php +++ b/src/Constants.php @@ -31,7 +31,7 @@ class Constants public const SDK_IDENTIFIER = 'PHP'; /** Default SDK version */ - public const SDK_VERSION = '4.3.0'; + public const SDK_VERSION = '4.4.0'; /** Base url for connect page (user will be redirected to this page eg. baseurl/app-id) */ public const CONNECT_BASE_URL = 'https://www.yoti.com/connect'; diff --git a/src/DocScan/Session/Create/SdkConfig.php b/src/DocScan/Session/Create/SdkConfig.php index a3c8086d..683b403a 100644 --- a/src/DocScan/Session/Create/SdkConfig.php +++ b/src/DocScan/Session/Create/SdkConfig.php @@ -68,6 +68,21 @@ class SdkConfig implements \JsonSerializable */ private $biometricConsentFlow; + /** + * @var string|null + */ + private $darkMode; + + /** + * @var string|null + */ + private $primaryColourDarkMode; + + /** + * @var string|null + */ + private $brandId; + /** * @param string|null $allowedCaptureMethods * @param string|null $primaryColour @@ -81,6 +96,9 @@ class SdkConfig implements \JsonSerializable * @param bool|null $allowHandoff * @param array|null $idDocumentTextDataExtractionRetriesConfig * @param string|null $biometricConsentFlow + * @param string|null $darkMode + * @param string|null $primaryColourDarkMode + * @param string|null $brandId */ public function __construct( ?string $allowedCaptureMethods, @@ -94,7 +112,10 @@ public function __construct( ?string $privacyPolicyUrl = null, ?bool $allowHandoff = null, ?array $idDocumentTextDataExtractionRetriesConfig = null, - ?string $biometricConsentFlow = null + ?string $biometricConsentFlow = null, + ?string $darkMode = null, + ?string $primaryColourDarkMode = null, + ?string $brandId = null ) { $this->allowedCaptureMethods = $allowedCaptureMethods; $this->primaryColour = $primaryColour; @@ -110,6 +131,9 @@ public function __construct( $this->attemptsConfiguration = new AttemptsConfiguration($idDocumentTextDataExtractionRetriesConfig); } $this->biometricConsentFlow = $biometricConsentFlow; + $this->darkMode = $darkMode; + $this->primaryColourDarkMode = $primaryColourDarkMode; + $this->brandId = $brandId; } /** @@ -129,7 +153,10 @@ public function jsonSerialize(): \stdClass 'privacy_policy_url' => $this->getPrivacyPolicyUrl(), 'allow_handoff' => $this->getAllowHandoff(), 'attempts_configuration' => $this->getAttemptsConfiguration(), - 'biometric_consent_flow' => $this->getBiometricConsentFlow() + 'biometric_consent_flow' => $this->getBiometricConsentFlow(), + 'dark_mode' => $this->getDarkMode(), + 'primary_colour_dark_mode' => $this->getPrimaryColourDarkMode(), + 'brand_id' => $this->getBrandId() ]); } @@ -228,4 +255,28 @@ public function getBiometricConsentFlow(): ?string { return $this->biometricConsentFlow; } + + /** + * @return string|null + */ + public function getDarkMode(): ?string + { + return $this->darkMode; + } + + /** + * @return string|null + */ + public function getPrimaryColourDarkMode(): ?string + { + return $this->primaryColourDarkMode; + } + + /** + * @return string|null + */ + public function getBrandId(): ?string + { + return $this->brandId; + } } diff --git a/src/DocScan/Session/Create/SdkConfigBuilder.php b/src/DocScan/Session/Create/SdkConfigBuilder.php index acf30fcc..67cfd4a7 100644 --- a/src/DocScan/Session/Create/SdkConfigBuilder.php +++ b/src/DocScan/Session/Create/SdkConfigBuilder.php @@ -71,6 +71,21 @@ class SdkConfigBuilder */ private $biometricConsentFlow; + /** + * @var string|null + */ + private $darkMode; + + /** + * @var string|null + */ + private $primaryColourDarkMode; + + /** + * @var string|null + */ + private $brandId; + public function withAllowsCamera(): self { return $this->withAllowedCaptureMethod(self::CAMERA); @@ -146,6 +161,7 @@ public function withBiometricConsentFlow(string $biometricConsentFlow): self $this->biometricConsentFlow = $biometricConsentFlow; return $this; } + /** * Allows configuring the number of attempts permitted for text extraction on an ID document * @@ -199,6 +215,41 @@ public function withIdDocumentTextExtractionGenericAttempts(int $genericRetries) return $this; } + public function withDarkMode(string $darkMode): self + { + $this->darkMode = $darkMode; + return $this; + } + + public function withDarkModeOn(): self + { + $this->darkMode = "ON"; + return $this; + } + + public function withDarkModeOff(): self + { + $this->darkMode = "OFF"; + return $this; + } + + public function withDarkModeAuto(): self + { + $this->darkMode = "AUTO"; + return $this; + } + + public function withPrimaryColourDarkMode(string $primaryColourDarkMode): self + { + $this->primaryColourDarkMode = $primaryColourDarkMode; + return $this; + } + + public function withBrandId(string $brandId): self + { + $this->brandId = $brandId; + return $this; + } public function build(): SdkConfig { @@ -214,7 +265,10 @@ public function build(): SdkConfig $this->privacyPolicyUrl, $this->allowHandoff, $this->idDocumentTextDataExtractionRetriesConfig, - $this->biometricConsentFlow + $this->biometricConsentFlow, + $this->darkMode, + $this->primaryColourDarkMode, + $this->brandId ); } } diff --git a/src/DocScan/Session/Retrieve/CustomAccountWatchlistCaSearchConfigResponse.php b/src/DocScan/Session/Retrieve/CustomAccountWatchlistCaSearchConfigResponse.php index efa7819d..6b95fd6c 100644 --- a/src/DocScan/Session/Retrieve/CustomAccountWatchlistCaSearchConfigResponse.php +++ b/src/DocScan/Session/Retrieve/CustomAccountWatchlistCaSearchConfigResponse.php @@ -35,7 +35,9 @@ public function __construct(array $searchConfig) $this->apiKey = $searchConfig['api_key']; $this->monitoring = $searchConfig['monitoring']; $this->clientRef = $searchConfig['client_ref']; - $this->tags = array_key_exists('tags', $searchConfig) ? json_decode($searchConfig['tags'], true) : []; + $this->tags = array_key_exists('tags', $searchConfig) && is_string($searchConfig['tags']) + ? json_decode($searchConfig['tags'], true) + : (array_key_exists('tags', $searchConfig) && is_array($searchConfig['tags']) ? $searchConfig['tags'] : []); } /** diff --git a/src/ShareUrl/Policy/WantedAttribute.php b/src/ShareUrl/Policy/WantedAttribute.php index a5b0f2ed..e525e446 100644 --- a/src/ShareUrl/Policy/WantedAttribute.php +++ b/src/ShareUrl/Policy/WantedAttribute.php @@ -32,17 +32,24 @@ class WantedAttribute implements \JsonSerializable */ private $acceptSelfAsserted; + /** + * @var bool|null + */ + private $optional; + /** * @param string $name * @param string $derivation * @param bool $acceptSelfAsserted * @param \Yoti\ShareUrl\Policy\Constraints $constraints + * @param bool $optional */ public function __construct( string $name, string $derivation = null, bool $acceptSelfAsserted = null, - Constraints $constraints = null + Constraints $constraints = null, + bool $optional = null ) { Validation::notEmptyString($name, 'name'); $this->name = $name; @@ -50,6 +57,7 @@ public function __construct( $this->derivation = $derivation; $this->acceptSelfAsserted = $acceptSelfAsserted; $this->constraints = $constraints; + $this->optional = $optional; } /** @@ -97,6 +105,14 @@ public function getAcceptSelfAsserted(): ?bool return $this->acceptSelfAsserted; } + /** + * @return bool|null + */ + public function getOptional(): ?bool + { + return $this->optional; + } + /** * @inheritDoc * @@ -106,7 +122,7 @@ public function jsonSerialize(): array { $json = [ 'name' => $this->getName(), - 'optional' => false, + 'optional' => $this->getOptional(), ]; if ($this->getDerivation() !== null) { @@ -121,6 +137,12 @@ public function jsonSerialize(): array $json['accept_self_asserted'] = $this->getAcceptSelfAsserted(); } + if ($this->getOptional() !== null) { + $json['optional'] = $this->getOptional(); + } + + + return $json; } diff --git a/src/ShareUrl/Policy/WantedAttributeBuilder.php b/src/ShareUrl/Policy/WantedAttributeBuilder.php index 37f381e7..9995cfdb 100644 --- a/src/ShareUrl/Policy/WantedAttributeBuilder.php +++ b/src/ShareUrl/Policy/WantedAttributeBuilder.php @@ -29,6 +29,10 @@ class WantedAttributeBuilder */ private $acceptSelfAsserted; + /** + * @var bool|null + */ + private $optional = false; /** * @param string $name * @@ -73,6 +77,16 @@ public function withAcceptSelfAsserted(?bool $acceptSelfAsserted = true): self return $this; } + /** + * @param bool $optional + * + * @return $this + */ + public function withOptional(?bool $optional = false): self + { + $this->optional = $optional; + return $this; + } /** * @return \Yoti\ShareUrl\Policy\WantedAttribute */ @@ -82,7 +96,8 @@ public function build(): WantedAttribute $this->name, $this->derivation, $this->acceptSelfAsserted, - $this->constraints + $this->constraints, + $this->optional ); } } diff --git a/tests/DocScan/Session/Create/SdkConfigBuilderTest.php b/tests/DocScan/Session/Create/SdkConfigBuilderTest.php index 3c84f5d2..2a70fc02 100644 --- a/tests/DocScan/Session/Create/SdkConfigBuilderTest.php +++ b/tests/DocScan/Session/Create/SdkConfigBuilderTest.php @@ -23,7 +23,9 @@ class SdkConfigBuilderTest extends TestCase private const SOME_CATEGORY = 'someCategory'; private const SOME_NUMBER_RETRIES = 5; private const SOME_BIOMETRIC_CONSENT_FLOW = 'someBiometricConsentFlow'; - + private const SOME_DARK_MODE = 'someDarkMode'; + private const SOME_PRIMARY_COLOUR_DARK_MODE = 'somePrimaryColourDarkMode'; + private const SOME_BRAND_ID = 'someBrandId'; /** * @test @@ -38,6 +40,7 @@ class SdkConfigBuilderTest extends TestCase * @covers ::withErrorUrl * @covers ::withPrivacyPolicyUrl * @covers ::withAllowHandoff + * @covers ::withBrandId * @covers \Yoti\DocScan\Session\Create\SdkConfig::__construct * @covers \Yoti\DocScan\Session\Create\SdkConfig::getAllowedCaptureMethods * @covers \Yoti\DocScan\Session\Create\SdkConfig::getPrimaryColour @@ -49,6 +52,9 @@ class SdkConfigBuilderTest extends TestCase * @covers \Yoti\DocScan\Session\Create\SdkConfig::getErrorUrl * @covers \Yoti\DocScan\Session\Create\SdkConfig::getPrivacyPolicyUrl * @covers \Yoti\DocScan\Session\Create\SdkConfig::getAllowHandoff + * @covers \Yoti\DocScan\Session\Create\SdkConfig::getDarkMode + * @covers \Yoti\DocScan\Session\Create\SdkConfig::getPrimaryColourDarkMode + * @covers \Yoti\DocScan\Session\Create\SdkConfig::getBrandId */ public function shouldCorrectlyBuildSdkConfig() { @@ -63,6 +69,10 @@ public function shouldCorrectlyBuildSdkConfig() ->withErrorUrl(self::SOME_ERROR_URL) ->withPrivacyPolicyUrl(self::SOME_PRIVACY_POLICY_URL) ->withAllowHandoff(true) + ->withBiometricConsentFlow(self::SOME_BIOMETRIC_CONSENT_FLOW) + ->withDarkMode(self::SOME_DARK_MODE) + ->withPrimaryColourDarkMode(self::SOME_PRIMARY_COLOUR_DARK_MODE) + ->withBrandId(self::SOME_BRAND_ID) ->build(); $this->assertEquals(self::SOME_CAPTURE_METHOD, $result->getAllowedCaptureMethods()); @@ -74,7 +84,11 @@ public function shouldCorrectlyBuildSdkConfig() $this->assertEquals(self::SOME_SUCCESS_URL, $result->getSuccessUrl()); $this->assertEquals(self::SOME_ERROR_URL, $result->getErrorUrl()); $this->assertEquals(self::SOME_PRIVACY_POLICY_URL, $result->getPrivacyPolicyUrl()); + $this->assertEquals(self::SOME_BIOMETRIC_CONSENT_FLOW, $result->getBiometricConsentFlow()); $this->assertTrue($result->getAllowHandoff()); + $this->assertEquals(self::SOME_DARK_MODE, $result->getDarkMode()); + $this->assertEquals(self::SOME_PRIMARY_COLOUR_DARK_MODE, $result->getPrimaryColourDarkMode()); + $this->assertEquals(self::SOME_BRAND_ID, $result->getBrandId()); } /** @@ -121,6 +135,8 @@ public function shouldProduceTheCorrectJsonString() ->withPrivacyPolicyUrl(self::SOME_PRIVACY_POLICY_URL) ->withAllowHandoff(true) ->withBiometricConsentFlow(self::SOME_BIOMETRIC_CONSENT_FLOW) + ->withPrimaryColourDarkMode(self::SOME_PRIMARY_COLOUR_DARK_MODE) + ->withDarkMode(self::SOME_DARK_MODE) ->build(); $expected = [ @@ -134,7 +150,9 @@ public function shouldProduceTheCorrectJsonString() 'error_url' => self::SOME_ERROR_URL, 'privacy_policy_url' => self::SOME_PRIVACY_POLICY_URL, 'allow_handoff' => true, - 'biometric_consent_flow' => self::SOME_BIOMETRIC_CONSENT_FLOW + 'biometric_consent_flow' => self::SOME_BIOMETRIC_CONSENT_FLOW, + 'dark_mode' => self::SOME_DARK_MODE, + 'primary_colour_dark_mode' => self::SOME_PRIMARY_COLOUR_DARK_MODE ]; $this->assertJsonStringEqualsJsonString(json_encode($expected), json_encode($result)); @@ -291,4 +309,43 @@ public function attemptsConfigurationShouldAllowMultipleCategories(): void ->getIdDocumentTextDataExtraction() ); } + + /** + * @test + * @covers ::withDarkModeAuto + */ + public function shouldSetCorrectValueWithDarkModeAuto() + { + $result = (new SdkConfigBuilder()) + ->withDarkModeAuto() + ->build(); + + $this->assertEquals('AUTO', $result->getDarkMode()); + } + + /** + * @test + * @covers ::withDarkModeOn + */ + public function shouldSetCorrectValueWithDarkModeOn() + { + $result = (new SdkConfigBuilder()) + ->withDarkModeOn() + ->build(); + + $this->assertEquals('ON', $result->getDarkMode()); + } + + /** + * @test + * @covers ::withDarkModeOff + */ + public function shouldSetCorrectValueWithDarkModeOff() + { + $result = (new SdkConfigBuilder()) + ->withDarkModeOff() + ->build(); + + $this->assertEquals('OFF', $result->getDarkMode()); + } } diff --git a/tests/ShareUrl/Policy/WantedAttributeBuilderTest.php b/tests/ShareUrl/Policy/WantedAttributeBuilderTest.php index 5abb542e..2b1c20f3 100644 --- a/tests/ShareUrl/Policy/WantedAttributeBuilderTest.php +++ b/tests/ShareUrl/Policy/WantedAttributeBuilderTest.php @@ -32,6 +32,7 @@ public function testBuild() $wantedAttribute = (new WantedAttributeBuilder()) ->withName($someName) ->withDerivation($someDerivation) + ->withOptional(false) ->build(); $expectedJsonData = [ @@ -91,6 +92,7 @@ public function testAcceptSelfAsserted() $wantedAttributeDefault = (new WantedAttributeBuilder()) ->withName($someName) ->withAcceptSelfAsserted() + ->withOptional(false) ->build(); $this->assertEquals(json_encode($expectedJsonData), json_encode($wantedAttributeDefault)); @@ -124,6 +126,7 @@ public function testWithoutAcceptSelfAsserted() $wantedAttribute = (new WantedAttributeBuilder()) ->withName($someName) ->withAcceptSelfAsserted(false) + ->withOptional(false) ->build(); $this->assertEquals(json_encode($expectedJsonData), json_encode($wantedAttribute)); @@ -149,6 +152,7 @@ public function testWithConstraints() $wantedAttribute = (new WantedAttributeBuilder()) ->withName($someName) + ->withOptional(false) ->withConstraints($constraints) ->build();