Feature: FinTS-TAN-Verfahren per Verbindung konfigurierbar + Decoupled-Polling-Fix
This commit is contained in:
parent
ed3d5d33f1
commit
4b25961190
4 changed files with 41 additions and 9 deletions
3
migrations/073_bank_sources_tan_mode_id.sql
Normal file
3
migrations/073_bank_sources_tan_mode_id.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE bank_sources
|
||||
ADD COLUMN IF NOT EXISTS tan_mode_id INT NULL DEFAULT NULL
|
||||
COMMENT 'Bevorzugte FinTS-TAN-Verfahren-ID (z.B. 913 für chipTAN QR); NULL = erstes verfügbares';
|
||||
|
|
@ -443,6 +443,7 @@ class BankController extends BaseController
|
|||
'fints_url' => $isFints ? (trim($_POST['fints_url'] ?? '') ?: null) : null,
|
||||
'benutzerkennung' => $isFints ? (trim($_POST['benutzerkennung'] ?? '') ?: null) : null,
|
||||
'pin' => $isFints ? (trim($_POST['pin'] ?? '') ?: null) : null,
|
||||
'tan_mode_id' => $isFints ? (($_POST['tan_mode_id'] ?? '') !== '' ? (int)$_POST['tan_mode_id'] : null) : null,
|
||||
'account_filter' => null, // Konten werden beim ersten Abruf ausgewählt
|
||||
]);
|
||||
|
||||
|
|
@ -547,6 +548,7 @@ class BankController extends BaseController
|
|||
'fints_url' => trim($_POST['fints_url'] ?? '') ?: null,
|
||||
'benutzerkennung' => trim($_POST['benutzerkennung'] ?? '') ?: null,
|
||||
'pin' => $newPin !== '' ? $newPin : $source['pin'],
|
||||
'tan_mode_id' => ($_POST['tan_mode_id'] ?? '') !== '' ? (int)$_POST['tan_mode_id'] : null,
|
||||
];
|
||||
$filterUpdate = BankSource::computeFilterFromPost(
|
||||
$source['account_filter'] ?? null,
|
||||
|
|
|
|||
|
|
@ -104,8 +104,25 @@ class FinTsFetchService
|
|||
$log(sprintf(' [%d] %s (ID %d)', $idx, $mode->getName(), $mode->getId()));
|
||||
}
|
||||
|
||||
$selectedTanMode = reset($tanModes);
|
||||
$log('Auswahl: ' . $selectedTanMode->getName() . ' (erstes verfügbares Verfahren)');
|
||||
$preferredId = isset($this->source['tan_mode_id']) && $this->source['tan_mode_id'] !== null
|
||||
? (int)$this->source['tan_mode_id']
|
||||
: null;
|
||||
$selectedTanMode = null;
|
||||
if ($preferredId !== null) {
|
||||
foreach ($tanModes as $mode) {
|
||||
if ($mode->getId() === $preferredId) {
|
||||
$selectedTanMode = $mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($selectedTanMode === null) {
|
||||
$log('WARNUNG: TAN-Verfahren ID ' . $preferredId . ' nicht gefunden – nutze erstes verfügbares.');
|
||||
}
|
||||
}
|
||||
if ($selectedTanMode === null) {
|
||||
$selectedTanMode = reset($tanModes);
|
||||
}
|
||||
$log('Auswahl: ' . $selectedTanMode->getName() . ' (ID ' . $selectedTanMode->getId() . ')');
|
||||
|
||||
$selectedTanMedium = null;
|
||||
if ($selectedTanMode->needsTanMedium()) {
|
||||
|
|
@ -288,11 +305,14 @@ class FinTsFetchService
|
|||
$period = max(1, (int)$tanMode->getPeriodicDecoupledCheckDelaySeconds());
|
||||
for ($attempt = 0; $attempt < $maxChecks; $attempt++) {
|
||||
try {
|
||||
$this->fints->checkDecoupledSubmission($action);
|
||||
return true;
|
||||
if ($this->fints->checkDecoupledSubmission($action)) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
sleep($period);
|
||||
$log(' → Polling-Fehler: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
sleep($period);
|
||||
}
|
||||
$log(' → Zeitüberschreitung bei App-Bestätigung.');
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -292,6 +292,11 @@ $fetchRangeOptions = [
|
|||
<label for="edit-fints-url">FinTS-Server-URL <span class="text-muted text-sm">(optional)</span></label>
|
||||
<input type="url" id="edit-fints-url" name="fints_url" placeholder="https://...">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-tan-mode-id">TAN-Verfahren-ID <span class="text-muted text-sm">(optional)</span></label>
|
||||
<input type="number" id="edit-tan-mode-id" name="tan_mode_id" min="1" placeholder="z.B. 913 für chipTAN QR">
|
||||
<div class="text-muted text-sm">Leer = erstes verfügbares Verfahren</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-fetch-range-fints">Abrufen ab</label>
|
||||
<select id="edit-fetch-range-fints" name="fetch_range" disabled>
|
||||
|
|
@ -463,6 +468,7 @@ $fetchRangeOptions = [
|
|||
const editBenutzer = document.getElementById('edit-benutzerkennung');
|
||||
const editPin = document.getElementById('edit-pin');
|
||||
const editFintsUrl = document.getElementById('edit-fints-url');
|
||||
const editTanModeId = document.getElementById('edit-tan-mode-id');
|
||||
const editAccountList = document.getElementById('edit-account-list');
|
||||
const editResetAcc = document.getElementById('edit-reset-accounts');
|
||||
const editFetchRangeApi = document.getElementById('edit-fetch-range-api');
|
||||
|
|
@ -839,10 +845,11 @@ $fetchRangeOptions = [
|
|||
editSandbox.checked = conn.sandbox === true;
|
||||
}
|
||||
if (isFints) {
|
||||
editBlz.value = conn.blz || '';
|
||||
editBenutzer.value = conn.benutzerkennung || '';
|
||||
editPin.value = '';
|
||||
editFintsUrl.value = conn.fints_url || '';
|
||||
editBlz.value = conn.blz || '';
|
||||
editBenutzer.value = conn.benutzerkennung || '';
|
||||
editPin.value = '';
|
||||
editFintsUrl.value = conn.fints_url || '';
|
||||
editTanModeId.value = conn.tan_mode_id != null ? conn.tan_mode_id : '';
|
||||
editResetAcc.checked = false;
|
||||
|
||||
// Konto-Checkboxen aus account_filter aufbauen
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue