Re-added askUserForTanProcedure() so user (also that one of the library) really has a change to select a TAN procedure. As default selection otherwise gets hidden deep inside fints4java lib and if library user's enter tan dialog does not support selecting TAN procedure user would never have the choice to select her preferred procedure.
This commit is contained in:
parent
954db89e2f
commit
e5d04fc3c8
|
@ -44,6 +44,12 @@ open class fints4javaBankingClient(
|
||||||
|
|
||||||
|
|
||||||
protected val client = FinTsClientForCustomer(bank, customer, webClient, base64Service, threadPool, object : FinTsClientCallback {
|
protected val client = FinTsClientForCustomer(bank, customer, webClient, base64Service, threadPool, object : FinTsClientCallback {
|
||||||
|
|
||||||
|
override fun askUserForTanProcedure(supportedTanProcedures: List<TanProcedure>, suggestedTanProcedure: TanProcedure?): TanProcedure? {
|
||||||
|
// we simply return suggestedTanProcedure as even so it's not user's preferred TAN procedure she still can select it in EnterTanDialog
|
||||||
|
return suggestedTanProcedure
|
||||||
|
}
|
||||||
|
|
||||||
override fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult {
|
override fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult {
|
||||||
mapper.updateTanMediaAndProcedures(account, customer)
|
mapper.updateTanMediaAndProcedures(account, customer)
|
||||||
|
|
||||||
|
|
|
@ -138,6 +138,15 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// do not ask user for tan at this stage
|
||||||
|
var didOverwriteUserUnselectedTanProcedure = false
|
||||||
|
if (customer.isTanProcedureSelected == false && customer.supportedTanProcedures.isNotEmpty()) {
|
||||||
|
|
||||||
|
didOverwriteUserUnselectedTanProcedure = true
|
||||||
|
customer.selectedTanProcedure = customer.supportedTanProcedures.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val synchronizeCustomerResponse = synchronizeCustomerSystemId(bank, customer)
|
val synchronizeCustomerResponse = synchronizeCustomerSystemId(bank, customer)
|
||||||
|
|
||||||
getTanMediaList(bank, customer, TanMedienArtVersion.Alle, TanMediumKlasse.AlleMedien)
|
getTanMediaList(bank, customer, TanMedienArtVersion.Alle, TanMediumKlasse.AlleMedien)
|
||||||
|
@ -145,6 +154,10 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
// also check if retrieving account transactions of last 90 days without tan is supported (and thereby may retrieve first account transactions)
|
// also check if retrieving account transactions of last 90 days without tan is supported (and thereby may retrieve first account transactions)
|
||||||
val transactionsOfLast90DaysResponse = tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, false)
|
val transactionsOfLast90DaysResponse = tryGetTransactionsOfLast90DaysWithoutTan(bank, customer, false)
|
||||||
|
|
||||||
|
if (didOverwriteUserUnselectedTanProcedure) {
|
||||||
|
customer.resetSelectedTanProcedure()
|
||||||
|
}
|
||||||
|
|
||||||
return AddAccountResponse(synchronizeCustomerResponse.toResponse(), bank, customer,
|
return AddAccountResponse(synchronizeCustomerResponse.toResponse(), bank, customer,
|
||||||
transactionsOfLast90DaysResponse.isSuccessful,
|
transactionsOfLast90DaysResponse.isSuccessful,
|
||||||
transactionsOfLast90DaysResponse.bookedTransactions,
|
transactionsOfLast90DaysResponse.bookedTransactions,
|
||||||
|
@ -519,11 +532,21 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
if (customer.supportedTanProcedures.isEmpty()) { // could not retrieve supported tan procedures for user
|
if (customer.supportedTanProcedures.isEmpty()) { // could not retrieve supported tan procedures for user
|
||||||
return Response(false, noTanProcedureSelected = true)
|
return Response(false, noTanProcedureSelected = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we know user's supported tan procedures, now ask user which one to select
|
||||||
|
callback.askUserForTanProcedure(customer.supportedTanProcedures, selectSuggestedTanProcedure(customer))?.let {
|
||||||
|
customer.selectedTanProcedure = it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response(customer.isTanProcedureSelected, noTanProcedureSelected = !!!customer.isTanProcedureSelected)
|
return Response(customer.isTanProcedureSelected, noTanProcedureSelected = !!!customer.isTanProcedureSelected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun selectSuggestedTanProcedure(customer: CustomerData): TanProcedure? {
|
||||||
|
return customer.supportedTanProcedures.firstOrNull { it.displayName.contains("manuell", true) == false }
|
||||||
|
?: customer.supportedTanProcedures.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun getAndHandleResponseForMessageThatMayRequiresTan(message: MessageBuilderResult, bank: BankData,
|
protected open fun getAndHandleResponseForMessageThatMayRequiresTan(message: MessageBuilderResult, bank: BankData,
|
||||||
customer: CustomerData, dialogData: DialogData): Response {
|
customer: CustomerData, dialogData: DialogData): Response {
|
||||||
|
@ -828,13 +851,6 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
|
|
||||||
if (response.supportedTanProceduresForUser.isNotEmpty()) {
|
if (response.supportedTanProceduresForUser.isNotEmpty()) {
|
||||||
customer.supportedTanProcedures = response.supportedTanProceduresForUser.mapNotNull { findTanProcedure(it, bank) }
|
customer.supportedTanProcedures = response.supportedTanProceduresForUser.mapNotNull { findTanProcedure(it, bank) }
|
||||||
|
|
||||||
if (customer.isTanProcedureSelected == false) {
|
|
||||||
(customer.supportedTanProcedures.firstOrNull { it.displayName.contains("manuell", true) == false }
|
|
||||||
?: customer.supportedTanProcedures.firstOrNull())?.let {
|
|
||||||
customer.selectedTanProcedure = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,29 @@
|
||||||
package net.dankito.fints
|
package net.dankito.fints
|
||||||
|
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
||||||
import net.dankito.fints.model.CustomerData
|
import net.dankito.fints.model.*
|
||||||
import net.dankito.fints.model.EnterTanGeneratorAtcResult
|
|
||||||
import net.dankito.fints.model.EnterTanResult
|
|
||||||
import net.dankito.fints.model.TanChallenge
|
|
||||||
|
|
||||||
|
|
||||||
interface FinTsClientCallback {
|
interface FinTsClientCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When user did not select a TAN procedure, this method gets called so that user selects one.
|
||||||
|
*
|
||||||
|
* As almost all FinTS messages need the selected TAN procedure, this method gets called quite early.
|
||||||
|
*
|
||||||
|
* As a simplification fints4java already suggests which TAN procedure may is the best one for user.
|
||||||
|
*
|
||||||
|
* If you do not support an enter tan dialog or if your enter tan dialog supports selecting a TAN procedure, it's
|
||||||
|
* best returning [suggestedTanProcedure] and to not show an extra select TAN procedure dialog.
|
||||||
|
*/
|
||||||
|
fun askUserForTanProcedure(supportedTanProcedures: List<TanProcedure>, suggestedTanProcedure: TanProcedure?): TanProcedure?
|
||||||
|
|
||||||
fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult
|
fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method gets called for chipTan TAN generators when the bank asks the customer to synchronize her/his TAN generator.
|
* This method gets called for chipTan TAN generators when the bank asks the customer to synchronize her/his TAN generator.
|
||||||
|
*
|
||||||
|
* If you do not support entering TAN generator ATC, return [EnterTanGeneratorAtcResult.userDidNotEnterTan]
|
||||||
*/
|
*/
|
||||||
fun enterTanGeneratorAtc(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult
|
fun enterTanGeneratorAtc(customer: CustomerData, tanMedium: TanGeneratorTanMedium): EnterTanGeneratorAtcResult
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,13 @@ public class JavaShowcase {
|
||||||
customer.setSelectedTanProcedure(new TanProcedure("", Sicherheitsfunktion.PIN_TAN_911, TanProcedureType.ChipTanOptisch));
|
customer.setSelectedTanProcedure(new TanProcedure("", Sicherheitsfunktion.PIN_TAN_911, TanProcedureType.ChipTanOptisch));
|
||||||
|
|
||||||
FinTsClientCallback callback = new FinTsClientCallback() {
|
FinTsClientCallback callback = new FinTsClientCallback() {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public TanProcedure askUserForTanProcedure(@NotNull List<? extends TanProcedure> supportedTanProcedures, @Nullable TanProcedure suggestedTanProcedure) {
|
||||||
|
return suggestedTanProcedure; // simply return suggestedTanProcedure as in most cases it's the best fitting one
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public EnterTanResult enterTan(@NotNull CustomerData customer, @NotNull TanChallenge tanChallenge) {
|
public EnterTanResult enterTan(@NotNull CustomerData customer, @NotNull TanChallenge tanChallenge) {
|
||||||
|
|
|
@ -30,6 +30,10 @@ class FinTsClientTest {
|
||||||
|
|
||||||
private val callback = object : FinTsClientCallback {
|
private val callback = object : FinTsClientCallback {
|
||||||
|
|
||||||
|
override fun askUserForTanProcedure(supportedTanProcedures: List<TanProcedure>, suggestedTanProcedure: TanProcedure?): TanProcedure? {
|
||||||
|
return suggestedTanProcedure // simply return suggestedTanProcedure as in most cases it's the best fitting one
|
||||||
|
}
|
||||||
|
|
||||||
override fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult {
|
override fun enterTan(customer: CustomerData, tanChallenge: TanChallenge): EnterTanResult {
|
||||||
didAskUserToEnterTan.set(true)
|
didAskUserToEnterTan.set(true)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue