diff --git a/lib/Classes.js b/lib/Classes.js index 037c08d..e3ffc3e 100644 --- a/lib/Classes.js +++ b/lib/Classes.js @@ -646,12 +646,6 @@ var Nachricht = function (proto_version) { me_msg.segments[me_msg.segments_ctr] = seg me_msg.segments_ctr++ - if (seg.name === 'HKKAZ') { - me_msg.addSeg( - Helper.newSegFromArray('HKTAN', 6, ['4', 'HKIDN', '', '', '', '', 'N', '', '', '', '']) - ) - } - return seg.nr } @@ -955,6 +949,25 @@ var Order = function (client) { } // 2. Add Segment msg.addSeg(int_send_msg[j].segment) + + // Kontoumsätze abrufen requires HKTAN + if (int_send_msg[j].segment.name === 'HKKAZ') { + let HKTAN_vers; + var tan_verfahren = me_order.client.bpd.tan.tan_verfahren[me_order.client.upd.availible_tan_verfahren[0]]; + try { + HKTAN_vers = tan_verfahren.HITAN_vers; + client.log.con.info({ + gv: 'HKKAZ' + }, `TAN-Verfahren: '${tan_verfahren.desc}', v${HKTAN_vers}`); + } catch (e) { + client.log.con.error(e, { + gv: 'HKKAZ' + }, `Error reading TAN-Verfahren data. Using HKTAN v6.`); + } + msg.addSeg( + Helper.newSegFromArray('HKTAN', HKTAN_vers ?? 6, ['4', 'HKIDN', '', '', '', '', 'N', '', '', '', '']) + ); + } } } // Send Segments to Destination diff --git a/lib/FinTSClient.js b/lib/FinTSClient.js index c0dd96f..7491141 100644 --- a/lib/FinTSClient.js +++ b/lib/FinTSClient.js @@ -398,8 +398,13 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, var HKVVB = Helper.newSegFromArray('HKVVB', 3, [me.bpd.vers_bpd, me.upd.vers_upd, 0, me.client_name, me.client_version]) msg.addSeg(HKVVB) + // in step 1 me.upd.availible_tan_verfahren[0] is always '999' and we use HKTAN_vers 6 + // in step 2 we use the tan_verfahren requested by the bank server and send the corresponding HITANS version + const tan_verfahren = me.bpd.tan.tan_verfahren[me.upd.availible_tan_verfahren[0]]; + const HKTAN_vers = tan_verfahren.HITAN_vers || 6; + msg.addSeg( - Helper.newSegFromArray('HKTAN', 6, ['4', 'HKIDN', '', '', '', '', 'N', '', '', '', '']) + Helper.newSegFromArray('HKTAN', HKTAN_vers, ['4', 'HKIDN', '', '', '', '', 'N', '', '', '', '']) ); if (me.kunden_id != 9999999999 && me.sys_id == 0) var syn = msg.addSeg(Helper.newSegFromArray('HKSYN', me.proto_version == 220 ? 2 : 3, [0])) // Synchronisierung starten @@ -539,46 +544,121 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, } try { // 5.4 Tan - var HITANS = recvMsg.selectSegByName('HITANS')[0] - if (HITANS.vers == 5) { + var HITANSs = recvMsg.selectSegByName('HITANS'); + + me.bpd.tan.tan_verfahren = {}; + for (var HITANS of HITANSs) { + me.log.gv.info({ + gv: 'HITANS' + }, 'Analyse HITANS v' + HITANS.vers); + var tan_data = HITANS.getEl(4) me.bpd.tan.one_step_availible = tan_data.getEl(1).toUpperCase() == 'J' me.bpd.tan.multiple_tan = tan_data.getEl(2).toUpperCase() == 'J' me.bpd.tan.hash_type = tan_data.getEl(3) - me.bpd.tan.tan_verfahren = {} - for (var i = 3; i < tan_data.data.length; i++) { - var sicherheitsfunktion = {} - sicherheitsfunktion.code = tan_data.data[i] - sicherheitsfunktion.one_two_step_vers = tan_data.data[i + 1] // "1": Einschrittverfahren, "2": Zweischritt - sicherheitsfunktion.tech_id = tan_data.data[i + 2] - sicherheitsfunktion.zka_tan_verfahren = tan_data.data[i + 3] - sicherheitsfunktion.vers_zka_tan_verf = tan_data.data[i + 4] - sicherheitsfunktion.desc = tan_data.data[i + 5] - sicherheitsfunktion.max_len_tan = tan_data.data[i + 6] - sicherheitsfunktion.tan_alphanum = tan_data.data[i + 7] == '2' - sicherheitsfunktion.txt_rueckwert = tan_data.data[i + 8] - sicherheitsfunktion.max_len_rueckwert = tan_data.data[i + 9] - sicherheitsfunktion.anz_tanlist = tan_data.data[i + 10] - sicherheitsfunktion.multi_tan = tan_data.data[i + 11].toUpperCase() == 'J' - sicherheitsfunktion.tan_zeit_diabez = tan_data.data[i + 12] - sicherheitsfunktion.tan_list_nr_req = tan_data.data[i + 13] - sicherheitsfunktion.auftragsstorno = tan_data.data[i + 14].toUpperCase() == 'J' - sicherheitsfunktion.sms_abu_konto_req = tan_data.data[i + 15] - sicherheitsfunktion.auftrag_konto = tan_data.data[i + 16] - sicherheitsfunktion.challange_class_req = tan_data.data[i + 17].toUpperCase() == 'J' - sicherheitsfunktion.challange_structured = tan_data.data[i + 18].toUpperCase() == 'J' - sicherheitsfunktion.initialisierungs_mod = tan_data.data[i + 19] - sicherheitsfunktion.bez_tan_med_req = tan_data.data[i + 20] - sicherheitsfunktion.anz_supported_tan_vers = tan_data.data[i + 21] - // sicherheitsfunktion.challange_value_req = tan_data.data[i+14].toUpperCase()=="J"; - me.bpd.tan.tan_verfahren[sicherheitsfunktion.code] = sicherheitsfunktion - i += 21 + + if (HITANS.vers == 5) { + for (var i = 3; i < tan_data.data.length; i+= 22) { + var sicherheitsfunktion = {} + sicherheitsfunktion.code = tan_data.data[i] + sicherheitsfunktion.one_two_step_vers = tan_data.data[i + 1] // "1": Einschrittverfahren, "2": Zweischritt + sicherheitsfunktion.tech_id = tan_data.data[i + 2] + sicherheitsfunktion.zka_tan_verfahren = tan_data.data[i + 3] + sicherheitsfunktion.vers_zka_tan_verf = tan_data.data[i + 4] + sicherheitsfunktion.desc = tan_data.data[i + 5] + sicherheitsfunktion.max_len_tan = tan_data.data[i + 6] + sicherheitsfunktion.tan_alphanum = tan_data.data[i + 7] == '2' + sicherheitsfunktion.txt_rueckwert = tan_data.data[i + 8] + sicherheitsfunktion.max_len_rueckwert = tan_data.data[i + 9] + sicherheitsfunktion.anz_tanlist = tan_data.data[i + 10] + sicherheitsfunktion.multi_tan = tan_data.data[i + 11]?.toUpperCase() == 'J' + sicherheitsfunktion.tan_zeit_diabez = tan_data.data[i + 12] + sicherheitsfunktion.tan_list_nr_req = tan_data.data[i + 13] + sicherheitsfunktion.auftragsstorno = tan_data.data[i + 14]?.toUpperCase() == 'J' + sicherheitsfunktion.sms_abu_konto_req = tan_data.data[i + 15] + sicherheitsfunktion.auftrag_konto = tan_data.data[i + 16] + sicherheitsfunktion.challange_class_req = tan_data.data[i + 17]?.toUpperCase() == 'J' + sicherheitsfunktion.challange_structured = tan_data.data[i + 18]?.toUpperCase() == 'J' + sicherheitsfunktion.initialisierungs_mod = tan_data.data[i + 19] + sicherheitsfunktion.bez_tan_med_req = tan_data.data[i + 20] + sicherheitsfunktion.anz_supported_tan_vers = tan_data.data[i + 21] + // sicherheitsfunktion.challange_value_req = tan_data.data[i+14].toUpperCase()=="J"; + + sicherheitsfunktion.HITAN_vers = HITANS.vers; + me.bpd.tan.tan_verfahren[sicherheitsfunktion.code] = sicherheitsfunktion + } + } else if (HITANS.vers == 6) { + for (var i = 3; i < tan_data.data.length; i+=21) { + var sicherheitsfunktion = {}; + sicherheitsfunktion.code = tan_data.data[i]; + sicherheitsfunktion.one_two_step_vers = tan_data.data[i + 1]; // "1": Einschrittverfahren, "2": Zweischritt + sicherheitsfunktion.tech_id = tan_data.data[i + 2]; + sicherheitsfunktion.zka_tan_verfahren = tan_data.data[i + 3]; + sicherheitsfunktion.vers_zka_tan_verf = tan_data.data[i + 4]; + sicherheitsfunktion.desc = tan_data.data[i + 5]; + sicherheitsfunktion.max_len_tan = tan_data.data[i + 6]; + sicherheitsfunktion.tan_alphanum = tan_data.data[i + 7] === '2'; + sicherheitsfunktion.txt_rueckwert = tan_data.data[i + 8]; + sicherheitsfunktion.max_len_rueckwert = tan_data.data[i + 9]; + sicherheitsfunktion.multi_tan = tan_data.data[i + 10]?.toUpperCase() === 'J'; + sicherheitsfunktion.tan_zeit_diabez = tan_data.data[i + 11]; + sicherheitsfunktion.auftragsstorno = tan_data.data[i + 12]?.toUpperCase() === 'J'; + sicherheitsfunktion.sms_abu_konto_req = tan_data.data[i + 13]; + sicherheitsfunktion.auftrag_konto = tan_data.data[i + 14]; + sicherheitsfunktion.challange_class_req = tan_data.data[i + 15]?.toUpperCase() === 'J'; + sicherheitsfunktion.challange_structured = tan_data.data[i + 16]?.toUpperCase() === 'J'; + sicherheitsfunktion.initialisierungs_mod = tan_data.data[i + 17]; + sicherheitsfunktion.bez_tan_med_req = tan_data.data[i + 18]; + sicherheitsfunktion.antwort_HHD_UC_req = tan_data.data[i + 19]?.toUpperCase() === 'J'; + sicherheitsfunktion.anz_supported_tan_vers = tan_data.data[i + 20]; + + sicherheitsfunktion.HITAN_vers = HITANS.vers; + me.bpd.tan.tan_verfahren[sicherheitsfunktion.code] = sicherheitsfunktion + } + } else if (HITANS.vers == 7) { + for (var i = 3; i < tan_data.data.length; i+=26) { + var sicherheitsfunktion = {}; + sicherheitsfunktion.code = tan_data.data[i]; + sicherheitsfunktion.one_two_step_vers = tan_data.data[i + 1]; // "1": Einschrittverfahren, "2": Zweischritt + sicherheitsfunktion.tech_id = tan_data.data[i + 2]; + sicherheitsfunktion.zka_tan_verfahren = tan_data.data[i + 3]; + sicherheitsfunktion.vers_zka_tan_verf = tan_data.data[i + 4]; + sicherheitsfunktion.desc = tan_data.data[i + 5]; + sicherheitsfunktion.max_len_tan = tan_data.data[i + 6]; + sicherheitsfunktion.tan_alphanum = tan_data.data[i + 7] === '2'; + sicherheitsfunktion.txt_rueckwert = tan_data.data[i + 8]; + sicherheitsfunktion.max_len_rueckwert = tan_data.data[i + 9]; + sicherheitsfunktion.multi_tan = tan_data.data[i + 10]?.toUpperCase() === 'J'; + sicherheitsfunktion.tan_zeit_diabez = tan_data.data[i + 11]; + sicherheitsfunktion.auftragsstorno = tan_data.data[i + 12]?.toUpperCase() === 'J'; + sicherheitsfunktion.sms_abu_konto_req = tan_data.data[i + 13]; + sicherheitsfunktion.auftrag_konto = tan_data.data[i + 14]; + sicherheitsfunktion.challange_class_req = tan_data.data[i + 15]?.toUpperCase() === 'J'; + sicherheitsfunktion.challange_structured = tan_data.data[i + 16]?.toUpperCase() === 'J'; + sicherheitsfunktion.initialisierungs_mod = tan_data.data[i + 17]; + sicherheitsfunktion.bez_tan_med_req = tan_data.data[i + 18]; + sicherheitsfunktion.antwort_HHD_UC_req = tan_data.data[i + 19]?.toUpperCase() === 'J'; + sicherheitsfunktion.anz_supported_tan_vers = tan_data.data[i + 20]; + sicherheitsfunktion.max_anz_statusabfr = tan_data.data[i + 21]; + sicherheitsfunktion.wait_first_statusabfr = tan_data.data[i + 22]; + sicherheitsfunktion.wait_next_statusabfr = tan_data.data[i + 23]; + sicherheitsfunktion.manual_confirm = tan_data.data[i + 24]; + sicherheitsfunktion.auto_statusabfr_erlaubt = tan_data.data[i + 25]?.toUpperCase() === 'J'; + + sicherheitsfunktion.HITAN_vers = HITANS.vers; + me.bpd.tan.tan_verfahren[sicherheitsfunktion.code] = sicherheitsfunktion + } } } + for (const [code, sicherheitsfunktion] of Object.entries(me.bpd.tan.tan_verfahren)){ + me.log.gv.info({ + gv: 'HITANS' + }, `HITANS entry ${code}: '${sicherheitsfunktion.desc}', v${sicherheitsfunktion.HITAN_vers}`); + } } catch (ee) { me.log.gv.error(ee, { gv: 'HITANS' - }, 'Error while analyse HITANS') + }, `Error while analyse HITANS: ${ee.toString()}`); } // 6. Analysiere UPD try { @@ -588,7 +668,7 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, } catch (ee) { me.log.gv.error(ee, { gv: 'HIUPA' - }, 'Error while analyse UPD') + }, `Error while analyse UPD: ${ee.toString()}`) } // 7. Analysiere Verfügbare Tan Verfahren try { @@ -626,7 +706,7 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, } catch (ee) { me.log.gv.error(ee, { gv: 'HKVVB' - }, 'Error while analyse HKVVB result Tan Verfahren') + }, 'Error while analyse HKVVB gv params') } try { cb(error, recvMsg, has_neu_url) @@ -1174,6 +1254,7 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, // Im Step 1 und 2 bleiben keine Verbindungen erhalten // Diese Verbindung auf jeden Fall beenden var neu_url = me.bpd.url + var neu_tan_verfahren = me.bpd.tan.tan_verfahren var neu_sig_method = me.upd.availible_tan_verfahren[0] me.bpd = original_bpd.clone() me.upd = original_upd.clone() @@ -1193,6 +1274,7 @@ var FinTSClient = function (in_blz, in_kunden_id, in_pin, in_bankenlist, logger, }) me.clear() me.bpd.url = neu_url + me.bpd.tan.tan_verfahren = neu_tan_verfahren me.upd.availible_tan_verfahren[0] = neu_sig_method me.sys_id = orig_sys_id me.last_signatur_id = orig_last_sig