From e25a2836644e6d656ae4baeaa06f614127326208 Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Tue, 20 Oct 2026 17:10:07 -0400 Subject: [PATCH 1/4] feat(VAPI-3321): add attestationLevel and identity to BXML Transfer --- src/Model/Bxml/AttestationLevel.php | 10 ++++++++++ src/Model/Bxml/Transfer.php | 6 ++++++ tests/Unit/Model/Bxml/TransferTest.php | 27 ++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/Model/Bxml/AttestationLevel.php diff --git a/src/Model/Bxml/AttestationLevel.php b/src/Model/Bxml/AttestationLevel.php new file mode 100644 index 00000000..1c665b3f --- /dev/null +++ b/src/Model/Bxml/AttestationLevel.php @@ -0,0 +1,10 @@ + $this->tag, 'diversionTreatment' => $this->diversionTreatment, 'diversionReason' => $this->diversionReason, + 'attestationLevel' => $this->attestationLevel, + 'identity' => $this->identity, ]; } } diff --git a/tests/Unit/Model/Bxml/TransferTest.php b/tests/Unit/Model/Bxml/TransferTest.php index eb6cc17e..214d9a87 100644 --- a/tests/Unit/Model/Bxml/TransferTest.php +++ b/tests/Unit/Model/Bxml/TransferTest.php @@ -2,6 +2,7 @@ namespace Bandwidth\Test\Unit\Model\Bxml; +use Bandwidth\Model\Bxml\AttestationLevel; use Bandwidth\Model\Bxml\DiversionReason; use Bandwidth\Model\Bxml\DiversionTreatment; use Bandwidth\Model\Bxml\Hangup; @@ -37,7 +38,8 @@ public function testAllAttributes(): void fallbackPassword: 'fallbackPass', tag: 'my-tag', diversionTreatment: DiversionTreatment::PROPAGATE, - diversionReason: DiversionReason::NO_ANSWER + diversionReason: DiversionReason::NO_ANSWER, + attestationLevel: AttestationLevel::B ); $this->assertSame( @@ -47,7 +49,28 @@ public function testAllAttributes(): void . ' transferCompleteFallbackUrl="/completeFallback"' . ' transferCompleteFallbackMethod="GET" username="user" password="pass"' . ' fallbackUsername="fallbackUser" fallbackPassword="fallbackPass" tag="my-tag"' - . ' diversionTreatment="propagate" diversionReason="no-answer"/>', + . ' diversionTreatment="propagate" diversionReason="no-answer"' + . ' attestationLevel="B"/>', + $transfer->toBxml() + ); + } + + public function testAttestationLevel(): void + { + $this->assertSame( + '', + (new Transfer(attestationLevel: AttestationLevel::A))->toBxml() + ); + } + + public function testIdentity(): void + { + $identity = 'eyJhbGciOiJFUzI1NiJ9.sig;info=;ppt="shaken"'; + $transfer = new Transfer(identity: $identity); + + $this->assertSame( + '', $transfer->toBxml() ); } From be52abe1f722b1ed8e3551aee941908fef83a868 Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Tue, 3 Nov 2026 12:10:50 -0500 Subject: [PATCH 2/4] VAPI-4422 Tighten Attestation Level and Identity Docs --- src/Model/Bxml/Transfer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Model/Bxml/Transfer.php b/src/Model/Bxml/Transfer.php index 3fa85eea..84a35e1f 100644 --- a/src/Model/Bxml/Transfer.php +++ b/src/Model/Bxml/Transfer.php @@ -21,8 +21,8 @@ class Transfer extends NestableVerb * @param string|null $tag Custom string sent with all future callbacks. Max 256 characters. * @param DiversionTreatment|null $diversionTreatment How Diversion headers are handled on the outbound leg. * @param DiversionReason|null $diversionReason Only considered when diversionTreatment is stack. - * @param AttestationLevel|null $attestationLevel STIR/SHAKEN attestation level Bandwidth signs at. US outbound only; ignored unless the account uses the Hosted Signing Service. Cannot be combined with identity. - * @param string|null $identity Pre-signed SIP Identity header value, passed unmodified and not verified by Bandwidth. Max 2000 characters. Cannot be combined with attestationLevel. + * @param AttestationLevel|null $attestationLevel STIR/SHAKEN attestation level to sign the transferred call with. Only applies to accounts using the Hosted Signing Service. Cannot be combined with identity. + * @param string|null $identity SIP Identity header value (PASSporT) signed by you, sent unmodified. Max 2000 characters. Cannot be combined with attestationLevel. */ public function __construct( array $transferTo = [], From d5ab9b07b567612bb45a6843d4c584cd746e6af2 Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Wed, 11 Nov 2026 11:33:44 -0500 Subject: [PATCH 3/4] refactor(VAPI-4422): rename Transfer attestationLevel to requestedAttestationLevel --- src/Model/Bxml/Transfer.php | 8 ++++---- tests/Unit/Model/Bxml/TransferTest.php | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Model/Bxml/Transfer.php b/src/Model/Bxml/Transfer.php index 84a35e1f..0350a784 100644 --- a/src/Model/Bxml/Transfer.php +++ b/src/Model/Bxml/Transfer.php @@ -21,8 +21,8 @@ class Transfer extends NestableVerb * @param string|null $tag Custom string sent with all future callbacks. Max 256 characters. * @param DiversionTreatment|null $diversionTreatment How Diversion headers are handled on the outbound leg. * @param DiversionReason|null $diversionReason Only considered when diversionTreatment is stack. - * @param AttestationLevel|null $attestationLevel STIR/SHAKEN attestation level to sign the transferred call with. Only applies to accounts using the Hosted Signing Service. Cannot be combined with identity. - * @param string|null $identity SIP Identity header value (PASSporT) signed by you, sent unmodified. Max 2000 characters. Cannot be combined with attestationLevel. + * @param AttestationLevel|null $requestedAttestationLevel STIR/SHAKEN attestation level to sign the transferred call with. Only applies to accounts using the Hosted Signing Service. Cannot be combined with identity. + * @param string|null $identity SIP Identity header value (PASSporT) signed by you, sent unmodified. Max 2000 characters. Cannot be combined with requestedAttestationLevel. */ public function __construct( array $transferTo = [], @@ -41,7 +41,7 @@ public function __construct( public readonly ?string $tag = null, public readonly ?DiversionTreatment $diversionTreatment = null, public readonly ?DiversionReason $diversionReason = null, - public readonly ?AttestationLevel $attestationLevel = null, + public readonly ?AttestationLevel $requestedAttestationLevel = null, public readonly ?string $identity = null, ) { parent::__construct('Transfer', null, $transferTo); @@ -70,7 +70,7 @@ protected function attributes(): array 'tag' => $this->tag, 'diversionTreatment' => $this->diversionTreatment, 'diversionReason' => $this->diversionReason, - 'attestationLevel' => $this->attestationLevel, + 'requestedAttestationLevel' => $this->requestedAttestationLevel, 'identity' => $this->identity, ]; } diff --git a/tests/Unit/Model/Bxml/TransferTest.php b/tests/Unit/Model/Bxml/TransferTest.php index 214d9a87..ed888a8c 100644 --- a/tests/Unit/Model/Bxml/TransferTest.php +++ b/tests/Unit/Model/Bxml/TransferTest.php @@ -39,7 +39,7 @@ public function testAllAttributes(): void tag: 'my-tag', diversionTreatment: DiversionTreatment::PROPAGATE, diversionReason: DiversionReason::NO_ANSWER, - attestationLevel: AttestationLevel::B + requestedAttestationLevel: AttestationLevel::B ); $this->assertSame( @@ -50,16 +50,16 @@ public function testAllAttributes(): void . ' transferCompleteFallbackMethod="GET" username="user" password="pass"' . ' fallbackUsername="fallbackUser" fallbackPassword="fallbackPass" tag="my-tag"' . ' diversionTreatment="propagate" diversionReason="no-answer"' - . ' attestationLevel="B"/>', + . ' requestedAttestationLevel="B"/>', $transfer->toBxml() ); } - public function testAttestationLevel(): void + public function testRequestedAttestationLevel(): void { $this->assertSame( - '', - (new Transfer(attestationLevel: AttestationLevel::A))->toBxml() + '', + (new Transfer(requestedAttestationLevel: AttestationLevel::A))->toBxml() ); } From b1869e1073a4fcb2fb88bd31cd1adf2ea74dba1f Mon Sep 17 00:00:00 2001 From: Nicolas Asanov Date: Wed, 11 Nov 2026 11:44:14 -0500 Subject: [PATCH 4/4] test(VAPI-4422): fold Transfer attestation and identity into existing tests --- tests/Unit/Model/Bxml/EnumTest.php | 8 ++++++++ tests/Unit/Model/Bxml/TransferTest.php | 25 ++++--------------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/tests/Unit/Model/Bxml/EnumTest.php b/tests/Unit/Model/Bxml/EnumTest.php index 4deda508..6e98bb23 100644 --- a/tests/Unit/Model/Bxml/EnumTest.php +++ b/tests/Unit/Model/Bxml/EnumTest.php @@ -2,6 +2,7 @@ namespace Bandwidth\Test\Unit\Model\Bxml; +use Bandwidth\Model\Bxml\AttestationLevel; use Bandwidth\Model\Bxml\DiversionReason; use Bandwidth\Model\Bxml\DiversionTreatment; use Bandwidth\Model\Bxml\FileFormat; @@ -13,6 +14,13 @@ class EnumTest extends TestCase { + public function testAttestationLevelValues(): void + { + $this->assertSame('A', AttestationLevel::A->value); + $this->assertSame('B', AttestationLevel::B->value); + $this->assertSame('C', AttestationLevel::C->value); + } + public function testHttpMethodValues(): void { $this->assertSame('GET', HttpMethod::GET->value); diff --git a/tests/Unit/Model/Bxml/TransferTest.php b/tests/Unit/Model/Bxml/TransferTest.php index ed888a8c..6fafbf2e 100644 --- a/tests/Unit/Model/Bxml/TransferTest.php +++ b/tests/Unit/Model/Bxml/TransferTest.php @@ -39,7 +39,8 @@ public function testAllAttributes(): void tag: 'my-tag', diversionTreatment: DiversionTreatment::PROPAGATE, diversionReason: DiversionReason::NO_ANSWER, - requestedAttestationLevel: AttestationLevel::B + requestedAttestationLevel: AttestationLevel::B, + identity: 'eyJhbGciOiJFUzI1NiJ9.sig;info=;ppt="shaken"' ); $this->assertSame( @@ -50,26 +51,8 @@ public function testAllAttributes(): void . ' transferCompleteFallbackMethod="GET" username="user" password="pass"' . ' fallbackUsername="fallbackUser" fallbackPassword="fallbackPass" tag="my-tag"' . ' diversionTreatment="propagate" diversionReason="no-answer"' - . ' requestedAttestationLevel="B"/>', - $transfer->toBxml() - ); - } - - public function testRequestedAttestationLevel(): void - { - $this->assertSame( - '', - (new Transfer(requestedAttestationLevel: AttestationLevel::A))->toBxml() - ); - } - - public function testIdentity(): void - { - $identity = 'eyJhbGciOiJFUzI1NiJ9.sig;info=;ppt="shaken"'; - $transfer = new Transfer(identity: $identity); - - $this->assertSame( - '', $transfer->toBxml() );