Implemented passing allowed TAN format and max TAN input length to UI so that controls can be set accordingly
This commit is contained in:
parent
fe5b2276c8
commit
c8f29e2390
|
@ -1138,6 +1138,7 @@ open class FinTsClient(
|
||||||
|
|
||||||
return TanProcedure(procedureName, parameters.securityFunction,
|
return TanProcedure(procedureName, parameters.securityFunction,
|
||||||
mapToTanProcedureType(parameters) ?: TanProcedureType.EnterTan, mapHhdVersion(parameters),
|
mapToTanProcedureType(parameters) ?: TanProcedureType.EnterTan, mapHhdVersion(parameters),
|
||||||
|
parameters.maxTanInputLength, parameters.allowedTanFormat,
|
||||||
parameters.nameOfTanMediaRequired == BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsMussAngegebenWerden)
|
parameters.nameOfTanMediaRequired == BezeichnungDesTanMediumsErforderlich.BezeichnungDesTanMediumsMussAngegebenWerden)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package net.dankito.banking.fints.model
|
package net.dankito.banking.fints.model
|
||||||
|
|
||||||
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion
|
import net.dankito.banking.fints.messages.datenelemente.implementierte.signatur.Sicherheitsfunktion
|
||||||
|
import net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat
|
||||||
|
|
||||||
|
|
||||||
open class TanProcedure(
|
open class TanProcedure(
|
||||||
|
@ -8,6 +9,8 @@ open class TanProcedure(
|
||||||
val securityFunction: Sicherheitsfunktion,
|
val securityFunction: Sicherheitsfunktion,
|
||||||
val type: TanProcedureType,
|
val type: TanProcedureType,
|
||||||
val hhdVersion: HHDVersion? = null,
|
val hhdVersion: HHDVersion? = null,
|
||||||
|
val maxTanInputLength: Int? = null,
|
||||||
|
val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric,
|
||||||
val nameOfTanMediaRequired: Boolean = false
|
val nameOfTanMediaRequired: Boolean = false
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package net.dankito.banking.ui.android.dialogs
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import android.text.InputFilter
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
@ -14,11 +15,10 @@ import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import kotlinx.android.synthetic.main.dialog_enter_tan.*
|
import kotlinx.android.synthetic.main.dialog_enter_tan.*
|
||||||
import kotlinx.android.synthetic.main.dialog_enter_tan.view.*
|
import kotlinx.android.synthetic.main.dialog_enter_tan.view.*
|
||||||
import kotlinx.android.synthetic.main.dialog_enter_tan.view.flickerCodeView
|
|
||||||
import net.dankito.banking.ui.android.R
|
import net.dankito.banking.ui.android.R
|
||||||
import net.dankito.banking.ui.android.di.BankingComponent
|
|
||||||
import net.dankito.banking.ui.android.adapter.TanMediumAdapter
|
import net.dankito.banking.ui.android.adapter.TanMediumAdapter
|
||||||
import net.dankito.banking.ui.android.adapter.TanProceduresAdapter
|
import net.dankito.banking.ui.android.adapter.TanProceduresAdapter
|
||||||
|
import net.dankito.banking.ui.android.di.BankingComponent
|
||||||
import net.dankito.banking.ui.android.listener.ListItemSelectedListener
|
import net.dankito.banking.ui.android.listener.ListItemSelectedListener
|
||||||
import net.dankito.banking.ui.model.Customer
|
import net.dankito.banking.ui.model.Customer
|
||||||
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
import net.dankito.banking.ui.model.responses.BankingClientResponse
|
||||||
|
@ -151,7 +151,14 @@ open class EnterTanDialog : DialogFragment() {
|
||||||
setupImageTanView(rootView)
|
setupImageTanView(rootView)
|
||||||
}
|
}
|
||||||
|
|
||||||
rootView.edtxtEnteredTan.inputType = InputType.TYPE_CLASS_NUMBER // TODO: is this always true that TAN is a number?
|
|
||||||
|
if (tanChallenge.tanProcedure.isNumericTan) {
|
||||||
|
rootView.edtxtEnteredTan.inputType = InputType.TYPE_CLASS_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
tanChallenge.tanProcedure.maxTanInputLength?.let { maxInputLength ->
|
||||||
|
rootView.edtxtEnteredTan.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(maxInputLength))
|
||||||
|
}
|
||||||
|
|
||||||
rootView.edtxtEnteredTan.setOnKeyListener { _, keyCode, _ ->
|
rootView.edtxtEnteredTan.setOnKeyListener { _, keyCode, _ ->
|
||||||
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
if (keyCode == KeyEvent.KEYCODE_ENTER) {
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package net.dankito.banking.ui.model.tan
|
||||||
|
|
||||||
|
|
||||||
|
enum class AllowedTanFormat {
|
||||||
|
|
||||||
|
Numeric,
|
||||||
|
|
||||||
|
Alphanumeric
|
||||||
|
|
||||||
|
}
|
|
@ -4,13 +4,18 @@ package net.dankito.banking.ui.model.tan
|
||||||
open class TanProcedure(
|
open class TanProcedure(
|
||||||
val displayName: String,
|
val displayName: String,
|
||||||
val type: TanProcedureType,
|
val type: TanProcedureType,
|
||||||
val bankInternalProcedureCode: String
|
val bankInternalProcedureCode: String,
|
||||||
|
val maxTanInputLength: Int? = null,
|
||||||
|
val allowedTanFormat: AllowedTanFormat = AllowedTanFormat.Alphanumeric
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
internal constructor() : this("", TanProcedureType.EnterTan, "") // for object deserializers
|
internal constructor() : this("", TanProcedureType.EnterTan, "") // for object deserializers
|
||||||
|
|
||||||
|
|
||||||
|
val isNumericTan: Boolean = allowedTanFormat == AllowedTanFormat.Numeric
|
||||||
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is TanProcedure) return false
|
if (other !is TanProcedure) return false
|
||||||
|
|
|
@ -73,14 +73,16 @@
|
||||||
<relationship name="supportedTanProcedures" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanProcedure"/>
|
<relationship name="supportedTanProcedures" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="PersistedTanProcedure"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="PersistedTanProcedure" representedClassName="PersistedTanProcedure" syncable="YES" codeGenerationType="class">
|
<entity name="PersistedTanProcedure" representedClassName="PersistedTanProcedure" syncable="YES" codeGenerationType="class">
|
||||||
|
<attribute name="allowedTanFormat" attributeType="String" defaultValueString=""/>
|
||||||
<attribute name="bankInternalProcedureCode" attributeType="String"/>
|
<attribute name="bankInternalProcedureCode" attributeType="String"/>
|
||||||
<attribute name="displayName" attributeType="String"/>
|
<attribute name="displayName" attributeType="String"/>
|
||||||
|
<attribute name="maxTanInputLength" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
|
||||||
<attribute name="type" attributeType="String"/>
|
<attribute name="type" attributeType="String"/>
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
<elements>
|
||||||
<element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/>
|
<element name="PersistedAccountTransaction" positionX="-36" positionY="45" width="128" height="553"/>
|
||||||
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="343"/>
|
<element name="PersistedBankAccount" positionX="-54" positionY="63" width="128" height="343"/>
|
||||||
<element name="PersistedCustomer" positionX="-63" positionY="-18" width="128" height="253"/>
|
<element name="PersistedCustomer" positionX="-63" positionY="-18" width="128" height="253"/>
|
||||||
<element name="PersistedTanProcedure" positionX="-54" positionY="135" width="128" height="88"/>
|
<element name="PersistedTanProcedure" positionX="-54" positionY="135" width="128" height="118"/>
|
||||||
</elements>
|
</elements>
|
||||||
</model>
|
</model>
|
|
@ -216,7 +216,9 @@ class Mapper {
|
||||||
let mapped = TanProcedure(
|
let mapped = TanProcedure(
|
||||||
displayName: map(tanProcedure.displayName),
|
displayName: map(tanProcedure.displayName),
|
||||||
type: mapTanProcedureType(tanProcedure.type),
|
type: mapTanProcedureType(tanProcedure.type),
|
||||||
bankInternalProcedureCode: map(tanProcedure.bankInternalProcedureCode)
|
bankInternalProcedureCode: map(tanProcedure.bankInternalProcedureCode),
|
||||||
|
maxTanInputLength: map(tanProcedure.maxTanInputLength),
|
||||||
|
allowedTanFormat: tanProcedure.allowedTanFormat == "numeric" ? .numeric : .alphanumeric
|
||||||
)
|
)
|
||||||
|
|
||||||
mappedTanProcedures[mapped] = tanProcedure
|
mappedTanProcedures[mapped] = tanProcedure
|
||||||
|
@ -235,6 +237,9 @@ class Mapper {
|
||||||
mapped.type = tanProcedure.type.name
|
mapped.type = tanProcedure.type.name
|
||||||
mapped.bankInternalProcedureCode = tanProcedure.bankInternalProcedureCode
|
mapped.bankInternalProcedureCode = tanProcedure.bankInternalProcedureCode
|
||||||
|
|
||||||
|
mapped.maxTanInputLength = map(tanProcedure.maxTanInputLength) ?? -1
|
||||||
|
mapped.allowedTanFormat = tanProcedure.allowedTanFormat.name
|
||||||
|
|
||||||
mappedTanProcedures[tanProcedure] = mapped
|
mappedTanProcedures[tanProcedure] = mapped
|
||||||
|
|
||||||
return mapped
|
return mapped
|
||||||
|
|
|
@ -105,7 +105,7 @@ struct EnterTanDialog: View {
|
||||||
.padding(.vertical, 2)
|
.padding(.vertical, 2)
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
UIKitTextField("Enter TAN:", text: $enteredTan, actionOnReturnKeyPress: {
|
UIKitTextField("Enter TAN:", text: $enteredTan, keyboardType: tanChallenge.tanProcedure.isNumericTan ? .numberPad : .default, actionOnReturnKeyPress: {
|
||||||
if self.isRequiredDataEntered() {
|
if self.isRequiredDataEntered() {
|
||||||
self.enteringTanDone()
|
self.enteringTanDone()
|
||||||
return true
|
return true
|
||||||
|
@ -214,9 +214,9 @@ struct EnterTanDialog_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let customer = Customer(bankCode: "", customerId: "", password: "", finTsServerAddress: "")
|
let customer = Customer(bankCode: "", customerId: "", password: "", finTsServerAddress: "")
|
||||||
customer.supportedTanProcedures = [
|
customer.supportedTanProcedures = [
|
||||||
TanProcedure(displayName: "chipTAN optisch", type: .chiptanflickercode, bankInternalProcedureCode: ""),
|
TanProcedure(displayName: "chipTAN optisch", type: .chiptanflickercode, bankInternalProcedureCode: "", maxTanInputLength: 6, allowedTanFormat: .numeric),
|
||||||
TanProcedure(displayName: "chipTAN QR", type: .chiptanqrcode, bankInternalProcedureCode: ""),
|
TanProcedure(displayName: "chipTAN QR", type: .chiptanqrcode, bankInternalProcedureCode: "", maxTanInputLength: 8, allowedTanFormat: .numeric),
|
||||||
TanProcedure(displayName: "Secure Super Duper Plus", type: .apptan, bankInternalProcedureCode: "")
|
TanProcedure(displayName: "Secure Super Duper Plus", type: .apptan, bankInternalProcedureCode: "", maxTanInputLength: 6, allowedTanFormat: .alphanumeric)
|
||||||
]
|
]
|
||||||
|
|
||||||
customer.tanMedia = [
|
customer.tanMedia = [
|
||||||
|
|
|
@ -72,7 +72,7 @@ struct ImageTanView: View {
|
||||||
struct ImageTanView_Previews: PreviewProvider {
|
struct ImageTanView_Previews: PreviewProvider {
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let tanChallenge = ImageTanChallenge(image: TanImage(mimeType: "image/png", imageBytes: KotlinByteArray(size: 0), decodingError: nil), messageToShowToUser: "", tanProcedure: TanProcedure(displayName: "", type: .phototan, bankInternalProcedureCode: ""))
|
let tanChallenge = ImageTanChallenge(image: TanImage(mimeType: "image/png", imageBytes: KotlinByteArray(size: 0), decodingError: nil), messageToShowToUser: "", tanProcedure: TanProcedure(displayName: "", type: .phototan, bankInternalProcedureCode: "", maxTanInputLength: 6, allowedTanFormat: .numeric))
|
||||||
|
|
||||||
return ImageTanView(tanChallenge)
|
return ImageTanView(tanChallenge)
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,9 @@ open class fints4kModelMapper {
|
||||||
return TanProcedure(
|
return TanProcedure(
|
||||||
tanProcedure.displayName,
|
tanProcedure.displayName,
|
||||||
mapTanProcedureType(tanProcedure.type),
|
mapTanProcedureType(tanProcedure.type),
|
||||||
tanProcedure.securityFunction.code
|
tanProcedure.securityFunction.code,
|
||||||
|
tanProcedure.maxTanInputLength,
|
||||||
|
mapAllowedTanFormat(tanProcedure.allowedTanFormat)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +259,13 @@ open class fints4kModelMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun mapAllowedTanFormat(allowedTanFormat: net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat): AllowedTanFormat {
|
||||||
|
return when (allowedTanFormat) {
|
||||||
|
net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat.Alphanumeric -> AllowedTanFormat.Alphanumeric
|
||||||
|
net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat.Numeric -> AllowedTanFormat.Numeric
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun findMappedTanProcedure(customer: Customer, tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure? {
|
protected open fun findMappedTanProcedure(customer: Customer, tanProcedure: net.dankito.banking.fints.model.TanProcedure): TanProcedure? {
|
||||||
return customer.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanProcedure.securityFunction.code }
|
return customer.supportedTanProcedures.firstOrNull { it.bankInternalProcedureCode == tanProcedure.securityFunction.code }
|
||||||
}
|
}
|
||||||
|
@ -350,7 +359,10 @@ open class fints4kModelMapper {
|
||||||
return net.dankito.banking.fints.model.TanProcedure(
|
return net.dankito.banking.fints.model.TanProcedure(
|
||||||
tanProcedure.displayName,
|
tanProcedure.displayName,
|
||||||
Sicherheitsfunktion.values().first { it.code == tanProcedure.bankInternalProcedureCode },
|
Sicherheitsfunktion.values().first { it.code == tanProcedure.bankInternalProcedureCode },
|
||||||
mapTanProcedureType(tanProcedure.type)
|
mapTanProcedureType(tanProcedure.type),
|
||||||
|
null, // TODO: where to get HDD Version from?
|
||||||
|
tanProcedure.maxTanInputLength,
|
||||||
|
mapAllowedTanFormat(tanProcedure.allowedTanFormat)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,6 +381,13 @@ open class fints4kModelMapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun mapAllowedTanFormat(allowedTanFormat: AllowedTanFormat): net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat {
|
||||||
|
return when (allowedTanFormat) {
|
||||||
|
AllowedTanFormat.Alphanumeric -> net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat.Alphanumeric
|
||||||
|
AllowedTanFormat.Numeric -> net.dankito.banking.fints.messages.datenelemente.implementierte.tan.AllowedTanFormat.Numeric
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open fun mapEnterTanResult(result: EnterTanResult, customer: CustomerData): net.dankito.banking.fints.model.EnterTanResult {
|
open fun mapEnterTanResult(result: EnterTanResult, customer: CustomerData): net.dankito.banking.fints.model.EnterTanResult {
|
||||||
result.changeTanProcedureTo?.let { changeTanProcedureTo ->
|
result.changeTanProcedureTo?.let { changeTanProcedureTo ->
|
||||||
return net.dankito.banking.fints.model.EnterTanResult.userAsksToChangeTanProcedure(mapTanProcedure(changeTanProcedureTo))
|
return net.dankito.banking.fints.model.EnterTanResult.userAsksToChangeTanProcedure(mapTanProcedure(changeTanProcedureTo))
|
||||||
|
|
Loading…
Reference in New Issue