- HKEKA v3/v4/v5 Segmente fuer phpFinTS implementiert (VR Bank unterstuetzt kein HKEKP) - GetElectronicStatement Action mit Base64-Erkennung und Quittungscode - PDF-Deduplizierung per MD5 (Bank sendet identische Saldenmitteilungen) - Saldenmitteilungen ohne Auszugsnummer werden uebersprungen - Datums-Validierung: 30.02. (Bank-Konvention) wird auf 28.02. korrigiert - Numerische Sortierung fuer statement_number (CAST statt String-Sort) - Jahr-Filter: statement_year=0 ausgeschlossen - Menue/Button: "Kontoauszuege" -> "Umsaetze" (statements.php zeigt MT940, nicht PDFs) - Redirect nach FinTS-Abruf auf aktuelles Jahr statt year=0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
64 lines
2.1 KiB
PHP
Executable file
64 lines
2.1 KiB
PHP
Executable file
<?php
|
|
|
|
namespace Fhp\Model;
|
|
|
|
use Fhp\Syntax\Bin;
|
|
|
|
class TanRequestChallengeImage
|
|
{
|
|
private $mimeType;
|
|
private $data;
|
|
|
|
public function __construct(Bin $bin)
|
|
{
|
|
$data = $bin->getData();
|
|
|
|
// Documentation: https://www.hbci-zka.de/dokumente/spezifikation_deutsch/hhd/Belegungsrichtlinien%20TANve1.5%20FV%20vom%202018-04-16.pdf
|
|
// II.3
|
|
|
|
// Matrix-Format:
|
|
// 2 bytes = length of mime type
|
|
// mime type as string
|
|
// 2 bytes = length of data
|
|
|
|
$dataLength = strlen($data);
|
|
if ($dataLength < 2) {
|
|
throw new \InvalidArgumentException(
|
|
"Invalid TAN challenge. Expected image MIME type but only found $dataLength bytes. ");
|
|
}
|
|
$mimeTypeLengthString = substr($data, 0, 2);
|
|
$mimeTypeLength = ord($mimeTypeLengthString[0]) * 256 + ord($mimeTypeLengthString[1]);
|
|
|
|
if ($dataLength < 2 + $mimeTypeLength + 2) {
|
|
throw new \InvalidArgumentException(
|
|
"Invalid TAN challenge. Expected image MIME type of length $mimeTypeLength but only found $dataLength bytes. " .
|
|
'Maybe the challenge is not an image but rather a URL or a flicker code.');
|
|
}
|
|
$this->mimeType = substr($data, 2, $mimeTypeLength);
|
|
|
|
$data = substr($data, 2 + $mimeTypeLength);
|
|
|
|
$dataLengthString = substr($data, 0, 2);
|
|
$expectedDataLength = ord($dataLengthString[0]) * 256 + ord($dataLengthString[1]);
|
|
$actualDataLength = strlen($data) - 2;
|
|
|
|
if ($expectedDataLength != $actualDataLength) {
|
|
// This exception is thrown, if there is an encoding problem
|
|
// f.e.: the serialized action was saved as a string, but not base64 encoded
|
|
throw new \InvalidArgumentException(
|
|
"Unexpected data length, expected $expectedDataLength but found $actualDataLength bytes.");
|
|
}
|
|
|
|
$this->data = substr($data, 2, $expectedDataLength);
|
|
}
|
|
|
|
public function getMimeType(): string
|
|
{
|
|
return $this->mimeType;
|
|
}
|
|
|
|
public function getData(): string
|
|
{
|
|
return $this->data;
|
|
}
|
|
}
|