From f5f3f34d3b3c1ed0a450f540834cfd1c6011efdf Mon Sep 17 00:00:00 2001 From: dankito Date: Mon, 21 Sep 2020 19:25:51 +0200 Subject: [PATCH] Renamed TanProcedure to TanMethod in fints4k --- .../net/dankito/banking/fints/FinTsClient.kt | 252 +++++++++--------- .../fints/callback/FinTsClientCallback.kt | 12 +- .../fints/callback/NoOpFinTsClientCallback.kt | 6 +- .../callback/SimpleFinTsClientCallback.kt | 8 +- .../banking/fints/messages/MessageBuilder.kt | 4 +- .../{ZkaTanProcedure.kt => ZkaTanMethod.kt} | 2 +- .../segmente/implementierte/Signaturkopf.kt | 4 +- .../banking/fints/model/AccountData.kt | 8 +- .../dankito/banking/fints/model/BankData.kt | 16 +- .../banking/fints/model/DialogContext.kt | 6 +- .../banking/fints/model/EnterTanResult.kt | 10 +- .../fints/model/FlickerCodeTanChallenge.kt | 6 +- .../banking/fints/model/ImageTanChallenge.kt | 6 +- .../banking/fints/model/TanChallenge.kt | 4 +- .../model/{TanProcedure.kt => TanMethod.kt} | 8 +- .../{TanProcedureType.kt => TanMethodType.kt} | 2 +- .../banking/fints/response/BankResponse.kt | 10 +- .../banking/fints/response/ResponseParser.kt | 90 +++---- .../response/client/FinTsClientResponse.kt | 8 +- .../client/GetUserTanMethodsResponse.kt | 28 ++ .../client/GetUserTanProceduresResponse.kt | 28 -- ... => SupportedTanMethodsForUserFeedback.kt} | 6 +- ...reParameters.kt => TanMethodParameters.kt} | 12 +- .../segments/TwoStepTanProcedureParameters.kt | 2 +- .../dankito/banking/fints/FinTsTestBase.kt | 2 +- .../fints/response/ResponseParserTest.kt | 24 +- .../dankito/banking/fints/JavaShowcase.java | 14 +- .../banking/fints/FinTsClientTestBase.kt | 18 +- .../bankdetails/BanksFinTsDetailsRetriever.kt | 66 ++--- .../dankito/banking/fints4kBankingClient.kt | 8 +- .../banking/mapper/fints4kModelMapper.kt | 100 +++---- 31 files changed, 385 insertions(+), 385 deletions(-) rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/{ZkaTanProcedure.kt => ZkaTanMethod.kt} (87%) rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/{TanProcedure.kt => TanMethod.kt} (88%) rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/{TanProcedureType.kt => TanMethodType.kt} (87%) create mode 100644 fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanMethodsResponse.kt delete mode 100644 fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/{SupportedTanProceduresForUserFeedback.kt => SupportedTanMethodsForUserFeedback.kt} (55%) rename fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/{TanProcedureParameters.kt => TanMethodParameters.kt} (85%) rename fints4k/src/{commonTest => jvm6Test}/java/net/dankito/banking/fints/JavaShowcase.java (95%) 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 c222151d..a45fdd65 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -115,15 +115,15 @@ open class FinTsClient( } - open fun getUsersTanProcedures(bank: BankData, callback: (FinTsClientResponse) -> Unit) { - getUsersTanProceduresInternal(bank) { + open fun getUsersTanMethods(bank: BankData, callback: (FinTsClientResponse) -> Unit) { + getUsersTanMethodsInternal(bank) { callback(FinTsClientResponse(it)) } } - protected open fun getUsersTanProceduresInternal(bank: BankData, callback: (BankResponse) -> Unit) { + protected open fun getUsersTanMethodsInternal(bank: BankData, callback: (BankResponse) -> Unit) { // 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()) + // user parameter (UPD) and allowed tan methods for user (therefore the resetSelectedTanMethod()) bank.resetBpdVersion() bank.resetUpdVersion() /** @@ -132,38 +132,38 @@ open class FinTsClient( * werden dann über den Rückmeldungscode=3920 zurückgemeldet. Im Rahmen dieses Prozesses darf keine UPD * zurückgeliefert werden und die Durchführung anderer Geschäftsvorfälle ist in einem solchen Dialog nicht erlaubt. */ - bank.resetSelectedTanProcedure() + bank.resetSelectedTanMethod() - // this is the only case where Einschritt-TAN-Verfahren is accepted: to get user's TAN procedures - val dialogContext = DialogContext(bank, product, versionOfSecurityProcedure = VersionDesSicherheitsverfahrens.Version_1) + // this is the only case where Einschritt-TAN-Verfahren is accepted: to get user's TAN methods + val dialogContext = DialogContext(bank, product, versionOfSecurityMethod = VersionDesSicherheitsverfahrens.Version_1) val message = messageBuilder.createInitDialogMessage(dialogContext) getAndHandleResponseForMessage(message, dialogContext) { response -> closeDialog(dialogContext) - handleGetUsersTanProceduresResponse(response, dialogContext, callback) + handleGetUsersTanMethodsResponse(response, dialogContext, callback) } } - protected open fun handleGetUsersTanProceduresResponse(response: BankResponse, dialogContext: DialogContext, callback: (BankResponse) -> Unit) { - val getUsersTanProceduresResponse = GetUserTanProceduresResponse(response) + protected open fun handleGetUsersTanMethodsResponse(response: BankResponse, dialogContext: DialogContext, callback: (BankResponse) -> Unit) { + val getUsersTanMethodsResponse = GetUserTanMethodsResponse(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.bank, getUsersTanProceduresResponse) + if (getUsersTanMethodsResponse.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, getUsersTanMethodsResponse) + updateCustomerData(dialogContext.bank, getUsersTanMethodsResponse) } - // 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(getUsersTanProceduresResponse)) { + // even though it is required by specification some banks don't support retrieving user's TAN method by setting TAN method to '999' + if (bankDoesNotSupportRetrievingUsersTanMethods(getUsersTanMethodsResponse)) { getBankAndCustomerInfoForNewUserViaAnonymousDialog(dialogContext.bank, callback) // TODO: should not be necessary anymore } else { - callback(getUsersTanProceduresResponse) + callback(getUsersTanMethodsResponse) } } - protected open fun bankDoesNotSupportRetrievingUsersTanProcedures(response: BankResponse): Boolean { + protected open fun bankDoesNotSupportRetrievingUsersTanMethods(response: BankResponse): Boolean { return response.successful == false && response.segmentFeedbacks.flatMap { it.feedbacks }.firstOrNull { it.responseCode == 9200 && it.message == "Gewähltes Zwei-Schritt-Verfahren nicht unterstützt." } != null @@ -175,13 +175,13 @@ open class FinTsClient( if (anonymousBankInfoResponse.successful == false) { callback(anonymousBankInfoResponse) } - else if (bank.tanProceduresSupportedByBank.isEmpty()) { // should only be a theoretical error + else if (bank.tanMethodSupportedByBank.isEmpty()) { // should only be a theoretical error callback(BankResponse(true, errorMessage = "Die TAN Verfahren der Bank konnten nicht ermittelt werden")) // TODO: translate } else { - bank.tanProceduresAvailableForUser = bank.tanProceduresSupportedByBank - getUsersTanProcedure(bank) + bank.tanMethodsAvailableForUser = bank.tanMethodSupportedByBank + getUsersTanMethod(bank) val dialogContext = DialogContext(bank, product) @@ -246,26 +246,26 @@ open class FinTsClient( val originalAreWeThatGentleToCloseDialogs = areWeThatGentleToCloseDialogs areWeThatGentleToCloseDialogs = false - /* First dialog: Get user's basic data like BPD, customer system ID and her TAN procedures */ + /* First dialog: Get user's basic data like BPD, customer system ID and her TAN methods */ - getUsersTanProceduresInternal(bank) { newUserInfoResponse -> + getUsersTanMethodsInternal(bank) { newUserInfoResponse -> if (newUserInfoResponse.successful == false) { // bank parameter (FinTS server address, ...) already seem to be wrong callback(AddAccountResponse(newUserInfoResponse, bank)) - return@getUsersTanProceduresInternal + return@getUsersTanMethodsInternal } // do not ask user for tan at this stage - var didOverwriteUserUnselectedTanProcedure = false - if (bank.isTanProcedureSelected == false && bank.tanProceduresAvailableForUser.isNotEmpty()) { + var didOverwriteUserUnselectedTanMethod = false + if (bank.isTanMethodSelected == false && bank.tanMethodsAvailableForUser.isNotEmpty()) { - if (bank.tanProceduresAvailableForUser.size == 1) { // user has only one TAN procedure -> set it and we're done - bank.selectedTanProcedure = bank.tanProceduresAvailableForUser.first() + if (bank.tanMethodsAvailableForUser.size == 1) { // user has only one TAN method -> set it and we're done + bank.selectedTanMethod = bank.tanMethodsAvailableForUser.first() } else { - didOverwriteUserUnselectedTanProcedure = true - bank.selectedTanProcedure = selectSuggestedTanProcedure(bank) ?: bank.tanProceduresAvailableForUser.first() + didOverwriteUserUnselectedTanMethod = true + bank.selectedTanMethod = selectSuggestedTanMethod(bank) ?: bank.tanMethodsAvailableForUser.first() // TODO: make settable which TAN method is the selected one, e.g. for a REST API a non visible one } } @@ -285,7 +285,7 @@ open class FinTsClient( /* Fourth dialog: Try to retrieve account balances and transactions of last 90 days without TAN */ - addAccountGetAccountBalancesAndTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, + addAccountGetAccountBalancesAndTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanMethod, originalAreWeThatGentleToCloseDialogs, callback) } } @@ -293,7 +293,7 @@ open class FinTsClient( } protected open fun addAccountGetAccountBalancesAndTransactions(bank: BankData, newUserInfoResponse: BankResponse, - didOverwriteUserUnselectedTanProcedure: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, + didOverwriteUserUnselectedTanMethod: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, callback: (AddAccountResponse) -> Unit) { // TODO: or add a default RetrievedAccountData instance for each account? val retrievedAccountData = mutableListOf() @@ -303,7 +303,7 @@ open class FinTsClient( var countRetrievedAccounts = 0 if (countAccountSupportingRetrievingTransactions == 0) { - addAccountAfterRetrievingTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, + addAccountAfterRetrievingTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanMethod, originalAreWeThatGentleToCloseDialogs, retrievedAccountData, callback) } @@ -313,7 +313,7 @@ open class FinTsClient( countRetrievedAccounts++ if (countRetrievedAccounts == countAccountSupportingRetrievingTransactions) { - addAccountAfterRetrievingTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanProcedure, originalAreWeThatGentleToCloseDialogs, + addAccountAfterRetrievingTransactions(bank, newUserInfoResponse, didOverwriteUserUnselectedTanMethod, originalAreWeThatGentleToCloseDialogs, retrievedAccountData, callback) } } @@ -321,11 +321,11 @@ open class FinTsClient( } protected open fun addAccountAfterRetrievingTransactions(bank: BankData, newUserInfoResponse: BankResponse, - didOverwriteUserUnselectedTanProcedure: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, + didOverwriteUserUnselectedTanMethod: Boolean, originalAreWeThatGentleToCloseDialogs: Boolean, retrievedAccountData: List, callback: (AddAccountResponse) -> Unit) { - if (didOverwriteUserUnselectedTanProcedure) { - bank.resetSelectedTanProcedure() + if (didOverwriteUserUnselectedTanMethod) { + bank.resetSelectedTanMethod() } areWeThatGentleToCloseDialogs = originalAreWeThatGentleToCloseDialogs @@ -440,7 +440,7 @@ open class FinTsClient( } private fun handleGetTanMediaListResponse(response: BankResponse, bank: BankData, callback: (GetTanMediaListResponse) -> Unit) { - // TAN media list (= TAN generator list) is only returned for users with chipTAN TAN procedures + // TAN media list (= TAN generator list) is only returned for users with chipTAN TAN methods val tanMediaList = if (response.successful == false) null else response.getFirstSegmentById(InstituteSegmentId.TanMediaList) @@ -532,16 +532,16 @@ open class FinTsClient( protected open fun initDialog(dialogContext: DialogContext, callback: (BankResponse) -> Unit) { - // we first need to retrieve supported tan procedures and jobs before we can do anything + // we first need to retrieve supported tan methods and jobs before we can do anything ensureBasicBankDataRetrieved(dialogContext.bank) { retrieveBasicBankDataResponse -> if (retrieveBasicBankDataResponse.successful == false) { callback(retrieveBasicBankDataResponse) } else { - // as in the next step we have to supply user's tan procedure, ensure user selected his or her - ensureTanProcedureIsSelected(dialogContext.bank) { tanProcedureSelectedResponse -> - if (tanProcedureSelectedResponse.successful == false) { - callback(tanProcedureSelectedResponse) + // as in the next step we have to supply user's tan method, ensure user selected his or her + ensureTanMethodIsSelected(dialogContext.bank) { tanMethodSelectedResponse -> + if (tanMethodSelectedResponse.successful == false) { + callback(tanMethodSelectedResponse) } else { initDialogAfterSuccessfulChecks(dialogContext, callback) @@ -595,13 +595,13 @@ open class FinTsClient( protected open fun ensureBasicBankDataRetrieved(bank: BankData, callback: (BankResponse) -> Unit) { - if (bank.tanProceduresSupportedByBank.isEmpty() || bank.supportedJobs.isEmpty()) { - getUsersTanProceduresInternal(bank) { getBankInfoResponse -> - if (getBankInfoResponse.successful == false || bank.tanProceduresSupportedByBank.isEmpty() + if (bank.tanMethodSupportedByBank.isEmpty() || bank.supportedJobs.isEmpty()) { + getUsersTanMethodsInternal(bank) { getBankInfoResponse -> + if (getBankInfoResponse.successful == false || bank.tanMethodSupportedByBank.isEmpty() || bank.supportedJobs.isEmpty()) { callback(BankResponse(false, errorMessage = - "Could not retrieve basic bank data like supported tan procedures or supported jobs")) // TODO: translate // TODO: add as messageToShowToUser + "Could not retrieve basic bank data like supported tan methods or supported jobs")) // TODO: translate // TODO: add as messageToShowToUser } else { callback(BankResponse(true)) @@ -613,48 +613,48 @@ open class FinTsClient( } } - protected open fun ensureTanProcedureIsSelected(bank: BankData, callback: (BankResponse) -> Unit) { - if (bank.isTanProcedureSelected == false) { - if (bank.tanProceduresAvailableForUser.isEmpty()) { - getUsersTanProceduresInternal(bank) { - if (bank.tanProceduresAvailableForUser.isEmpty()) { // could not retrieve supported tan procedures for user - callback(BankResponse(false, noTanProcedureSelected = true)) + protected open fun ensureTanMethodIsSelected(bank: BankData, callback: (BankResponse) -> Unit) { + if (bank.isTanMethodSelected == false) { + if (bank.tanMethodsAvailableForUser.isEmpty()) { + getUsersTanMethodsInternal(bank) { + if (bank.tanMethodsAvailableForUser.isEmpty()) { // could not retrieve supported tan methods for user + callback(BankResponse(false, noTanMethodSelected = true)) } else { - getUsersTanProcedure(bank) - callback(BankResponse(bank.isTanProcedureSelected, noTanProcedureSelected = !!!bank.isTanProcedureSelected)) + getUsersTanMethod(bank) + callback(BankResponse(bank.isTanMethodSelected, noTanMethodSelected = !!!bank.isTanMethodSelected)) } } } else { - getUsersTanProcedure(bank) - callback(BankResponse(bank.isTanProcedureSelected, noTanProcedureSelected = !!!bank.isTanProcedureSelected)) + getUsersTanMethod(bank) + callback(BankResponse(bank.isTanMethodSelected, noTanMethodSelected = !!!bank.isTanMethodSelected)) } } else { - callback(BankResponse(bank.isTanProcedureSelected, noTanProcedureSelected = !!!bank.isTanProcedureSelected)) + callback(BankResponse(bank.isTanMethodSelected, noTanMethodSelected = !!!bank.isTanMethodSelected)) } } - protected open fun getUsersTanProcedure(bank: BankData) { - if (bank.tanProceduresAvailableForUser.size == 1) { // user has only one TAN procedure -> set it and we're done - bank.selectedTanProcedure = bank.tanProceduresAvailableForUser.first() + protected open fun getUsersTanMethod(bank: BankData) { + if (bank.tanMethodsAvailableForUser.size == 1) { // user has only one TAN method -> set it and we're done + bank.selectedTanMethod = bank.tanMethodsAvailableForUser.first() } else { - // we know user's supported tan procedures, now ask user which one to select - callback.askUserForTanProcedure(bank.tanProceduresAvailableForUser, selectSuggestedTanProcedure(bank)) { selectedTanProcedure -> - selectedTanProcedure?.let { - bank.selectedTanProcedure = selectedTanProcedure + // we know user's supported tan methods, now ask user which one to select + callback.askUserForTanMethod(bank.tanMethodsAvailableForUser, selectSuggestedTanMethod(bank)) { selectedTanMethod -> + selectedTanMethod?.let { + bank.selectedTanMethod = selectedTanMethod } } } } - protected open fun selectSuggestedTanProcedure(bank: BankData): TanProcedure? { - return bank.tanProceduresAvailableForUser.firstOrNull { it.type != TanProcedureType.ChipTanUsb && it.type != TanProcedureType.SmsTan && it.type != TanProcedureType.ChipTanManuell } - ?: bank.tanProceduresAvailableForUser.firstOrNull { it.type != TanProcedureType.ChipTanUsb && it.type != TanProcedureType.SmsTan } - ?: bank.tanProceduresAvailableForUser.firstOrNull { it.type != TanProcedureType.ChipTanUsb } - ?: bank.tanProceduresAvailableForUser.firstOrNull() + protected open fun selectSuggestedTanMethod(bank: BankData): TanMethod? { + return bank.tanMethodsAvailableForUser.firstOrNull { it.type != TanMethodType.ChipTanUsb && it.type != TanMethodType.SmsTan && it.type != TanMethodType.ChipTanManuell } + ?: bank.tanMethodsAvailableForUser.firstOrNull { it.type != TanMethodType.ChipTanUsb && it.type != TanMethodType.SmsTan } + ?: bank.tanMethodsAvailableForUser.firstOrNull { it.type != TanMethodType.ChipTanUsb } + ?: bank.tanMethodsAvailableForUser.firstOrNull() } @@ -855,36 +855,36 @@ open class FinTsClient( } protected open fun createTanChallenge(tanResponse: TanResponse, bank: BankData): TanChallenge { - // TODO: is this true for all tan procedures? + // TODO: is this true for all tan methods? val messageToShowToUser = tanResponse.challenge ?: "" val challenge = tanResponse.challengeHHD_UC ?: "" - val tanProcedure = bank.selectedTanProcedure + val tanMethod = bank.selectedTanMethod - return when (tanProcedure.type) { - TanProcedureType.ChipTanFlickercode -> - FlickerCodeTanChallenge(FlickerCodeDecoder().decodeChallenge(challenge, tanProcedure.hhdVersion ?: HHDVersion.HHD_1_4), // HHD 1.4 is currently the most used version - messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier) + return when (tanMethod.type) { + TanMethodType.ChipTanFlickercode -> + FlickerCodeTanChallenge(FlickerCodeDecoder().decodeChallenge(challenge, tanMethod.hhdVersion ?: HHDVersion.HHD_1_4), // HHD 1.4 is currently the most used version + messageToShowToUser, challenge, tanMethod, tanResponse.tanMediaIdentifier) - TanProcedureType.ChipTanQrCode, TanProcedureType.ChipTanPhotoTanMatrixCode, - TanProcedureType.QrCode, TanProcedureType.photoTan -> - ImageTanChallenge(TanImageDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier) + TanMethodType.ChipTanQrCode, TanMethodType.ChipTanPhotoTanMatrixCode, + TanMethodType.QrCode, TanMethodType.photoTan -> + ImageTanChallenge(TanImageDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanMethod, tanResponse.tanMediaIdentifier) - else -> TanChallenge(messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier) + else -> TanChallenge(messageToShowToUser, challenge, tanMethod, tanResponse.tanMediaIdentifier) } } protected open fun handleEnterTanResult(enteredTanResult: EnterTanResult, tanResponse: TanResponse, response: BankResponse, dialogContext: DialogContext, callback: (BankResponse) -> Unit) { - if (enteredTanResult.changeTanProcedureTo != null) { - handleUserAsksToChangeTanProcedureAndResendLastMessage(enteredTanResult.changeTanProcedureTo, dialogContext, callback) + if (enteredTanResult.changeTanMethodTo != null) { + handleUserAsksToChangeTanMethodAndResendLastMessage(enteredTanResult.changeTanMethodTo, dialogContext, callback) } else if (enteredTanResult.changeTanMediumTo is TanGeneratorTanMedium) { handleUserAsksToChangeTanMediumAndResendLastMessage(enteredTanResult.changeTanMediumTo, dialogContext, enteredTanResult.changeTanMediumResultCallback, callback) } else if (enteredTanResult.enteredTan == null) { - // i tried to send a HKTAN with cancelJob = true but then i saw there are no tan procedures that support cancellation (at least not at my bank) + // i tried to send a HKTAN with cancelJob = true but then i saw there are no tan methods that support cancellation (at least not at my bank) // but it's not required anyway, tan times out after some time. Simply don't respond anything and close dialog response.tanRequiredButUserDidNotEnterOne = true @@ -902,9 +902,9 @@ open class FinTsClient( getAndHandleResponseForMessage(message, dialogContext, callback) } - protected open fun handleUserAsksToChangeTanProcedureAndResendLastMessage(changeTanProcedureTo: TanProcedure, dialogContext: DialogContext, callback: (BankResponse) -> Unit) { + protected open fun handleUserAsksToChangeTanMethodAndResendLastMessage(changeTanMethodTo: TanMethod, dialogContext: DialogContext, callback: (BankResponse) -> Unit) { - dialogContext.bank.selectedTanProcedure = changeTanProcedureTo + dialogContext.bank.selectedTanMethod = changeTanMethodTo val lastCreatedMessage = dialogContext.currentMessage @@ -958,7 +958,7 @@ open class FinTsClient( } } else { - val errorMessage = "There's no last action (like retrieve account transactions, transfer money, ...) to re-send with new TAN procedure. Probably an internal programming error." // TODO: translate + val errorMessage = "There's no last action (like retrieve account transactions, transfer money, ...) to re-send with new TAN method. Probably an internal programming error." // TODO: translate callback(BankResponse(false, errorMessage = errorMessage)) // should never come to this } } @@ -982,7 +982,7 @@ open class FinTsClient( } response.getFirstSegmentById(InstituteSegmentId.TanInfo)?.let { tanInfo -> - bank.tanProceduresSupportedByBank = mapToTanProcedures(tanInfo) + bank.tanMethodSupportedByBank = mapToTanMethods(tanInfo) } response.getFirstSegmentById(InstituteSegmentId.CommunicationInfo)?.let { communicationInfo -> @@ -1097,17 +1097,17 @@ open class FinTsClient( } } - if (response.supportedTanProceduresForUser.isNotEmpty()) { - bank.tanProceduresAvailableForUser = response.supportedTanProceduresForUser.mapNotNull { findTanProcedure(it, bank) } + if (response.supportedTanMethodsForUser.isNotEmpty()) { + bank.tanMethodsAvailableForUser = response.supportedTanMethodsForUser.mapNotNull { findTanMethod(it, bank) } - if (bank.tanProceduresAvailableForUser.firstOrNull { it.securityFunction == bank.selectedTanProcedure.securityFunction } == null) { // supportedTanProcedures don't contain selectedTanProcedure anymore - bank.resetSelectedTanProcedure() + if (bank.tanMethodsAvailableForUser.firstOrNull { it.securityFunction == bank.selectedTanMethod.securityFunction } == null) { // supportedTanMethods don't contain selectedTanMethod anymore + bank.resetSelectedTanMethod() } } } - protected open fun findTanProcedure(securityFunction: Sicherheitsfunktion, bank: BankData): TanProcedure? { - return bank.tanProceduresSupportedByBank.firstOrNull { it.securityFunction == securityFunction } + protected open fun findTanMethod(securityFunction: Sicherheitsfunktion, bank: BankData): TanMethod? { + return bank.tanMethodSupportedByBank.firstOrNull { it.securityFunction == securityFunction } } protected open fun setAllowedJobsForAccount(bank: BankData, account: AccountData, supportedJobs: List) { @@ -1127,83 +1127,83 @@ open class FinTsClient( account.setSupportsFeature(AccountFeature.InstantPayment, messageBuilder.supportsSepaInstantPaymentBankTransfer(bank, account)) } - protected open fun mapToTanProcedures(tanInfo: TanInfo): List { - return tanInfo.tanProcedureParameters.procedureParameters.mapNotNull { - mapToTanProcedure(it) + protected open fun mapToTanMethods(tanInfo: TanInfo): List { + return tanInfo.tanProcedureParameters.methodParameters.mapNotNull { + mapToTanMethod(it) } } - protected open fun mapToTanProcedure(parameters: TanProcedureParameters): TanProcedure? { - val procedureName = parameters.procedureName + protected open fun mapToTanMethod(parameters: TanMethodParameters): TanMethod? { + val methodName = parameters.methodName // we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2 - if (procedureName.toLowerCase() == "itan") { + if (methodName.toLowerCase() == "itan") { return null } - return TanProcedure(procedureName, parameters.securityFunction, - mapToTanProcedureType(parameters) ?: TanProcedureType.EnterTan, mapHhdVersion(parameters), + return TanMethod(methodName, parameters.securityFunction, + mapToTanMethodType(parameters) ?: TanMethodType.EnterTan, mapHhdVersion(parameters), parameters.maxTanInputLength, parameters.allowedTanFormat, parameters.nameOfTanMediaRequired == BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsMussAngegebenWerden) } - protected open fun mapToTanProcedureType(parameters: TanProcedureParameters): TanProcedureType? { - val name = parameters.procedureName.toLowerCase() + protected open fun mapToTanMethodType(parameters: TanMethodParameters): TanMethodType? { + val name = parameters.methodName.toLowerCase() return when { // names are like 'chipTAN (comfort) manuell', 'Smart(-)TAN plus (manuell)' and // technical identification is 'HHD'. Exception: there's one that states itself as 'chipTAN (Manuell)' - // but its ZkaTanProcedure is set to 'HHDOPT1' -> handle ChipTanManuell before ChipTanFlickercode - parameters.zkaTanProcedure == ZkaTanProcedure.HHD || name.contains("manuell") -> - TanProcedureType.ChipTanManuell + // but its ZkaTanMethod is set to 'HHDOPT1' -> handle ChipTanManuell before ChipTanFlickercode + parameters.zkaTanMethod == ZkaTanMethod.HHD || name.contains("manuell") -> + TanMethodType.ChipTanManuell // names are like 'chipTAN optisch/comfort', 'SmartTAN (plus) optic/USB', 'chipTAN (Flicker)' and // technical identification is 'HHDOPT1' - parameters.zkaTanProcedure == ZkaTanProcedure.HHDOPT1 || - tanProcedureNameContains(name, "optisch", "optic", "comfort", "flicker") -> - TanProcedureType.ChipTanFlickercode + parameters.zkaTanMethod == ZkaTanMethod.HHDOPT1 || + tanMethodNameContains(name, "optisch", "optic", "comfort", "flicker") -> + TanMethodType.ChipTanFlickercode - // 'Smart-TAN plus optisch / USB' seems to be a Flickertan procedure -> test for 'optisch' first - name.contains("usb") -> TanProcedureType.ChipTanUsb + // 'Smart-TAN plus optisch / USB' seems to be a Flickertan method -> test for 'optisch' first + name.contains("usb") -> TanMethodType.ChipTanUsb // QRTAN+ from 1822 direct has nothing to do with chipTAN QR. name.contains("qr") -> { - if (tanProcedureNameContains(name, "chipTAN", "Smart")) TanProcedureType.ChipTanQrCode - else TanProcedureType.QrCode + if (tanMethodNameContains(name, "chipTAN", "Smart")) TanMethodType.ChipTanQrCode + else TanMethodType.QrCode } // photoTAN from Commerzbank (comdirect), Deutsche Bank, norisbank has nothing to do with chipTAN photo name.contains("photo") -> { // e.g. 'Smart-TAN photo' / description 'Challenge' - if (tanProcedureNameContains(name, "chipTAN", "Smart")) TanProcedureType.ChipTanPhotoTanMatrixCode + if (tanMethodNameContains(name, "chipTAN", "Smart")) TanMethodType.ChipTanPhotoTanMatrixCode // e.g. 'photoTAN-Verfahren', description 'Freigabe durch photoTAN' - else TanProcedureType.photoTan + else TanMethodType.photoTan } - tanProcedureNameContains(name, "SMS", "mobile", "mTAN") -> TanProcedureType.SmsTan + tanMethodNameContains(name, "SMS", "mobile", "mTAN") -> TanMethodType.SmsTan // 'flateXSecure' identifies itself as 'PPTAN' instead of 'AppTAN' // 'activeTAN-Verfahren' can actually be used either with an app or a reader; it's like chipTAN QR but without a chip card - tanProcedureNameContains(name, "push", "app", "BestSign", "SecureGo", "TAN2go", "activeTAN", "easyTAN", "SecurePlus", "TAN+") - || technicalTanProcedureIdentificationContains(parameters, "SECURESIGN", "PPTAN") -> - TanProcedureType.AppTan + tanMethodNameContains(name, "push", "app", "BestSign", "SecureGo", "TAN2go", "activeTAN", "easyTAN", "SecurePlus", "TAN+") + || technicalTanMethodIdentificationContains(parameters, "SECURESIGN", "PPTAN") -> + TanMethodType.AppTan // we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2 else -> null } } - protected open fun mapHhdVersion(parameters: TanProcedureParameters): HHDVersion? { + protected open fun mapHhdVersion(parameters: TanMethodParameters): HHDVersion? { return when { - technicalTanProcedureIdentificationContains(parameters, "HHD1.4") -> HHDVersion.HHD_1_4 - technicalTanProcedureIdentificationContains(parameters, "HHD1.3") -> HHDVersion.HHD_1_3 - parameters.versionZkaTanProcedure?.contains("1.4") == true -> HHDVersion.HHD_1_4 - parameters.versionZkaTanProcedure?.contains("1.3") == true -> HHDVersion.HHD_1_4 + technicalTanMethodIdentificationContains(parameters, "HHD1.4") -> HHDVersion.HHD_1_4 + technicalTanMethodIdentificationContains(parameters, "HHD1.3") -> HHDVersion.HHD_1_3 + parameters.versionZkaTanMethod?.contains("1.4") == true -> HHDVersion.HHD_1_4 + parameters.versionZkaTanMethod?.contains("1.3") == true -> HHDVersion.HHD_1_4 else -> null } } - protected open fun tanProcedureNameContains(name: String, vararg namesToTest: String): Boolean { + protected open fun tanMethodNameContains(name: String, vararg namesToTest: String): Boolean { namesToTest.forEach { nameToTest -> if (name.contains(nameToTest.toLowerCase())) { return true @@ -1213,9 +1213,9 @@ open class FinTsClient( return false } - protected open fun technicalTanProcedureIdentificationContains(parameters: TanProcedureParameters, vararg valuesToTest: String): Boolean { + protected open fun technicalTanMethodIdentificationContains(parameters: TanMethodParameters, vararg valuesToTest: String): Boolean { valuesToTest.forEach { valueToTest -> - if (parameters.technicalTanProcedureIdentification.contains(valueToTest, true)) { + if (parameters.technicalTanMethodIdentification.contains(valueToTest, true)) { return true } } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/FinTsClientCallback.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/FinTsClientCallback.kt index 64799c51..715de801 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/FinTsClientCallback.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/FinTsClientCallback.kt @@ -7,16 +7,16 @@ import net.dankito.banking.fints.model.* interface FinTsClientCallback { /** - * When user did not select a TAN procedure, this method gets called so that user selects one. + * When user did not select a TAN method, 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 almost all FinTS messages need the selected TAN method, this method gets called quite early. * - * As a simplification fints4k already suggests which TAN procedure may is the best one for user. + * As a simplification fints4k already suggests which TAN method 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. + * If you do not support an enter tan dialog or if your enter tan dialog supports selecting a TAN method, it's + * best returning [suggestedTanMethod] and to not show an extra select TAN method dialog. */ - fun askUserForTanProcedure(supportedTanProcedures: List, suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) + fun askUserForTanMethod(supportedTanMethods: List, suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) fun enterTan(bank: BankData, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/NoOpFinTsClientCallback.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/NoOpFinTsClientCallback.kt index ccd5f6df..eb1533d7 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/NoOpFinTsClientCallback.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/NoOpFinTsClientCallback.kt @@ -6,10 +6,10 @@ import net.dankito.banking.fints.model.* open class NoOpFinTsClientCallback : FinTsClientCallback { - override fun askUserForTanProcedure(supportedTanProcedures: List, - suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) { + override fun askUserForTanMethod(supportedTanMethods: List, + suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) { - callback(suggestedTanProcedure) + callback(suggestedTanMethod) } override fun enterTan(bank: BankData, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/SimpleFinTsClientCallback.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/SimpleFinTsClientCallback.kt index 76ec7537..4c325d91 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/SimpleFinTsClientCallback.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/callback/SimpleFinTsClientCallback.kt @@ -7,13 +7,13 @@ import net.dankito.banking.fints.model.* open class SimpleFinTsClientCallback( protected val enterTan: ((bank: BankData, tanChallenge: TanChallenge) -> EnterTanResult)? = null, protected val enterTanGeneratorAtc: ((bank: BankData, tanMedium: TanGeneratorTanMedium) -> EnterTanGeneratorAtcResult)? = null, - protected val askUserForTanProcedure: ((supportedTanProcedures: List, suggestedTanProcedure: TanProcedure?) -> TanProcedure?)? = null + protected val askUserForTanMethod: ((supportedTanMethods: List, suggestedTanMethod: TanMethod?) -> TanMethod?)? = null ) : FinTsClientCallback { - override fun askUserForTanProcedure(supportedTanProcedures: List, - suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) { + override fun askUserForTanMethod(supportedTanMethods: List, + suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) { - callback(askUserForTanProcedure?.invoke(supportedTanProcedures, suggestedTanProcedure) ?: suggestedTanProcedure) + callback(askUserForTanMethod?.invoke(supportedTanMethods, suggestedTanMethod) ?: suggestedTanMethod) } override fun enterTan(bank: BankData, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt index 5b048bcb..60cd24a8 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/MessageBuilder.kt @@ -117,7 +117,7 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg if (segmentIdForTwoStepTanProcess != null) { segments.add(createTwoStepTanSegment(segmentIdForTwoStepTanProcess, dialogContext)) } - else if (dialogContext.bank.isTanProcedureSelected) { + else if (dialogContext.bank.isTanMethodSelected) { segments.add(createTwoStepTanSegment(CustomerSegmentId.Identification, dialogContext)) } @@ -484,7 +484,7 @@ open class MessageBuilder(protected val generator: ISegmentNumberGenerator = Seg protected open fun getTanMediaIdentifierIfRequired(dialogContext: DialogContext): String? { val bank = dialogContext.bank - if (bank.isTanProcedureSelected && bank.selectedTanProcedure.nameOfTanMediaRequired) { + if (bank.isTanMethodSelected && bank.selectedTanMethod.nameOfTanMediaRequired) { return bank.tanMedia.firstOrNull { it.mediumName != null }?.mediumName } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanProcedure.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanMethod.kt similarity index 87% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanProcedure.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanMethod.kt index 093e64bf..c10b5135 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanProcedure.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/datenelemente/implementierte/tan/ZkaTanMethod.kt @@ -1,7 +1,7 @@ package net.dankito.banking.fints.messages.datenelemente.implementierte.tan -enum class ZkaTanProcedure { +enum class ZkaTanMethod { HHD, diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/Signaturkopf.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/Signaturkopf.kt index 81c6f98d..b7ecab04 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/Signaturkopf.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/messages/segmente/implementierte/Signaturkopf.kt @@ -38,8 +38,8 @@ open class Signaturkopf( Sicherheitsprofil( Sicherheitsverfahren.PIN_TAN_Verfahren, versionOfSecurityProcedure - ), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure; the only exception is the first dialog to get user's TAN procedures which allows to use one step tan procedure (as we don't know TAN procedures yet) - SicherheitsfunktionKodiert(bank.selectedTanProcedure.securityFunction), + ), // fints4k only supports Pin/Tan and PSD2 requires two step tan procedure; the only exception is the first dialog to get user's TAN methods which allows to use one step tan procedure (as we don't know TAN method yet) + SicherheitsfunktionKodiert(bank.selectedTanMethod.securityFunction), Sicherheitskontrollreferenz(securityControlReference), // allowed: <>0 BereichDerSicherheitsapplikationKodiert(BereichDerSicherheitsapplikation.SignaturkopfUndHBCINutzdaten), // allowed: 1 ? RolleDesSicherheitslieferantenKodiert(), // allowed: 1 diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountData.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountData.kt index 6c8a3533..aa06aba2 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountData.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/AccountData.kt @@ -24,19 +24,19 @@ open class AccountData( internal constructor() : this("", null, Laenderkennzeichen.Germany, "", null, "", null, null, "", null, null, listOf()) // for object deserializers - protected open val supportedFeatures = mutableSetOf() + protected open val _supportedFeatures = mutableSetOf() open fun supportsFeature(feature: AccountFeature): Boolean { - return supportedFeatures.contains(feature) + return _supportedFeatures.contains(feature) } open fun setSupportsFeature(feature: AccountFeature, isSupported: Boolean) { if (isSupported) { - supportedFeatures.add(feature) + _supportedFeatures.add(feature) } else { - supportedFeatures.remove(feature) + _supportedFeatures.remove(feature) } } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/BankData.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/BankData.kt index d56c0278..b50e406f 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/BankData.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/BankData.kt @@ -24,9 +24,9 @@ open class BankData( open var customerName: String = "", open var updVersion: Int = UPDVersion.VersionNotReceivedYet, - open var tanProceduresSupportedByBank: List = listOf(), - open var tanProceduresAvailableForUser: List = listOf(), - open var selectedTanProcedure: TanProcedure = TanProcedureNotSelected, + open var tanMethodSupportedByBank: List = listOf(), + open var tanMethodsAvailableForUser: List = listOf(), + open var selectedTanMethod: TanMethod = TanMethodNotSelected, open var tanMedia: List = listOf(), open var changeTanMediumParameters: ChangeTanMediaParameters? = null, open var pinInfo: PinInfo? = null, @@ -51,7 +51,7 @@ open class BankData( companion object { val SecurityFunctionNotSelected = Sicherheitsfunktion.Einschritt_Verfahren - val TanProcedureNotSelected = TanProcedure("NOT_SELECTED", SecurityFunctionNotSelected, TanProcedureType.EnterTan) + val TanMethodNotSelected = TanMethod("NOT_SELECTED", SecurityFunctionNotSelected, TanMethodType.EnterTan) // TODO: is the BIC really needed at anonymous dialog init? fun anonymous(bankCode: String, finTs3ServerAddress: String, bic: String): BankData { @@ -70,8 +70,8 @@ open class BankData( get() = ArrayList(_accounts) - open val isTanProcedureSelected: Boolean - get() = selectedTanProcedure != TanProcedureNotSelected + open val isTanMethodSelected: Boolean + get() = selectedTanMethod != TanMethodNotSelected open fun addAccount(account: AccountData) { @@ -105,8 +105,8 @@ open class BankData( updVersion = UPDVersion.VersionNotReceivedYet } - open fun resetSelectedTanProcedure() { - selectedTanProcedure = TanProcedureNotSelected + open fun resetSelectedTanMethod() { + selectedTanMethod = TanMethodNotSelected } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/DialogContext.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/DialogContext.kt index 5fdaf2f7..b7f7ee4d 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/DialogContext.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/DialogContext.kt @@ -13,10 +13,10 @@ open class DialogContext( var dialogId: String = InitialDialogId, var response: BankResponse? = null, var didBankCloseDialog: Boolean = false, - versionOfSecurityProcedure: VersionDesSicherheitsverfahrens = VersionDesSicherheitsverfahrens.Version_2, - var previousMessageInDialog: MessageBuilderResult? = null, // for PinTan almost always the case except for getting a user's TAN procedures + versionOfSecurityMethod: VersionDesSicherheitsverfahrens = VersionDesSicherheitsverfahrens.Version_2, + var previousMessageInDialog: MessageBuilderResult? = null, // for PinTan almost always the case except for getting a user's TAN methods var chunkedResponseHandler: ((BankResponse) -> Unit)? = null -) : MessageBaseData(bank, product, versionOfSecurityProcedure) { +) : MessageBaseData(bank, product, versionOfSecurityMethod) { companion object { const val InitialDialogId = "0" diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/EnterTanResult.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/EnterTanResult.kt index fb23e8ff..dafdebe3 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/EnterTanResult.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/EnterTanResult.kt @@ -6,7 +6,7 @@ import net.dankito.banking.fints.response.client.FinTsClientResponse open class EnterTanResult protected constructor( val enteredTan: String?, - val changeTanProcedureTo: TanProcedure? = null, + val changeTanMethodTo: TanMethod? = null, val changeTanMediumTo: TanMedium? = null, val changeTanMediumResultCallback: ((FinTsClientResponse) -> Unit)? = null ) { @@ -21,8 +21,8 @@ open class EnterTanResult protected constructor( return EnterTanResult(null) } - fun userAsksToChangeTanProcedure(changeTanProcedureTo: TanProcedure): EnterTanResult { - return EnterTanResult(null, changeTanProcedureTo) + fun userAsksToChangeTanMethod(changeTanMethodTo: TanMethod): EnterTanResult { + return EnterTanResult(null, changeTanMethodTo) } fun userAsksToChangeTanMedium(changeTanMediumTo: TanMedium, changeTanMediumResultCallback: ((FinTsClientResponse) -> Unit)?): EnterTanResult { @@ -32,8 +32,8 @@ open class EnterTanResult protected constructor( } override fun toString(): String { - if (changeTanProcedureTo != null) { - return "User asks to change TAN procedure to $changeTanProcedureTo" + if (changeTanMethodTo != null) { + return "User asks to change TAN method to $changeTanMethodTo" } if (changeTanMediumTo != null) { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/FlickerCodeTanChallenge.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/FlickerCodeTanChallenge.kt index 08a5f4a2..c463d89b 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/FlickerCodeTanChallenge.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/FlickerCodeTanChallenge.kt @@ -7,12 +7,12 @@ open class FlickerCodeTanChallenge( val flickerCode: FlickerCode, messageToShowToUser: String, challenge: String, - tanProcedure: TanProcedure, + tanMethod: TanMethod, tanMediaIdentifier: String? -) : TanChallenge(messageToShowToUser, challenge, tanProcedure, tanMediaIdentifier) { +) : TanChallenge(messageToShowToUser, challenge, tanMethod, tanMediaIdentifier) { override fun toString(): String { - return "$tanProcedure (medium: $tanMediaIdentifier) $flickerCode: $messageToShowToUser" + return "$tanMethod (medium: $tanMediaIdentifier) $flickerCode: $messageToShowToUser" } } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/ImageTanChallenge.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/ImageTanChallenge.kt index 039feaaa..39140bcb 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/ImageTanChallenge.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/ImageTanChallenge.kt @@ -7,12 +7,12 @@ open class ImageTanChallenge( val image: TanImage, messageToShowToUser: String, challenge: String, - tanProcedure: TanProcedure, + tanMethod: TanMethod, tanMediaIdentifier: String? -) : TanChallenge(messageToShowToUser, challenge, tanProcedure, tanMediaIdentifier) { +) : TanChallenge(messageToShowToUser, challenge, tanMethod, tanMediaIdentifier) { override fun toString(): String { - return "$tanProcedure (medium: $tanMediaIdentifier) $image: $messageToShowToUser" + return "$tanMethod (medium: $tanMediaIdentifier) $image: $messageToShowToUser" } } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanChallenge.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanChallenge.kt index d9d733a7..9464a035 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanChallenge.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanChallenge.kt @@ -4,12 +4,12 @@ package net.dankito.banking.fints.model open class TanChallenge( val messageToShowToUser: String, val challenge: String, - val tanProcedure: TanProcedure, + val tanMethod: TanMethod, val tanMediaIdentifier: String? ) { override fun toString(): String { - return "$tanProcedure (medium: $tanMediaIdentifier): $messageToShowToUser" + return "$tanMethod (medium: $tanMediaIdentifier): $messageToShowToUser" } } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedure.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethod.kt similarity index 88% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedure.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethod.kt index 2670a672..717e2fc8 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedure.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethod.kt @@ -4,10 +4,10 @@ import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur. import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat -open class TanProcedure( +open class TanMethod( open val displayName: String, open val securityFunction: Sicherheitsfunktion, - open val type: TanProcedureType, + open val type: TanMethodType, open val hhdVersion: HHDVersion? = null, open val maxTanInputLength: Int? = null, open val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric, @@ -15,13 +15,13 @@ open class TanProcedure( ) { - internal constructor() : this("", Sicherheitsfunktion.Einschritt_Verfahren, TanProcedureType.EnterTan) // for object deserializers + internal constructor() : this("", Sicherheitsfunktion.Einschritt_Verfahren, TanMethodType.EnterTan) // for object deserializers override fun equals(other: Any?): Boolean { if (this === other) return true - if (other !is TanProcedure) return false + if (other !is TanMethod) return false if (displayName != other.displayName) return false if (securityFunction != other.securityFunction) return false diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedureType.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethodType.kt similarity index 87% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedureType.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethodType.kt index d0b55c65..f22d0a7b 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanProcedureType.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/TanMethodType.kt @@ -1,7 +1,7 @@ package net.dankito.banking.fints.model -enum class TanProcedureType { +enum class TanMethodType { EnterTan, diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/BankResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/BankResponse.kt index d4cc4d2c..79ef2609 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/BankResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/BankResponse.kt @@ -17,7 +17,7 @@ open class BankResponse( * When a serious error occurred during web request or response parsing. */ val errorMessage: String? = null, - val noTanProcedureSelected: Boolean = false, + val noTanMethodSelected: Boolean = false, val messageCreationError: MessageBuilderResult? = null ) { @@ -32,7 +32,7 @@ open class BankResponse( open var tanRequiredButWeWereToldToAbortIfSo = false open val successful: Boolean - get() = noTanProcedureSelected == false && couldCreateMessage && didReceiveResponse + get() = noTanMethodSelected == false && couldCreateMessage && didReceiveResponse && responseContainsErrors == false && tanRequiredButUserDidNotEnterOne == false && tanRequiredButWeWereToldToAbortIfSo == false @@ -89,10 +89,10 @@ open class BankResponse( open val supportedJobs: List get() = receivedSegments.mapNotNull { it as? JobParameters } - open val supportedTanProceduresForUser: List + open val supportedTanMethodsForUser: List get() = segmentFeedbacks.flatMap { it.feedbacks } - .filterIsInstance() - .flatMap { it.supportedTanProcedures } + .filterIsInstance() + .flatMap { it.supportedTanMethods } open fun getFirstSegmentById(id: ISegmentId): T? { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt index ed87172e..00f7d99d 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/ResponseParser.kt @@ -33,7 +33,7 @@ open class ResponseParser( const val AufsetzpunktResponseCode = 3040 - const val SupportedTanProceduresForUserResponseCode = 3920 + const val SupportedTanMethodsForUserResponseCode = 3920 private val log = LoggerFactory.getLogger(ResponseParser::class) @@ -155,9 +155,9 @@ open class ResponseParser( val referencedDataElement = parseStringToNullIfEmpty(dataElements[1]) val message = parseString(dataElements[2]) - if (responseCode == SupportedTanProceduresForUserResponseCode) { - val supportedProcedures = parseCodeEnum(dataElements.subList(3, dataElements.size), Sicherheitsfunktion.values()) - return SupportedTanProceduresForUserFeedback(supportedProcedures, message) + if (responseCode == SupportedTanMethodsForUserResponseCode) { + val supportedMethods = parseCodeEnum(dataElements.subList(3, dataElements.size), Sicherheitsfunktion.values()) + return SupportedTanMethodsForUserFeedback(supportedMethods, message) } else if (responseCode == AufsetzpunktResponseCode) { return AufsetzpunktFeedback(parseString(dataElements[3]), message) @@ -375,81 +375,81 @@ open class ResponseParser( val proceduresDataElements = dataElements.subList(3, dataElements.size) return TwoStepTanProcedureParameters(oneStepProcedureAllowed, moreThanOneTanDependentJobPerMessageAllowed, - jobHashValue, mapToTanProcedureParameters(proceduresDataElements)) + jobHashValue, mapToTanMethodParameters(proceduresDataElements)) } - protected open fun mapToTanProcedureParameters(proceduresDataElements: List): List { + protected open fun mapToTanMethodParameters(methodsDataElements: List): List { // TODO: this throws an error for HITANS in version 4, but PSD2 needs HKTAN at least in version 6 anyway - val parsedProceduresParameters = mutableListOf() - var remainingDataElements = proceduresDataElements + val parsedMethodsParameters = mutableListOf() + var remainingDataElements = methodsDataElements while (remainingDataElements.size >= 20) { // parameters have at least 20 data elements, the last element is optional - val dataElementForNextProcedure = if (remainingDataElements.size >= 21) remainingDataElements.subList(0, 21) + val dataElementForNextMethod = if (remainingDataElements.size >= 21) remainingDataElements.subList(0, 21) else remainingDataElements.subList(0, 20) - val procedureParameters = mapToSingleTanProcedureParameters(dataElementForNextProcedure) - parsedProceduresParameters.add(procedureParameters) + val methodParameters = mapToSingleTanMethodParameters(dataElementForNextMethod) + parsedMethodsParameters.add(methodParameters) - val has21ElementsParsed = procedureParameters.countSupportedActiveTanMedia != null || - (dataElementForNextProcedure.size >= 21 && dataElementForNextProcedure[20].isBlank()) + val has21ElementsParsed = methodParameters.countSupportedActiveTanMedia != null || + (dataElementForNextMethod.size >= 21 && dataElementForNextMethod[20].isBlank()) if (has21ElementsParsed) remainingDataElements = remainingDataElements.subList(21, remainingDataElements.size) else remainingDataElements = remainingDataElements.subList(20, remainingDataElements.size) } - return parsedProceduresParameters + return parsedMethodsParameters } - protected open fun mapToSingleTanProcedureParameters(procedureDataElements: List): TanProcedureParameters { + protected open fun mapToSingleTanMethodParameters(methodDataElements: List): TanMethodParameters { - return TanProcedureParameters( - parseCodeEnum(procedureDataElements[0], Sicherheitsfunktion.values()), - parseCodeEnum(procedureDataElements[1], TanProcess.values()), - parseString(procedureDataElements[2]), - tryToParseZkaTanProcedure(procedureDataElements[3]), - parseStringToNullIfEmpty(procedureDataElements[4]), - parseString(procedureDataElements[5]), - parseInt(procedureDataElements[6]), - parseCodeEnum(procedureDataElements[7], AllowedTanFormat.values()), - parseString(procedureDataElements[8]), - parseInt(procedureDataElements[9]), + return TanMethodParameters( + parseCodeEnum(methodDataElements[0], Sicherheitsfunktion.values()), + parseCodeEnum(methodDataElements[1], TanProcess.values()), + parseString(methodDataElements[2]), + tryToParseZkaTanMethod(methodDataElements[3]), + parseStringToNullIfEmpty(methodDataElements[4]), + parseString(methodDataElements[5]), + parseInt(methodDataElements[6]), + parseCodeEnum(methodDataElements[7], AllowedTanFormat.values()), + parseString(methodDataElements[8]), + parseInt(methodDataElements[9]), // for HITANS 4 and 5 here is another "Anzahl unterstützter aktiver TAN-Listen" Integer element - parseBoolean(procedureDataElements[10]), - parseCodeEnum(procedureDataElements[11], TanZeitUndDialogbezug.values()), + parseBoolean(methodDataElements[10]), + parseCodeEnum(methodDataElements[11], TanZeitUndDialogbezug.values()), // for HITANS 4 and 5 here is another "TAN-Listennummer erforderlich" code element - parseBoolean(procedureDataElements[12]), - tryToParseSmsAbbuchungskontoErforderlich(procedureDataElements[13]), - tryToParseAuftraggeberkontoErforderlich(procedureDataElements[14]), - parseBoolean(procedureDataElements[15]), - parseBoolean(procedureDataElements[16]), - parseCodeEnum(procedureDataElements[17], Initialisierungsmodus.values()), - parseCodeEnum(procedureDataElements[18], BezeichnungDesTanMediumsErforderlich.values()), - parseBoolean(procedureDataElements[19]), - if (procedureDataElements.size > 20) parseNullableInt(procedureDataElements[20]) else null + parseBoolean(methodDataElements[12]), + tryToParseSmsAbbuchungskontoErforderlich(methodDataElements[13]), + tryToParseAuftraggeberkontoErforderlich(methodDataElements[14]), + parseBoolean(methodDataElements[15]), + parseBoolean(methodDataElements[16]), + parseCodeEnum(methodDataElements[17], Initialisierungsmodus.values()), + parseCodeEnum(methodDataElements[18], BezeichnungDesTanMediumsErforderlich.values()), + parseBoolean(methodDataElements[19]), + if (methodDataElements.size > 20) parseNullableInt(methodDataElements[20]) else null ) } - protected open fun tryToParseZkaTanProcedure(mayZkaTanProcedure: String): ZkaTanProcedure? { - if (mayZkaTanProcedure.isBlank()) { + protected open fun tryToParseZkaTanMethod(mayZkaTanMethod: String): ZkaTanMethod? { + if (mayZkaTanMethod.isBlank()) { return null } try { - val lowerCaseMayZkaTanProcedure = mayZkaTanProcedure.toLowerCase() + val lowerCaseMayZkaTanMethod = mayZkaTanMethod.toLowerCase() - if (lowerCaseMayZkaTanProcedure == "mobiletan" || lowerCaseMayZkaTanProcedure == "mtan") { - return ZkaTanProcedure.mobileTAN + if (lowerCaseMayZkaTanMethod == "mobiletan" || lowerCaseMayZkaTanMethod == "mtan") { + return ZkaTanMethod.mobileTAN } - if (lowerCaseMayZkaTanProcedure == "apptan" || lowerCaseMayZkaTanProcedure == "phototan") { - return ZkaTanProcedure.appTAN + if (lowerCaseMayZkaTanMethod == "apptan" || lowerCaseMayZkaTanMethod == "phototan") { + return ZkaTanMethod.appTAN } // TODO: what about these values, all returned by banks in anonymous dialog initialization: // BestSign, HHDUSB1, Secoder_UC, ZkaTANMode, photoTAN, QRTAN, 1822TAN+ - return ZkaTanProcedure.valueOf(mayZkaTanProcedure) + return ZkaTanMethod.valueOf(mayZkaTanMethod) } catch (ignored: Exception) { } return null diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/FinTsClientResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/FinTsClientResponse.kt index 0c703178..0b68dc67 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/FinTsClientResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/FinTsClientResponse.kt @@ -8,7 +8,7 @@ open class FinTsClientResponse( open val successful: Boolean, - open val noTanProcedureSelected: Boolean, + open val noTanMethodSelected: Boolean, open val isStrongAuthenticationRequired: Boolean, open val tanRequired: TanResponse? = null, @@ -31,7 +31,7 @@ open class FinTsClientResponse( ) { - constructor(response: BankResponse) : this(response.successful, response.noTanProcedureSelected, + constructor(response: BankResponse) : this(response.successful, response.noTanMethodSelected, response.isStrongAuthenticationRequired, response.tanResponse, response.errorsToShowToUser, response.errorMessage, response.tanRequiredButUserDidNotEnterOne, response.tanRequiredButWeWereToldToAbortIfSo, response.messageCreationError?.isJobAllowed ?: true, @@ -41,8 +41,8 @@ open class FinTsClientResponse( override fun toString(): String { - if (noTanProcedureSelected) { - return "Error: No TAN procedure selected" + if (noTanMethodSelected) { + return "Error: No TAN method selected" } if (isJobAllowed == false) { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanMethodsResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanMethodsResponse.kt new file mode 100644 index 00000000..df89c53e --- /dev/null +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanMethodsResponse.kt @@ -0,0 +1,28 @@ +package net.dankito.banking.fints.response.client + +import net.dankito.banking.fints.response.BankResponse +import net.dankito.banking.fints.response.ResponseParser + + +open class GetUserTanMethodsResponse(bankResponse: BankResponse) + : BankResponse(bankResponse.didReceiveResponse, bankResponse.receivedResponse, bankResponse.receivedSegments, + bankResponse.errorMessage, bankResponse.noTanMethodSelected, bankResponse.messageCreationError) { + + /** + * comdirect sends "9955::Unzulässiges TAN-Verfahren." even though '999' is a valid TAN method + * for init dialog if user's TAN methods are not known yet and it contains a '3920:' feedback with user's TAN methods + * -> if it contains a '3920:' feedback with user's TAN methods, then it's still a success. + */ + override val successful: Boolean + get() = noTanMethodSelected == false && couldCreateMessage && didReceiveResponse + && tanRequiredButUserDidNotEnterOne == false + && (responseContainsErrors == false || containsUsersTanMethodsFeedback()) + + protected open fun containsUsersTanMethodsFeedback(): Boolean { + val usersSupportedTanMethodsFeedback = segmentFeedbacks.flatMap { it.feedbacks } + .firstOrNull { it.responseCode == ResponseParser.SupportedTanMethodsForUserResponseCode } + + return usersSupportedTanMethodsFeedback != null + } + +} \ No newline at end of file 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 deleted file mode 100644 index 7dea5c72..00000000 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetUserTanProceduresResponse.kt +++ /dev/null @@ -1,28 +0,0 @@ -package net.dankito.banking.fints.response.client - -import net.dankito.banking.fints.response.BankResponse -import net.dankito.banking.fints.response.ResponseParser - - -open class GetUserTanProceduresResponse(bankResponse: BankResponse) - : BankResponse(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 and it contains a '3920:' feedback with user's TAN procedures - * -> if it contains a '3920:' feedback with user's TAN procedures, then it's still a success. - */ - override val successful: Boolean - get() = noTanProcedureSelected == false && couldCreateMessage && didReceiveResponse - && tanRequiredButUserDidNotEnterOne == false - && (responseContainsErrors == false || containsUsersTanProceduresFeedback()) - - protected open fun containsUsersTanProceduresFeedback(): Boolean { - val usersSupportedTanProceduresFeedback = segmentFeedbacks.flatMap { it.feedbacks } - .firstOrNull { it.responseCode == ResponseParser.SupportedTanProceduresForUserResponseCode } - - return usersSupportedTanProceduresFeedback != null - } - -} \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanProceduresForUserFeedback.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanMethodsForUserFeedback.kt similarity index 55% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanProceduresForUserFeedback.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanMethodsForUserFeedback.kt index 8fe37ef0..4cf8f34e 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanProceduresForUserFeedback.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/SupportedTanMethodsForUserFeedback.kt @@ -3,8 +3,8 @@ package net.dankito.banking.fints.response.segments import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion import net.dankito.banking.fints.response.ResponseParser -open class SupportedTanProceduresForUserFeedback( - val supportedTanProcedures: List, +open class SupportedTanMethodsForUserFeedback( + val supportedTanMethods: List, message: String ) - : Feedback(ResponseParser.SupportedTanProceduresForUserResponseCode, message) \ No newline at end of file + : Feedback(ResponseParser.SupportedTanMethodsForUserResponseCode, message) \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanProcedureParameters.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanMethodParameters.kt similarity index 85% rename from fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanProcedureParameters.kt rename to fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanMethodParameters.kt index a8a3dcf3..1fe97d17 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanProcedureParameters.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TanMethodParameters.kt @@ -4,13 +4,13 @@ import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur. import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.* -open class TanProcedureParameters( +open class TanMethodParameters( val securityFunction: Sicherheitsfunktion, val tanProcess: TanProcess, - val technicalTanProcedureIdentification: String, - val zkaTanProcedure: ZkaTanProcedure?, - val versionZkaTanProcedure: String?, - val procedureName: String, + val technicalTanMethodIdentification: String, + val zkaTanMethod: ZkaTanMethod?, + val versionZkaTanMethod: String?, + val methodName: String, val maxTanInputLength: Int, val allowedTanFormat: AllowedTanFormat, val descriptionToShowToUser: String, @@ -35,7 +35,7 @@ open class TanProcedureParameters( override fun toString(): String { - return "$procedureName $technicalTanProcedureIdentification" + return "$methodName $technicalTanMethodIdentification" } } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TwoStepTanProcedureParameters.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TwoStepTanProcedureParameters.kt index 6268ad59..87fa937d 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TwoStepTanProcedureParameters.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/segments/TwoStepTanProcedureParameters.kt @@ -5,7 +5,7 @@ open class TwoStepTanProcedureParameters( val oneStepProcedureAllowed: Boolean, val moreThanOneTanDependentJobPerMessageAllowed: Boolean, val jobHashValue: String, // not evaluated for PIN/TAN - val procedureParameters: List + val methodParameters: List ) { internal constructor() : this(false, false, "", listOf()) // for object deserializers diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/FinTsTestBase.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/FinTsTestBase.kt index 4a7a6b0d..a3fb495b 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/FinTsTestBase.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/FinTsTestBase.kt @@ -36,7 +36,7 @@ abstract class FinTsTestBase { const val ControlReference = "4477" - val Bank = BankData(BankCode, CustomerId, Pin, BankFinTsServerAddress, Bic, "", BankCountryCode, selectedTanProcedure = TanProcedure("chipTAN-optisch", SecurityFunction, TanProcedureType.ChipTanFlickercode), selectedLanguage = Language) + val Bank = BankData(BankCode, CustomerId, Pin, BankFinTsServerAddress, Bic, "", BankCountryCode, selectedTanMethod = TanMethod("chipTAN-optisch", SecurityFunction, TanMethodType.ChipTanFlickercode), selectedLanguage = Language) val Currency = "EUR" diff --git a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt index a6fddfb2..597041f5 100644 --- a/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt +++ b/fints4k/src/commonTest/kotlin/net/dankito/banking/fints/response/ResponseParserTest.kt @@ -245,7 +245,7 @@ class ResponseParserTest : FinTsTestBase() { } @Test - fun parseSegmentFeedback_AllowedUserTanProcedures() { + fun parseSegmentFeedback_AllowedUserTanMethods() { // when val result = underTest.parse("HIRMS:4:2:4+3050::BPD nicht mehr aktuell, aktuelle Version enthalten.+3920::Zugelassene Zwei-Schritt-Verfahren für den Benutzer.:910:911:912:913+0020::Der Auftrag wurde ausgeführt.") @@ -256,7 +256,7 @@ class ResponseParserTest : FinTsTestBase() { expect(result.segmentFeedbacks).hasSize(1) - expect(result.supportedTanProceduresForUser).containsExactly(Sicherheitsfunktion.PIN_TAN_910, + expect(result.supportedTanMethodsForUser).containsExactly(Sicherheitsfunktion.PIN_TAN_910, Sicherheitsfunktion.PIN_TAN_911, Sicherheitsfunktion.PIN_TAN_912, Sicherheitsfunktion.PIN_TAN_913) val segmentFeedback = result.segmentFeedbacks.first() @@ -272,8 +272,8 @@ class ResponseParserTest : FinTsTestBase() { expect(firstFeedback.parameter).toBe(null) val secondFeedback = segmentFeedback.feedbacks[1] - expect(secondFeedback is SupportedTanProceduresForUserFeedback).isTrue() - expect((secondFeedback as SupportedTanProceduresForUserFeedback).supportedTanProcedures) + expect(secondFeedback is SupportedTanMethodsForUserFeedback).isTrue() + expect((secondFeedback as SupportedTanMethodsForUserFeedback).supportedTanMethods) .containsExactly(Sicherheitsfunktion.PIN_TAN_910,Sicherheitsfunktion.PIN_TAN_911, Sicherheitsfunktion.PIN_TAN_912, Sicherheitsfunktion.PIN_TAN_913) expect(secondFeedback.responseCode).toBe(3920) @@ -726,8 +726,8 @@ class ResponseParserTest : FinTsTestBase() { expect(segment.tanProcedureParameters.moreThanOneTanDependentJobPerMessageAllowed).isFalse() expect(segment.tanProcedureParameters.jobHashValue).toBe("0") - expect(segment.tanProcedureParameters.procedureParameters).hasSize(7) - expect(segment.tanProcedureParameters.procedureParameters.map { it.procedureName }) + expect(segment.tanProcedureParameters.methodParameters).hasSize(7) + expect(segment.tanProcedureParameters.methodParameters.map { it.methodName }) .containsExactly("chipTAN manuell", "chipTAN optisch", "chipTAN-USB", "chipTAN-QR", "smsTAN", "pushTAN", "iTAN") } @@ -751,8 +751,8 @@ class ResponseParserTest : FinTsTestBase() { expect(segment.tanProcedureParameters.moreThanOneTanDependentJobPerMessageAllowed).isFalse() expect(segment.tanProcedureParameters.jobHashValue).toBe("0") - expect(segment.tanProcedureParameters.procedureParameters).hasSize(2) - expect(segment.tanProcedureParameters.procedureParameters.map { it.procedureName }) + expect(segment.tanProcedureParameters.methodParameters).hasSize(2) + expect(segment.tanProcedureParameters.methodParameters.map { it.methodName }) .containsExactly("mobileTAN-Verfahren", "photoTAN-Verfahren") } ?: run { fail("No segment of type TanInfo found in ${result.receivedSegments}") } @@ -775,8 +775,8 @@ class ResponseParserTest : FinTsTestBase() { expect(segment.tanProcedureParameters.moreThanOneTanDependentJobPerMessageAllowed).isFalse() expect(segment.tanProcedureParameters.jobHashValue).toBe("0") - expect(segment.tanProcedureParameters.procedureParameters).hasSize(5) - expect(segment.tanProcedureParameters.procedureParameters.map { it.procedureName }) + expect(segment.tanProcedureParameters.methodParameters).hasSize(5) + expect(segment.tanProcedureParameters.methodParameters.map { it.methodName }) .containsExactly("SMS-TAN", "chipTAN comfort", "chipTAN comfort manuell", "BV AppTAN", "PhotoTAN") } ?: run { fail("No segment of type TanInfo found in ${result.receivedSegments}") } @@ -799,8 +799,8 @@ class ResponseParserTest : FinTsTestBase() { expect(segment.tanProcedureParameters.moreThanOneTanDependentJobPerMessageAllowed).isFalse() expect(segment.tanProcedureParameters.jobHashValue).toBe("1") - expect(segment.tanProcedureParameters.procedureParameters).hasSize(6) - expect(segment.tanProcedureParameters.procedureParameters.map { it.procedureName }) + expect(segment.tanProcedureParameters.methodParameters).hasSize(6) + expect(segment.tanProcedureParameters.methodParameters.map { it.methodName }) .containsExactly("iTAN", "mobile TAN", "App-basiertes Verfahren", "chipTAN 1.4", "chipTAN 1.4 manuell", "Vorlagen und Informationen") } diff --git a/fints4k/src/commonTest/java/net/dankito/banking/fints/JavaShowcase.java b/fints4k/src/jvm6Test/java/net/dankito/banking/fints/JavaShowcase.java similarity index 95% rename from fints4k/src/commonTest/java/net/dankito/banking/fints/JavaShowcase.java rename to fints4k/src/jvm6Test/java/net/dankito/banking/fints/JavaShowcase.java index 69b2ef63..6803de47 100644 --- a/fints4k/src/commonTest/java/net/dankito/banking/fints/JavaShowcase.java +++ b/fints4k/src/jvm6Test/java/net/dankito/banking/fints/JavaShowcase.java @@ -14,7 +14,7 @@ import net.dankito.banking.fints.model.CustomerData; import net.dankito.banking.fints.model.EnterTanGeneratorAtcResult; import net.dankito.banking.fints.model.EnterTanResult; import net.dankito.banking.fints.model.TanChallenge; -import net.dankito.banking.fints.model.TanProcedure; +import net.dankito.banking.fints.model.TanMethod; import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium; import net.dankito.banking.fints.model.mapper.BankDataMapper; import net.dankito.banking.fints.response.client.AddAccountResponse; @@ -86,11 +86,11 @@ public class JavaShowcase { FinTsClientCallback callback = new FinTsClientCallback() { @Override - public TanProcedure askUserForTanProcedure(List supportedTanProcedures, TanProcedure suggestedTanProcedure) { - // E.g. show a dialog to ask for user's TAN procedure. - // In most cases it's senseful to simply return suggestedTanProcedure and to let - // user select TAN procedure when entering TAN is required (see enterTan() below) - return suggestedTanProcedure; + public TanMethod askUserForTanMethod(List supportedTanMethods, TanMethod suggestedTanMethod) { + // E.g. show a dialog to ask for user's TAN method. + // In most cases it's senseful to simply return suggestedTanMethod and to let + // user select TAN method when entering TAN is required (see enterTan() below) + return suggestedTanMethod; } @Override @@ -103,7 +103,7 @@ public class JavaShowcase { @Override public EnterTanGeneratorAtcResult enterTanGeneratorAtc(CustomerData customer, TanGeneratorTanMedium tanMedium) { - // needed only in rare cases to synchronize TAN generator for chipTAN procedures. E.g. show + // needed only in rare cases to synchronize TAN generator for chipTAN methods. E.g. show // - Android: net.dankito.banking.ui.android.dialogs.EnterAtcDialog return EnterTanGeneratorAtcResult.Companion.userDidNotEnterAtc(); // user did not enter TAN and ATC. aborts operation } diff --git a/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/FinTsClientTestBase.kt b/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/FinTsClientTestBase.kt index 85ee9f72..02fd2bf7 100644 --- a/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/FinTsClientTestBase.kt +++ b/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/FinTsClientTestBase.kt @@ -48,16 +48,16 @@ open class FinTsClientTestBase { } - private var didAskUserForTanProcedure = false + private var didAskUserForTanMethod = false private var didAskUserToEnterTan = false private val callback = object : FinTsClientCallback { - override fun askUserForTanProcedure(supportedTanProcedures: List, suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) { - didAskUserForTanProcedure = true - callback(suggestedTanProcedure) // simply return suggestedTanProcedure as in most cases it's the best fitting one + override fun askUserForTanMethod(supportedTanMethods: List, suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) { + didAskUserForTanMethod = true + callback(suggestedTanMethod) // simply return suggestedTanMethod as in most cases it's the best fitting one } override fun enterTan(bank: BankData, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) { @@ -93,7 +93,7 @@ open class FinTsClientTestBase { // then expect(result.successful).isTrue() expect(BankDataAnonymous.supportedHbciVersions).isNotEmpty() - expect(BankDataAnonymous.tanProceduresSupportedByBank).isNotEmpty() + expect(BankDataAnonymous.tanMethodSupportedByBank).isNotEmpty() expect(BankDataAnonymous.supportedJobs).isNotEmpty() expect(BankDataAnonymous.supportedLanguages).isNotEmpty() expect(BankDataAnonymous.bankName).isNotEmpty() @@ -122,16 +122,16 @@ open class FinTsClientTestBase { expect(result.successful).isTrue() - expect(didAskUserForTanProcedure).isFalse() + expect(didAskUserForTanMethod).isFalse() expect(Bank.bankName).isNotEmpty() expect(Bank.supportedJobs).isNotEmpty() // supported jobs are now known - expect(Bank.tanProceduresSupportedByBank).isNotEmpty() // supported tan procedures are now known + expect(Bank.tanMethodSupportedByBank).isNotEmpty() // supported tan methods are now known expect(Bank.supportedHbciVersions).isNotEmpty() // supported HBIC versions are now known expect(Bank.supportedLanguages).isNotEmpty() // supported languages are now known expect(Bank.customerName).isNotEmpty() - expect(Bank.tanProceduresAvailableForUser).isNotEmpty() + expect(Bank.tanMethodsAvailableForUser).isNotEmpty() expect(Bank.selectedLanguage).notToBe(Dialogsprache.Default) // language is set now expect(Bank.customerSystemId).notToBe(KundensystemStatus.SynchronizingCustomerSystemId.code) // customer system id is now set expect(Bank.customerSystemStatus).toBe(KundensystemStatusWerte.Benoetigt) // customerSystemStatus is set now @@ -174,7 +174,7 @@ open class FinTsClientTestBase { @Test fun getTanMediaList() { - // this test is only senseful for accounts using chipTAN / TAN generator as TAN procedure + // this test is only senseful for accounts using chipTAN / TAN generator as TAN method underTest.getAnonymousBankInfo(Bank) { } diff --git a/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/bankdetails/BanksFinTsDetailsRetriever.kt b/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/bankdetails/BanksFinTsDetailsRetriever.kt index 1f7078c1..cd2d6446 100644 --- a/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/bankdetails/BanksFinTsDetailsRetriever.kt +++ b/fints4k/src/jvm6Test/kotlin/net/dankito/banking/fints/bankdetails/BanksFinTsDetailsRetriever.kt @@ -16,7 +16,7 @@ import net.dankito.banking.bankfinder.BankInfo import net.dankito.banking.fints.response.BankResponse import net.dankito.banking.fints.response.segments.SepaAccountInfoParameters import net.dankito.banking.fints.response.segments.TanInfo -import net.dankito.banking.fints.response.segments.TanProcedureParameters +import net.dankito.banking.fints.response.segments.TanMethodParameters import net.dankito.banking.fints.util.* import net.dankito.banking.fints.webclient.KtorWebClient import org.apache.commons.csv.CSVFormat @@ -59,19 +59,19 @@ class BanksFinTsDetailsRetriever { super.updateBankData(bank, response) } - fun mapToTanProcedureTypePublic(parameters: TanProcedureParameters): TanProcedureType? { - return super.mapToTanProcedureType(parameters) + fun mapToTanMethodTypePublic(parameters: TanMethodParameters): TanMethodType? { + return super.mapToTanMethodType(parameters) } } private val requestNotSuccessful = mutableListOf() - private val tanProcedureParameter = mutableMapOf>() - private val tanProcedureTypes = mutableMapOf>() + private val tanMethodParameter = mutableMapOf>() + private val tanMethodTypes = mutableMapOf>() - private val tanProcedureParameterTechnicalIdentification = mutableSetOf() - private val tanProcedureParameterVersionZkaTanProcedure = mutableSetOf() + private val tanMethodParameterTechnicalIdentification = mutableSetOf() + private val tanMethodParameterVersionZkaTanMethod = mutableSetOf() private val requiresSmsAbbuchungskonto = mutableListOf() private val requiresAuftraggeberkonto = mutableListOf() @@ -167,10 +167,10 @@ class BanksFinTsDetailsRetriever { val supportsHKCCS1 = supportsJobInVersion(bank, "HKCCS", 1) val tanInfo = anonymousBankInfoResponse.receivedSegments.filterIsInstance(TanInfo::class.java) - val tanProcedureParameters = tanInfo.flatMap { it.tanProcedureParameters.procedureParameters } - val supportedTanProcedures = tanProcedureParameters.map { it.technicalTanProcedureIdentification } - val hhd13Supported = supportedTanProcedures.firstOrNull { it.startsWith("hhd1.3", true) } != null - val hhd14Supported = supportedTanProcedures.firstOrNull { it.startsWith("hhd1.4", true) } != null + val tanMethodParameters = tanInfo.flatMap { it.tanProcedureParameters.methodParameters } + val supportedTanMethods = tanMethodParameters.map { it.technicalTanMethodIdentification } + val hhd13Supported = supportedTanMethods.firstOrNull { it.startsWith("hhd1.3", true) } != null + val hhd14Supported = supportedTanMethods.firstOrNull { it.startsWith("hhd1.4", true) } != null val supportedHKTANVersions = tanInfo.map { it.segmentVersion } val supportedHKSALVersions = getSupportedVersions(bank, "HKSAL") @@ -184,8 +184,8 @@ class BanksFinTsDetailsRetriever { csvPrinter.printRecord(bankInfo.bankCode, bankInfo.name, bankInfo.city, bank.bpdVersion, - bank.tanProceduresSupportedByBank.joinToString(", ") { it.securityFunction.code + ": " + it.displayName + " (" + it.type + ")" }, - supportedTanProcedures.joinToString(", "), + bank.tanMethodSupportedByBank.joinToString(", ") { it.securityFunction.code + ": " + it.displayName + " (" + it.type + ")" }, + supportedTanMethods.joinToString(", "), hhd13Supported, hhd14Supported, supportsHKTAN6, @@ -203,41 +203,41 @@ class BanksFinTsDetailsRetriever { bank.supportedJobs.joinToString(", ") { it.jobName + " " + it.segmentVersion } ) - tanProcedureParameters.forEach { procedureParameter -> - if (tanProcedureParameter.containsKey(procedureParameter.procedureName) == false) { - tanProcedureParameter.put(procedureParameter.procedureName, mutableSetOf(procedureParameter)) + tanMethodParameters.forEach { methodParameter -> + if (tanMethodParameter.containsKey(methodParameter.methodName) == false) { + tanMethodParameter.put(methodParameter.methodName, mutableSetOf(methodParameter)) } else { - tanProcedureParameter[procedureParameter.procedureName]?.add(procedureParameter) + tanMethodParameter[methodParameter.methodName]?.add(methodParameter) } - val tanProcedureType = finTsClient.mapToTanProcedureTypePublic(procedureParameter) - if (tanProcedureTypes.containsKey(tanProcedureType) == false) { - tanProcedureTypes.put(tanProcedureType, mutableSetOf(procedureParameter)) + val tanMethodType = finTsClient.mapToTanMethodTypePublic(methodParameter) + if (tanMethodTypes.containsKey(tanMethodType) == false) { + tanMethodTypes.put(tanMethodType, mutableSetOf(methodParameter)) } else { - tanProcedureTypes[tanProcedureType]?.add(procedureParameter) + tanMethodTypes[tanMethodType]?.add(methodParameter) } - tanProcedureParameterTechnicalIdentification.add(procedureParameter.technicalTanProcedureIdentification) - tanProcedureParameterVersionZkaTanProcedure.add(procedureParameter.versionZkaTanProcedure) + tanMethodParameterTechnicalIdentification.add(methodParameter.technicalTanMethodIdentification) + tanMethodParameterVersionZkaTanMethod.add(methodParameter.versionZkaTanMethod) - if (procedureParameter.smsDebitAccountRequired == SmsAbbuchungskontoErforderlich.SmsAbbuchungskontoMussAngegebenWerden) { + if (methodParameter.smsDebitAccountRequired == SmsAbbuchungskontoErforderlich.SmsAbbuchungskontoMussAngegebenWerden) { requiresSmsAbbuchungskonto.add(bankInfo) } - if (procedureParameter.initiatorAccountRequired == AuftraggeberkontoErforderlich.AuftraggeberkontoMussAngegebenWerdenWennImGeschaeftsvorfallEnthalten) { + if (methodParameter.initiatorAccountRequired == AuftraggeberkontoErforderlich.AuftraggeberkontoMussAngegebenWerdenWennImGeschaeftsvorfallEnthalten) { requiresAuftraggeberkonto.add(bankInfo) } - if (procedureParameter.challengeClassRequired) { + if (methodParameter.challengeClassRequired) { requiresChallengeClass.add(bankInfo) } - if (procedureParameter.signatureStructured) { + if (methodParameter.signatureStructured) { signatureStructured.add(bankInfo) } - if (procedureParameter.nameOfTanMediaRequired == BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsMussAngegebenWerden) { + if (methodParameter.nameOfTanMediaRequired == BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsMussAngegebenWerden) { requiresNameOfTanMedia.add(bankInfo) } - if (procedureParameter.hhdUcResponseRequired) { + if (methodParameter.hhdUcResponseRequired) { requiresHhdUcResponse.add(bankInfo) } } @@ -283,11 +283,11 @@ class BanksFinTsDetailsRetriever { private fun printStatistics() { log.info("Did not receive response from Banks ${printBanks(requestNotSuccessful)}") - log.info("Mapped tanProcedureTypes: ${tanProcedureTypes.map { System.lineSeparator() + it.key + ": " + it.value.map { it.procedureName + " " + it.zkaTanProcedure + " " + it.technicalTanProcedureIdentification + " (" + it.descriptionToShowToUser + ")" }.toSet().joinToString(", ") }}\n\n") - log.info("TanProcedureParameters:${tanProcedureParameter.map { System.lineSeparator() + it.key + ": " + it.value.map { it.securityFunction.code + " " + it.zkaTanProcedure + " " + it.technicalTanProcedureIdentification + " (" + it.descriptionToShowToUser + ")" }.toSet().joinToString(", ") } }\n\n") + log.info("Mapped tanMethodTypes: ${tanMethodTypes.map { System.lineSeparator() + it.key + ": " + it.value.map { it.methodName + " " + it.zkaTanMethod + " " + it.technicalTanMethodIdentification + " (" + it.descriptionToShowToUser + ")" }.toSet().joinToString(", ") }}\n\n") + log.info("TanMethodParameters:${tanMethodParameter.map { System.lineSeparator() + it.key + ": " + it.value.map { it.securityFunction.code + " " + it.zkaTanMethod + " " + it.technicalTanMethodIdentification + " (" + it.descriptionToShowToUser + ")" }.toSet().joinToString(", ") } }\n\n") - log.info("TanProcedureParameters TechnicalIdentification:${tanProcedureParameterTechnicalIdentification.joinToString(", ") } \n\n") - log.info("TanProcedureParameters VersionZkaTanProcedure:${tanProcedureParameterVersionZkaTanProcedure.joinToString(", ") } \n\n") + log.info("TanMethodParameters TechnicalIdentification:${tanMethodParameterTechnicalIdentification.joinToString(", ") } \n\n") + log.info("TanMethodParameters VersionZkaTanMethod:${tanMethodParameterVersionZkaTanMethod.joinToString(", ") } \n\n") log.info("Requires SmsAbbuchungskonto ${printBanks(requiresSmsAbbuchungskonto)}") // no (only 2) log.info("Requires Auftraggeberkonto ${printBanks(requiresAuftraggeberkonto)}") // yes, a lot of (12631) diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt index 3089819d..858b5584 100644 --- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt +++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/fints4kBankingClient.kt @@ -219,8 +219,8 @@ open class fints4kBankingClient( protected open fun createFinTsClientCallback(clientCallback: BankingClientCallback): FinTsClientCallback { return object : FinTsClientCallback { - override fun askUserForTanProcedure(supportedTanProcedures: List, suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) { - handleAskUserForTanProcedure(supportedTanProcedures, suggestedTanProcedure, callback) + override fun askUserForTanMethod(supportedTanMethods: List, suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) { + handleAskUserForTanProcedure(supportedTanMethods, suggestedTanMethod, callback) } override fun enterTan(bank: BankData, tanChallenge: TanChallenge, callback: (EnterTanResult) -> Unit) { @@ -234,9 +234,9 @@ open class fints4kBankingClient( } } - protected open fun handleAskUserForTanProcedure(supportedTanProcedures: List, suggestedTanProcedure: TanProcedure?, callback: (TanProcedure?) -> Unit) { + protected open fun handleAskUserForTanProcedure(supportedTanMethods: List, suggestedTanMethod: TanMethod?, callback: (TanMethod?) -> Unit) { // we simply return suggestedTanProcedure as even so it's not user's preferred TAN procedure she still can select it in EnterTanDialog - callback(suggestedTanProcedure) + callback(suggestedTanMethod) } protected open fun handleEnterTan(bank: BankData, tanChallenge: TanChallenge, enterTanCallback: (EnterTanResult) -> Unit, clientCallback: BankingClientCallback) { diff --git a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt index ffaae806..f37c4592 100644 --- a/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt +++ b/ui/fints4kBankingClient/src/commonMain/kotlin/net/dankito/banking/mapper/fints4kModelMapper.kt @@ -81,11 +81,11 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { customer.accounts = mapBankAccounts(customer, bank.accounts) - updateTanMediaAndProcedures(customer, bank) + updateTanMediaAndMethods(customer, bank) } /** - * In UI only customerId, password, (bankCode,) and selected TAN procedure can be set + * In UI only customerId, password, (bankCode,) and selected TAN method can be set */ open fun mapChangesFromUiToClientModel(customer: TypedCustomer, bank: BankData) { bank.customerId = customer.customerId @@ -93,7 +93,7 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { bank.bankCode = customer.bankCode - bank.selectedTanProcedure = findTanProcedure(bank, customer.selectedTanProcedure) ?: bank.selectedTanProcedure + bank.selectedTanMethod = findTanMethod(bank, customer.selectedTanProcedure) ?: bank.selectedTanMethod } @@ -235,13 +235,13 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } - open fun updateTanMediaAndProcedures(account: TypedCustomer, bank: BankData) { - account.supportedTanProcedures = bank.tanProceduresAvailableForUser.map { tanProcedure -> - findMappedTanProcedure(account, tanProcedure) ?: mapTanProcedure(tanProcedure) + open fun updateTanMediaAndMethods(account: TypedCustomer, bank: BankData) { + account.supportedTanProcedures = bank.tanMethodsAvailableForUser.map { tanMethod -> + findMappedTanMethod(account, tanMethod) ?: mapTanMethod(tanMethod) } - if (bank.isTanProcedureSelected) { - account.selectedTanProcedure = findMappedTanProcedure(account, bank.selectedTanProcedure) + if (bank.isTanMethodSelected) { + account.selectedTanProcedure = findMappedTanMethod(account, bank.selectedTanMethod) } else { account.selectedTanProcedure = null @@ -253,32 +253,32 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } - open fun mapTanProcedures(tanProcedures: List): List { - return tanProcedures.map { mapTanProcedure(it) } + open fun mapTanMethods(tanMethods: List): List { + return tanMethods.map { mapTanMethod(it) } } - open fun mapTanProcedure(tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure { + open fun mapTanMethod(tanMethod: net.dankito.banking.fints.model.TanMethod): TanProcedure { return modelCreator.createTanProcedure( - tanProcedure.displayName, - mapTanProcedureType(tanProcedure.type), - tanProcedure.securityFunction.code, - tanProcedure.maxTanInputLength, - mapAllowedTanFormat(tanProcedure.allowedTanFormat) + tanMethod.displayName, + mapTanMethodType(tanMethod.type), + tanMethod.securityFunction.code, + tanMethod.maxTanInputLength, + mapAllowedTanFormat(tanMethod.allowedTanFormat) ) } - open fun mapTanProcedureType(type: net.dankito.banking.fints.model.TanProcedureType): TanProcedureType { + open fun mapTanMethodType(type: net.dankito.banking.fints.model.TanMethodType): TanProcedureType { return when (type) { - net.dankito.banking.fints.model.TanProcedureType.EnterTan -> TanProcedureType.EnterTan - net.dankito.banking.fints.model.TanProcedureType.ChipTanManuell -> TanProcedureType.ChipTanManuell - net.dankito.banking.fints.model.TanProcedureType.ChipTanFlickercode -> TanProcedureType.ChipTanFlickercode - net.dankito.banking.fints.model.TanProcedureType.ChipTanUsb -> TanProcedureType.ChipTanUsb - net.dankito.banking.fints.model.TanProcedureType.ChipTanQrCode -> TanProcedureType.ChipTanQrCode - net.dankito.banking.fints.model.TanProcedureType.ChipTanPhotoTanMatrixCode -> TanProcedureType.ChipTanPhotoTanMatrixCode - net.dankito.banking.fints.model.TanProcedureType.SmsTan -> TanProcedureType.SmsTan - net.dankito.banking.fints.model.TanProcedureType.AppTan -> TanProcedureType.AppTan - net.dankito.banking.fints.model.TanProcedureType.photoTan -> TanProcedureType.photoTan - net.dankito.banking.fints.model.TanProcedureType.QrCode -> TanProcedureType.QrCode + net.dankito.banking.fints.model.TanMethodType.EnterTan -> TanProcedureType.EnterTan + net.dankito.banking.fints.model.TanMethodType.ChipTanManuell -> TanProcedureType.ChipTanManuell + net.dankito.banking.fints.model.TanMethodType.ChipTanFlickercode -> TanProcedureType.ChipTanFlickercode + net.dankito.banking.fints.model.TanMethodType.ChipTanUsb -> TanProcedureType.ChipTanUsb + net.dankito.banking.fints.model.TanMethodType.ChipTanQrCode -> TanProcedureType.ChipTanQrCode + net.dankito.banking.fints.model.TanMethodType.ChipTanPhotoTanMatrixCode -> TanProcedureType.ChipTanPhotoTanMatrixCode + net.dankito.banking.fints.model.TanMethodType.SmsTan -> TanProcedureType.SmsTan + net.dankito.banking.fints.model.TanMethodType.AppTan -> TanProcedureType.AppTan + net.dankito.banking.fints.model.TanMethodType.photoTan -> TanProcedureType.photoTan + net.dankito.banking.fints.model.TanMethodType.QrCode -> TanProcedureType.QrCode } } @@ -289,16 +289,16 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } } - protected open fun findMappedTanProcedure(customer: TypedCustomer, tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure? { - return customer.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanProcedure.securityFunction.code } + protected open fun findMappedTanMethod(customer: TypedCustomer, tanMethod: net.dankito.banking.fints.model.TanMethod): TanProcedure? { + return customer.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanMethod.securityFunction.code } } - protected open fun findTanProcedure(bank: BankData, tanProcedure: TanProcedure?): net.dankito.banking.fints.model.TanProcedure? { + protected open fun findTanMethod(bank: BankData, tanProcedure: TanProcedure?): net.dankito.banking.fints.model.TanMethod? { if (tanProcedure == null) { return null } - return bank.tanProceduresAvailableForUser.firstOrNull { it.securityFunction.code == tanProcedure.bankInternalProcedureCode } + return bank.tanMethodsAvailableForUser.firstOrNull { it.securityFunction.code == tanProcedure.bankInternalProcedureCode } } protected open fun findMappedTanMedium(customer: TypedCustomer, tanMedium: net.dankito.banking.fints.messages.datenelemente.implementierte.tan.TanMedium): TanMedium? { @@ -393,29 +393,29 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } - open fun mapTanProcedure(tanProcedure: TanProcedure): net.dankito.banking.fints.model.TanProcedure { - return net.dankito.banking.fints.model.TanProcedure( + open fun mapTanMethod(tanProcedure: TanProcedure): net.dankito.banking.fints.model.TanMethod { + return net.dankito.banking.fints.model.TanMethod( tanProcedure.displayName, Sicherheitsfunktion.values().first { it.code == tanProcedure.bankInternalProcedureCode }, - mapTanProcedureType(tanProcedure.type), + mapTanMethodType(tanProcedure.type), null, // TODO: where to get HDD Version from? tanProcedure.maxTanInputLength, mapAllowedTanFormat(tanProcedure.allowedTanFormat) ) } - open fun mapTanProcedureType(type: TanProcedureType): net.dankito.banking.fints.model.TanProcedureType { + open fun mapTanMethodType(type: TanProcedureType): net.dankito.banking.fints.model.TanMethodType { return when (type) { - TanProcedureType.EnterTan -> net.dankito.banking.fints.model.TanProcedureType.EnterTan - TanProcedureType.ChipTanManuell -> net.dankito.banking.fints.model.TanProcedureType.ChipTanManuell - TanProcedureType.ChipTanFlickercode -> net.dankito.banking.fints.model.TanProcedureType.ChipTanFlickercode - TanProcedureType.ChipTanUsb -> net.dankito.banking.fints.model.TanProcedureType.ChipTanUsb - TanProcedureType.ChipTanQrCode -> net.dankito.banking.fints.model.TanProcedureType.ChipTanQrCode - TanProcedureType.ChipTanPhotoTanMatrixCode -> net.dankito.banking.fints.model.TanProcedureType.ChipTanPhotoTanMatrixCode - TanProcedureType.SmsTan -> net.dankito.banking.fints.model.TanProcedureType.SmsTan - TanProcedureType.AppTan -> net.dankito.banking.fints.model.TanProcedureType.AppTan - TanProcedureType.photoTan -> net.dankito.banking.fints.model.TanProcedureType.photoTan - TanProcedureType.QrCode -> net.dankito.banking.fints.model.TanProcedureType.QrCode + TanProcedureType.EnterTan -> net.dankito.banking.fints.model.TanMethodType.EnterTan + TanProcedureType.ChipTanManuell -> net.dankito.banking.fints.model.TanMethodType.ChipTanManuell + TanProcedureType.ChipTanFlickercode -> net.dankito.banking.fints.model.TanMethodType.ChipTanFlickercode + TanProcedureType.ChipTanUsb -> net.dankito.banking.fints.model.TanMethodType.ChipTanUsb + TanProcedureType.ChipTanQrCode -> net.dankito.banking.fints.model.TanMethodType.ChipTanQrCode + TanProcedureType.ChipTanPhotoTanMatrixCode -> net.dankito.banking.fints.model.TanMethodType.ChipTanPhotoTanMatrixCode + TanProcedureType.SmsTan -> net.dankito.banking.fints.model.TanMethodType.SmsTan + TanProcedureType.AppTan -> net.dankito.banking.fints.model.TanMethodType.AppTan + TanProcedureType.photoTan -> net.dankito.banking.fints.model.TanMethodType.photoTan + TanProcedureType.QrCode -> net.dankito.banking.fints.model.TanMethodType.QrCode } } @@ -427,8 +427,8 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } open fun mapEnterTanResult(result: EnterTanResult, bank: BankData): net.dankito.banking.fints.model.EnterTanResult { - result.changeTanProcedureTo?.let { changeTanProcedureTo -> - return net.dankito.banking.fints.model.EnterTanResult.userAsksToChangeTanProcedure(mapTanProcedure(changeTanProcedureTo)) + result.changeTanProcedureTo?.let { changeTanMethodTo -> + return net.dankito.banking.fints.model.EnterTanResult.userAsksToChangeTanMethod(mapTanMethod(changeTanMethodTo)) } result.changeTanMediumTo?.let { changeTanMediumTo -> @@ -462,13 +462,13 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { } return TanChallenge(tanChallenge.messageToShowToUser, - mapTanProcedure(tanChallenge.tanProcedure) + mapTanMethod(tanChallenge.tanMethod) ) } open fun mapTanChallenge(tanChallenge: net.dankito.banking.fints.model.FlickerCodeTanChallenge): FlickerCodeTanChallenge { return FlickerCodeTanChallenge(mapFlickerCode(tanChallenge.flickerCode), tanChallenge.messageToShowToUser, - mapTanProcedure(tanChallenge.tanProcedure) + mapTanMethod(tanChallenge.tanMethod) ) } @@ -478,7 +478,7 @@ open class fints4kModelMapper(protected val modelCreator: IModelCreator) { open fun mapTanChallenge(tanChallenge: net.dankito.banking.fints.model.ImageTanChallenge): ImageTanChallenge { return ImageTanChallenge(mapTanImage(tanChallenge.image), tanChallenge.messageToShowToUser, - mapTanProcedure(tanChallenge.tanProcedure) + mapTanMethod(tanChallenge.tanMethod) ) }