taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit a65f2682814c2a8ed8c148322d959cef226b234b
parent 685de878b071628f06781af18a6ffb90f07b9452
Author: Marc Stibane <marc@taler.net>
Date:   Tue,  2 Sep 2025 13:26:48 +0200

Improve totp

Diffstat:
MTalerWallet1/Controllers/PublicConstants.swift | 5++++-
MTalerWallet1/Helper/SwiftNFC.swift | 9+++++----
MTalerWallet1/Views/HelperViews/GradientBorder.swift | 47+++++++++++++++++++++++++++++++++++++++++++----
MTalerWallet1/Views/Transactions/TransactionPayDetailV.swift | 3+--
4 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/TalerWallet1/Controllers/PublicConstants.swift b/TalerWallet1/Controllers/PublicConstants.swift @@ -50,7 +50,6 @@ public let SETTINGS = "gear" // 􀍟 public let QRBUTTON = "qrcode.viewfinder" // 􀎻 1.0 (iOS 13) public let QRCODE = "qrcode" // 􀖂 1.0 (iOS 13) public let NFCLOGO = "wave.3.right.circle" // 􀭹 2.0 (iOS 14) -public let LOCKCLOCK = "lock.badge.clock" // 􂆉 5.0 (iOS 17) public let CONFIRM_BANK = "circle.fill" // 􀀁 badge in PendingRow, TransactionRow and TransactionSummary public let NEEDS_KYC = "star.fill" // 􀋃 badge in PendingRow, TransactionRow and TransactionSummary @@ -105,6 +104,10 @@ public let ICONNAME_ZOOM_OUT = "taler.right.and.left.fill" // 􀟧 public let SYSTEM_ZOOM_IN = "arrowtriangle.left.and.line.vertical.and.arrowtriangle.right.fill" // 􀟦 3.0 (iOS 15) public let SYSTEM_ZOOM_OUT = "arrowtriangle.right.and.line.vertical.and.arrowtriangle.left.fill" // 􀟧 3.0 (iOS 15) +public let ICONNAME_LOCKCLOCK = "taler.lock.clock" // 􂆉 +public let SYSTEM_LOCKCLOCK = "lock.badge.clock" // 􂆉 5.0 (iOS 17) +public let FALLBACK_LOCK = "lock" // 􀎠 1.0 (iOS 13) + public let HTTPS = "https://" //public let DEMOBANK = HTTPS + "bAnK.dEmO.tAlEr.nEt" // should be weird to read, but still work //public let DEMOEXCHANGE = HTTPS + "eXcHaNgE.dEmO.tAlEr.nEt" diff --git a/TalerWallet1/Helper/SwiftNFC.swift b/TalerWallet1/Helper/SwiftNFC.swift @@ -77,15 +77,16 @@ public class NFCWriter: NSObject, ObservableObject, NFCNDEFReaderSessionDelegate public var endAlert = "" public var msg = "" public var type = "T" // T=TAG - U=URL - + public var data: Data? = nil + public var session: NFCNDEFReaderSession? - public func write(_ data: String) { + public func write(_ data: Data? = nil) { guard NFCNDEFReaderSession.readingAvailable else { print("Error readingAvailable") return } - msg = data + self.data = data session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false) if let session { session.alertMessage = self.startAlert @@ -138,7 +139,7 @@ public class NFCWriter: NSObject, ObservableObject, NFCNDEFReaderSessionDelegate format: .nfcWellKnown, type: Data("\(self.type)".utf8), identifier: Data(), - payload: Data("\(self.msg)".utf8) + payload: self.data ?? Data("\(self.msg)".utf8) ) } else { payload = NFCNDEFPayload.wellKnownTypeURIPayload(string: "\(self.msg)") diff --git a/TalerWallet1/Views/HelperViews/GradientBorder.swift b/TalerWallet1/Views/HelperViews/GradientBorder.swift @@ -108,8 +108,15 @@ struct BorderWithHCE<Content: View>: View { } } // MARK: - +extension FixedWidthInteger { + var data: Data { + let data = withUnsafeBytes(of: self) { Data($0) } + return data + } +} + struct BorderWithNFC<Content: View>: View { - let talerURI: String // might be a TOTP code + let totpString: String // might be a TOTP code let nfcHint: Bool let size: CGFloat let scanHints: (String, String)? @@ -121,9 +128,41 @@ struct BorderWithNFC<Content: View>: View { @State private var showTOTP = false @ObservedObject var nfcWriter = NFCWriter() + var lockImage: Image { + let name = ICONNAME_LOCKCLOCK + let sysName = SYSTEM_LOCKCLOCK // 􂆉 "lock.badge.clock" + if UIImage(named: name) != nil { + return Image(name) + } else if UIImage(systemName: sysName) != nil { + return Image(systemName: sysName) + } else { + return Image(systemName: FALLBACK_LOCK) + } + } + + private var MAGIC_HEADER: Data { + Data(fromUInt8Array: [ + 0x42, // totp magic header + ]) + } // 42 + + var totpData: Data { + var data = MAGIC_HEADER // 0x42 = "B" + let totpArray = totpString.components(separatedBy: "\n") + for totpCode in totpArray { + if let totpInt = UInt32(totpCode) { + let intData = totpInt.data +// print(data, totpInt, intData) + data.append(intData) + } + } +// print(data) + return data + } + var body: some View { // let _ = Self._printChanges() - let totpCode = Image(systemName: LOCKCLOCK) // 􂆉 "lock.badge.clock" + let totpCode = lockImage let totpButton = Button(minimalistic ? "\(totpCode)" : "\(totpCode) Show TOTP code") { withAnimation { showTOTP = true } } @@ -141,7 +180,7 @@ struct BorderWithNFC<Content: View>: View { let nfcLogo = Image(systemName: NFCLOGO) // 􀭹 "wave.3.right.circle" let nfcButton = Button(minimalistic ? "\(nfcLogo)" : "\(nfcLogo) Write NFC") { - nfcWriter.write(talerURI) + nfcWriter.write(totpData) }.buttonStyle(TalerButtonStyle(type: .prominent)) VStack { @@ -158,7 +197,7 @@ struct BorderWithNFC<Content: View>: View { background: WalletColors().backgroundColor) { content() - .onTapGesture(count: 1) { nfcWriter.write(talerURI) } + .onTapGesture(count: 1) { nfcWriter.write(totpData) } } hint } else { diff --git a/TalerWallet1/Views/Transactions/TransactionPayDetailV.swift b/TalerWallet1/Views/Transactions/TransactionPayDetailV.swift @@ -24,8 +24,7 @@ struct TransactionPayDetailV: View { let totp = Text(posConfirmation) .talerFont(.title1) if #available(iOS 17.7, *) { - let talerURI = posConfirmation - BorderWithNFC(talerURI: talerURI, nfcHint: true, size: 250, scanHints: nil) { + BorderWithNFC(totpString: posConfirmation, nfcHint: true, size: 250, scanHints: nil) { totp } } else {