diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 8ef9f42d..1c8a1e9c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -31,6 +31,36 @@ jobs: - run: composer test + php8-4: + name: Unit Tests php8.4 (php ${{ matrix.php-version }}) + runs-on: ubuntu-latest + # always run on push events + # only run on pull_request_target event when pull request pulls from fork repository + if: > + github.event_name == 'push' || + github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository + strategy: + fail-fast: false + matrix: + php-version: [ 8.4 ] + + steps: + - uses: actions/checkout@v2 + + - uses: shivammathur/setup-php@2.9.0 + with: + php-version: ${{ matrix.php-version }} + + # Remove php-cs-fixer until compatible with PHP 8 + # This step might be removable if php-cs-fixer is compatible with 8.4 by the time this runs + - run: composer remove --dev --no-update --no-interaction friendsofphp/php-cs-fixer + + - run: composer self-update + + - run: composer install --no-interaction --prefer-source --dev + + - run: composer test + php7-4: name: Unit Tests php7.4 (php ${{ matrix.php-version }}) runs-on: ubuntu-latest @@ -109,4 +139,3 @@ jobs: - run: composer install --no-interaction --prefer-source --dev - run: composer test - diff --git a/composer.json b/composer.json index 01038195..86cb5318 100755 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "homepage": "https://yoti.com", "license": "MIT", "require": { - "php": "^7.4 || ^8.0 || ^8.1", + "php": "^7.4 || ^8.0 || ^8.1 || ^8.4", "ext-json": "*", "google/protobuf": "^3.10", "phpseclib/phpseclib": "^3.0", diff --git a/src/Aml/Profile.php b/src/Aml/Profile.php index b0ee2a10..d03219c3 100644 --- a/src/Aml/Profile.php +++ b/src/Aml/Profile.php @@ -50,7 +50,7 @@ class Profile implements \JsonSerializable * @param \Yoti\Aml\Address $amlAddress * @param null|string $ssn */ - public function __construct($givenNames, $familyName, Address $amlAddress, string $ssn = null) + public function __construct(string $givenNames, string $familyName, Address $amlAddress, ?string $ssn = null) { $this->givenNames = $givenNames; $this->familyName = $familyName; diff --git a/src/DocScan/Session/Create/Check/RequestedLivenessConfig.php b/src/DocScan/Session/Create/Check/RequestedLivenessConfig.php index 050655db..07db4fea 100644 --- a/src/DocScan/Session/Create/Check/RequestedLivenessConfig.php +++ b/src/DocScan/Session/Create/Check/RequestedLivenessConfig.php @@ -23,7 +23,7 @@ class RequestedLivenessConfig implements RequestedCheckConfigInterface */ private $manualCheck; - public function __construct(string $livenessType, int $maxRetries, string $manualCheck = null) + public function __construct(string $livenessType, int $maxRetries, ?string $manualCheck = null) { $this->livenessType = $livenessType; $this->maxRetries = $maxRetries; diff --git a/src/DocScan/Session/Create/ImportTokenBuilder.php b/src/DocScan/Session/Create/ImportTokenBuilder.php index 84340213..b40dd9bf 100644 --- a/src/DocScan/Session/Create/ImportTokenBuilder.php +++ b/src/DocScan/Session/Create/ImportTokenBuilder.php @@ -10,7 +10,7 @@ class ImportTokenBuilder private int $ttl; - public function withTtl(int $ttl = null): ImportTokenBuilder + public function withTtl(?int $ttl = null): ImportTokenBuilder { $this->ttl = $ttl ?? self::DEFAULT_TTL; diff --git a/src/DocScan/Session/Create/SdkConfig.php b/src/DocScan/Session/Create/SdkConfig.php index 683b403a..43c0498d 100644 --- a/src/DocScan/Session/Create/SdkConfig.php +++ b/src/DocScan/Session/Create/SdkConfig.php @@ -72,12 +72,12 @@ class SdkConfig implements \JsonSerializable * @var string|null */ private $darkMode; - + /** * @var string|null */ private $primaryColourDarkMode; - + /** * @var string|null */ @@ -263,7 +263,7 @@ public function getDarkMode(): ?string { return $this->darkMode; } - + /** * @return string|null */ diff --git a/src/DocScan/Session/Create/SdkConfigBuilder.php b/src/DocScan/Session/Create/SdkConfigBuilder.php index 67cfd4a7..5a4661dd 100644 --- a/src/DocScan/Session/Create/SdkConfigBuilder.php +++ b/src/DocScan/Session/Create/SdkConfigBuilder.php @@ -75,7 +75,7 @@ class SdkConfigBuilder * @var string|null */ private $darkMode; - + /** * @var string|null */ @@ -161,7 +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 * diff --git a/src/Exception/ActivityDetailsException.php b/src/Exception/ActivityDetailsException.php index 1913be81..d01f61ac 100644 --- a/src/Exception/ActivityDetailsException.php +++ b/src/Exception/ActivityDetailsException.php @@ -25,7 +25,7 @@ public function __construct( $message = "", ?ResponseInterface $response = null, ?array $responseBody = null, - \Throwable $previous = null + ?\Throwable $previous = null ) { parent::__construct($message, $response, $previous); diff --git a/src/Exception/base/YotiException.php b/src/Exception/base/YotiException.php index 8dde0005..b6a7d2e6 100644 --- a/src/Exception/base/YotiException.php +++ b/src/Exception/base/YotiException.php @@ -20,7 +20,7 @@ class YotiException extends \Exception * @param ResponseInterface|null $response * @param \Throwable|null $previous */ - public function __construct($message = "", ?ResponseInterface $response = null, \Throwable $previous = null) + public function __construct($message = "", ?ResponseInterface $response = null, ?\Throwable $previous = null) { parent::__construct($this->formatMessage($message, $response), 0, $previous); diff --git a/src/Http/Exception/NetworkException.php b/src/Http/Exception/NetworkException.php index 0879d9f9..814871f7 100644 --- a/src/Http/Exception/NetworkException.php +++ b/src/Http/Exception/NetworkException.php @@ -19,7 +19,7 @@ class NetworkException extends ClientException implements NetworkExceptionInterf public function __construct( string $message, RequestInterface $request, - \Throwable $previous = null + ?\Throwable $previous = null ) { $this->setRequest($request); parent::__construct($message, 0, $previous); diff --git a/src/Http/Exception/RequestException.php b/src/Http/Exception/RequestException.php index 2ce34d5d..6c3a946c 100644 --- a/src/Http/Exception/RequestException.php +++ b/src/Http/Exception/RequestException.php @@ -19,7 +19,7 @@ class RequestException extends ClientException implements RequestExceptionInterf public function __construct( string $message, RequestInterface $request, - \Throwable $previous = null + ?\Throwable $previous = null ) { $this->setRequest($request); parent::__construct($message, 0, $previous); diff --git a/src/Http/RequestBuilder.php b/src/Http/RequestBuilder.php index 8afff19e..e2413181 100644 --- a/src/Http/RequestBuilder.php +++ b/src/Http/RequestBuilder.php @@ -73,9 +73,9 @@ class RequestBuilder private $multipartEntity; /** - * @param \Yoti\Util\Config $config + * @param \Yoti\Util\Config|null $config */ - public function __construct(Config $config = null) + public function __construct(?Config $config = null) { $this->config = $config ?? new Config(); } diff --git a/src/Http/RequestSigner.php b/src/Http/RequestSigner.php index 99bdff79..abf09fe0 100644 --- a/src/Http/RequestSigner.php +++ b/src/Http/RequestSigner.php @@ -26,7 +26,7 @@ public static function sign( PemFile $pemFile, string $endpoint, string $httpMethod, - Payload $payload = null + ?Payload $payload = null ): string { $messageToSign = "{$httpMethod}&$endpoint"; if ($payload instanceof Payload) { diff --git a/src/Identity/Content/ApplicationContent.php b/src/Identity/Content/ApplicationContent.php index 8487fc4a..7c0d267f 100644 --- a/src/Identity/Content/ApplicationContent.php +++ b/src/Identity/Content/ApplicationContent.php @@ -10,7 +10,7 @@ class ApplicationContent private ?ApplicationProfile $profile; private ?ExtraData $extraData; - public function __construct(ApplicationProfile $profile = null, ExtraData $extraData = null) + public function __construct(?ApplicationProfile $profile = null, ?ExtraData $extraData = null) { $this->profile = $profile; $this->extraData = $extraData; diff --git a/src/Identity/Content/Content.php b/src/Identity/Content/Content.php index 9cf61c01..cef3ef37 100644 --- a/src/Identity/Content/Content.php +++ b/src/Identity/Content/Content.php @@ -9,7 +9,7 @@ class Content private ?string $profile; private ?string $extraData; - public function __construct(string $profile = null, string $extraData = null) + public function __construct(?string $profile = null, ?string $extraData = null) { $this->profile = $profile; $this->extraData = $extraData; diff --git a/src/Identity/Content/UserContent.php b/src/Identity/Content/UserContent.php index a32c2dfd..a69e24fd 100644 --- a/src/Identity/Content/UserContent.php +++ b/src/Identity/Content/UserContent.php @@ -10,7 +10,7 @@ class UserContent private ?UserProfile $profile; private ?ExtraData $extraData; - public function __construct(UserProfile $profile = null, ExtraData $extraData = null) + public function __construct(?UserProfile $profile = null, ?ExtraData $extraData = null) { $this->profile = $profile; $this->extraData = $extraData; diff --git a/src/Identity/Policy/PolicyBuilder.php b/src/Identity/Policy/PolicyBuilder.php index a3b8f479..8ad89aaa 100644 --- a/src/Identity/Policy/PolicyBuilder.php +++ b/src/Identity/Policy/PolicyBuilder.php @@ -51,8 +51,8 @@ public function withWantedAttribute(WantedAttribute $wantedAttribute): self */ public function withWantedAttributeByName( string $name, - array $constraints = null, - bool $acceptSelfAsserted = null + ?array $constraints = null, + ?bool $acceptSelfAsserted = null ): self { $wantedAttributeBuilder = (new WantedAttributeBuilder()) ->withName($name); @@ -71,7 +71,7 @@ public function withWantedAttributeByName( /** * @param Constraint[]|null $constraints */ - public function withFamilyName(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withFamilyName(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_FAMILY_NAME, @@ -83,7 +83,7 @@ public function withFamilyName(array $constraints = null, bool $acceptSelfAssert /** * @param Constraint[]|null $constraints */ - public function withGivenNames(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withGivenNames(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_GIVEN_NAMES, @@ -95,7 +95,7 @@ public function withGivenNames(array $constraints = null, bool $acceptSelfAssert /** * @param Constraint[]|null $constraints */ - public function withFullName(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withFullName(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_FULL_NAME, @@ -107,7 +107,7 @@ public function withFullName(array $constraints = null, bool $acceptSelfAsserted /** * @param Constraint[]|null $constraints */ - public function withDateOfBirth(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withDateOfBirth(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DATE_OF_BIRTH, @@ -119,7 +119,7 @@ public function withDateOfBirth(array $constraints = null, bool $acceptSelfAsser /** * @param Constraint[]|null $constraints */ - public function withAgeOver(int $age, array $constraints = null, bool $acceptSelfAsserted = null): self + public function withAgeOver(int $age, ?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withAgeDerivedAttribute( UserProfile::AGE_OVER . $age, @@ -131,7 +131,7 @@ public function withAgeOver(int $age, array $constraints = null, bool $acceptSel /** * @param Constraint[]|null $constraints */ - public function withAgeUnder(int $age, array $constraints = null, bool $acceptSelfAsserted = null): self + public function withAgeUnder(int $age, ?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withAgeDerivedAttribute( UserProfile::AGE_UNDER . $age, @@ -145,8 +145,8 @@ public function withAgeUnder(int $age, array $constraints = null, bool $acceptSe */ public function withAgeDerivedAttribute( string $derivation, - array $constraints = null, - bool $acceptSelfAsserted = null + ?array $constraints = null, + ?bool $acceptSelfAsserted = null ): self { $wantedAttributeBuilder = (new WantedAttributeBuilder()) ->withName(UserProfile::ATTR_DATE_OF_BIRTH) @@ -166,7 +166,7 @@ public function withAgeDerivedAttribute( /** * @param Constraint[]|null $constraints */ - public function withGender(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withGender(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_GENDER, @@ -178,7 +178,7 @@ public function withGender(array $constraints = null, bool $acceptSelfAsserted = /** * @param Constraint[]|null $constraints */ - public function withPostalAddress(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withPostalAddress(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_POSTAL_ADDRESS, @@ -190,7 +190,7 @@ public function withPostalAddress(array $constraints = null, bool $acceptSelfAss /** * @param Constraint[]|null $constraints */ - public function withStructuredPostalAddress(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withStructuredPostalAddress(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_STRUCTURED_POSTAL_ADDRESS, @@ -202,7 +202,7 @@ public function withStructuredPostalAddress(array $constraints = null, bool $acc /** * @param Constraint[]|null $constraints */ - public function withNationality(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withNationality(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_NATIONALITY, @@ -214,7 +214,7 @@ public function withNationality(array $constraints = null, bool $acceptSelfAsser /** * @param Constraint[]|null $constraints */ - public function withPhoneNumber(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withPhoneNumber(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_PHONE_NUMBER, @@ -226,7 +226,7 @@ public function withPhoneNumber(array $constraints = null, bool $acceptSelfAsser /** * @param Constraint[]|null $constraints */ - public function withSelfie(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withSelfie(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_SELFIE, @@ -238,7 +238,7 @@ public function withSelfie(array $constraints = null, bool $acceptSelfAsserted = /** * @param Constraint[]|null $constraints */ - public function withDocumentDetails(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withDocumentDetails(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DOCUMENT_DETAILS, @@ -250,7 +250,7 @@ public function withDocumentDetails(array $constraints = null, bool $acceptSelfA /** * @param Constraint[]|null $constraints */ - public function withDocumentImages(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withDocumentImages(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DOCUMENT_IMAGES, @@ -262,7 +262,7 @@ public function withDocumentImages(array $constraints = null, bool $acceptSelfAs /** * @param Constraint[]|null $constraints */ - public function withEmail(array $constraints = null, bool $acceptSelfAsserted = null): self + public function withEmail(?array $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_EMAIL_ADDRESS, diff --git a/src/Identity/Policy/WantedAttribute.php b/src/Identity/Policy/WantedAttribute.php index dc34da79..47005af1 100644 --- a/src/Identity/Policy/WantedAttribute.php +++ b/src/Identity/Policy/WantedAttribute.php @@ -29,10 +29,10 @@ class WantedAttribute implements \JsonSerializable */ public function __construct( string $name, - string $derivation = null, + ?string $derivation = null, bool $optional = false, - bool $acceptSelfAsserted = null, - array $constraints = null + ?bool $acceptSelfAsserted = null, + ?array $constraints = null ) { Validation::notEmptyString($name, 'name'); $this->name = $name; diff --git a/src/Identity/ReceiptBuilder.php b/src/Identity/ReceiptBuilder.php index 0851a088..1ec378f2 100644 --- a/src/Identity/ReceiptBuilder.php +++ b/src/Identity/ReceiptBuilder.php @@ -42,14 +42,14 @@ public function withSessionId(string $sessionId): self return $this; } - public function withRememberMeId(string $rememberMeId = null): self + public function withRememberMeId(?string $rememberMeId = null): self { $this->rememberMeId = $rememberMeId; return $this; } - public function withParentRememberMeId(string $parentRememberMeId = null): self + public function withParentRememberMeId(?string $parentRememberMeId = null): self { $this->parentRememberMeId = $parentRememberMeId; @@ -63,28 +63,28 @@ public function withTimestamp(\DateTime $timestamp): self return $this; } - public function withApplicationContent(ApplicationProfile $profile, ExtraData $extraData = null): self + public function withApplicationContent(ApplicationProfile $profile, ?ExtraData $extraData = null): self { $this->applicationContent = new ApplicationContent($profile, $extraData); return $this; } - public function withUserContent(UserProfile $profile = null, ExtraData $extraData = null): self + public function withUserContent(?UserProfile $profile = null, ?ExtraData $extraData = null): self { $this->userContent = new UserContent($profile, $extraData); return $this; } - public function withError(string $error = null): self + public function withError(?string $error = null): self { $this->error = $error; return $this; } - public function withErrorReason(ErrorReason $errorReason = null): self + public function withErrorReason(?ErrorReason $errorReason = null): self { $this->errorReason = $errorReason; diff --git a/src/Identity/ReceiptParser.php b/src/Identity/ReceiptParser.php index 904ef7b7..39fae9ee 100644 --- a/src/Identity/ReceiptParser.php +++ b/src/Identity/ReceiptParser.php @@ -21,7 +21,7 @@ class ReceiptParser */ private $logger; - public function __construct(LoggerInterface $logger = null) + public function __construct(?LoggerInterface $logger = null) { $this->logger = $logger ?? new Logger(); } diff --git a/src/Profile/Attribute.php b/src/Profile/Attribute.php index 1117f728..39f1d8b2 100644 --- a/src/Profile/Attribute.php +++ b/src/Profile/Attribute.php @@ -36,7 +36,7 @@ class Attribute * @param Anchor[] $anchors * @param string|null $id */ - public function __construct(string $name, $value, array $anchors, string $id = null) + public function __construct(string $name, $value, array $anchors, ?string $id = null) { $this->name = $name; $this->value = $value; diff --git a/src/Profile/ExtraData/AttributeIssuanceDetails.php b/src/Profile/ExtraData/AttributeIssuanceDetails.php index 019350c6..31d6e9ca 100644 --- a/src/Profile/ExtraData/AttributeIssuanceDetails.php +++ b/src/Profile/ExtraData/AttributeIssuanceDetails.php @@ -25,10 +25,10 @@ class AttributeIssuanceDetails /** * @param string $token - * @param \DateTime $expiryDate + * @param \DateTime|null $expiryDate * @param \Yoti\Profile\ExtraData\AttributeDefinition[] $issuingAttributes */ - public function __construct(string $token, \DateTime $expiryDate = null, array $issuingAttributes = []) + public function __construct(string $token, ?\DateTime $expiryDate = null, array $issuingAttributes = []) { $this->token = $token; diff --git a/src/Profile/Util/Attribute/AnchorConverter.php b/src/Profile/Util/Attribute/AnchorConverter.php index a13d6147..93f9b130 100644 --- a/src/Profile/Util/Attribute/AnchorConverter.php +++ b/src/Profile/Util/Attribute/AnchorConverter.php @@ -60,8 +60,31 @@ private static function decodeAnchorValue(string $extEncodedValue): string { $encodedBER = ASN1::extractBER($extEncodedValue); $decodedValArr = ASN1::decodeBER($encodedBER); + if (isset($decodedValArr[0]['content'][0]['content'])) { - return $decodedValArr[0]['content'][0]['content']; + $value = $decodedValArr[0]['content'][0]['content']; + + if (!is_string($value)) { + return ''; + } + + $detectionOrder = mb_detect_order(); + $encoding = mb_detect_encoding($value, is_array($detectionOrder) ? $detectionOrder : null, true); + + if (is_string($encoding)) { + if ($encoding !== 'UTF-8') { + // PHPStan implies $value is string, $encoding is valid string, so result is string. + return mb_convert_encoding($value, 'UTF-8', $encoding); + } + // It is UTF-8 + return $value; + } else { // $encoding is false (detection failed) + if (!mb_check_encoding($value, 'UTF-8')) { + // PHPStan implies $value is string, so result is string. + return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1'); + } + return $value; // It's valid UTF-8 despite detection failing + } } return ''; } @@ -108,16 +131,28 @@ private static function convertCertToX509(string $certificate): \stdClass $X509 = new X509(); $X509Data = $X509->loadX509($certificate); - /** We need because of new 3.0 version phpseclib @link https://github.com/phpseclib/phpseclib/issues/1738 */ array_walk_recursive($X509Data, function (&$item): void { - if (is_string($item) && mb_detect_encoding($item) != 'ASCII') { - $item = base64_encode($item); + if (is_string($item)) { + $detectionOrder = mb_detect_order(); + $encoding = mb_detect_encoding($item, is_array($detectionOrder) ? $detectionOrder : null, true); + + if (is_string($encoding)) { + if ($encoding !== 'UTF-8' && $encoding !== 'ASCII') { + // PHPStan implies $item is string, $encoding is valid string, so result is string. + // The 'else' branch for base64_encode was deemed unreachable by PHPStan. + $item = mb_convert_encoding($item, 'UTF-8', $encoding); + } + // If $encoding is 'UTF-8' or 'ASCII', $item is left as is. + } else { // $encoding is false (detection failed) + if (!mb_check_encoding($item, 'UTF-8') && !mb_check_encoding($item, 'ASCII')) { + $item = base64_encode($item); + } + // If it's valid UTF-8/ASCII despite detection failing, $item is left as is. + } } }); $decodedX509Data = Json::decode(Json::encode(Json::convertFromLatin1ToUtf8Recursively($X509Data)), false); - // Ensure serial number is cast to string. - // @see \phpseclib\Math\BigInteger::__toString() $decodedX509Data ->tbsCertificate ->serialNumber diff --git a/src/ShareUrl/Policy/DynamicPolicyBuilder.php b/src/ShareUrl/Policy/DynamicPolicyBuilder.php index 4d3ba083..72aa6f85 100644 --- a/src/ShareUrl/Policy/DynamicPolicyBuilder.php +++ b/src/ShareUrl/Policy/DynamicPolicyBuilder.php @@ -77,8 +77,8 @@ public function withWantedAttribute(WantedAttribute $wantedAttribute): self */ public function withWantedAttributeByName( string $name, - Constraints $constraints = null, - bool $acceptSelfAsserted = null + ?Constraints $constraints = null, + ?bool $acceptSelfAsserted = null ): self { $wantedAttributeBuilder = (new WantedAttributeBuilder()) ->withName($name); @@ -100,7 +100,7 @@ public function withWantedAttributeByName( * * @return $this */ - public function withFamilyName(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withFamilyName(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_FAMILY_NAME, @@ -115,7 +115,7 @@ public function withFamilyName(Constraints $constraints = null, bool $acceptSelf * * @return self */ - public function withGivenNames(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withGivenNames(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_GIVEN_NAMES, @@ -130,7 +130,7 @@ public function withGivenNames(Constraints $constraints = null, bool $acceptSelf * * @return self */ - public function withFullName(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withFullName(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_FULL_NAME, @@ -145,7 +145,7 @@ public function withFullName(Constraints $constraints = null, bool $acceptSelfAs * * @return $this */ - public function withDateOfBirth(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withDateOfBirth(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DATE_OF_BIRTH, @@ -161,7 +161,7 @@ public function withDateOfBirth(Constraints $constraints = null, bool $acceptSel * * @return $this */ - public function withAgeOver(int $age, Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withAgeOver(int $age, ?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withAgeDerivedAttribute( UserProfile::AGE_OVER . (string) $age, @@ -177,7 +177,7 @@ public function withAgeOver(int $age, Constraints $constraints = null, bool $acc * * @return $this */ - public function withAgeUnder(int $age, Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withAgeUnder(int $age, ?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withAgeDerivedAttribute( UserProfile::AGE_UNDER . (string) $age, @@ -195,8 +195,8 @@ public function withAgeUnder(int $age, Constraints $constraints = null, bool $ac */ public function withAgeDerivedAttribute( string $derivation, - Constraints $constraints = null, - bool $acceptSelfAsserted = null + ?Constraints $constraints = null, + ?bool $acceptSelfAsserted = null ): self { $wantedAttributeBuilder = (new WantedAttributeBuilder()) ->withName(UserProfile::ATTR_DATE_OF_BIRTH) @@ -216,7 +216,7 @@ public function withAgeDerivedAttribute( * * @return $this */ - public function withGender(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withGender(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_GENDER, @@ -231,7 +231,7 @@ public function withGender(Constraints $constraints = null, bool $acceptSelfAsse * * @return $this */ - public function withPostalAddress(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withPostalAddress(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_POSTAL_ADDRESS, @@ -246,7 +246,7 @@ public function withPostalAddress(Constraints $constraints = null, bool $acceptS * * @return $this */ - public function withStructuredPostalAddress(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withStructuredPostalAddress(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_STRUCTURED_POSTAL_ADDRESS, @@ -261,7 +261,7 @@ public function withStructuredPostalAddress(Constraints $constraints = null, boo * * @return $this */ - public function withNationality(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withNationality(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_NATIONALITY, @@ -276,7 +276,7 @@ public function withNationality(Constraints $constraints = null, bool $acceptSel * * @return $this */ - public function withPhoneNumber(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withPhoneNumber(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_PHONE_NUMBER, @@ -291,7 +291,7 @@ public function withPhoneNumber(Constraints $constraints = null, bool $acceptSel * * @return $this */ - public function withSelfie(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withSelfie(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_SELFIE, @@ -306,7 +306,7 @@ public function withSelfie(Constraints $constraints = null, bool $acceptSelfAsse * * @return $this */ - public function withDocumentDetails(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withDocumentDetails(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DOCUMENT_DETAILS, @@ -321,7 +321,7 @@ public function withDocumentDetails(Constraints $constraints = null, bool $accep * * @return $this */ - public function withDocumentImages(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withDocumentImages(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_DOCUMENT_IMAGES, @@ -336,7 +336,7 @@ public function withDocumentImages(Constraints $constraints = null, bool $accept * * @return $this */ - public function withEmail(Constraints $constraints = null, bool $acceptSelfAsserted = null): self + public function withEmail(?Constraints $constraints = null, ?bool $acceptSelfAsserted = null): self { return $this->withWantedAttributeByName( UserProfile::ATTR_EMAIL_ADDRESS, @@ -411,7 +411,7 @@ public function withIdentityProfileRequirements($identityProfileRequirements): s * @param object $advancedIdentityProfileRequirements * @return $this */ - public function withAdvancedIdentityProfileRequirements($advancedIdentityProfileRequirements): self + public function withAdvIdentityProfileReqs($advancedIdentityProfileRequirements): self { $this->advancedIdentityProfileRequirements = $advancedIdentityProfileRequirements; return $this; diff --git a/src/ShareUrl/Policy/WantedAttribute.php b/src/ShareUrl/Policy/WantedAttribute.php index e525e446..d176070a 100644 --- a/src/ShareUrl/Policy/WantedAttribute.php +++ b/src/ShareUrl/Policy/WantedAttribute.php @@ -46,10 +46,10 @@ class WantedAttribute implements \JsonSerializable */ public function __construct( string $name, - string $derivation = null, - bool $acceptSelfAsserted = null, - Constraints $constraints = null, - bool $optional = null + ?string $derivation = null, + ?bool $acceptSelfAsserted = null, + ?Constraints $constraints = null, + ?bool $optional = null ) { Validation::notEmptyString($name, 'name'); $this->name = $name; diff --git a/src/Util/Json.php b/src/Util/Json.php index 8be63f78..81f7bdb7 100644 --- a/src/Util/Json.php +++ b/src/Util/Json.php @@ -65,7 +65,7 @@ private static function validate(): void public static function convertFromLatin1ToUtf8Recursively($dat) { if (is_string($dat)) { - return utf8_encode($dat); + return mb_convert_encoding($dat, 'UTF-8', 'ISO-8859-1'); } elseif (is_array($dat)) { $ret = []; foreach ($dat as $i => $d) { diff --git a/tests/Aml/ResultTest.php b/tests/Aml/ResultTest.php index 76dd42d0..86f83eaf 100644 --- a/tests/Aml/ResultTest.php +++ b/tests/Aml/ResultTest.php @@ -21,6 +21,11 @@ class ResultTest extends TestCase */ public $amlResult; + /** + * @var \PHPUnit\Framework\MockObject\MockObject&\Psr\Http\Message\ResponseInterface + */ + private $responseMock; + public function setup(): void { $this->responseMock = $this->createMock(ResponseInterface::class); diff --git a/tests/DocScan/Session/Create/SdkConfigBuilderTest.php b/tests/DocScan/Session/Create/SdkConfigBuilderTest.php index 2a70fc02..846f2433 100644 --- a/tests/DocScan/Session/Create/SdkConfigBuilderTest.php +++ b/tests/DocScan/Session/Create/SdkConfigBuilderTest.php @@ -322,7 +322,7 @@ public function shouldSetCorrectValueWithDarkModeAuto() $this->assertEquals('AUTO', $result->getDarkMode()); } - + /** * @test * @covers ::withDarkModeOn diff --git a/tests/Profile/BaseProfileTest.php b/tests/Profile/BaseProfileTest.php index 71fce4bb..20c7b122 100644 --- a/tests/Profile/BaseProfileTest.php +++ b/tests/Profile/BaseProfileTest.php @@ -138,7 +138,7 @@ public function testGetAttributeById() $givenNamesAttribute = new ProtobufAttribute([ 'name' => self::SOME_ATTRIBUTE, - 'value' => utf8_decode('Alan'), + 'value' => mb_convert_encoding('Alan', 'ISO-8859-1', 'UTF-8'), 'content_type' => self::CONTENT_TYPE_STRING, ]); $newAttribute = AttributeConverter::convertToYotiAttribute($givenNamesAttribute); diff --git a/tests/Profile/Util/EncryptedDataTest.php b/tests/Profile/Util/EncryptedDataTest.php index 1680c9a8..4d1e8741 100644 --- a/tests/Profile/Util/EncryptedDataTest.php +++ b/tests/Profile/Util/EncryptedDataTest.php @@ -28,6 +28,11 @@ class EncrypedDataTest extends TestCase */ private $wrappedKey; + /** + * @var \Yoti\Protobuf\Compubapi\EncryptedData + */ + private $encryptedDataProto; + /** * Setup test data. */ diff --git a/tests/ShareUrl/Policy/DynamicPolicyBuilderTest.php b/tests/ShareUrl/Policy/DynamicPolicyBuilderTest.php index 0980b58e..0c1680a6 100644 --- a/tests/ShareUrl/Policy/DynamicPolicyBuilderTest.php +++ b/tests/ShareUrl/Policy/DynamicPolicyBuilderTest.php @@ -719,7 +719,7 @@ public function testWithAdvancedIdentityProfileRequirements() ]; $dynamicPolicy = (new DynamicPolicyBuilder()) - ->withAdvancedIdentityProfileRequirements($advancedIdentityProfileSample) + ->withAdvIdentityProfileReqs($advancedIdentityProfileSample) ->build(); $this->assertEquals(json_encode($expectedWantedAttributeData), json_encode($dynamicPolicy)); diff --git a/tests/Util/JsonTest.php b/tests/Util/JsonTest.php index df232c6e..30a9b29b 100644 --- a/tests/Util/JsonTest.php +++ b/tests/Util/JsonTest.php @@ -81,18 +81,27 @@ public function testWithoutNullValues() */ public function testConvertFromLatin1ToUtf8Recursively() { - $latin1String = utf8_decode('éàê'); - $latin1Array = [utf8_decode('éàê'), utf8_decode('çî')]; - $nestedLatin1Array = [utf8_decode('éàê'), [utf8_decode('çî'), utf8_decode('üñ')]]; + $latin1String = mb_convert_encoding('éàê', 'ISO-8859-1', 'UTF-8'); + $latin1Array = [ + mb_convert_encoding('éàê', 'ISO-8859-1', 'UTF-8'), + mb_convert_encoding('çî', 'ISO-8859-1', 'UTF-8') + ]; + $nestedLatin1Array = [ + mb_convert_encoding('éàê', 'ISO-8859-1', 'UTF-8'), + [ + mb_convert_encoding('çî', 'ISO-8859-1', 'UTF-8'), + mb_convert_encoding('üñ', 'ISO-8859-1', 'UTF-8') + ] + ]; $latin1Object = new \stdClass(); - $latin1Object->property1 = utf8_decode('éàê'); - $latin1Object->property2 = utf8_decode('çî'); + $latin1Object->property1 = mb_convert_encoding('éàê', 'ISO-8859-1', 'UTF-8'); + $latin1Object->property2 = mb_convert_encoding('çî', 'ISO-8859-1', 'UTF-8'); $nestedLatin1Object = new \stdClass(); - $nestedLatin1Object->property = utf8_decode('çî'); + $nestedLatin1Object->property = mb_convert_encoding('çî', 'ISO-8859-1', 'UTF-8'); $latin1ObjectWithNestedObject = new \stdClass(); - $latin1ObjectWithNestedObject->property1 = utf8_decode('éàê'); + $latin1ObjectWithNestedObject->property1 = mb_convert_encoding('éàê', 'ISO-8859-1', 'UTF-8'); $latin1ObjectWithNestedObject->property2 = $nestedLatin1Object; $this->assertSame('éàê', Json::convertFromLatin1ToUtf8Recursively($latin1String));