commit a65f2682814c2a8ed8c148322d959cef226b234b
parent 685de878b071628f06781af18a6ffb90f07b9452
Author: Marc Stibane <marc@taler.net>
Date: Tue, 2 Sep 2025 13:26:48 +0200
Improve totp
Diffstat:
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 {