From 31a6d71f879c0e49108b05d7d52e166ce28ae5b4 Mon Sep 17 00:00:00 2001 From: OS-ricardomoreirasilva Date: Thu, 14 Apr 2022 13:17:24 +0100 Subject: [PATCH] fix: Avoid Keychain's errSecInteractionNotAllowed error on iOS 15 For iOS 15, on SecureStorage's init method, if ProtectedData is unavailable, add an observer for the UIApplicationProtectedDataDidBecomeAvailable notification that re-triggers init when it becomes available. --- CHANGELOG | 5 +++++ package.json | 2 +- plugin.xml | 2 +- src/ios/SecureStorage.m | 27 +++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0bf0f645..29fbdc6f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,11 @@ Changelog ========= +2.6.8-OS12 - 2022-04-14 +------------------ + +- Fix: For iOS 15, on the `init` method, if ProtectedData is unavailable, add an observer for the `UIApplicationProtectedDataDidBecomeAvailable` notification that re-triggers `init` when it becomes available. (RMET-1417) + 2.6.8-OS11 - 2022-04-12 ------------------ diff --git a/package.json b/package.json index f724615a..b63c6a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cordova-plugin-secure-storage", - "version": "2.6.8-OS11", + "version": "2.6.8-OS12", "description": "Secure storage plugin for iOS & Android", "author": "Yiorgis Gozadinos ", "contributors": [ diff --git a/plugin.xml b/plugin.xml index 1bbd3784..02f32de4 100644 --- a/plugin.xml +++ b/plugin.xml @@ -2,7 +2,7 @@ + version="2.6.8-OS12"> SecureStorage Crypho AS diff --git a/src/ios/SecureStorage.m b/src/ios/SecureStorage.m index 68edbb40..3f930730 100644 --- a/src/ios/SecureStorage.m +++ b/src/ios/SecureStorage.m @@ -4,10 +4,37 @@ #import #import "SAMKeychain.h" +@interface SecureStorage () + +/// This local property is used to store the command to execute when SecureStorage tries to access Keychain without Protected Data Access being available. It's included as a fix for the iOS 15 pre-warm functionality. +@property(nonatomic, strong) CDVInvokedUrlCommand *savedCommand API_AVAILABLE(ios(15)); + +@end + @implementation SecureStorage +/// Method triggered when the `UIApplicationProtectedDataDidBecomeAvailable` notification is trigged. +- (void)dataBecameAvailableNotification:(NSNotification *)notification API_AVAILABLE(ios(15)) +{ + // Re-triggers the `init` method as before, using the stored command + [self init:self.savedCommand]; +} + - (void)init:(CDVInvokedUrlCommand*)command { + if (@available(iOS 15, *)) { + // if Protected Data Acess is not yet available, the app observes the `dataBecomeAvailableNotification:`, so that the method resumes when the notification is triggered + if (!UIApplication.sharedApplication.isProtectedDataAvailable) { + self.savedCommand = command; + [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(dataBecameAvailableNotification:) name:UIApplicationProtectedDataDidBecomeAvailable object:nil]; + return; + } + + // all good, we can remove what was added and proceed. + self.savedCommand = nil; + [NSNotificationCenter.defaultCenter removeObserver:self name:UIApplicationProtectedDataDidBecomeAvailable object:nil]; + } + CFTypeRef accessibility; NSString *keychainAccessibility; NSDictionary *keychainAccesssibilityMapping;