Implemented mapping all tan procedures returned from German banks: Merged photoTAN and PushTan with appTAN, added ChipTanUsb and ChipTanPhotoTanMatrixCode, renamed ChipTanOptisch to ChipTanFlickercode
This commit is contained in:
parent
4d50ded3fa
commit
95ce20b5bb
|
@ -7,13 +7,15 @@ enum class TanProcedureType {
|
||||||
|
|
||||||
ChipTanManuell,
|
ChipTanManuell,
|
||||||
|
|
||||||
ChipTanOptisch,
|
ChipTanFlickercode,
|
||||||
|
|
||||||
|
ChipTanUsb,
|
||||||
|
|
||||||
ChipTanQrCode,
|
ChipTanQrCode,
|
||||||
|
|
||||||
PhotoTan,
|
ChipTanPhotoTanMatrixCode,
|
||||||
|
|
||||||
SmsTan,
|
SmsTan,
|
||||||
|
|
||||||
PushTan
|
AppTan
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ import javax.inject.Inject
|
||||||
open class EnterTanDialog : DialogFragment() {
|
open class EnterTanDialog : DialogFragment() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val OpticalTanProcedures = listOf(TanProcedureType.ChipTanOptisch, TanProcedureType.ChipTanQrCode, TanProcedureType.PhotoTan)
|
val OpticalTanProcedures = listOf(TanProcedureType.ChipTanFlickercode, TanProcedureType.ChipTanQrCode, TanProcedureType.ChipTanPhotoTanMatrixCode)
|
||||||
|
|
||||||
const val DialogTag = "EnterTanDialog"
|
const val DialogTag = "EnterTanDialog"
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,11 +217,12 @@ open class fints4javaModelMapper {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
net.dankito.fints.model.TanProcedureType.EnterTan -> TanProcedureType.EnterTan
|
net.dankito.fints.model.TanProcedureType.EnterTan -> TanProcedureType.EnterTan
|
||||||
net.dankito.fints.model.TanProcedureType.ChipTanManuell -> TanProcedureType.ChipTanManuell
|
net.dankito.fints.model.TanProcedureType.ChipTanManuell -> TanProcedureType.ChipTanManuell
|
||||||
net.dankito.fints.model.TanProcedureType.ChipTanOptisch -> TanProcedureType.ChipTanOptisch
|
net.dankito.fints.model.TanProcedureType.ChipTanFlickercode -> TanProcedureType.ChipTanFlickercode
|
||||||
|
net.dankito.fints.model.TanProcedureType.ChipTanUsb -> TanProcedureType.ChipTanUsb
|
||||||
net.dankito.fints.model.TanProcedureType.ChipTanQrCode -> TanProcedureType.ChipTanQrCode
|
net.dankito.fints.model.TanProcedureType.ChipTanQrCode -> TanProcedureType.ChipTanQrCode
|
||||||
net.dankito.fints.model.TanProcedureType.PhotoTan -> TanProcedureType.PhotoTan
|
net.dankito.fints.model.TanProcedureType.ChipTanPhotoTanMatrixCode -> TanProcedureType.ChipTanPhotoTanMatrixCode
|
||||||
net.dankito.fints.model.TanProcedureType.SmsTan -> TanProcedureType.SmsTan
|
net.dankito.fints.model.TanProcedureType.SmsTan -> TanProcedureType.SmsTan
|
||||||
net.dankito.fints.model.TanProcedureType.PushTan -> TanProcedureType.PushTan
|
net.dankito.fints.model.TanProcedureType.AppTan -> TanProcedureType.AppTan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,11 +301,12 @@ open class fints4javaModelMapper {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
TanProcedureType.EnterTan -> net.dankito.fints.model.TanProcedureType.EnterTan
|
TanProcedureType.EnterTan -> net.dankito.fints.model.TanProcedureType.EnterTan
|
||||||
TanProcedureType.ChipTanManuell -> net.dankito.fints.model.TanProcedureType.ChipTanManuell
|
TanProcedureType.ChipTanManuell -> net.dankito.fints.model.TanProcedureType.ChipTanManuell
|
||||||
TanProcedureType.ChipTanOptisch -> net.dankito.fints.model.TanProcedureType.ChipTanOptisch
|
TanProcedureType.ChipTanFlickercode -> net.dankito.fints.model.TanProcedureType.ChipTanFlickercode
|
||||||
|
TanProcedureType.ChipTanUsb -> net.dankito.fints.model.TanProcedureType.ChipTanUsb
|
||||||
TanProcedureType.ChipTanQrCode -> net.dankito.fints.model.TanProcedureType.ChipTanQrCode
|
TanProcedureType.ChipTanQrCode -> net.dankito.fints.model.TanProcedureType.ChipTanQrCode
|
||||||
TanProcedureType.PhotoTan -> net.dankito.fints.model.TanProcedureType.PhotoTan
|
TanProcedureType.ChipTanPhotoTanMatrixCode -> net.dankito.fints.model.TanProcedureType.ChipTanPhotoTanMatrixCode
|
||||||
TanProcedureType.SmsTan -> net.dankito.fints.model.TanProcedureType.SmsTan
|
TanProcedureType.SmsTan -> net.dankito.fints.model.TanProcedureType.SmsTan
|
||||||
TanProcedureType.PushTan -> net.dankito.fints.model.TanProcedureType.PushTan
|
TanProcedureType.AppTan -> net.dankito.fints.model.TanProcedureType.AppTan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.dankito.fints.messages.datenelemente.implementierte.signatur.Sicherhe
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanGeneratorTanMedium
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMedienArtVersion
|
||||||
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.TanMediumKlasse
|
||||||
|
import net.dankito.fints.messages.datenelemente.implementierte.tan.ZkaTanProcedure
|
||||||
import net.dankito.fints.messages.segmente.id.CustomerSegmentId
|
import net.dankito.fints.messages.segmente.id.CustomerSegmentId
|
||||||
import net.dankito.fints.model.*
|
import net.dankito.fints.model.*
|
||||||
import net.dankito.fints.response.InstituteSegmentId
|
import net.dankito.fints.response.InstituteSegmentId
|
||||||
|
@ -694,10 +695,10 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
val tanProcedure = customer.selectedTanProcedure
|
val tanProcedure = customer.selectedTanProcedure
|
||||||
|
|
||||||
return when (tanProcedure.type) {
|
return when (tanProcedure.type) {
|
||||||
TanProcedureType.ChipTanOptisch, TanProcedureType.ChipTanManuell ->
|
TanProcedureType.ChipTanFlickercode, TanProcedureType.ChipTanManuell ->
|
||||||
FlickerCodeTanChallenge(FlickerCodeDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
FlickerCodeTanChallenge(FlickerCodeDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
||||||
|
|
||||||
TanProcedureType.ChipTanQrCode, TanProcedureType.PhotoTan ->
|
TanProcedureType.ChipTanQrCode, TanProcedureType.ChipTanPhotoTanMatrixCode ->
|
||||||
ImageTanChallenge(TanImageDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
ImageTanChallenge(TanImageDecoder().decodeChallenge(challenge), messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
||||||
|
|
||||||
else -> TanChallenge(messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
else -> TanChallenge(messageToShowToUser, challenge, tanProcedure, tanResponse.tanMediaIdentifier)
|
||||||
|
@ -913,28 +914,71 @@ open class FinTsClient @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun mapToTanProcedureType(parameters: TanProcedureParameters): TanProcedureType? {
|
protected open fun mapToTanProcedureType(parameters: TanProcedureParameters): TanProcedureType? {
|
||||||
val nameLowerCase = parameters.procedureName.toLowerCase()
|
val name = parameters.procedureName.toLowerCase()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
nameLowerCase.contains("photo") -> TanProcedureType.PhotoTan
|
// 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
|
||||||
|
|
||||||
nameLowerCase.contains("chiptan") -> {
|
// names are like 'chipTAN optisch/comfort', 'SmartTAN (plus) optic/USB', 'chipTAN (Flicker)' and
|
||||||
return when {
|
// technical identification is 'HHDOPT1'
|
||||||
nameLowerCase.contains("qr") -> TanProcedureType.ChipTanQrCode
|
parameters.zkaTanProcedure == ZkaTanProcedure.HHDOPT1 ||
|
||||||
nameLowerCase.contains("manuell") -> TanProcedureType.ChipTanManuell
|
tanProcedureNameContains(name, "optisch", "optic", "comfort", "flicker") ->
|
||||||
else -> TanProcedureType.ChipTanOptisch
|
TanProcedureType.ChipTanFlickercode
|
||||||
}
|
|
||||||
|
// 'Smart-TAN plus optisch / USB' seems to be a Flickertan procedure -> test for 'optisch' first
|
||||||
|
name.contains("usb") -> TanProcedureType.ChipTanUsb
|
||||||
|
|
||||||
|
// QRTAN+ from 1822 direct has nothing to do with chipTAN QR.
|
||||||
|
name.contains("qr") -> {
|
||||||
|
if (tanProcedureNameContains(name, "chipTAN", "Smart")) TanProcedureType.ChipTanQrCode
|
||||||
|
else TanProcedureType.AppTan
|
||||||
}
|
}
|
||||||
|
|
||||||
nameLowerCase.contains("push") -> return TanProcedureType.PushTan
|
// photoTAN from Commerzbank (comdirect), Deutsche Bank, norisbank has nothing to do with chipTAN photo
|
||||||
nameLowerCase.contains("sms") || nameLowerCase.contains("mobile") -> return TanProcedureType.SmsTan
|
name.contains("photo") -> {
|
||||||
|
// e.g. 'Smart-TAN photo' / description 'Challenge'
|
||||||
|
if (tanProcedureNameContains(name, "chipTAN", "Smart")) TanProcedureType.ChipTanPhotoTanMatrixCode
|
||||||
|
// e.g. 'photoTAN-Verfahren', description 'Freigabe durch photoTAN'
|
||||||
|
else TanProcedureType.AppTan
|
||||||
|
}
|
||||||
|
|
||||||
|
tanProcedureNameContains(name, "SMS", "mobile", "mTAN") -> TanProcedureType.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
|
||||||
|
|
||||||
// TODO: what about other tan procedures we're not aware of?
|
|
||||||
// we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2
|
// we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun tanProcedureNameContains(name: String, vararg namesToTest: String): Boolean {
|
||||||
|
namesToTest.forEach { nameToTest ->
|
||||||
|
if (name.contains(nameToTest.toLowerCase())) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun technicalTanProcedureIdentificationContains(parameters: TanProcedureParameters, vararg valuesToTest: String): Boolean {
|
||||||
|
valuesToTest.forEach { valueToTest ->
|
||||||
|
if (parameters.technicalTanProcedureIdentification.contains(valueToTest, true)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun isJobSupported(account: AccountData, supportedJob: JobParameters): Boolean {
|
protected open fun isJobSupported(account: AccountData, supportedJob: JobParameters): Boolean {
|
||||||
for (allowedJobName in account.allowedJobNames) {
|
for (allowedJobName in account.allowedJobNames) {
|
||||||
if (allowedJobName == supportedJob.jobName) {
|
if (allowedJobName == supportedJob.jobName) {
|
||||||
|
|
|
@ -13,8 +13,6 @@ enum class ZkaTanProcedure {
|
||||||
|
|
||||||
// values not specified by standard but found out there in the wild
|
// values not specified by standard but found out there in the wild
|
||||||
|
|
||||||
photoTAN,
|
|
||||||
|
|
||||||
appTAN
|
appTAN
|
||||||
|
|
||||||
}
|
}
|
|
@ -7,14 +7,16 @@ enum class TanProcedureType {
|
||||||
|
|
||||||
ChipTanManuell,
|
ChipTanManuell,
|
||||||
|
|
||||||
ChipTanOptisch,
|
ChipTanFlickercode,
|
||||||
|
|
||||||
|
ChipTanUsb,
|
||||||
|
|
||||||
ChipTanQrCode,
|
ChipTanQrCode,
|
||||||
|
|
||||||
PhotoTan,
|
ChipTanPhotoTanMatrixCode,
|
||||||
|
|
||||||
SmsTan,
|
SmsTan,
|
||||||
|
|
||||||
PushTan
|
AppTan
|
||||||
|
|
||||||
}
|
}
|
|
@ -390,7 +390,7 @@ open class ResponseParser @JvmOverloads constructor(
|
||||||
return ZkaTanProcedure.mobileTAN
|
return ZkaTanProcedure.mobileTAN
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lowerCaseMayZkaTanProcedure == "apptan") {
|
if (lowerCaseMayZkaTanProcedure == "apptan" || lowerCaseMayZkaTanProcedure == "phototan") {
|
||||||
return ZkaTanProcedure.appTAN
|
return ZkaTanProcedure.appTAN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ abstract class FinTsTestBase {
|
||||||
|
|
||||||
const val ControlReference = "4477"
|
const val ControlReference = "4477"
|
||||||
|
|
||||||
val Customer = CustomerData(CustomerId, Pin, selectedTanProcedure = TanProcedure("chipTAN-optisch", SecurityFunction, TanProcedureType.ChipTanOptisch), selectedLanguage = Language)
|
val Customer = CustomerData(CustomerId, Pin, selectedTanProcedure = TanProcedure("chipTAN-optisch", SecurityFunction, TanProcedureType.ChipTanFlickercode), selectedLanguage = Language)
|
||||||
|
|
||||||
val Currency = "EUR"
|
val Currency = "EUR"
|
||||||
|
|
||||||
|
|
|
@ -88,12 +88,12 @@ open class hbci4jModelMapper {
|
||||||
net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.ChipTanQrCode, code)
|
net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.ChipTanQrCode, code)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.ChipTanOptisch, code)
|
net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.ChipTanFlickercode, code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
displayNameLowerCase.contains("sms") -> net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.SmsTan, code)
|
displayNameLowerCase.contains("sms") -> net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.SmsTan, code)
|
||||||
displayNameLowerCase.contains("push") -> net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.PushTan, code)
|
displayNameLowerCase.contains("push") -> net.dankito.banking.ui.model.tan.TanProcedure(displayName, TanProcedureType.AppTan, code)
|
||||||
|
|
||||||
// we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2
|
// we filter out iTAN and Einschritt-Verfahren as they are not permitted anymore according to PSD2
|
||||||
else -> null
|
else -> null
|
||||||
|
|
Loading…
Reference in New Issue