Compare commits

..

No commits in common. "44a875eeeca949e48d1b03e1b2e9984e14588df8" and "4fbb0425e634f728edf16fce0b6c9c19696b5446" have entirely different histories.

4 changed files with 15 additions and 48 deletions

View File

@ -21,7 +21,7 @@ open class TanChallenge(
* As [availableTanMethods] also contains selected TanMethod, we didn't want to duplicate this object. Use
* [selectedTanMethod] to get selected TanMethod or iterate over [availableTanMethods] and filter selected one by this id.
*/
open val selectedTanMethodIdentifier: String,
open val selectedTanMethodId: String,
/**
* When adding an account, frontend has no UserAccount object in BankingClientCallback to know which TanMethods are
* available for user.
@ -38,7 +38,7 @@ open class TanChallenge(
* As [availableTanMedia] also contains selected TanMedium, we didn't want to duplicate this object. Use
* [selectedTanMedium] to get selected TanMedium or iterate over [availableTanMedia] and filter selected one by this medium name.
*/
open val selectedTanMediumIdentifier: String? = null,
open val selectedTanMediumName: String? = null,
open val availableTanMedia: List<TanMedium> = emptyList(),
open val tanImage: TanImage? = null,
@ -56,11 +56,11 @@ open class TanChallenge(
@get:JsonIgnore
open val selectedTanMethod: TanMethod
get() = availableTanMethods.first { it.identifier == selectedTanMethodIdentifier }
get() = availableTanMethods.first { it.identifier == selectedTanMethodId }
@get:JsonIgnore
open val selectedTanMedium: TanMedium?
get() = availableTanMedia.firstOrNull { it.mediumName == selectedTanMediumIdentifier }
get() = availableTanMedia.firstOrNull { it.mediumName == selectedTanMediumName }
/**

View File

@ -292,11 +292,11 @@ open class FinTs4kMapper {
val action = mapActionRequiringTan(challenge.forAction)
val tanMethods = challenge.bank.tanMethodsAvailableForUser.map { mapTanMethod(it) }
val selectedTanMethodIdentifier = challenge.tanMethod.securityFunction.code
val selectedTanMethodId = challenge.tanMethod.securityFunction.code
val tanMedia = challenge.bank.tanMedia.map { mapTanMedium(it) }
// TanMedium has not natural id in FinTS model so we have to create our own one
val selectedTanMediumIdentifier = challenge.bank.selectedTanMedium?.let { selected -> tanMedia.firstOrNull { it == selected } }?.identifier
val selectedTanMediumName = challenge.bank.selectedTanMedium?.let { selected -> tanMedia.firstOrNull { it == selected } }?.identifier
val bank = mapToBankViewInfo(challenge.bank)
val account = challenge.account?.let { mapToBankAccountViewInfo(it) }
@ -304,7 +304,7 @@ open class FinTs4kMapper {
val tanImage = if (challenge is ImageTanChallenge) mapTanImage(challenge.image) else null
val flickerCode = if (challenge is FlickerCodeTanChallenge) mapFlickerCode(challenge.flickerCode) else null
return object : TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodIdentifier, tanMethods, selectedTanMediumIdentifier, tanMedia, tanImage, flickerCode, bank, account, challenge.tanExpirationTime, challenge.challengeCreationTimestamp) {
return object : TanChallenge(type, action, challenge.messageToShowToUser, selectedTanMethodId, tanMethods, selectedTanMediumName, tanMedia, tanImage, flickerCode, bank, account, challenge.tanExpirationTime, challenge.challengeCreationTimestamp) {
override fun addTanExpiredCallback(callback: () -> Unit) {
challenge.addTanExpiredCallback(callback)
}

View File

@ -82,10 +82,7 @@ class ShowUsage {
This fetches the booked account transactions of the last 90 days. In most cases no TAN is required for this.
#### GetAccountData parameter
You can also specify options e.g. which transactions you would like to retrieve:
You can also specify options e.g. which transactions should be retrieved:
```kotlin
val options = GetAccountDataOptions(
@ -98,40 +95,20 @@ val options = GetAccountDataOptions(
val response = client.getAccountData(options)
```
#### TAN handling
Retrieving transactions older than 90 days or sometimes even log in requires a TAN, so add TAN handling in Client Callback:
Retrieving transactions older than 90 days requires a TAN, so add TAN handling in Client Callback:
```kotlin
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
val tan: String? = null // if a TAN is required, read TAN from command line, add a UI, ...
val tan: String? = null // if a TAN is required, add a UI or ...
callback.invoke(EnterTanResult(tan)) // ... set a break point here, get TAN e.g. from your TAN app, set tan variable in debugger view and resume debugger
})
```
E.g. TAN handling on the command line:
```kotlin
println("Enter password for $bankCode:")
val password = readln() // as an alternative for hard coding password; of course can also be done for bankCode and login name
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
println("A TAN is required for ${tanChallenge.forAction}. Selected TAN method is '${tanChallenge.selectedTanMethod.displayName}'. Messsage of your credit institute:")
println(tanChallenge.messageToShowToUser)
println("Get TAN from your TAN app etc., enter it and press Enter (or press Enter without an input to abort process):")
val tan: String? = readlnOrNull().takeUnless { it.isNullOrBlank() } // map empty input to null to abort process
callback.invoke(EnterTanResult(tan))
})
```
#### Error handling
Add some error handling by checking `response.error`:
```kotlin
response.error?.let{ error ->
println("Could not fetch account data: ${error.type} ${error.internalError ?: error.errorMessagesFromBank.joinToString()}")
println("Could not fetch account data: ${error.internalError ?: error.errorMessagesFromBank.joinToString()}")
}
```

View File

@ -42,16 +42,9 @@ class ShowUsage {
}
fun getAccountDataFullExample() {
println("Enter password for $bankCode:")
val password = readln() // as an alternative for hard coding password; of course can also be done for bankCode and login name
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
println("A TAN is required for ${tanChallenge.forAction}. Selected TAN method is '${tanChallenge.selectedTanMethod.displayName}'. Messsage of your credit institute:")
println(tanChallenge.messageToShowToUser)
println("Get TAN from your TAN app etc., enter it and press Enter (or press Enter without an input to abort process):")
val tan: String? = readlnOrNull().takeUnless { it.isNullOrBlank() } // map empty input to null to abort process
callback.invoke(EnterTanResult(tan))
val tan: String? = null // if a TAN is required, add a UI or ...
callback.invoke(EnterTanResult(tan)) // ... set a break point here, get TAN e.g. from your TAN app, set tan variable in debugger view and resume debugger
})
val options = GetAccountDataOptions(
@ -64,7 +57,7 @@ class ShowUsage {
val response = client.getAccountData(options)
response.error?.let{ error ->
println("Could not fetch account data: ${error.type} ${error.internalError ?: error.errorMessagesFromBank.joinToString()}")
println("Could not fetch account data: ${error.internalError ?: error.errorMessagesFromBank.joinToString()}")
}
printReceivedData(response)
@ -72,10 +65,7 @@ class ShowUsage {
fun updateAccountTransactions() {
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback { tanChallenge, callback ->
val tan: String? = readlnOrNull() // if a TAN is required, read TAN from command line, add a UI, ...
callback.invoke(EnterTanResult(tan)) // ... set a break point here, get TAN e.g. from your TAN app, set tan variable in debugger view and resume debugger
})
val client = FinTs4kBankingClientForUser(bankCode, loginName, password, SimpleBankingClientCallback())
// simulate account transactions we retrieved last time
val today = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).date