diff --git a/DGCAWallet.xcodeproj/project.pbxproj b/DGCAWallet.xcodeproj/project.pbxproj index c312e10..d512f58 100644 --- a/DGCAWallet.xcodeproj/project.pbxproj +++ b/DGCAWallet.xcodeproj/project.pbxproj @@ -686,7 +686,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.0; + MARKETING_VERSION = 1.0.1; PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAWallet.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -707,7 +707,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.0; + MARKETING_VERSION = 1.0.1; PRODUCT_BUNDLE_IDENTIFIER = "com.t-systems.DGCAWallet.dev"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; diff --git a/DGCAWallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DGCAWallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 975a0fe..4e9fc9d 100644 --- a/DGCAWallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DGCAWallet.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "repositoryURL": "https://github.com/eu-digital-green-certificates/dgca-app-core-ios", "state": { "branch": "main", - "revision": "0792980147e02bf6db0738af157bb2a8d31ea3cf", + "revision": "98c54595046e40068b570b69bd04a15668874569", "version": null } }, @@ -24,8 +24,8 @@ "repositoryURL": "https://github.com/SCENEE/FloatingPanel", "state": { "branch": null, - "revision": "16fea625be25d9a713630a4a43cbc0778740ebf4", - "version": "2.3.0" + "revision": "da4668aa2b8277dd8ce2741ac5c39394431400fc", + "version": "2.3.1" } }, { diff --git a/DGCAWallet/Services/SecureBackground.swift b/DGCAWallet/Services/SecureBackground.swift index c2a2086..0e65485 100644 --- a/DGCAWallet/Services/SecureBackground.swift +++ b/DGCAWallet/Services/SecureBackground.swift @@ -62,7 +62,7 @@ struct SecureBackground { static var paused = false static var activation = Date() - public static func checkId(completion: ((Bool) -> Void)?) { + public static func checkId(from controller: UIViewController? = nil, completion: ((Bool) -> Void)?) { guard !paused else { return } @@ -70,22 +70,19 @@ struct SecureBackground { let context = LAContext() context.localizedCancelTitle = l10n("auth.later") let reason = l10n("auth.confirm") - var error: NSError? - guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else { - paused = false - completion?(true) - return - } - context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason ) { success, _ in + context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason ) { success, err in if success { - // Move to the main thread because a state update triggers UI changes. - DispatchQueue.main.async { - paused = false - completion?(true) - } + paused = false + completion?(true) } else { paused = false - completion?(false) + if controller == nil || (err as? LAError)?.code != LAError.passcodeNotSet { + completion?(false) + return + } + controller?.showAlert(title: l10n("auth.confirm"), subtitle: l10n("auth.error")) { _ in + completion?(false) + } } } } diff --git a/DGCAWallet/SupportingFiles/AppDelegate.swift b/DGCAWallet/SupportingFiles/AppDelegate.swift index d422606..36a57f1 100644 --- a/DGCAWallet/SupportingFiles/AppDelegate.swift +++ b/DGCAWallet/SupportingFiles/AppDelegate.swift @@ -28,13 +28,19 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - + var window: UIWindow? func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - // Override point for customization after application launch. - return true + if #available(iOS 13, *) { + return true + } else { + self.window = UIWindow() + self.window!.rootViewController = UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() + self.window!.makeKeyAndVisible() + return true + } } func applicationWillResignActive(_ application: UIApplication) { diff --git a/DGCAWallet/SupportingFiles/SceneDelegate.swift b/DGCAWallet/SupportingFiles/SceneDelegate.swift index 966b8e6..7e8f53a 100644 --- a/DGCAWallet/SupportingFiles/SceneDelegate.swift +++ b/DGCAWallet/SupportingFiles/SceneDelegate.swift @@ -26,16 +26,23 @@ import UIKit +@available(iOS 13.0, *) class SceneDelegate: UIResponder, UIWindowSceneDelegate { - var window: UIWindow? + func scene(_ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions) { + if let windowScene = scene as? UIWindowScene { + self.window = UIWindow(windowScene: windowScene) + self.window!.rootViewController = UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() + self.window!.makeKeyAndVisible() + } + } - @available(iOS 13.0, *) func sceneWillResignActive(_ scene: UIScene) { SecureBackground.enable() } - @available(iOS 13.0, *) func sceneDidBecomeActive(_ scene: UIScene) { SecureBackground.disable() } diff --git a/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings b/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings index 672dbc2..241f383 100644 --- a/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings +++ b/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings @@ -41,6 +41,8 @@ "tan.label" = "TAN: %@"; "auth.confirm" = "Confirm Identity"; "auth.later" = "Try Later"; +"auth.error" = "Could not verify device ownership. Please try setting a passcode for this device before opening the app."; "cert.delete.title" = "Delete Certificate"; "cert.delete.body" = "Are you sure you want to delete this certificate? This action cannot be undone."; +"tap-to-reveal" = "tap to reveal"; "app-version" = "App Version %@"; diff --git a/DGCAWallet/ViewControllers/CertCode.swift b/DGCAWallet/ViewControllers/CertCode.swift index 0a93f92..59fdd0c 100644 --- a/DGCAWallet/ViewControllers/CertCode.swift +++ b/DGCAWallet/ViewControllers/CertCode.swift @@ -40,6 +40,14 @@ class CertCodeVC: UIViewController { imageView.image = hCert.qrCode tanLabel.text = "" + if tan != nil { + tanLabel.text = String(format: l10n("tan.label"), l10n("tap-to-reveal")) + tanLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapToReveal))) + tanLabel.isUserInteractionEnabled = true + } + } + + @IBAction func tapToReveal() { if let tan = tan { tanLabel.text = String(format: l10n("tan.label"), tan) } diff --git a/DGCAWallet/ViewControllers/CertificateViewer.swift b/DGCAWallet/ViewControllers/CertificateViewer.swift index a26adb6..d489005 100644 --- a/DGCAWallet/ViewControllers/CertificateViewer.swift +++ b/DGCAWallet/ViewControllers/CertificateViewer.swift @@ -36,12 +36,15 @@ class CertificateViewerVC: UIViewController { @IBOutlet weak var cancelButton: UIButton! @IBOutlet weak var cancelButtonConstraint: NSLayoutConstraint! - var hCert: HCert! + var hCert: HCert? var tan: String? weak var childDismissedDelegate: CertViewerDelegate? public var isSaved = true func draw() { + guard let hCert = hCert else { + return + } nameLabel.text = hCert.fullName if !isSaved { dismissButton.setTitle(l10n("btn.save"), for: .normal) @@ -53,16 +56,16 @@ class CertificateViewerVC: UIViewController { view.layoutIfNeeded() } - override func viewDidLoad() { - super.viewDidLoad() - - draw() - } - - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) - return + if #available(iOS 13.0, *) { + draw() + } else { + DispatchQueue.main.async { [weak self] in + self?.draw() + } + } } var newCertAdded = false diff --git a/DGCAWallet/ViewControllers/Home.swift b/DGCAWallet/ViewControllers/Home.swift index fed1b42..3c078e0 100644 --- a/DGCAWallet/ViewControllers/Home.swift +++ b/DGCAWallet/ViewControllers/Home.swift @@ -68,11 +68,13 @@ class HomeVC: UIViewController { showAlert(title: l10n("info.outdated"), subtitle: l10n("info.outdated.body")) return } - SecureBackground.checkId { [weak self] in - if $0 { - self?.performSegue(withIdentifier: "list", sender: self) - } else { - self?.checkId() + SecureBackground.checkId(from: self) { success in + DispatchQueue.main.async { [weak self] in + if success { + self?.performSegue(withIdentifier: "list", sender: self) + } else { + self?.checkId() + } } } } diff --git a/DGCAWallet/ViewControllers/List.swift b/DGCAWallet/ViewControllers/List.swift index b1b9760..503f07d 100644 --- a/DGCAWallet/ViewControllers/List.swift +++ b/DGCAWallet/ViewControllers/List.swift @@ -40,6 +40,10 @@ class ListVC: UIViewController { } } + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + override func viewDidLoad() { super.viewDidLoad() @@ -138,6 +142,14 @@ extension ListVC: CertViewerDelegate { } extension ListVC: ScanVCDelegate { + func disableBackgroundDetection() { + SecureBackground.paused = true + } + + func enableBackgroundDetection() { + SecureBackground.paused = false + } + func hCertScanned(_ cert: HCert) { newHCertScanned = cert DispatchQueue.main.async { [weak self] in diff --git a/Localization/DGCAWallet/en.xcloc/Localized Contents/en.xliff b/Localization/DGCAWallet/en.xcloc/Localized Contents/en.xliff index 4fab032..20b11d2 100644 --- a/Localization/DGCAWallet/en.xcloc/Localized Contents/en.xliff +++ b/Localization/DGCAWallet/en.xcloc/Localized Contents/en.xliff @@ -180,6 +180,11 @@ Confirm Identity + + Could not verify device ownership. Please try setting a passcode for this device before opening the app. + Could not verify device ownership. Please try setting a passcode for this device before opening the app. + + Try Later Try Later @@ -268,6 +273,11 @@ TAN: %@ + + tap to reveal + tap to reveal + + diff --git a/Localization/DGCAWallet/en.xcloc/Source Contents/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings b/Localization/DGCAWallet/en.xcloc/Source Contents/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings index 672dbc2..241f383 100644 --- a/Localization/DGCAWallet/en.xcloc/Source Contents/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings +++ b/Localization/DGCAWallet/en.xcloc/Source Contents/DGCAWallet/SupportingFiles/en.lproj/Localizable.strings @@ -41,6 +41,8 @@ "tan.label" = "TAN: %@"; "auth.confirm" = "Confirm Identity"; "auth.later" = "Try Later"; +"auth.error" = "Could not verify device ownership. Please try setting a passcode for this device before opening the app."; "cert.delete.title" = "Delete Certificate"; "cert.delete.body" = "Are you sure you want to delete this certificate? This action cannot be undone."; +"tap-to-reveal" = "tap to reveal"; "app-version" = "App Version %@"; diff --git a/context.jsonc b/context.jsonc index 40e68fa..bffa97d 100644 --- a/context.jsonc +++ b/context.jsonc @@ -6,7 +6,7 @@ // catch-all for normal versions "privacyUrl": "https://publications.europa.eu/en/web/about-us/legal-notices/eu-mobile-apps", "context": { - "url": "https://dgca-issuance-web.cfapps.eu10.hana.ondemand.com/dgca-issuance-service/context", + "url": "https://issuance-dgca-test.cfapps.eu10.hana.ondemand.com/dgca-issuance-service/context", "pubKeys": [ "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E=" @@ -14,7 +14,7 @@ }, "endpoints": { "claim": { - "url": "https://dgca-issuance-web.cfapps.eu10.hana.ondemand.com/dgca-issuance-service/dgci/wallet/claim", + "url": "https://issuance-dgca-test.cfapps.eu10.hana.ondemand.com/dgca-issuance-service/dgci/wallet/claim", "pubKeys": [ "lKdU1EbQubxyDDm2q3N8KclZ2C94Num3xXjG0pk+3eI=", "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="