From 458da2a54238c23aa71dcc438d59ac1192e57ec8 Mon Sep 17 00:00:00 2001 From: dankito Date: Tue, 1 Sep 2020 13:54:28 +0200 Subject: [PATCH] Fixed (once again) that Comdirect returns an error when fetching user's TAN procedure with TAN procedure code '999' but returns user's TAN procedures anyway --- .../net/dankito/banking/fints/FinTsClient.kt | 23 ++++++++-------- .../client/GetUserTanProceduresResponse.kt | 26 +++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt index 0cdfa500..9ec91252 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -15,10 +15,7 @@ import net.dankito.banking.fints.model.* import net.dankito.banking.fints.response.InstituteSegmentId import net.dankito.banking.fints.response.Response import net.dankito.banking.fints.response.ResponseParser -import net.dankito.banking.fints.response.client.AddAccountResponse -import net.dankito.banking.fints.response.client.FinTsClientResponse -import net.dankito.banking.fints.response.client.GetTanMediaListResponse -import net.dankito.banking.fints.response.client.GetTransactionsResponse +import net.dankito.banking.fints.response.client.* import net.dankito.banking.fints.response.segments.* import net.dankito.banking.fints.tan.FlickerCodeDecoder import net.dankito.banking.fints.tan.TanImageDecoder @@ -113,7 +110,7 @@ open class FinTsClient( open fun getUsersTanProcedures(bank: BankData, customer: CustomerData, callback: (AddAccountResponse) -> Unit) { - // just to ensure settings are in its initial state and that bank sends use bank parameter (BPD), + // just to ensure settings are in its initial state and that bank sends us bank parameter (BPD), // user parameter (UPD) and allowed tan procedures for user (therefore the resetSelectedTanProcedure()) bank.resetBpdVersion() customer.resetUpdVersion() @@ -138,17 +135,19 @@ open class FinTsClient( } protected open fun handleGetUsersTanProceduresResponse(response: Response, dialogContext: DialogContext, callback: (AddAccountResponse) -> Unit) { - if (response.successful) { // TODO: really update data only on complete successfully response? as it may contain useful information anyway // TODO: extract method for this code part - updateBankData(dialogContext.bank, response) - updateCustomerData(dialogContext.customer, dialogContext.bank, response) + val getUsersTanProceduresResponse = GetUserTanProceduresResponse(response) + + if (getUsersTanProceduresResponse.successful) { // TODO: really update data only on complete successfully response? as it may contain useful information anyway // TODO: extract method for this code part + updateBankData(dialogContext.bank, getUsersTanProceduresResponse) + updateCustomerData(dialogContext.customer, dialogContext.bank, getUsersTanProceduresResponse) } // even though it is required by specification some banks don't support retrieving user's TAN procedure by setting TAN procedure to '999' - if (bankDoesNotSupportRetrievingUsersTanProcedures(response)) { + if (bankDoesNotSupportRetrievingUsersTanProcedures(getUsersTanProceduresResponse)) { getBankAndCustomerInfoForNewUserViaAnonymousDialog(dialogContext.bank, dialogContext.customer, callback) // TODO: should not be necessary anymore } else { - callback(AddAccountResponse(response, dialogContext.bank, dialogContext.customer)) + callback(AddAccountResponse(getUsersTanProceduresResponse, dialogContext.bank, dialogContext.customer)) } } @@ -282,7 +281,9 @@ open class FinTsClient( } } - protected open fun addAccountGetAccountBalancesAndTransactions(customer: CustomerData, bank: BankData, newUserInfoResponse: AddAccountResponse, didOverwriteUserUnselectedTanProcedure: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, callback: (AddAccountResponse) -> Unit) { + protected open fun addAccountGetAccountBalancesAndTransactions(customer: CustomerData, bank: BankData, newUserInfoResponse: AddAccountResponse, + didOverwriteUserUnselectedTanProcedure: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, + callback: (AddAccountResponse) -> Unit) { val transactionsOfLast90DaysResponses = mutableListOf() val balances = mutableMapOf() diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt new file mode 100644 index 00000000..61f87279 --- /dev/null +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt @@ -0,0 +1,26 @@ +package net.dankito.banking.fints.response.client + +import net.dankito.banking.fints.response.Response + + +open class GetUserTanProceduresResponse(bankResponse: Response) + : Response(bankResponse.didReceiveResponse, bankResponse.receivedResponse, bankResponse.receivedSegments, + bankResponse.errorMessage, bankResponse.noTanProcedureSelected, bankResponse.messageCreationError) { + + /** + * comdirect sends "9955::Unzulässiges TAN-Verfahren." even though '999' is a valid TAN procedure + * for init dialog if user's TAN procedures are not known yet + * -> check if the only error is '9955', then it's still a success. + */ + override val successful: Boolean + get() = noTanProcedureSelected == false && couldCreateMessage && didReceiveResponse + && tanRequiredButUserDidNotEnterOne == false + && (responseContainsErrors == false || containsOnlyInvalidTanProcedureError()) + + protected open fun containsOnlyInvalidTanProcedureError(): Boolean { + val errorFeedbacks = segmentFeedbacks.flatMap { it.feedbacks }.filter { it.isError } + + return errorFeedbacks.size == 1 && errorFeedbacks.first().responseCode == 9955 + } + +} \ No newline at end of file