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 927aef16..7e0e0ae3 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClient.kt @@ -53,7 +53,7 @@ open class FinTsClient( if (getAccountInfoResponse.successful == false || param.retrieveOnlyAccountInfo) { return GetAccountDataResponse(mapper.mapErrorCode(getAccountInfoResponse), mapper.mapErrorMessages(getAccountInfoResponse), null, - getAccountInfoResponse.messageLogWithoutSensitiveData, bank) + getAccountInfoResponse.messageLog, bank) } else { return getAccountData(param, getAccountInfoResponse.bank, getAccountInfoResponse.bank.accounts, getAccountInfoResponse) } @@ -69,7 +69,7 @@ open class FinTsClient( if (accountsSupportingRetrievingTransactions.isEmpty()) { val errorMessage = "None of the accounts ${accounts.map { it.productName }} supports retrieving balance or transactions" // TODO: translate - return GetAccountDataResponse(ErrorCode.NoneOfTheAccountsSupportsRetrievingData, errorMessage, mapper.map(bank), previousJobResponse?.messageLogWithoutSensitiveData ?: listOf(), bank) + return GetAccountDataResponse(ErrorCode.NoneOfTheAccountsSupportsRetrievingData, errorMessage, mapper.map(bank), previousJobResponse?.messageLog ?: listOf(), bank) } accountsSupportingRetrievingTransactions.forEach { account -> @@ -115,7 +115,7 @@ open class FinTsClient( if (getAccountInfoResponse.successful == false) { return TransferMoneyResponse(mapper.mapErrorCode(getAccountInfoResponse), mapper.mapErrorMessages(getAccountInfoResponse), - getAccountInfoResponse.messageLogWithoutSensitiveData, bank) + getAccountInfoResponse.messageLog, bank) } else { return transferMoneyAsync(param, recipientBankIdentifier, getAccountInfoResponse.bank, getAccountInfoResponse.bank.accounts, getAccountInfoResponse) } @@ -129,14 +129,14 @@ open class FinTsClient( val accountToUse: AccountData if (accountsSupportingTransfer.isEmpty()) { - return TransferMoneyResponse(ErrorCode.NoAccountSupportsMoneyTransfer, "None of the accounts $accounts supports money transfer", previousJobResponse?.messageLogWithoutSensitiveData ?: listOf(), bank) + return TransferMoneyResponse(ErrorCode.NoAccountSupportsMoneyTransfer, "None of the accounts $accounts supports money transfer", previousJobResponse?.messageLog ?: listOf(), bank) } else if (accountsSupportingTransfer.size == 1) { accountToUse = accountsSupportingTransfer.first() } else { val selectedAccount = param.selectAccountToUseForTransfer?.invoke(accountsSupportingTransfer) if (selectedAccount == null) { - return TransferMoneyResponse(ErrorCode.MoreThanOneAccountSupportsMoneyTransfer, "More than one of the accounts $accountsSupportingTransfer supports money transfer, so we cannot clearly determine which one to use for this transfer", previousJobResponse?.messageLogWithoutSensitiveData ?: listOf(), bank) + return TransferMoneyResponse(ErrorCode.MoreThanOneAccountSupportsMoneyTransfer, "More than one of the accounts $accountsSupportingTransfer supports money transfer, so we cannot clearly determine which one to use for this transfer", previousJobResponse?.messageLog ?: listOf(), bank) } accountToUse = selectedAccount diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt index 8c29c709..afa30d96 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/FinTsClientForCustomer.kt @@ -20,7 +20,7 @@ open class FinTsClientForCustomer( protected val client = FinTsClientDeprecated(config, callback) - open val messageLogWithoutSensitiveData: List = mutableListOf() + open val messageLog: List = mutableListOf() open suspend fun addAccountAsync(): AddAccountResponse { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/config/FinTsClientOptions.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/config/FinTsClientOptions.kt index 57d6dfc7..cab7bfa6 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/config/FinTsClientOptions.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/config/FinTsClientOptions.kt @@ -3,6 +3,7 @@ package net.dankito.banking.fints.config import net.dankito.banking.fints.model.ProductData data class FinTsClientOptions( + val removeSensitiveDataFromMessageLog: Boolean = true, val version: String = "1.0.0", // TODO: get version dynamically val productName: String = "15E53C26816138699C7B6A3E8" ) { diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt index 739fbbf9..c3f5768f 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/log/MessageLogCollector.kt @@ -1,8 +1,8 @@ package net.dankito.banking.fints.log -import net.codinux.log.Logger import net.codinux.log.LoggerFactory import net.codinux.log.logger +import net.dankito.banking.fints.config.FinTsClientOptions import net.dankito.banking.fints.model.BankData import net.dankito.banking.fints.model.MessageLogEntry import net.dankito.banking.fints.model.MessageLogEntryType @@ -12,7 +12,9 @@ import net.dankito.banking.fints.extensions.toStringWithMinDigits import kotlin.reflect.KClass -open class MessageLogCollector { +open class MessageLogCollector( + private val options: FinTsClientOptions = FinTsClientOptions() +) { companion object { val FindAccountTransactionsStartRegex = Regex("^HIKAZ:\\d:\\d:\\d\\+@\\d+@", RegexOption.MULTILINE) @@ -26,12 +28,12 @@ open class MessageLogCollector { } - protected open val messageLog = ArrayList() // TODO: make thread safe like with CopyOnWriteArrayList + protected open val _messageLog = ArrayList() // TODO: make thread safe like with CopyOnWriteArrayList // in either case remove sensitive data after response is parsed as otherwise some information like account holder name and accounts may is not set yet on BankData - open val messageLogWithoutSensitiveData: List + open val messageLog: List // safe CPU cycles by only formatting and removing sensitive data if messageLog is really requested - get() = messageLog.map { MessageLogEntry(it.type, it.context, it.messageTrace, createMessageForLog(it), it.error, it.time) } + get() = _messageLog.map { MessageLogEntry(it.type, it.context, it.messageTrace, createMessageForLog(it), it.error, it.time) } private fun createMessageForLog(logEntry: MessageLogEntry): String { val message = if (logEntry.type == MessageLogEntryType.Error) { @@ -40,7 +42,11 @@ open class MessageLogCollector { logEntry.messageTrace + "\n" + prettyPrintHbciMessage(logEntry.message) } - return safelyRemoveSensitiveDataFromMessage(message, logEntry.context.bank) + return if (options.removeSensitiveDataFromMessageLog) { + safelyRemoveSensitiveDataFromMessage(message, logEntry.context.bank) + } else { + message + } } @@ -62,7 +68,7 @@ open class MessageLogCollector { } protected open fun addMessageLogEntry(type: MessageLogEntryType, context: MessageContext, messageTrace: String, message: String, error: Throwable? = null) { - messageLog.add(MessageLogEntry(type, context, messageTrace, message, error)) + _messageLog.add(MessageLogEntry(type, context, messageTrace, message, error)) } diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/mapper/FinTsModelMapper.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/mapper/FinTsModelMapper.kt index d6508cea..f8674e70 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/mapper/FinTsModelMapper.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/mapper/FinTsModelMapper.kt @@ -158,7 +158,7 @@ open class FinTsModelMapper { } open fun mergeMessageLog(vararg responses: FinTsClientResponse?): List { - return responses.filterNotNull().flatMap { it.messageLogWithoutSensitiveData } + return responses.filterNotNull().flatMap { it.messageLog } } } \ No newline at end of file diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/JobContext.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/JobContext.kt index 0ec9ffee..694943dc 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/JobContext.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/model/JobContext.kt @@ -24,7 +24,7 @@ open class JobContext( * Only set if the current context is for a specific account (like get account's transactions). */ open val account: AccountData? = null, - protected open val messageLogCollector: MessageLogCollector = MessageLogCollector() + protected open val messageLogCollector: MessageLogCollector = MessageLogCollector(config.options) ) : MessageBaseData(bank, config.options.product), IMessageLogAppender { companion object { @@ -38,8 +38,8 @@ open class JobContext( open val responseParser: ResponseParser = ResponseParser(logAppender = this) - open val messageLogWithoutSensitiveData: List - get() = messageLogCollector.messageLogWithoutSensitiveData + open val messageLog: List + get() = messageLogCollector.messageLog open var dialog: DialogContext = DialogContext() // create null value so that variable is not 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 e61a13f4..ed63ec7a 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 @@ -17,7 +17,7 @@ open class FinTsClientResponse( open val isStrongAuthenticationRequired: Boolean, open val tanRequired: TanResponse? = null, - open val messageLogWithoutSensitiveData: List, + open val messageLog: List, /** * A fints4k internal error like an error occurred during web request or response parsing. @@ -43,7 +43,7 @@ open class FinTsClientResponse( constructor(context: JobContext, response: BankResponse) : this(response.successful, response.didReceiveResponse, response.noTanMethodSelected, - response.isStrongAuthenticationRequired, response.tanResponse, context.messageLogWithoutSensitiveData, + response.isStrongAuthenticationRequired, response.tanResponse, context.messageLog, response.internalError, response.errorsToShowToUser, response.isPinLocked, response.wrongCredentialsEntered, response.tanRequiredButUserDidNotEnterOne, response.tanRequiredButWeWereToldToAbortIfSo, response.messageThatCouldNotBeCreated?.isJobAllowed ?: true, diff --git a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetTransactionsResponse.kt b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetTransactionsResponse.kt index 32664155..a21aac4c 100644 --- a/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetTransactionsResponse.kt +++ b/fints4k/src/commonMain/kotlin/net/dankito/banking/fints/response/client/GetTransactionsResponse.kt @@ -8,7 +8,7 @@ open class GetTransactionsResponse( errorMessage: String? = null ) : FinTsClientResponse(isSuccessful(retrievedResponses), retrievedResponses.all { it.didReceiveResponse }, retrievedResponses.any { it.noTanMethodSelected }, retrievedResponses.any { it.isStrongAuthenticationRequired }, retrievedResponses.map { it.tanRequired }.firstOrNull(), - retrievedResponses.flatMap { it.messageLogWithoutSensitiveData }, + retrievedResponses.flatMap { it.messageLog }, errorMessage ?: retrievedResponses.mapNotNull { it.internalError }.joinToString("\r\n"), retrievedResponses.flatMap { it.errorMessagesFromBank }, retrievedResponses.any { it.isPinLocked }, retrievedResponses.any { it.wrongCredentialsEntered }, retrievedResponses.any { it.userCancelledAction },