From 00122580c576764afc8f48cb7d68ca54963a70dc Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 06:58:37 -0500 Subject: [PATCH 01/17] fix broken provisioning profiles --- Cely Demo/Cely Demo.entitlements | 2 +- Cely.xcodeproj/project.pbxproj | 38 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cely Demo/Cely Demo.entitlements b/Cely Demo/Cely Demo.entitlements index d067d0d..ef507d9 100644 --- a/Cely Demo/Cely Demo.entitlements +++ b/Cely Demo/Cely Demo.entitlements @@ -4,7 +4,7 @@ keychain-access-groups - $(AppIdentifierPrefix)com.cely.Cely-Demo + $(AppIdentifierPrefix)com.cely-tools.Cely-Demo diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index ddc3cdd..0420685 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -666,7 +666,7 @@ TargetAttributes = { 1F28642A1E89578700EE8180 = { CreatedOnToolsVersion = 8.2.1; - DevelopmentTeam = 7CX9JN6SPG; + DevelopmentTeam = H367AL682C; LastSwiftMigration = 0900; ProvisioningStyle = Automatic; SystemCapabilities = { @@ -1001,11 +1001,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "Cely Demo/Cely Demo.entitlements"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 7CX9JN6SPG; + DEVELOPMENT_TEAM = H367AL682C; INFOPLIST_FILE = "Cely Demo/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.Cely.Cely-Demo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; }; @@ -1017,11 +1017,11 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "Cely Demo/Cely Demo.entitlements"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - DEVELOPMENT_TEAM = 7CX9JN6SPG; + DEVELOPMENT_TEAM = H367AL682C; INFOPLIST_FILE = "Cely Demo/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.Cely.Cely-Demo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; }; @@ -1157,7 +1157,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -1180,7 +1180,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Default; @@ -1201,7 +1201,7 @@ INFOPLIST_FILE = Sources/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = watchos; SKIP_INSTALL = YES; @@ -1226,7 +1226,7 @@ INFOPLIST_FILE = Sources/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = watchos; SKIP_INSTALL = YES; @@ -1252,7 +1252,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -1277,7 +1277,7 @@ INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = macosx; SKIP_INSTALL = YES; @@ -1298,7 +1298,7 @@ INFOPLIST_FILE = "Sources/Info-tvOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = appletvos; SKIP_INSTALL = YES; @@ -1322,7 +1322,7 @@ INFOPLIST_FILE = "Sources/Info-tvOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.Cely; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; PRODUCT_NAME = Cely; SDKROOT = appletvos; SKIP_INSTALL = YES; @@ -1344,7 +1344,7 @@ INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_SWIFT_FLAGS = "-D DEBUG -D TEST"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -1363,7 +1363,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cely Demo.app/Cely Demo"; @@ -1379,7 +1379,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "Tests/Info-tvOS.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -1397,7 +1397,7 @@ FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "Tests/Info-tvOS.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_VERSION = 3.0; @@ -1417,7 +1417,7 @@ INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -1437,7 +1437,7 @@ INFOPLIST_FILE = Tests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; - PRODUCT_BUNDLE_IDENTIFIER = com.Cely.Cely.CelyTests; + PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.CelyTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_VERSION = 3.0; From e9b1db1ed0d5048f7f5fc5928b16e060ae4328bb Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 06:58:49 -0500 Subject: [PATCH 02/17] fix broken embedded framework --- Cely.xcodeproj/project.pbxproj | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index 0420685..71eb133 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -81,7 +81,8 @@ 1F68B0451E8951AA001A0161 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */; }; 1F68B0461E8951AA001A0161 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */; }; 1F68B0471E8951AA001A0161 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */; }; - 1FB2CEF11E8D3E2D00E1A5F6 /* Cely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; }; + 31238F162331019400D6CBC3 /* Cely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; }; + 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31817D1122FBCA15004FF30F /* CelyKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31817D1022FBCA15004FF30F /* CelyKeychain.swift */; }; 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */; }; 3549BB501DA38A2000C63030 /* Cely.h in Headers */ = {isa = PBXBuildFile; fileRef = 3549BB181DA3890B00C63030 /* Cely.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -124,6 +125,20 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + 31238F182331019400D6CBC3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 1F28642B1E89578700EE8180 /* Cely Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cely Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 1F28642D1E89578700EE8180 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -200,7 +215,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 1FB2CEF11E8D3E2D00E1A5F6 /* Cely.framework in Frameworks */, + 31238F162331019400D6CBC3 /* Cely.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -516,6 +531,7 @@ 1F2864271E89578700EE8180 /* Sources */, 1F2864281E89578700EE8180 /* Frameworks */, 1F2864291E89578700EE8180 /* Resources */, + 31238F182331019400D6CBC3 /* Embed Frameworks */, ); buildRules = ( ); From 37d564049506e632ab5cd20b040328eb419de00a Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 07:27:35 -0500 Subject: [PATCH 03/17] remove LocksmithError --- Cely.xcodeproj/project.pbxproj | 14 +- Sources/CelyConstants.swift | 2 +- Sources/CelyKeychain.swift | 50 +- Sources/CelySecureStorage.swift | 3 - Sources/CelyStorage.swift | 2 +- Sources/LocksmithError.swift | 54 - Sources/Storage/CelySecureStatus.swift | 1252 ++++++++++++++++++++++++ Tests/CelyStorageTests.swift | 2 +- Tests/CelyTests.swift | 36 +- Tests/ConstantsAndProtocolTests.swift | 7 - 10 files changed, 1299 insertions(+), 123 deletions(-) delete mode 100755 Sources/LocksmithError.swift create mode 100644 Sources/Storage/CelySecureStatus.swift diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index 71eb133..c23caeb 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -44,10 +44,6 @@ 1F68AFEE1E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; 1F68AFEF1E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; 1F68AFF01E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; - 1F68AFF91E89505A001A0161 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */; }; - 1F68AFFA1E89505A001A0161 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */; }; - 1F68AFFB1E89505A001A0161 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */; }; - 1F68AFFC1E89505A001A0161 /* LocksmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */; }; 1F68B0041E895069001A0161 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0011E895069001A0161 /* Assets.xcassets */; }; 1F68B0051E895069001A0161 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0011E895069001A0161 /* Assets.xcassets */; }; 1F68B0061E895069001A0161 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0011E895069001A0161 /* Assets.xcassets */; }; @@ -83,6 +79,7 @@ 1F68B0471E8951AA001A0161 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */; }; 31238F162331019400D6CBC3 /* Cely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; }; 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 31238F1A233103D500D6CBC3 /* CelySecureStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */; }; 31817D1122FBCA15004FF30F /* CelyKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31817D1022FBCA15004FF30F /* CelyKeychain.swift */; }; 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */; }; 3549BB501DA38A2000C63030 /* Cely.h in Headers */ = {isa = PBXBuildFile; fileRef = 3549BB181DA3890B00C63030 /* Cely.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -156,7 +153,6 @@ 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyProtocols.swift; sourceTree = ""; }; 1F68AFD71E89505A001A0161 /* CelyStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyStorage.swift; sourceTree = ""; }; 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyWindowManager.swift; sourceTree = ""; }; - 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocksmithError.swift; sourceTree = ""; }; 1F68B0011E895069001A0161 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = "Supporting Files/Assets.xcassets"; sourceTree = ""; }; 1F68B0021E895069001A0161 /* Cely.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Cely.storyboard; path = "Supporting Files/Cely.storyboard"; sourceTree = ""; }; 1F68B0031E895069001A0161 /* CelyLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyLoginViewController.swift; sourceTree = ""; }; @@ -170,6 +166,7 @@ 1F68B01C1E89519A001A0161 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = TestStoryboard.storyboard; path = Frameworks/TestStoryboard.storyboard; sourceTree = ""; }; 1F9D24071E8D49C700FB4BE6 /* Cely Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Cely Demo.entitlements"; sourceTree = ""; }; + 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CelySecureStatus.swift; path = Storage/CelySecureStatus.swift; sourceTree = ""; }; 31817D1022FBCA15004FF30F /* CelyKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyKeychain.swift; sourceTree = ""; }; 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStorage.swift; sourceTree = ""; }; 3549BB171DA3890B00C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -372,11 +369,11 @@ children = ( 1F68AFD41E89505A001A0161 /* Cely.swift */, 1F68AFD51E89505A001A0161 /* CelyConstants.swift */, + 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */, 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */, 1F68AFD71E89505A001A0161 /* CelyStorage.swift */, 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */, 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */, - 1F68AFDB1E89505A001A0161 /* LocksmithError.swift */, 31817D1022FBCA15004FF30F /* CelyKeychain.swift */, ); name = Core; @@ -876,12 +873,12 @@ 1F68AFE51E89505A001A0161 /* CelyProtocols.swift in Sources */, 1F68AFE11E89505A001A0161 /* CelyConstants.swift in Sources */, 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */, + 31238F1A233103D500D6CBC3 /* CelySecureStatus.swift in Sources */, 1F68B00C1E895069001A0161 /* CelyLoginViewController.swift in Sources */, 1F68AFE91E89505A001A0161 /* CelyStorage.swift in Sources */, 31817D1122FBCA15004FF30F /* CelyKeychain.swift in Sources */, 1F68AFED1E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFDD1E89505A001A0161 /* Cely.swift in Sources */, - 1F68AFF91E89505A001A0161 /* LocksmithError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -895,7 +892,6 @@ 1F68AFEC1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFF01E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFE01E89505A001A0161 /* Cely.swift in Sources */, - 1F68AFFC1E89505A001A0161 /* LocksmithError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -909,7 +905,6 @@ 1F68AFEA1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFEE1E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFDE1E89505A001A0161 /* Cely.swift in Sources */, - 1F68AFFA1E89505A001A0161 /* LocksmithError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -923,7 +918,6 @@ 1F68AFEB1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFEF1E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFDF1E89505A001A0161 /* Cely.swift in Sources */, - 1F68AFFB1E89505A001A0161 /* LocksmithError.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/CelyConstants.swift b/Sources/CelyConstants.swift index 4a08125..53ce3e3 100644 --- a/Sources/CelyConstants.swift +++ b/Sources/CelyConstants.swift @@ -33,7 +33,7 @@ public enum CelyOptions { // enum result on whether or not Cely successfully saved your data public enum StorageResult: Equatable { case success - case fail(LocksmithError) + case fail(CelySecureStatus) } public func == (lhs: StorageResult, rhs: StorageResult) -> Bool { diff --git a/Sources/CelyKeychain.swift b/Sources/CelyKeychain.swift index 05c58b7..7e161c1 100644 --- a/Sources/CelyKeychain.swift +++ b/Sources/CelyKeychain.swift @@ -9,14 +9,13 @@ import Foundation internal struct CelyKeychain { - // query to identify Cely Credentials private let baseQuery: [String: Any] = [ kSecClass as String: kSecClassInternetPassword, kSecAttrLabel as String: "cely.secure.store.key", - kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked + kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked, ] - + private var searchQuery: [String: Any] { var queryCopy = baseQuery queryCopy[kSecMatchLimit as String] = kSecMatchLimitOne @@ -24,56 +23,55 @@ internal struct CelyKeychain { queryCopy[kSecReturnData as String] = true return queryCopy } - + func clearKeychain() -> StorageResult { let status = SecItemDelete(baseQuery as CFDictionary) - let errorStatus = LocksmithError(fromStatusCode: Int(status)) - guard errorStatus == .noError - else { return StorageResult.fail(errorStatus) } + let errorStatus = CelySecureStatus(status: status) + guard errorStatus == .success + else { return StorageResult.fail(errorStatus) } return .success } - + func getCredentials() throws -> [String: Any] { var item: CFTypeRef? let status = SecItemCopyMatching(searchQuery as CFDictionary, &item) - guard status != errSecItemNotFound else { throw LocksmithError.notFound } - guard status == errSecSuccess else { throw LocksmithError.undefined } - + guard status == errSecSuccess else { throw CelySecureStatus(status: status) } + do { - guard let existingItem = item as? [String : Any], + guard let existingItem = item as? [String: Any], let secureData = existingItem[kSecValueData as String] as? Data, - let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String : Any] - else { throw LocksmithError.decode } + let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String: Any] + else { throw CelySecureStatus.decode } return loadedDictionary } } - - func set(_ secrets: [String : Any]) -> StorageResult { + + func set(_ secrets: [String: Any]) -> StorageResult { var queryCopy = baseQuery let storeData = NSKeyedArchiver.archivedData(withRootObject: secrets) queryCopy[kSecValueData as String] = storeData - + // try adding first let status: OSStatus = SecItemAdd(queryCopy as CFDictionary, nil) - let err = LocksmithError(fromStatusCode: Int(status)) - if err == .noError { + let code = CelySecureStatus(status: status) + if code == .success { return .success - } else if err == .duplicate { + } else if code == .duplicateItem { // already exists, should update instead return update(secrets: secrets) } - return .fail(err) + return .fail(code) } - - private func update(secrets: [String : Any]) -> StorageResult { + + private func update(secrets: [String: Any]) -> StorageResult { let secretData = NSKeyedArchiver.archivedData(withRootObject: secrets) let updateDictionary = [kSecValueData as String: secretData] let status: OSStatus = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) - let err = LocksmithError(fromStatusCode: Int(status)) - if err == .noError { + let code = CelySecureStatus(status: status) + if code == .success { return .success } - return .fail(err) + return .fail(code) } } diff --git a/Sources/CelySecureStorage.swift b/Sources/CelySecureStorage.swift index 73352b4..a5adb69 100644 --- a/Sources/CelySecureStorage.swift +++ b/Sources/CelySecureStorage.swift @@ -16,9 +16,6 @@ internal class CelySecureStorage { do { let credentials = try _celyKeychain.getCredentials() store = credentials - } catch let error as LocksmithError { - print("Failed to retrieve store from keychain") - print(error) } catch { print("Failed to retrieve store from keychain") print(error) diff --git a/Sources/CelyStorage.swift b/Sources/CelyStorage.swift index 17d767d..502cc4a 100644 --- a/Sources/CelyStorage.swift +++ b/Sources/CelyStorage.swift @@ -67,7 +67,7 @@ public class CelyStorage: CelyStorageProtocol { /// /// - returns: `Boolean` on whether or not it successfully saved public func set(_ value: Any?, forKey key: String, securely secure: Bool = false, persisted: Bool = false) -> StorageResult { - guard let val = value else { return .fail(.undefined) } + guard let val = value else { return .fail(.param) } if secure { return secureStore.set(val, forKey: key) } else { diff --git a/Sources/LocksmithError.swift b/Sources/LocksmithError.swift deleted file mode 100755 index 1dc3501..0000000 --- a/Sources/LocksmithError.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// LocksmithError.swift -// Cely -// -// Created by Matthew Palmer on 7/31/16. -// Copyright © 2016 Matthew Palmer. All rights reserved. -// - -import Foundation - -// MARK: Locksmith Error -public enum LocksmithError: String, Error { - case allocate = "Failed to allocate memory." - case authFailed = "Authorization/Authentication failed." - case decode = "Unable to decode the provided data." - case duplicate = "The item already exists." - case interactionNotAllowed = "Interaction with the Security Server is not allowed." - case noError = "No error." - case notAvailable = "No trust results are available." - case notFound = "The item cannot be found." - case param = "One or more parameters passed to the function were not valid." - case requestNotSet = "The request was not set" - case typeNotFound = "The type was not found" - case unableToClear = "Unable to clear the keychain" - case undefined = "An undefined error occurred" - case unimplemented = "Function or operation not implemented." - - public init(fromStatusCode code: Int) { - switch code { - case Int(errSecSuccess): - self = .noError - case Int(errSecAllocate): - self = .allocate - case Int(errSecAuthFailed): - self = .authFailed - case Int(errSecDecode): - self = .decode - case Int(errSecDuplicateItem): - self = .duplicate - case Int(errSecInteractionNotAllowed): - self = .interactionNotAllowed - case Int(errSecItemNotFound): - self = .notFound - case Int(errSecNotAvailable): - self = .notAvailable - case Int(errSecParam): - self = .param - case Int(errSecUnimplemented): - self = .unimplemented - default: - self = .undefined - } - } -} diff --git a/Sources/Storage/CelySecureStatus.swift b/Sources/Storage/CelySecureStatus.swift new file mode 100644 index 0000000..edf554b --- /dev/null +++ b/Sources/Storage/CelySecureStatus.swift @@ -0,0 +1,1252 @@ +// +// CelySecureStatus.swift +// Cely-iOS +// +// Created by Fabian Buentello on 9/17/19. +// Copyright © 2019 Fabian Buentello. All rights reserved. +// + +import Foundation + +// https://github.com/kishikawakatsumi/KeychainAccess/blob/3a9c83cf8b8cfaecd1097916fae803e1b1d6447f/Lib/KeychainAccess/Keychain.swift#L1695 + +public enum CelySecureStatus: OSStatus, Error { + case success = 0 + case unimplemented = -4 + case diskFull = -34 + case io = -36 + case opWr = -49 + case param = -50 + case wrPerm = -61 + case allocate = -108 + case userCanceled = -128 + case badReq = -909 + case internalComponent = -2070 + case notAvailable = -25291 + case readOnly = -25292 + case authFailed = -25293 + case noSuchKeychain = -25294 + case invalidKeychain = -25295 + case duplicateKeychain = -25296 + case duplicateCallback = -25297 + case invalidCallback = -25298 + case duplicateItem = -25299 + case itemNotFound = -25300 + case bufferTooSmall = -25301 + case dataTooLarge = -25302 + case noSuchAttr = -25303 + case invalidItemRef = -25304 + case invalidSearchRef = -25305 + case noSuchClass = -25306 + case noDefaultKeychain = -25307 + case interactionNotAllowed = -25308 + case readOnlyAttr = -25309 + case wrongSecVersion = -25310 + case keySizeNotAllowed = -25311 + case noStorageModule = -25312 + case noCertificateModule = -25313 + case noPolicyModule = -25314 + case interactionRequired = -25315 + case dataNotAvailable = -25316 + case dataNotModifiable = -25317 + case createChainFailed = -25318 + case invalidPrefsDomain = -25319 + case inDarkWake = -25320 + case aclNotSimple = -25240 + case policyNotFound = -25241 + case invalidTrustSetting = -25242 + case noAccessForItem = -25243 + case invalidOwnerEdit = -25244 + case trustNotAvailable = -25245 + case unsupportedFormat = -25256 + case unknownFormat = -25257 + case keyIsSensitive = -25258 + case multiplePrivKeys = -25259 + case passphraseRequired = -25260 + case invalidPasswordRef = -25261 + case invalidTrustSettings = -25262 + case noTrustSettings = -25263 + case pkcs12VerifyFailure = -25264 + case invalidCertificate = -26265 + case notSigner = -26267 + case policyDenied = -26270 + case invalidKey = -26274 + case decode = -26275 + case `internal` = -26276 + case unsupportedAlgorithm = -26268 + case unsupportedOperation = -26271 + case unsupportedPadding = -26273 + case itemInvalidKey = -34000 + case itemInvalidKeyType = -34001 + case itemInvalidValue = -34002 + case itemClassMissing = -34003 + case itemMatchUnsupported = -34004 + case useItemListUnsupported = -34005 + case useKeychainUnsupported = -34006 + case useKeychainListUnsupported = -34007 + case returnDataUnsupported = -34008 + case returnAttributesUnsupported = -34009 + case returnRefUnsupported = -34010 + case returnPersitentRefUnsupported = -34011 + case valueRefUnsupported = -34012 + case valuePersistentRefUnsupported = -34013 + case returnMissingPointer = -34014 + case matchLimitUnsupported = -34015 + case itemIllegalQuery = -34016 + case waitForCallback = -34017 + case missingEntitlement = -34018 + case upgradePending = -34019 + case mpSignatureInvalid = -25327 + case otrTooOld = -25328 + case otrIDTooNew = -25329 + case serviceNotAvailable = -67585 + case insufficientClientID = -67586 + case deviceReset = -67587 + case deviceFailed = -67588 + case appleAddAppACLSubject = -67589 + case applePublicKeyIncomplete = -67590 + case appleSignatureMismatch = -67591 + case appleInvalidKeyStartDate = -67592 + case appleInvalidKeyEndDate = -67593 + case conversionError = -67594 + case appleSSLv2Rollback = -67595 + case quotaExceeded = -67596 + case fileTooBig = -67597 + case invalidDatabaseBlob = -67598 + case invalidKeyBlob = -67599 + case incompatibleDatabaseBlob = -67600 + case incompatibleKeyBlob = -67601 + case hostNameMismatch = -67602 + case unknownCriticalExtensionFlag = -67603 + case noBasicConstraints = -67604 + case noBasicConstraintsCA = -67605 + case invalidAuthorityKeyID = -67606 + case invalidSubjectKeyID = -67607 + case invalidKeyUsageForPolicy = -67608 + case invalidExtendedKeyUsage = -67609 + case invalidIDLinkage = -67610 + case pathLengthConstraintExceeded = -67611 + case invalidRoot = -67612 + case crlExpired = -67613 + case crlNotValidYet = -67614 + case crlNotFound = -67615 + case crlServerDown = -67616 + case crlBadURI = -67617 + case unknownCertExtension = -67618 + case unknownCRLExtension = -67619 + case crlNotTrusted = -67620 + case crlPolicyFailed = -67621 + case idpFailure = -67622 + case smimeEmailAddressesNotFound = -67623 + case smimeBadExtendedKeyUsage = -67624 + case smimeBadKeyUsage = -67625 + case smimeKeyUsageNotCritical = -67626 + case smimeNoEmailAddress = -67627 + case smimeSubjAltNameNotCritical = -67628 + case sslBadExtendedKeyUsage = -67629 + case ocspBadResponse = -67630 + case ocspBadRequest = -67631 + case ocspUnavailable = -67632 + case ocspStatusUnrecognized = -67633 + case endOfData = -67634 + case incompleteCertRevocationCheck = -67635 + case networkFailure = -67636 + case ocspNotTrustedToAnchor = -67637 + case recordModified = -67638 + case ocspSignatureError = -67639 + case ocspNoSigner = -67640 + case ocspResponderMalformedReq = -67641 + case ocspResponderInternalError = -67642 + case ocspResponderTryLater = -67643 + case ocspResponderSignatureRequired = -67644 + case ocspResponderUnauthorized = -67645 + case ocspResponseNonceMismatch = -67646 + case codeSigningBadCertChainLength = -67647 + case codeSigningNoBasicConstraints = -67648 + case codeSigningBadPathLengthConstraint = -67649 + case codeSigningNoExtendedKeyUsage = -67650 + case codeSigningDevelopment = -67651 + case resourceSignBadCertChainLength = -67652 + case resourceSignBadExtKeyUsage = -67653 + case trustSettingDeny = -67654 + case invalidSubjectName = -67655 + case unknownQualifiedCertStatement = -67656 + case mobileMeRequestQueued = -67657 + case mobileMeRequestRedirected = -67658 + case mobileMeServerError = -67659 + case mobileMeServerNotAvailable = -67660 + case mobileMeServerAlreadyExists = -67661 + case mobileMeServerServiceErr = -67662 + case mobileMeRequestAlreadyPending = -67663 + case mobileMeNoRequestPending = -67664 + case mobileMeCSRVerifyFailure = -67665 + case mobileMeFailedConsistencyCheck = -67666 + case notInitialized = -67667 + case invalidHandleUsage = -67668 + case pvcReferentNotFound = -67669 + case functionIntegrityFail = -67670 + case internalError = -67671 + case memoryError = -67672 + case invalidData = -67673 + case mdsError = -67674 + case invalidPointer = -67675 + case selfCheckFailed = -67676 + case functionFailed = -67677 + case moduleManifestVerifyFailed = -67678 + case invalidGUID = -67679 + case invalidHandle = -67680 + case invalidDBList = -67681 + case invalidPassthroughID = -67682 + case invalidNetworkAddress = -67683 + case crlAlreadySigned = -67684 + case invalidNumberOfFields = -67685 + case verificationFailure = -67686 + case unknownTag = -67687 + case invalidSignature = -67688 + case invalidName = -67689 + case invalidCertificateRef = -67690 + case invalidCertificateGroup = -67691 + case tagNotFound = -67692 + case invalidQuery = -67693 + case invalidValue = -67694 + case callbackFailed = -67695 + case aclDeleteFailed = -67696 + case aclReplaceFailed = -67697 + case aclAddFailed = -67698 + case aclChangeFailed = -67699 + case invalidAccessCredentials = -67700 + case invalidRecord = -67701 + case invalidACL = -67702 + case invalidSampleValue = -67703 + case incompatibleVersion = -67704 + case privilegeNotGranted = -67705 + case invalidScope = -67706 + case pvcAlreadyConfigured = -67707 + case invalidPVC = -67708 + case emmLoadFailed = -67709 + case emmUnloadFailed = -67710 + case addinLoadFailed = -67711 + case invalidKeyRef = -67712 + case invalidKeyHierarchy = -67713 + case addinUnloadFailed = -67714 + case libraryReferenceNotFound = -67715 + case invalidAddinFunctionTable = -67716 + case invalidServiceMask = -67717 + case moduleNotLoaded = -67718 + case invalidSubServiceID = -67719 + case attributeNotInContext = -67720 + case moduleManagerInitializeFailed = -67721 + case moduleManagerNotFound = -67722 + case eventNotificationCallbackNotFound = -67723 + case inputLengthError = -67724 + case outputLengthError = -67725 + case privilegeNotSupported = -67726 + case deviceError = -67727 + case attachHandleBusy = -67728 + case notLoggedIn = -67729 + case algorithmMismatch = -67730 + case keyUsageIncorrect = -67731 + case keyBlobTypeIncorrect = -67732 + case keyHeaderInconsistent = -67733 + case unsupportedKeyFormat = -67734 + case unsupportedKeySize = -67735 + case invalidKeyUsageMask = -67736 + case unsupportedKeyUsageMask = -67737 + case invalidKeyAttributeMask = -67738 + case unsupportedKeyAttributeMask = -67739 + case invalidKeyLabel = -67740 + case unsupportedKeyLabel = -67741 + case invalidKeyFormat = -67742 + case unsupportedVectorOfBuffers = -67743 + case invalidInputVector = -67744 + case invalidOutputVector = -67745 + case invalidContext = -67746 + case invalidAlgorithm = -67747 + case invalidAttributeKey = -67748 + case missingAttributeKey = -67749 + case invalidAttributeInitVector = -67750 + case missingAttributeInitVector = -67751 + case invalidAttributeSalt = -67752 + case missingAttributeSalt = -67753 + case invalidAttributePadding = -67754 + case missingAttributePadding = -67755 + case invalidAttributeRandom = -67756 + case missingAttributeRandom = -67757 + case invalidAttributeSeed = -67758 + case missingAttributeSeed = -67759 + case invalidAttributePassphrase = -67760 + case missingAttributePassphrase = -67761 + case invalidAttributeKeyLength = -67762 + case missingAttributeKeyLength = -67763 + case invalidAttributeBlockSize = -67764 + case missingAttributeBlockSize = -67765 + case invalidAttributeOutputSize = -67766 + case missingAttributeOutputSize = -67767 + case invalidAttributeRounds = -67768 + case missingAttributeRounds = -67769 + case invalidAlgorithmParms = -67770 + case missingAlgorithmParms = -67771 + case invalidAttributeLabel = -67772 + case missingAttributeLabel = -67773 + case invalidAttributeKeyType = -67774 + case missingAttributeKeyType = -67775 + case invalidAttributeMode = -67776 + case missingAttributeMode = -67777 + case invalidAttributeEffectiveBits = -67778 + case missingAttributeEffectiveBits = -67779 + case invalidAttributeStartDate = -67780 + case missingAttributeStartDate = -67781 + case invalidAttributeEndDate = -67782 + case missingAttributeEndDate = -67783 + case invalidAttributeVersion = -67784 + case missingAttributeVersion = -67785 + case invalidAttributePrime = -67786 + case missingAttributePrime = -67787 + case invalidAttributeBase = -67788 + case missingAttributeBase = -67789 + case invalidAttributeSubprime = -67790 + case missingAttributeSubprime = -67791 + case invalidAttributeIterationCount = -67792 + case missingAttributeIterationCount = -67793 + case invalidAttributeDLDBHandle = -67794 + case missingAttributeDLDBHandle = -67795 + case invalidAttributeAccessCredentials = -67796 + case missingAttributeAccessCredentials = -67797 + case invalidAttributePublicKeyFormat = -67798 + case missingAttributePublicKeyFormat = -67799 + case invalidAttributePrivateKeyFormat = -67800 + case missingAttributePrivateKeyFormat = -67801 + case invalidAttributeSymmetricKeyFormat = -67802 + case missingAttributeSymmetricKeyFormat = -67803 + case invalidAttributeWrappedKeyFormat = -67804 + case missingAttributeWrappedKeyFormat = -67805 + case stagedOperationInProgress = -67806 + case stagedOperationNotStarted = -67807 + case verifyFailed = -67808 + case querySizeUnknown = -67809 + case blockSizeMismatch = -67810 + case publicKeyInconsistent = -67811 + case deviceVerifyFailed = -67812 + case invalidLoginName = -67813 + case alreadyLoggedIn = -67814 + case invalidDigestAlgorithm = -67815 + case invalidCRLGroup = -67816 + case certificateCannotOperate = -67817 + case certificateExpired = -67818 + case certificateNotValidYet = -67819 + case certificateRevoked = -67820 + case certificateSuspended = -67821 + case insufficientCredentials = -67822 + case invalidAction = -67823 + case invalidAuthority = -67824 + case verifyActionFailed = -67825 + case invalidCertAuthority = -67826 + case invaldCRLAuthority = -67827 + case invalidCRLEncoding = -67828 + case invalidCRLType = -67829 + case invalidCRL = -67830 + case invalidFormType = -67831 + case invalidID = -67832 + case invalidIdentifier = -67833 + case invalidIndex = -67834 + case invalidPolicyIdentifiers = -67835 + case invalidTimeString = -67836 + case invalidReason = -67837 + case invalidRequestInputs = -67838 + case invalidResponseVector = -67839 + case invalidStopOnPolicy = -67840 + case invalidTuple = -67841 + case multipleValuesUnsupported = -67842 + case notTrusted = -67843 + case noDefaultAuthority = -67844 + case rejectedForm = -67845 + case requestLost = -67846 + case requestRejected = -67847 + case unsupportedAddressType = -67848 + case unsupportedService = -67849 + case invalidTupleGroup = -67850 + case invalidBaseACLs = -67851 + case invalidTupleCredendtials = -67852 + case invalidEncoding = -67853 + case invalidValidityPeriod = -67854 + case invalidRequestor = -67855 + case requestDescriptor = -67856 + case invalidBundleInfo = -67857 + case invalidCRLIndex = -67858 + case noFieldValues = -67859 + case unsupportedFieldFormat = -67860 + case unsupportedIndexInfo = -67861 + case unsupportedLocality = -67862 + case unsupportedNumAttributes = -67863 + case unsupportedNumIndexes = -67864 + case unsupportedNumRecordTypes = -67865 + case fieldSpecifiedMultiple = -67866 + case incompatibleFieldFormat = -67867 + case invalidParsingModule = -67868 + case databaseLocked = -67869 + case datastoreIsOpen = -67870 + case missingValue = -67871 + case unsupportedQueryLimits = -67872 + case unsupportedNumSelectionPreds = -67873 + case unsupportedOperator = -67874 + case invalidDBLocation = -67875 + case invalidAccessRequest = -67876 + case invalidIndexInfo = -67877 + case invalidNewOwner = -67878 + case invalidModifyMode = -67879 + case missingRequiredExtension = -67880 + case extendedKeyUsageNotCritical = -67881 + case timestampMissing = -67882 + case timestampInvalid = -67883 + case timestampNotTrusted = -67884 + case timestampServiceNotAvailable = -67885 + case timestampBadAlg = -67886 + case timestampBadRequest = -67887 + case timestampBadDataFormat = -67888 + case timestampTimeNotAvailable = -67889 + case timestampUnacceptedPolicy = -67890 + case timestampUnacceptedExtension = -67891 + case timestampAddInfoNotAvailable = -67892 + case timestampSystemFailure = -67893 + case signingTimeMissing = -67894 + case timestampRejection = -67895 + case timestampWaiting = -67896 + case timestampRevocationWarning = -67897 + case timestampRevocationNotification = -67898 + case unexpectedError = -99999 +} + +extension CelySecureStatus: RawRepresentable, CustomStringConvertible { + public init(status: OSStatus) { + if let mappedStatus = CelySecureStatus(rawValue: status) { + self = mappedStatus + } else { + self = .unexpectedError + } + } + + public var description: String { + switch self { + case .success: + return "No error." + case .unimplemented: + return "Function or operation not implemented." + case .diskFull: + return "The disk is full." + case .io: + return "I/O error (bummers)" + case .opWr: + return "file already open with with write permission" + case .param: + return "One or more parameters passed to a function were not valid." + case .wrPerm: + return "write permissions error" + case .allocate: + return "Failed to allocate memory." + case .userCanceled: + return "User canceled the operation." + case .badReq: + return "Bad parameter or invalid state for operation." + case .internalComponent: + return "" + case .notAvailable: + return "No keychain is available. You may need to restart your computer." + case .readOnly: + return "This keychain cannot be modified." + case .authFailed: + return "The user name or passphrase you entered is not correct." + case .noSuchKeychain: + return "The specified keychain could not be found." + case .invalidKeychain: + return "The specified keychain is not a valid keychain file." + case .duplicateKeychain: + return "A keychain with the same name already exists." + case .duplicateCallback: + return "The specified callback function is already installed." + case .invalidCallback: + return "The specified callback function is not valid." + case .duplicateItem: + return "The specified item already exists in the keychain." + case .itemNotFound: + return "The specified item could not be found in the keychain." + case .bufferTooSmall: + return "There is not enough memory available to use the specified item." + case .dataTooLarge: + return "This item contains information which is too large or in a format that cannot be displayed." + case .noSuchAttr: + return "The specified attribute does not exist." + case .invalidItemRef: + return "The specified item is no longer valid. It may have been deleted from the keychain." + case .invalidSearchRef: + return "Unable to search the current keychain." + case .noSuchClass: + return "The specified item does not appear to be a valid keychain item." + case .noDefaultKeychain: + return "A default keychain could not be found." + case .interactionNotAllowed: + return "User interaction is not allowed." + case .readOnlyAttr: + return "The specified attribute could not be modified." + case .wrongSecVersion: + return "This keychain was created by a different version of the system software and cannot be opened." + case .keySizeNotAllowed: + return "This item specifies a key size which is too large." + case .noStorageModule: + return "A required component (data storage module) could not be loaded. You may need to restart your computer." + case .noCertificateModule: + return "A required component (certificate module) could not be loaded. You may need to restart your computer." + case .noPolicyModule: + return "A required component (policy module) could not be loaded. You may need to restart your computer." + case .interactionRequired: + return "User interaction is required, but is currently not allowed." + case .dataNotAvailable: + return "The contents of this item cannot be retrieved." + case .dataNotModifiable: + return "The contents of this item cannot be modified." + case .createChainFailed: + return "One or more certificates required to validate this certificate cannot be found." + case .invalidPrefsDomain: + return "The specified preferences domain is not valid." + case .inDarkWake: + return "In dark wake, no UI possible" + case .aclNotSimple: + return "The specified access control list is not in standard (simple) form." + case .policyNotFound: + return "The specified policy cannot be found." + case .invalidTrustSetting: + return "The specified trust setting is invalid." + case .noAccessForItem: + return "The specified item has no access control." + case .invalidOwnerEdit: + return "Invalid attempt to change the owner of this item." + case .trustNotAvailable: + return "No trust results are available." + case .unsupportedFormat: + return "Import/Export format unsupported." + case .unknownFormat: + return "Unknown format in import." + case .keyIsSensitive: + return "Key material must be wrapped for export." + case .multiplePrivKeys: + return "An attempt was made to import multiple private keys." + case .passphraseRequired: + return "Passphrase is required for import/export." + case .invalidPasswordRef: + return "The password reference was invalid." + case .invalidTrustSettings: + return "The Trust Settings Record was corrupted." + case .noTrustSettings: + return "No Trust Settings were found." + case .pkcs12VerifyFailure: + return "MAC verification failed during PKCS12 import (wrong password?)" + case .invalidCertificate: + return "This certificate could not be decoded." + case .notSigner: + return "A certificate was not signed by its proposed parent." + case .policyDenied: + return "The certificate chain was not trusted due to a policy not accepting it." + case .invalidKey: + return "The provided key material was not valid." + case .decode: + return "Unable to decode the provided data." + case .internal: + return "An internal error occurred in the Security framework." + case .unsupportedAlgorithm: + return "An unsupported algorithm was encountered." + case .unsupportedOperation: + return "The operation you requested is not supported by this key." + case .unsupportedPadding: + return "The padding you requested is not supported." + case .itemInvalidKey: + return "A string key in dictionary is not one of the supported keys." + case .itemInvalidKeyType: + return "A key in a dictionary is neither a CFStringRef nor a CFNumberRef." + case .itemInvalidValue: + return "A value in a dictionary is an invalid (or unsupported) CF type." + case .itemClassMissing: + return "No kSecItemClass key was specified in a dictionary." + case .itemMatchUnsupported: + return "The caller passed one or more kSecMatch keys to a function which does not support matches." + case .useItemListUnsupported: + return "The caller passed in a kSecUseItemList key to a function which does not support it." + case .useKeychainUnsupported: + return "The caller passed in a kSecUseKeychain key to a function which does not support it." + case .useKeychainListUnsupported: + return "The caller passed in a kSecUseKeychainList key to a function which does not support it." + case .returnDataUnsupported: + return "The caller passed in a kSecReturnData key to a function which does not support it." + case .returnAttributesUnsupported: + return "The caller passed in a kSecReturnAttributes key to a function which does not support it." + case .returnRefUnsupported: + return "The caller passed in a kSecReturnRef key to a function which does not support it." + case .returnPersitentRefUnsupported: + return "The caller passed in a kSecReturnPersistentRef key to a function which does not support it." + case .valueRefUnsupported: + return "The caller passed in a kSecValueRef key to a function which does not support it." + case .valuePersistentRefUnsupported: + return "The caller passed in a kSecValuePersistentRef key to a function which does not support it." + case .returnMissingPointer: + return "The caller passed asked for something to be returned but did not pass in a result pointer." + case .matchLimitUnsupported: + return "The caller passed in a kSecMatchLimit key to a call which does not support limits." + case .itemIllegalQuery: + return "The caller passed in a query which contained too many keys." + case .waitForCallback: + return "This operation is incomplete, until the callback is invoked (not an error)." + case .missingEntitlement: + return "Internal error when a required entitlement isn't present, client has neither application-identifier nor keychain-access-groups entitlements." + case .upgradePending: + return "Error returned if keychain database needs a schema migration but the device is locked, clients should wait for a device unlock notification and retry the command." + case .mpSignatureInvalid: + return "Signature invalid on MP message" + case .otrTooOld: + return "Message is too old to use" + case .otrIDTooNew: + return "Key ID is too new to use! Message from the future?" + case .serviceNotAvailable: + return "The required service is not available." + case .insufficientClientID: + return "The client ID is not correct." + case .deviceReset: + return "A device reset has occurred." + case .deviceFailed: + return "A device failure has occurred." + case .appleAddAppACLSubject: + return "Adding an application ACL subject failed." + case .applePublicKeyIncomplete: + return "The public key is incomplete." + case .appleSignatureMismatch: + return "A signature mismatch has occurred." + case .appleInvalidKeyStartDate: + return "The specified key has an invalid start date." + case .appleInvalidKeyEndDate: + return "The specified key has an invalid end date." + case .conversionError: + return "A conversion error has occurred." + case .appleSSLv2Rollback: + return "A SSLv2 rollback error has occurred." + case .quotaExceeded: + return "The quota was exceeded." + case .fileTooBig: + return "The file is too big." + case .invalidDatabaseBlob: + return "The specified database has an invalid blob." + case .invalidKeyBlob: + return "The specified database has an invalid key blob." + case .incompatibleDatabaseBlob: + return "The specified database has an incompatible blob." + case .incompatibleKeyBlob: + return "The specified database has an incompatible key blob." + case .hostNameMismatch: + return "A host name mismatch has occurred." + case .unknownCriticalExtensionFlag: + return "There is an unknown critical extension flag." + case .noBasicConstraints: + return "No basic constraints were found." + case .noBasicConstraintsCA: + return "No basic CA constraints were found." + case .invalidAuthorityKeyID: + return "The authority key ID is not valid." + case .invalidSubjectKeyID: + return "The subject key ID is not valid." + case .invalidKeyUsageForPolicy: + return "The key usage is not valid for the specified policy." + case .invalidExtendedKeyUsage: + return "The extended key usage is not valid." + case .invalidIDLinkage: + return "The ID linkage is not valid." + case .pathLengthConstraintExceeded: + return "The path length constraint was exceeded." + case .invalidRoot: + return "The root or anchor certificate is not valid." + case .crlExpired: + return "The CRL has expired." + case .crlNotValidYet: + return "The CRL is not yet valid." + case .crlNotFound: + return "The CRL was not found." + case .crlServerDown: + return "The CRL server is down." + case .crlBadURI: + return "The CRL has a bad Uniform Resource Identifier." + case .unknownCertExtension: + return "An unknown certificate extension was encountered." + case .unknownCRLExtension: + return "An unknown CRL extension was encountered." + case .crlNotTrusted: + return "The CRL is not trusted." + case .crlPolicyFailed: + return "The CRL policy failed." + case .idpFailure: + return "The issuing distribution point was not valid." + case .smimeEmailAddressesNotFound: + return "An email address mismatch was encountered." + case .smimeBadExtendedKeyUsage: + return "The appropriate extended key usage for SMIME was not found." + case .smimeBadKeyUsage: + return "The key usage is not compatible with SMIME." + case .smimeKeyUsageNotCritical: + return "The key usage extension is not marked as critical." + case .smimeNoEmailAddress: + return "No email address was found in the certificate." + case .smimeSubjAltNameNotCritical: + return "The subject alternative name extension is not marked as critical." + case .sslBadExtendedKeyUsage: + return "The appropriate extended key usage for SSL was not found." + case .ocspBadResponse: + return "The OCSP response was incorrect or could not be parsed." + case .ocspBadRequest: + return "The OCSP request was incorrect or could not be parsed." + case .ocspUnavailable: + return "OCSP service is unavailable." + case .ocspStatusUnrecognized: + return "The OCSP server did not recognize this certificate." + case .endOfData: + return "An end-of-data was detected." + case .incompleteCertRevocationCheck: + return "An incomplete certificate revocation check occurred." + case .networkFailure: + return "A network failure occurred." + case .ocspNotTrustedToAnchor: + return "The OCSP response was not trusted to a root or anchor certificate." + case .recordModified: + return "The record was modified." + case .ocspSignatureError: + return "The OCSP response had an invalid signature." + case .ocspNoSigner: + return "The OCSP response had no signer." + case .ocspResponderMalformedReq: + return "The OCSP responder was given a malformed request." + case .ocspResponderInternalError: + return "The OCSP responder encountered an internal error." + case .ocspResponderTryLater: + return "The OCSP responder is busy, try again later." + case .ocspResponderSignatureRequired: + return "The OCSP responder requires a signature." + case .ocspResponderUnauthorized: + return "The OCSP responder rejected this request as unauthorized." + case .ocspResponseNonceMismatch: + return "The OCSP response nonce did not match the request." + case .codeSigningBadCertChainLength: + return "Code signing encountered an incorrect certificate chain length." + case .codeSigningNoBasicConstraints: + return "Code signing found no basic constraints." + case .codeSigningBadPathLengthConstraint: + return "Code signing encountered an incorrect path length constraint." + case .codeSigningNoExtendedKeyUsage: + return "Code signing found no extended key usage." + case .codeSigningDevelopment: + return "Code signing indicated use of a development-only certificate." + case .resourceSignBadCertChainLength: + return "Resource signing has encountered an incorrect certificate chain length." + case .resourceSignBadExtKeyUsage: + return "Resource signing has encountered an error in the extended key usage." + case .trustSettingDeny: + return "The trust setting for this policy was set to Deny." + case .invalidSubjectName: + return "An invalid certificate subject name was encountered." + case .unknownQualifiedCertStatement: + return "An unknown qualified certificate statement was encountered." + case .mobileMeRequestQueued: + return "The MobileMe request will be sent during the next connection." + case .mobileMeRequestRedirected: + return "The MobileMe request was redirected." + case .mobileMeServerError: + return "A MobileMe server error occurred." + case .mobileMeServerNotAvailable: + return "The MobileMe server is not available." + case .mobileMeServerAlreadyExists: + return "The MobileMe server reported that the item already exists." + case .mobileMeServerServiceErr: + return "A MobileMe service error has occurred." + case .mobileMeRequestAlreadyPending: + return "A MobileMe request is already pending." + case .mobileMeNoRequestPending: + return "MobileMe has no request pending." + case .mobileMeCSRVerifyFailure: + return "A MobileMe CSR verification failure has occurred." + case .mobileMeFailedConsistencyCheck: + return "MobileMe has found a failed consistency check." + case .notInitialized: + return "A function was called without initializing CSSM." + case .invalidHandleUsage: + return "The CSSM handle does not match with the service type." + case .pvcReferentNotFound: + return "A reference to the calling module was not found in the list of authorized callers." + case .functionIntegrityFail: + return "A function address was not within the verified module." + case .internalError: + return "An internal error has occurred." + case .memoryError: + return "A memory error has occurred." + case .invalidData: + return "Invalid data was encountered." + case .mdsError: + return "A Module Directory Service error has occurred." + case .invalidPointer: + return "An invalid pointer was encountered." + case .selfCheckFailed: + return "Self-check has failed." + case .functionFailed: + return "A function has failed." + case .moduleManifestVerifyFailed: + return "A module manifest verification failure has occurred." + case .invalidGUID: + return "An invalid GUID was encountered." + case .invalidHandle: + return "An invalid handle was encountered." + case .invalidDBList: + return "An invalid DB list was encountered." + case .invalidPassthroughID: + return "An invalid passthrough ID was encountered." + case .invalidNetworkAddress: + return "An invalid network address was encountered." + case .crlAlreadySigned: + return "The certificate revocation list is already signed." + case .invalidNumberOfFields: + return "An invalid number of fields were encountered." + case .verificationFailure: + return "A verification failure occurred." + case .unknownTag: + return "An unknown tag was encountered." + case .invalidSignature: + return "An invalid signature was encountered." + case .invalidName: + return "An invalid name was encountered." + case .invalidCertificateRef: + return "An invalid certificate reference was encountered." + case .invalidCertificateGroup: + return "An invalid certificate group was encountered." + case .tagNotFound: + return "The specified tag was not found." + case .invalidQuery: + return "The specified query was not valid." + case .invalidValue: + return "An invalid value was detected." + case .callbackFailed: + return "A callback has failed." + case .aclDeleteFailed: + return "An ACL delete operation has failed." + case .aclReplaceFailed: + return "An ACL replace operation has failed." + case .aclAddFailed: + return "An ACL add operation has failed." + case .aclChangeFailed: + return "An ACL change operation has failed." + case .invalidAccessCredentials: + return "Invalid access credentials were encountered." + case .invalidRecord: + return "An invalid record was encountered." + case .invalidACL: + return "An invalid ACL was encountered." + case .invalidSampleValue: + return "An invalid sample value was encountered." + case .incompatibleVersion: + return "An incompatible version was encountered." + case .privilegeNotGranted: + return "The privilege was not granted." + case .invalidScope: + return "An invalid scope was encountered." + case .pvcAlreadyConfigured: + return "The PVC is already configured." + case .invalidPVC: + return "An invalid PVC was encountered." + case .emmLoadFailed: + return "The EMM load has failed." + case .emmUnloadFailed: + return "The EMM unload has failed." + case .addinLoadFailed: + return "The add-in load operation has failed." + case .invalidKeyRef: + return "An invalid key was encountered." + case .invalidKeyHierarchy: + return "An invalid key hierarchy was encountered." + case .addinUnloadFailed: + return "The add-in unload operation has failed." + case .libraryReferenceNotFound: + return "A library reference was not found." + case .invalidAddinFunctionTable: + return "An invalid add-in function table was encountered." + case .invalidServiceMask: + return "An invalid service mask was encountered." + case .moduleNotLoaded: + return "A module was not loaded." + case .invalidSubServiceID: + return "An invalid subservice ID was encountered." + case .attributeNotInContext: + return "An attribute was not in the context." + case .moduleManagerInitializeFailed: + return "A module failed to initialize." + case .moduleManagerNotFound: + return "A module was not found." + case .eventNotificationCallbackNotFound: + return "An event notification callback was not found." + case .inputLengthError: + return "An input length error was encountered." + case .outputLengthError: + return "An output length error was encountered." + case .privilegeNotSupported: + return "The privilege is not supported." + case .deviceError: + return "A device error was encountered." + case .attachHandleBusy: + return "The CSP handle was busy." + case .notLoggedIn: + return "You are not logged in." + case .algorithmMismatch: + return "An algorithm mismatch was encountered." + case .keyUsageIncorrect: + return "The key usage is incorrect." + case .keyBlobTypeIncorrect: + return "The key blob type is incorrect." + case .keyHeaderInconsistent: + return "The key header is inconsistent." + case .unsupportedKeyFormat: + return "The key header format is not supported." + case .unsupportedKeySize: + return "The key size is not supported." + case .invalidKeyUsageMask: + return "The key usage mask is not valid." + case .unsupportedKeyUsageMask: + return "The key usage mask is not supported." + case .invalidKeyAttributeMask: + return "The key attribute mask is not valid." + case .unsupportedKeyAttributeMask: + return "The key attribute mask is not supported." + case .invalidKeyLabel: + return "The key label is not valid." + case .unsupportedKeyLabel: + return "The key label is not supported." + case .invalidKeyFormat: + return "The key format is not valid." + case .unsupportedVectorOfBuffers: + return "The vector of buffers is not supported." + case .invalidInputVector: + return "The input vector is not valid." + case .invalidOutputVector: + return "The output vector is not valid." + case .invalidContext: + return "An invalid context was encountered." + case .invalidAlgorithm: + return "An invalid algorithm was encountered." + case .invalidAttributeKey: + return "A key attribute was not valid." + case .missingAttributeKey: + return "A key attribute was missing." + case .invalidAttributeInitVector: + return "An init vector attribute was not valid." + case .missingAttributeInitVector: + return "An init vector attribute was missing." + case .invalidAttributeSalt: + return "A salt attribute was not valid." + case .missingAttributeSalt: + return "A salt attribute was missing." + case .invalidAttributePadding: + return "A padding attribute was not valid." + case .missingAttributePadding: + return "A padding attribute was missing." + case .invalidAttributeRandom: + return "A random number attribute was not valid." + case .missingAttributeRandom: + return "A random number attribute was missing." + case .invalidAttributeSeed: + return "A seed attribute was not valid." + case .missingAttributeSeed: + return "A seed attribute was missing." + case .invalidAttributePassphrase: + return "A passphrase attribute was not valid." + case .missingAttributePassphrase: + return "A passphrase attribute was missing." + case .invalidAttributeKeyLength: + return "A key length attribute was not valid." + case .missingAttributeKeyLength: + return "A key length attribute was missing." + case .invalidAttributeBlockSize: + return "A block size attribute was not valid." + case .missingAttributeBlockSize: + return "A block size attribute was missing." + case .invalidAttributeOutputSize: + return "An output size attribute was not valid." + case .missingAttributeOutputSize: + return "An output size attribute was missing." + case .invalidAttributeRounds: + return "The number of rounds attribute was not valid." + case .missingAttributeRounds: + return "The number of rounds attribute was missing." + case .invalidAlgorithmParms: + return "An algorithm parameters attribute was not valid." + case .missingAlgorithmParms: + return "An algorithm parameters attribute was missing." + case .invalidAttributeLabel: + return "A label attribute was not valid." + case .missingAttributeLabel: + return "A label attribute was missing." + case .invalidAttributeKeyType: + return "A key type attribute was not valid." + case .missingAttributeKeyType: + return "A key type attribute was missing." + case .invalidAttributeMode: + return "A mode attribute was not valid." + case .missingAttributeMode: + return "A mode attribute was missing." + case .invalidAttributeEffectiveBits: + return "An effective bits attribute was not valid." + case .missingAttributeEffectiveBits: + return "An effective bits attribute was missing." + case .invalidAttributeStartDate: + return "A start date attribute was not valid." + case .missingAttributeStartDate: + return "A start date attribute was missing." + case .invalidAttributeEndDate: + return "An end date attribute was not valid." + case .missingAttributeEndDate: + return "An end date attribute was missing." + case .invalidAttributeVersion: + return "A version attribute was not valid." + case .missingAttributeVersion: + return "A version attribute was missing." + case .invalidAttributePrime: + return "A prime attribute was not valid." + case .missingAttributePrime: + return "A prime attribute was missing." + case .invalidAttributeBase: + return "A base attribute was not valid." + case .missingAttributeBase: + return "A base attribute was missing." + case .invalidAttributeSubprime: + return "A subprime attribute was not valid." + case .missingAttributeSubprime: + return "A subprime attribute was missing." + case .invalidAttributeIterationCount: + return "An iteration count attribute was not valid." + case .missingAttributeIterationCount: + return "An iteration count attribute was missing." + case .invalidAttributeDLDBHandle: + return "A database handle attribute was not valid." + case .missingAttributeDLDBHandle: + return "A database handle attribute was missing." + case .invalidAttributeAccessCredentials: + return "An access credentials attribute was not valid." + case .missingAttributeAccessCredentials: + return "An access credentials attribute was missing." + case .invalidAttributePublicKeyFormat: + return "A public key format attribute was not valid." + case .missingAttributePublicKeyFormat: + return "A public key format attribute was missing." + case .invalidAttributePrivateKeyFormat: + return "A private key format attribute was not valid." + case .missingAttributePrivateKeyFormat: + return "A private key format attribute was missing." + case .invalidAttributeSymmetricKeyFormat: + return "A symmetric key format attribute was not valid." + case .missingAttributeSymmetricKeyFormat: + return "A symmetric key format attribute was missing." + case .invalidAttributeWrappedKeyFormat: + return "A wrapped key format attribute was not valid." + case .missingAttributeWrappedKeyFormat: + return "A wrapped key format attribute was missing." + case .stagedOperationInProgress: + return "A staged operation is in progress." + case .stagedOperationNotStarted: + return "A staged operation was not started." + case .verifyFailed: + return "A cryptographic verification failure has occurred." + case .querySizeUnknown: + return "The query size is unknown." + case .blockSizeMismatch: + return "A block size mismatch occurred." + case .publicKeyInconsistent: + return "The public key was inconsistent." + case .deviceVerifyFailed: + return "A device verification failure has occurred." + case .invalidLoginName: + return "An invalid login name was detected." + case .alreadyLoggedIn: + return "The user is already logged in." + case .invalidDigestAlgorithm: + return "An invalid digest algorithm was detected." + case .invalidCRLGroup: + return "An invalid CRL group was detected." + case .certificateCannotOperate: + return "The certificate cannot operate." + case .certificateExpired: + return "An expired certificate was detected." + case .certificateNotValidYet: + return "The certificate is not yet valid." + case .certificateRevoked: + return "The certificate was revoked." + case .certificateSuspended: + return "The certificate was suspended." + case .insufficientCredentials: + return "Insufficient credentials were detected." + case .invalidAction: + return "The action was not valid." + case .invalidAuthority: + return "The authority was not valid." + case .verifyActionFailed: + return "A verify action has failed." + case .invalidCertAuthority: + return "The certificate authority was not valid." + case .invaldCRLAuthority: + return "The CRL authority was not valid." + case .invalidCRLEncoding: + return "The CRL encoding was not valid." + case .invalidCRLType: + return "The CRL type was not valid." + case .invalidCRL: + return "The CRL was not valid." + case .invalidFormType: + return "The form type was not valid." + case .invalidID: + return "The ID was not valid." + case .invalidIdentifier: + return "The identifier was not valid." + case .invalidIndex: + return "The index was not valid." + case .invalidPolicyIdentifiers: + return "The policy identifiers are not valid." + case .invalidTimeString: + return "The time specified was not valid." + case .invalidReason: + return "The trust policy reason was not valid." + case .invalidRequestInputs: + return "The request inputs are not valid." + case .invalidResponseVector: + return "The response vector was not valid." + case .invalidStopOnPolicy: + return "The stop-on policy was not valid." + case .invalidTuple: + return "The tuple was not valid." + case .multipleValuesUnsupported: + return "Multiple values are not supported." + case .notTrusted: + return "The trust policy was not trusted." + case .noDefaultAuthority: + return "No default authority was detected." + case .rejectedForm: + return "The trust policy had a rejected form." + case .requestLost: + return "The request was lost." + case .requestRejected: + return "The request was rejected." + case .unsupportedAddressType: + return "The address type is not supported." + case .unsupportedService: + return "The service is not supported." + case .invalidTupleGroup: + return "The tuple group was not valid." + case .invalidBaseACLs: + return "The base ACLs are not valid." + case .invalidTupleCredendtials: + return "The tuple credentials are not valid." + case .invalidEncoding: + return "The encoding was not valid." + case .invalidValidityPeriod: + return "The validity period was not valid." + case .invalidRequestor: + return "The requestor was not valid." + case .requestDescriptor: + return "The request descriptor was not valid." + case .invalidBundleInfo: + return "The bundle information was not valid." + case .invalidCRLIndex: + return "The CRL index was not valid." + case .noFieldValues: + return "No field values were detected." + case .unsupportedFieldFormat: + return "The field format is not supported." + case .unsupportedIndexInfo: + return "The index information is not supported." + case .unsupportedLocality: + return "The locality is not supported." + case .unsupportedNumAttributes: + return "The number of attributes is not supported." + case .unsupportedNumIndexes: + return "The number of indexes is not supported." + case .unsupportedNumRecordTypes: + return "The number of record types is not supported." + case .fieldSpecifiedMultiple: + return "Too many fields were specified." + case .incompatibleFieldFormat: + return "The field format was incompatible." + case .invalidParsingModule: + return "The parsing module was not valid." + case .databaseLocked: + return "The database is locked." + case .datastoreIsOpen: + return "The data store is open." + case .missingValue: + return "A missing value was detected." + case .unsupportedQueryLimits: + return "The query limits are not supported." + case .unsupportedNumSelectionPreds: + return "The number of selection predicates is not supported." + case .unsupportedOperator: + return "The operator is not supported." + case .invalidDBLocation: + return "The database location is not valid." + case .invalidAccessRequest: + return "The access request is not valid." + case .invalidIndexInfo: + return "The index information is not valid." + case .invalidNewOwner: + return "The new owner is not valid." + case .invalidModifyMode: + return "The modify mode is not valid." + case .missingRequiredExtension: + return "A required certificate extension is missing." + case .extendedKeyUsageNotCritical: + return "The extended key usage extension was not marked critical." + case .timestampMissing: + return "A timestamp was expected but was not found." + case .timestampInvalid: + return "The timestamp was not valid." + case .timestampNotTrusted: + return "The timestamp was not trusted." + case .timestampServiceNotAvailable: + return "The timestamp service is not available." + case .timestampBadAlg: + return "An unrecognized or unsupported Algorithm Identifier in timestamp." + case .timestampBadRequest: + return "The timestamp transaction is not permitted or supported." + case .timestampBadDataFormat: + return "The timestamp data submitted has the wrong format." + case .timestampTimeNotAvailable: + return "The time source for the Timestamp Authority is not available." + case .timestampUnacceptedPolicy: + return "The requested policy is not supported by the Timestamp Authority." + case .timestampUnacceptedExtension: + return "The requested extension is not supported by the Timestamp Authority." + case .timestampAddInfoNotAvailable: + return "The additional information requested is not available." + case .timestampSystemFailure: + return "The timestamp request cannot be handled due to system failure." + case .signingTimeMissing: + return "A signing time was expected but was not found." + case .timestampRejection: + return "A timestamp transaction was rejected." + case .timestampWaiting: + return "A timestamp transaction is waiting." + case .timestampRevocationWarning: + return "A timestamp authority revocation warning was issued." + case .timestampRevocationNotification: + return "A timestamp authority revocation notification was issued." + case .unexpectedError: + return "Unexpected error has occurred." + } + } +} + +let KeychainAccessErrorDomain = "com.cely-tools.Cely.error" + +extension CelySecureStatus: CustomNSError { + public static let errorDomain = KeychainAccessErrorDomain + + public var errorCode: Int { + return Int(rawValue) + } + + public var errorUserInfo: [String: Any] { + return [NSLocalizedDescriptionKey: description] + } +} diff --git a/Tests/CelyStorageTests.swift b/Tests/CelyStorageTests.swift index 80d582d..ce470bc 100644 --- a/Tests/CelyStorageTests.swift +++ b/Tests/CelyStorageTests.swift @@ -106,7 +106,7 @@ class StorageTests: XCTestCase { let successStatus = success == StorageResult.success XCTAssert(successStatus, dummy.failedToSet()) } else { - XCTAssert(StorageResult.fail(.undefined) == success, "You're not supposed to be able to set nil in the storage.") + XCTAssert(StorageResult.fail(.param) == success, "You're not supposed to be able to set nil in the storage.") } } } diff --git a/Tests/CelyTests.swift b/Tests/CelyTests.swift index e2a6275..4ac2403 100644 --- a/Tests/CelyTests.swift +++ b/Tests/CelyTests.swift @@ -6,8 +6,8 @@ // Copyright © 2016 Fabian Buentello. All rights reserved. // -import XCTest @testable import Cely +import XCTest class DummyUser: CelyUser { enum Property: CelyProperty { case Username = "username" @@ -17,16 +17,15 @@ class DummyUser: CelyUser { } class DummyStorage: CelyStorageProtocol { - - public var dummyStorage: [String : Any?] = [ - "username":"testUser", - "token":"helloToken" + public var dummyStorage: [String: Any?] = [ + "username": "testUser", + "token": "helloToken", ] static var successful_setCalls = 0 static var successful_removeCalls = 0 - func set(_ value: Any?, forKey key: String, securely secure: Bool = true, persisted: Bool = false) -> StorageResult { - if value == nil { return .fail(.undefined) } + func set(_ value: Any?, forKey _: String, securely _: Bool = true, persisted _: Bool = false) -> StorageResult { + if value == nil { return .fail(.param) } DummyStorage.successful_setCalls += 1 return .success } @@ -40,18 +39,17 @@ class DummyStorage: CelyStorageProtocol { } } - /// Tests for Cely Framework class CelyTests: XCTestCase { var _properties: [DummyUser.Property]! var raw_properties: [CelyProperty] { #if swift(>=4.1) - return _properties.compactMap({"\($0.rawValue)"}) + return _properties.compactMap { "\($0.rawValue)" } #else - return _properties.flatMap({"\($0.rawValue)"}) + return _properties.flatMap { "\($0.rawValue)" } #endif - } + var triggeredNotification: String! override func setUp() { super.setUp() @@ -68,8 +66,8 @@ class CelyTests: XCTestCase { object: nil) _properties = [.Username, .Token] - Cely.setup(with: nil, forModel: DummyUser(), requiredProperties: _properties, withOptions:[ - .storage: DummyStorage() + Cely.setup(with: nil, forModel: DummyUser(), requiredProperties: _properties, withOptions: [ + .storage: DummyStorage(), ]) } @@ -82,17 +80,15 @@ class CelyTests: XCTestCase { } override func tearDown() { - NotificationCenter.default.removeObserver(self) super.tearDown() } - func testSetup() { #if swift(>=4.1) - let testRequiredProperties: [String] = _properties.compactMap({"\($0.rawValue)"}) + let testRequiredProperties: [String] = _properties.compactMap { "\($0.rawValue)" } #else - let testRequiredProperties: [String] = _properties.flatMap({"\($0.rawValue)"}) + let testRequiredProperties: [String] = _properties.flatMap { "\($0.rawValue)" } #endif XCTAssert(Cely.requiredProperties == testRequiredProperties, "Cely does not match the mock results") @@ -101,7 +97,7 @@ class CelyTests: XCTestCase { func testCurrentLogin_LoggedIn_Status() { testSetup() - let status = Cely.currentLoginStatus(fromStorage:DummyStorage()) + let status = Cely.currentLoginStatus(fromStorage: DummyStorage()) XCTAssert(status == .loggedIn, "User failed to have status of being .loggedIn") let statusWithParameters = Cely.currentLoginStatus(requiredProperties: [DummyUser.Property.Username.rawValue, DummyUser.Property.Token.rawValue], fromStorage: DummyStorage()) @@ -116,7 +112,7 @@ class CelyTests: XCTestCase { Cely.requiredProperties.append(DummyUser.Property.Email.rawValue) - let status = Cely.currentLoginStatus(fromStorage:DummyStorage()) + let status = Cely.currentLoginStatus(fromStorage: DummyStorage()) XCTAssert(status == .loggedOut, "User failed to have status of being .loggedOut") let statusWithParameters = Cely.currentLoginStatus(requiredProperties: [DummyUser.Property.Email.rawValue], fromStorage: DummyStorage()) @@ -141,7 +137,7 @@ class CelyTests: XCTestCase { func testSaveProperty() { XCTAssert(Cely.save(3, forKey: "number") == StorageResult.success, "failed to save Number") XCTAssert(Cely.save("string", forKey: "string") == StorageResult.success, "failed to save string") - XCTAssert(Cely.save(nil, forKey: "nilValue") == StorageResult.fail(.undefined), "failed to save nilValue") + XCTAssert(Cely.save(nil, forKey: "nilValue") == StorageResult.fail(.param), "failed to save nilValue") XCTAssert(Cely.save("token", forKey: "tokenString") == StorageResult.success, "failed to save tokenString") XCTAssert(DummyStorage.successful_setCalls == 3, "`Cely.store` and `DummyStorage` are not consistent") diff --git a/Tests/ConstantsAndProtocolTests.swift b/Tests/ConstantsAndProtocolTests.swift index 7badd61..7625ea1 100644 --- a/Tests/ConstantsAndProtocolTests.swift +++ b/Tests/ConstantsAndProtocolTests.swift @@ -43,13 +43,6 @@ extension ConstantsAndProtocolTests { XCTAssertEqual(fakeTextField.leftSpacer, 0, "leftSpacer was supposed to return 0") } - - func testStorageResultEquatable() { - let successResult = StorageResult.success - let failureResult = StorageResult.fail(.undefined) - - XCTAssertNotEqual(successResult, failureResult, "Results were not supposed to be equal") - } } // MARK: - Test Protocols From 25f8157ce88f17073364c2976817df2893340da6 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 07:30:15 -0500 Subject: [PATCH 04/17] move storage files --- Cely.xcodeproj/project.pbxproj | 24 ++++++++++--------- Sources/{ => Storage}/CelyKeychain.swift | 0 Sources/{ => Storage}/CelySecureStorage.swift | 0 Sources/{ => Storage}/CelyStorage.swift | 0 4 files changed, 13 insertions(+), 11 deletions(-) rename Sources/{ => Storage}/CelyKeychain.swift (100%) rename Sources/{ => Storage}/CelySecureStorage.swift (100%) rename Sources/{ => Storage}/CelyStorage.swift (100%) diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index c23caeb..f5b07b9 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -37,9 +37,6 @@ 1F68AFE71E89505A001A0161 /* CelyProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */; }; 1F68AFE81E89505A001A0161 /* CelyProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */; }; 1F68AFE91E89505A001A0161 /* CelyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD71E89505A001A0161 /* CelyStorage.swift */; }; - 1F68AFEA1E89505A001A0161 /* CelyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD71E89505A001A0161 /* CelyStorage.swift */; }; - 1F68AFEB1E89505A001A0161 /* CelyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD71E89505A001A0161 /* CelyStorage.swift */; }; - 1F68AFEC1E89505A001A0161 /* CelyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD71E89505A001A0161 /* CelyStorage.swift */; }; 1F68AFED1E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; 1F68AFEE1E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; 1F68AFEF1E89505A001A0161 /* CelyWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */; }; @@ -166,7 +163,7 @@ 1F68B01C1E89519A001A0161 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = TestStoryboard.storyboard; path = Frameworks/TestStoryboard.storyboard; sourceTree = ""; }; 1F9D24071E8D49C700FB4BE6 /* Cely Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Cely Demo.entitlements"; sourceTree = ""; }; - 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = CelySecureStatus.swift; path = Storage/CelySecureStatus.swift; sourceTree = ""; }; + 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStatus.swift; sourceTree = ""; }; 31817D1022FBCA15004FF30F /* CelyKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyKeychain.swift; sourceTree = ""; }; 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStorage.swift; sourceTree = ""; }; 3549BB171DA3890B00C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -289,6 +286,17 @@ path = "Cely Demo"; sourceTree = ""; }; + 311B5E3023310901002166E1 /* Storage */ = { + isa = PBXGroup; + children = ( + 1F68AFD71E89505A001A0161 /* CelyStorage.swift */, + 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */, + 31817D1022FBCA15004FF30F /* CelyKeychain.swift */, + 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */, + ); + path = Storage; + sourceTree = ""; + }; 3549BAFB1DA387DB00C63030 = { isa = PBXGroup; children = ( @@ -367,14 +375,11 @@ 3549BB5C1DA38AA500C63030 /* Core */ = { isa = PBXGroup; children = ( + 311B5E3023310901002166E1 /* Storage */, 1F68AFD41E89505A001A0161 /* Cely.swift */, 1F68AFD51E89505A001A0161 /* CelyConstants.swift */, - 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */, 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */, - 1F68AFD71E89505A001A0161 /* CelyStorage.swift */, - 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */, 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */, - 31817D1022FBCA15004FF30F /* CelyKeychain.swift */, ); name = Core; sourceTree = ""; @@ -889,7 +894,6 @@ 1F68AFE81E89505A001A0161 /* CelyProtocols.swift in Sources */, 1F68AFE41E89505A001A0161 /* CelyConstants.swift in Sources */, 1F68B00F1E895069001A0161 /* CelyLoginViewController.swift in Sources */, - 1F68AFEC1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFF01E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFE01E89505A001A0161 /* Cely.swift in Sources */, ); @@ -902,7 +906,6 @@ 1F68AFE61E89505A001A0161 /* CelyProtocols.swift in Sources */, 1F68AFE21E89505A001A0161 /* CelyConstants.swift in Sources */, 1F68B00D1E895069001A0161 /* CelyLoginViewController.swift in Sources */, - 1F68AFEA1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFEE1E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFDE1E89505A001A0161 /* Cely.swift in Sources */, ); @@ -915,7 +918,6 @@ 1F68AFE71E89505A001A0161 /* CelyProtocols.swift in Sources */, 1F68AFE31E89505A001A0161 /* CelyConstants.swift in Sources */, 1F68B00E1E895069001A0161 /* CelyLoginViewController.swift in Sources */, - 1F68AFEB1E89505A001A0161 /* CelyStorage.swift in Sources */, 1F68AFEF1E89505A001A0161 /* CelyWindowManager.swift in Sources */, 1F68AFDF1E89505A001A0161 /* Cely.swift in Sources */, ); diff --git a/Sources/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift similarity index 100% rename from Sources/CelyKeychain.swift rename to Sources/Storage/CelyKeychain.swift diff --git a/Sources/CelySecureStorage.swift b/Sources/Storage/CelySecureStorage.swift similarity index 100% rename from Sources/CelySecureStorage.swift rename to Sources/Storage/CelySecureStorage.swift diff --git a/Sources/CelyStorage.swift b/Sources/Storage/CelyStorage.swift similarity index 100% rename from Sources/CelyStorage.swift rename to Sources/Storage/CelyStorage.swift From c69c969cd6fda17ee9e58494d800cdc675dd7286 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 07:33:54 -0500 Subject: [PATCH 05/17] rename CelySecureStatus to CelyStorageError --- Cely.xcodeproj/project.pbxproj | 8 ++++---- Sources/CelyConstants.swift | 2 +- Sources/Storage/CelyKeychain.swift | 10 +++++----- .../{CelySecureStatus.swift => CelyStorageError.swift} | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) rename Sources/Storage/{CelySecureStatus.swift => CelyStorageError.swift} (99%) diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index f5b07b9..bb3a75c 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -76,7 +76,7 @@ 1F68B0471E8951AA001A0161 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */; }; 31238F162331019400D6CBC3 /* Cely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; }; 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 31238F1A233103D500D6CBC3 /* CelySecureStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */; }; + 31238F1A233103D500D6CBC3 /* CelyStorageError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31238F19233103D500D6CBC3 /* CelyStorageError.swift */; }; 31817D1122FBCA15004FF30F /* CelyKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31817D1022FBCA15004FF30F /* CelyKeychain.swift */; }; 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */; }; 3549BB501DA38A2000C63030 /* Cely.h in Headers */ = {isa = PBXBuildFile; fileRef = 3549BB181DA3890B00C63030 /* Cely.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -163,7 +163,7 @@ 1F68B01C1E89519A001A0161 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = TestStoryboard.storyboard; path = Frameworks/TestStoryboard.storyboard; sourceTree = ""; }; 1F9D24071E8D49C700FB4BE6 /* Cely Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Cely Demo.entitlements"; sourceTree = ""; }; - 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStatus.swift; sourceTree = ""; }; + 31238F19233103D500D6CBC3 /* CelyStorageError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyStorageError.swift; sourceTree = ""; }; 31817D1022FBCA15004FF30F /* CelyKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyKeychain.swift; sourceTree = ""; }; 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStorage.swift; sourceTree = ""; }; 3549BB171DA3890B00C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -292,7 +292,7 @@ 1F68AFD71E89505A001A0161 /* CelyStorage.swift */, 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */, 31817D1022FBCA15004FF30F /* CelyKeychain.swift */, - 31238F19233103D500D6CBC3 /* CelySecureStatus.swift */, + 31238F19233103D500D6CBC3 /* CelyStorageError.swift */, ); path = Storage; sourceTree = ""; @@ -878,7 +878,7 @@ 1F68AFE51E89505A001A0161 /* CelyProtocols.swift in Sources */, 1F68AFE11E89505A001A0161 /* CelyConstants.swift in Sources */, 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */, - 31238F1A233103D500D6CBC3 /* CelySecureStatus.swift in Sources */, + 31238F1A233103D500D6CBC3 /* CelyStorageError.swift in Sources */, 1F68B00C1E895069001A0161 /* CelyLoginViewController.swift in Sources */, 1F68AFE91E89505A001A0161 /* CelyStorage.swift in Sources */, 31817D1122FBCA15004FF30F /* CelyKeychain.swift in Sources */, diff --git a/Sources/CelyConstants.swift b/Sources/CelyConstants.swift index 53ce3e3..857e9db 100644 --- a/Sources/CelyConstants.swift +++ b/Sources/CelyConstants.swift @@ -33,7 +33,7 @@ public enum CelyOptions { // enum result on whether or not Cely successfully saved your data public enum StorageResult: Equatable { case success - case fail(CelySecureStatus) + case fail(CelyStorageError) } public func == (lhs: StorageResult, rhs: StorageResult) -> Bool { diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index 7e161c1..ea25c8b 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -26,7 +26,7 @@ internal struct CelyKeychain { func clearKeychain() -> StorageResult { let status = SecItemDelete(baseQuery as CFDictionary) - let errorStatus = CelySecureStatus(status: status) + let errorStatus = CelyStorageError(status: status) guard errorStatus == .success else { return StorageResult.fail(errorStatus) } return .success @@ -35,13 +35,13 @@ internal struct CelyKeychain { func getCredentials() throws -> [String: Any] { var item: CFTypeRef? let status = SecItemCopyMatching(searchQuery as CFDictionary, &item) - guard status == errSecSuccess else { throw CelySecureStatus(status: status) } + guard status == errSecSuccess else { throw CelyStorageError(status: status) } do { guard let existingItem = item as? [String: Any], let secureData = existingItem[kSecValueData as String] as? Data, let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String: Any] - else { throw CelySecureStatus.decode } + else { throw CelyStorageError.decode } return loadedDictionary } } @@ -53,7 +53,7 @@ internal struct CelyKeychain { // try adding first let status: OSStatus = SecItemAdd(queryCopy as CFDictionary, nil) - let code = CelySecureStatus(status: status) + let code = CelyStorageError(status: status) if code == .success { return .success } else if code == .duplicateItem { @@ -68,7 +68,7 @@ internal struct CelyKeychain { let secretData = NSKeyedArchiver.archivedData(withRootObject: secrets) let updateDictionary = [kSecValueData as String: secretData] let status: OSStatus = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) - let code = CelySecureStatus(status: status) + let code = CelyStorageError(status: status) if code == .success { return .success } diff --git a/Sources/Storage/CelySecureStatus.swift b/Sources/Storage/CelyStorageError.swift similarity index 99% rename from Sources/Storage/CelySecureStatus.swift rename to Sources/Storage/CelyStorageError.swift index edf554b..9eb9eab 100644 --- a/Sources/Storage/CelySecureStatus.swift +++ b/Sources/Storage/CelyStorageError.swift @@ -1,5 +1,5 @@ // -// CelySecureStatus.swift +// CelyStorageError.swift // Cely-iOS // // Created by Fabian Buentello on 9/17/19. @@ -10,7 +10,7 @@ import Foundation // https://github.com/kishikawakatsumi/KeychainAccess/blob/3a9c83cf8b8cfaecd1097916fae803e1b1d6447f/Lib/KeychainAccess/Keychain.swift#L1695 -public enum CelySecureStatus: OSStatus, Error { +public enum CelyStorageError: OSStatus, Error { case success = 0 case unimplemented = -4 case diskFull = -34 @@ -416,9 +416,9 @@ public enum CelySecureStatus: OSStatus, Error { case unexpectedError = -99999 } -extension CelySecureStatus: RawRepresentable, CustomStringConvertible { +extension CelyStorageError: RawRepresentable, CustomStringConvertible { public init(status: OSStatus) { - if let mappedStatus = CelySecureStatus(rawValue: status) { + if let mappedStatus = CelyStorageError(rawValue: status) { self = mappedStatus } else { self = .unexpectedError @@ -1239,7 +1239,7 @@ extension CelySecureStatus: RawRepresentable, CustomStringConvertible { let KeychainAccessErrorDomain = "com.cely-tools.Cely.error" -extension CelySecureStatus: CustomNSError { +extension CelyStorageError: CustomNSError { public static let errorDomain = KeychainAccessErrorDomain public var errorCode: Int { From 78e6802a82aedefb98fdce9c2ace506891b94ca2 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 07:49:36 -0500 Subject: [PATCH 06/17] port over to Swift Result --- Cely Demo/AppDelegate.swift | 2 +- Cely Demo/User.swift | 4 ++-- Sources/Cely.swift | 2 +- Sources/CelyProtocols.swift | 2 +- Sources/Storage/CelyKeychain.swift | 20 +++++++++--------- Sources/Storage/CelySecureStorage.swift | 9 ++++++--- Sources/Storage/CelyStorage.swift | 6 +++--- Tests/CelyStorageTests.swift | 10 +++------ Tests/CelyTests.swift | 27 ++++++++++++++++++------- 9 files changed, 47 insertions(+), 35 deletions(-) diff --git a/Cely Demo/AppDelegate.swift b/Cely Demo/AppDelegate.swift index 961790a..68f9165 100644 --- a/Cely Demo/AppDelegate.swift +++ b/Cely Demo/AppDelegate.swift @@ -19,7 +19,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Cely.setup(with: window!, forModel: User(), requiredProperties: [.token], withOptions: [ .loginCompletionBlock: { (username: String, password: String) in if username == "asdf" && password == "asdf" { - if User.save("FAKETOKEN:\(username)\(password)", as: .token) == .success { + if case .success = User.save("FAKETOKEN:\(username)\(password)", as: .token) { Cely.changeStatus(to: .loggedIn) } } diff --git a/Cely Demo/User.swift b/Cely Demo/User.swift index 91842ff..e232d16 100644 --- a/Cely Demo/User.swift +++ b/Cely Demo/User.swift @@ -34,7 +34,7 @@ struct User: CelyUser { } } - @discardableResult func save(_ value: Any) -> StorageResult { + @discardableResult func save(_ value: Any) -> Result { return Cely.save(value, forKey: rawValue, securely: securely(), persisted: persisted()) } @@ -48,7 +48,7 @@ struct User: CelyUser { extension User { - @discardableResult static func save(_ value: Any, as property: Property) -> StorageResult { + @discardableResult static func save(_ value: Any, as property: Property) -> Result { return property.save(value) } diff --git a/Sources/Cely.swift b/Sources/Cely.swift index 12296ea..3c5c73f 100644 --- a/Sources/Cely.swift +++ b/Sources/Cely.swift @@ -89,7 +89,7 @@ extension Cely { /// - parameter persist: `Boolean`: Keep data after logout /// /// - returns: `Boolean`: Whether or not your value was successfully set. - @discardableResult public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> StorageResult { + @discardableResult public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result { return store.set(value, forKey: key, securely: secure, persisted: persist) } diff --git a/Sources/CelyProtocols.swift b/Sources/CelyProtocols.swift index 4934a38..0592154 100644 --- a/Sources/CelyProtocols.swift +++ b/Sources/CelyProtocols.swift @@ -16,7 +16,7 @@ public protocol CelyUser { /// Protocol a storage class must abide by in order for Cely to use it public protocol CelyStorageProtocol { - func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) -> StorageResult + func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) -> Result func get(_ key: String) -> Any? func removeAllData() } diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index ea25c8b..3923a6b 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -46,7 +46,7 @@ internal struct CelyKeychain { } } - func set(_ secrets: [String: Any]) -> StorageResult { + func set(_ secrets: [String: Any]) -> Result { var queryCopy = baseQuery let storeData = NSKeyedArchiver.archivedData(withRootObject: secrets) queryCopy[kSecValueData as String] = storeData @@ -54,24 +54,24 @@ internal struct CelyKeychain { // try adding first let status: OSStatus = SecItemAdd(queryCopy as CFDictionary, nil) let code = CelyStorageError(status: status) - if code == .success { - return .success - } else if code == .duplicateItem { - // already exists, should update instead + switch code { + case .success: + return .success(()) + case .duplicateItem: return update(secrets: secrets) + default: + return .failure(code) } - - return .fail(code) } - private func update(secrets: [String: Any]) -> StorageResult { + private func update(secrets: [String: Any]) -> Result { let secretData = NSKeyedArchiver.archivedData(withRootObject: secrets) let updateDictionary = [kSecValueData as String: secretData] let status: OSStatus = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) let code = CelyStorageError(status: status) if code == .success { - return .success + return .success(()) } - return .fail(code) + return .failure(code) } } diff --git a/Sources/Storage/CelySecureStorage.swift b/Sources/Storage/CelySecureStorage.swift index a5adb69..369ba4e 100644 --- a/Sources/Storage/CelySecureStorage.swift +++ b/Sources/Storage/CelySecureStorage.swift @@ -31,14 +31,17 @@ internal class CelySecureStorage { } } - func set(_ value: Any, forKey key: String) -> StorageResult { + func set(_ value: Any, forKey key: String) -> Result { var storeCopy = store storeCopy[key] = value let result = _celyKeychain.set(storeCopy) - if result == .success { + switch result { + case .success: store[key] = value + return .success(()) + default: + return result } - return result } func get(_ key: String) -> Any? { diff --git a/Sources/Storage/CelyStorage.swift b/Sources/Storage/CelyStorage.swift index 502cc4a..88f9f93 100644 --- a/Sources/Storage/CelyStorage.swift +++ b/Sources/Storage/CelyStorage.swift @@ -66,8 +66,8 @@ public class CelyStorage: CelyStorageProtocol { /// - parameter persisted: `Boolean`: Keep data after logout /// /// - returns: `Boolean` on whether or not it successfully saved - public func set(_ value: Any?, forKey key: String, securely secure: Bool = false, persisted: Bool = false) -> StorageResult { - guard let val = value else { return .fail(.param) } + public func set(_ value: Any?, forKey key: String, securely secure: Bool = false, persisted: Bool = false) -> Result { + guard let val = value else { return .failure(.param) } if secure { return secureStore.set(val, forKey: key) } else { @@ -81,7 +81,7 @@ public class CelyStorage: CelyStorageProtocol { UserDefaults.standard.setPersistentDomain(CelyStorage.sharedInstance.storage, forName: kCelyDomain) UserDefaults.standard.synchronize() } - return .success + return .success(()) } /// Retrieve user data from key diff --git a/Tests/CelyStorageTests.swift b/Tests/CelyStorageTests.swift index ce470bc..e58751b 100644 --- a/Tests/CelyStorageTests.swift +++ b/Tests/CelyStorageTests.swift @@ -83,8 +83,6 @@ class StorageTests: XCTestCase { Dummy(key: "testFloat_secure", value: 1.058, storeSecurely: true), Dummy(key: "testInt", value: 100, storeSecurely: false), Dummy(key: "testInt_secure", value: 100, storeSecurely: true), - Dummy(key: "testNil", value: nil, storeSecurely: false), - Dummy(key: "testNil_secure", value: nil, storeSecurely: true), Dummy(key: "testArrayOfStrings", value: ["string1 success", "string2 success"], storeSecurely: false), Dummy(key: "testArrayOfStrings_secure", value: ["string1 success", "string2 success"], storeSecurely: true), Dummy(key: "testArrayOfNumbers", value: [50, 48.5, 895.5], storeSecurely: false), @@ -101,12 +99,10 @@ class StorageTests: XCTestCase { func testSavingData() { dummyData.forEach { dummy in - let success = store.set(dummy.value, forKey: dummy.key, securely: dummy.storeSecurely, persisted: dummy.persisted) - if dummy.value != nil { - let successStatus = success == StorageResult.success - XCTAssert(successStatus, dummy.failedToSet()) + let status = store.set(dummy.value, forKey: dummy.key, securely: dummy.storeSecurely, persisted: dummy.persisted) + if case .success = status { } else { - XCTAssert(StorageResult.fail(.param) == success, "You're not supposed to be able to set nil in the storage.") + XCTFail(dummy.failedToSet()) } } } diff --git a/Tests/CelyTests.swift b/Tests/CelyTests.swift index 4ac2403..5485a8e 100644 --- a/Tests/CelyTests.swift +++ b/Tests/CelyTests.swift @@ -24,10 +24,10 @@ class DummyStorage: CelyStorageProtocol { static var successful_setCalls = 0 static var successful_removeCalls = 0 - func set(_ value: Any?, forKey _: String, securely _: Bool = true, persisted _: Bool = false) -> StorageResult { - if value == nil { return .fail(.param) } + func set(_ value: Any?, forKey _: String, securely _: Bool = true, persisted _: Bool = false) -> Result { + if value == nil { return .failure(.param) } DummyStorage.successful_setCalls += 1 - return .success + return .success(()) } func get(_ key: String) -> Any? { @@ -135,10 +135,23 @@ class CelyTests: XCTestCase { } func testSaveProperty() { - XCTAssert(Cely.save(3, forKey: "number") == StorageResult.success, "failed to save Number") - XCTAssert(Cely.save("string", forKey: "string") == StorageResult.success, "failed to save string") - XCTAssert(Cely.save(nil, forKey: "nilValue") == StorageResult.fail(.param), "failed to save nilValue") - XCTAssert(Cely.save("token", forKey: "tokenString") == StorageResult.success, "failed to save tokenString") + do { + try Cely.save(3, forKey: "number").get() + } catch { + XCTFail("failed to save Number") + } + + do { + try Cely.save("string", forKey: "string").get() + } catch { + XCTFail("failed to save string") + } + + do { + try Cely.save("token", forKey: "tokenString").get() + } catch { + XCTFail("failed to save tokenString") + } XCTAssert(DummyStorage.successful_setCalls == 3, "`Cely.store` and `DummyStorage` are not consistent") } From b7aae149b1faf4b55e0911b9b5cb6ab7b1a81d00 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Tue, 17 Sep 2019 08:00:26 -0500 Subject: [PATCH 07/17] rename CelyStorageStatus.success to CelyStorageStatus.noError --- Sources/CelyConstants.swift | 19 ------------------- Sources/Storage/CelyKeychain.swift | 11 +++++------ Sources/Storage/CelySecureStorage.swift | 10 +++++----- Sources/Storage/CelyStorageError.swift | 4 ++-- 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/Sources/CelyConstants.swift b/Sources/CelyConstants.swift index 857e9db..0667b1c 100644 --- a/Sources/CelyConstants.swift +++ b/Sources/CelyConstants.swift @@ -30,25 +30,6 @@ public enum CelyOptions { case celyAnimator } -// enum result on whether or not Cely successfully saved your data -public enum StorageResult: Equatable { - case success - case fail(CelyStorageError) -} - -public func == (lhs: StorageResult, rhs: StorageResult) -> Bool { - switch (lhs, rhs) { - case (let .fail(error1), let .fail(error2)): - return error1 == error2 - - case (.success, .success): - return true - - default: - return false - } -} - internal extension UITextField { @IBInspectable var leftSpacer: CGFloat { diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index 3923a6b..9d73e81 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -24,12 +24,11 @@ internal struct CelyKeychain { return queryCopy } - func clearKeychain() -> StorageResult { + func clearKeychain() -> Result { let status = SecItemDelete(baseQuery as CFDictionary) let errorStatus = CelyStorageError(status: status) - guard errorStatus == .success - else { return StorageResult.fail(errorStatus) } - return .success + guard errorStatus == .noError else { return .failure(errorStatus) } + return .success(()) } func getCredentials() throws -> [String: Any] { @@ -55,7 +54,7 @@ internal struct CelyKeychain { let status: OSStatus = SecItemAdd(queryCopy as CFDictionary, nil) let code = CelyStorageError(status: status) switch code { - case .success: + case .noError: return .success(()) case .duplicateItem: return update(secrets: secrets) @@ -69,7 +68,7 @@ internal struct CelyKeychain { let updateDictionary = [kSecValueData as String: secretData] let status: OSStatus = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) let code = CelyStorageError(status: status) - if code == .success { + if code == .noError { return .success(()) } return .failure(code) diff --git a/Sources/Storage/CelySecureStorage.swift b/Sources/Storage/CelySecureStorage.swift index 369ba4e..e7f200f 100644 --- a/Sources/Storage/CelySecureStorage.swift +++ b/Sources/Storage/CelySecureStorage.swift @@ -22,13 +22,13 @@ internal class CelySecureStorage { } } - func clearStorage() { - let status = _celyKeychain.clearKeychain() - if status != .success { - print("Failed to clear keychain, error: \(status)") - } else { + @discardableResult func clearStorage() -> Result { + let result = _celyKeychain.clearKeychain() + if case .success = result { store = [:] + return .success(()) } + return result } func set(_ value: Any, forKey key: String) -> Result { diff --git a/Sources/Storage/CelyStorageError.swift b/Sources/Storage/CelyStorageError.swift index 9eb9eab..973887d 100644 --- a/Sources/Storage/CelyStorageError.swift +++ b/Sources/Storage/CelyStorageError.swift @@ -11,7 +11,7 @@ import Foundation // https://github.com/kishikawakatsumi/KeychainAccess/blob/3a9c83cf8b8cfaecd1097916fae803e1b1d6447f/Lib/KeychainAccess/Keychain.swift#L1695 public enum CelyStorageError: OSStatus, Error { - case success = 0 + case noError = 0 case unimplemented = -4 case diskFull = -34 case io = -36 @@ -427,7 +427,7 @@ extension CelyStorageError: RawRepresentable, CustomStringConvertible { public var description: String { switch self { - case .success: + case .noError: return "No error." case .unimplemented: return "Function or operation not implemented." From 658131305fc82207c2adb7a471f59119754ac1ab Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Mon, 23 Sep 2019 20:32:53 -0500 Subject: [PATCH 08/17] skeleton for verbosity cely flag --- Sources/Cely.swift | 16 +++++++++++++++- Sources/Storage/CelyKeychain.swift | 10 +++++++--- Sources/Storage/CelySecureStorage.swift | 10 ++++++---- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/Sources/Cely.swift b/Sources/Cely.swift index 0174170..f7f20af 100644 --- a/Sources/Cely.swift +++ b/Sources/Cely.swift @@ -21,6 +21,11 @@ public struct Cely { /// A Completion Block that is expecting a `username:String` and a `password:String` public static var loginCompletionBlock: CelyLoginCompletion? + // TODO: decide on having a verbosity CelyOption flag. + // There's some errors (`.itemNotFound`) that are expected to happen and + // I'm not sure if I want to silence them + internal static var verbosity = false + /// Sets up Cely within your application /// /// - parameter window: `UIWindow` of your application. @@ -84,7 +89,8 @@ extension Cely { /// - parameter persist: `Boolean`: Keep data after logout /// /// - returns: `Boolean`: Whether or not your value was successfully set. - @discardableResult public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result { + @discardableResult + public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result { return store.set(value, forKey: key, securely: secure, persisted: persist) } @@ -110,3 +116,11 @@ extension Cely { return currentLoginStatus() == .loggedIn } } + +internal extension Cely { + static func debugPrint(str: CustomStringConvertible) { + if verbosity { + print(str) + } + } +} diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index 9d73e81..64dbb93 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -31,16 +31,20 @@ internal struct CelyKeychain { return .success(()) } - func getCredentials() throws -> [String: Any] { + func getProtectedData() throws -> [String: Any] { var item: CFTypeRef? let status = SecItemCopyMatching(searchQuery as CFDictionary, &item) - guard status == errSecSuccess else { throw CelyStorageError(status: status) } + guard status == errSecSuccess else { + throw CelyStorageError(status: status) + } do { guard let existingItem = item as? [String: Any], let secureData = existingItem[kSecValueData as String] as? Data, let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String: Any] - else { throw CelyStorageError.decode } + else { + throw CelyStorageError.missingValue + } return loadedDictionary } } diff --git a/Sources/Storage/CelySecureStorage.swift b/Sources/Storage/CelySecureStorage.swift index a458357..35b5f56 100644 --- a/Sources/Storage/CelySecureStorage.swift +++ b/Sources/Storage/CelySecureStorage.swift @@ -14,11 +14,13 @@ internal class CelySecureStorage { init() { do { - let credentials = try _celyKeychain.getCredentials() - store = credentials + let currentProtectedData = try _celyKeychain.getProtectedData() + store = currentProtectedData + } catch let error as CelyStorageError { + // Expect this error to happen if first keychain is empty :) + Cely.debugPrint(str: error.description) } catch { - print("Failed to retrieve store from keychain") - print(error) + Cely.debugPrint(str: error.localizedDescription) } } From 2f70f0753d2f3519770294f709c9d14006ab93bd Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Sat, 28 Sep 2019 10:39:21 -0500 Subject: [PATCH 09/17] Refactored code to throw inside of internal classes but still return `Result` with public facing methods --- Cely Demo/User.swift | 4 +- Sources/Cely.swift | 21 +++++++--- Sources/CelyProtocols.swift | 4 +- Sources/Storage/CelyKeychain.swift | 56 ++++++++++++------------- Sources/Storage/CelySecureStorage.swift | 32 +++++--------- Sources/Storage/CelyStorage.swift | 15 +++---- Tests/CelyStorageTests.swift | 8 ++-- Tests/CelyTests.swift | 7 ++-- 8 files changed, 73 insertions(+), 74 deletions(-) diff --git a/Cely Demo/User.swift b/Cely Demo/User.swift index dfdbb45..22896a9 100644 --- a/Cely Demo/User.swift +++ b/Cely Demo/User.swift @@ -33,7 +33,7 @@ struct User: CelyUser { } } - @discardableResult func save(_ value: Any) -> Result { + @discardableResult func save(_ value: Any) -> Result { return Cely.save(value, forKey: rawValue, securely: securely(), persisted: persisted()) } @@ -46,7 +46,7 @@ struct User: CelyUser { // MARK: - Save/Get User Properties extension User { - @discardableResult static func save(_ value: Any, as property: Property) -> Result { + @discardableResult static func save(_ value: Any, as property: Property) -> Result { return property.save(value) } diff --git a/Sources/Cely.swift b/Sources/Cely.swift index f7f20af..b2da1d5 100644 --- a/Sources/Cely.swift +++ b/Sources/Cely.swift @@ -90,8 +90,13 @@ extension Cely { /// /// - returns: `Boolean`: Whether or not your value was successfully set. @discardableResult - public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result { - return store.set(value, forKey: key, securely: secure, persisted: persist) + public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result { + do { + try store.set(value, forKey: key, securely: secure, persisted: persist) + return .success(()) + } catch { + return .failure(error) + } } /// Perform action like `LoggedIn` or `LoggedOut` @@ -104,9 +109,15 @@ extension Cely { /// Log user out /// /// - parameter store: Storage `Cely` will be using. Defaulted to `CelyStorageProtocol` - public static func logout(useStorage store: CelyStorageProtocol = store) { - store.removeAllData() - changeStatus(to: .loggedOut) + @discardableResult + public static func logout(useStorage store: CelyStorageProtocol = store) -> Result { + do { + try store.clearStorage() + changeStatus(to: .loggedOut) + return .success(()) + } catch { + return .failure(error) + } } /// Returns whether or not the user is logged in diff --git a/Sources/CelyProtocols.swift b/Sources/CelyProtocols.swift index afec9ba..ca0cc86 100644 --- a/Sources/CelyProtocols.swift +++ b/Sources/CelyProtocols.swift @@ -16,9 +16,9 @@ public protocol CelyUser { /// Protocol a storage class must abide by in order for Cely to use it public protocol CelyStorageProtocol { - func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) -> Result + func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) throws func get(_ key: String) -> Any? - func removeAllData() + func clearStorage() throws } /// Protocol that allows styles to be applied to Cely's default LoginViewController diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index 64dbb93..bb7ba8e 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -24,57 +24,55 @@ internal struct CelyKeychain { return queryCopy } - func clearKeychain() -> Result { + func clearKeychain() throws { let status = SecItemDelete(baseQuery as CFDictionary) let errorStatus = CelyStorageError(status: status) - guard errorStatus == .noError else { return .failure(errorStatus) } - return .success(()) + guard errorStatus == .noError else { + throw errorStatus + } } func getProtectedData() throws -> [String: Any] { var item: CFTypeRef? let status = SecItemCopyMatching(searchQuery as CFDictionary, &item) - guard status == errSecSuccess else { - throw CelyStorageError(status: status) + let errorStatus = CelyStorageError(status: status) + guard errorStatus == .noError else { + throw errorStatus } - do { - guard let existingItem = item as? [String: Any], - let secureData = existingItem[kSecValueData as String] as? Data, - let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String: Any] - else { - throw CelyStorageError.missingValue - } - return loadedDictionary + guard let existingItem = item as? [String: Any], + let secureData = existingItem[kSecValueData as String] as? Data, + let loadedDictionary = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(secureData) as? [String: Any] + else { + throw CelyStorageError.missingValue } + + return loadedDictionary } - func set(_ secrets: [String: Any]) -> Result { + func set(_ secrets: [String: Any]) throws { var queryCopy = baseQuery let storeData = NSKeyedArchiver.archivedData(withRootObject: secrets) queryCopy[kSecValueData as String] = storeData // try adding first - let status: OSStatus = SecItemAdd(queryCopy as CFDictionary, nil) - let code = CelyStorageError(status: status) - switch code { - case .noError: - return .success(()) - case .duplicateItem: - return update(secrets: secrets) - default: - return .failure(code) + let status = SecItemAdd(queryCopy as CFDictionary, nil) + let errorStatus = CelyStorageError(status: status) + + switch errorStatus { + case .noError: return + case .duplicateItem: return try update(secrets: secrets) + default: throw errorStatus } } - private func update(secrets: [String: Any]) -> Result { + private func update(secrets: [String: Any]) throws { let secretData = NSKeyedArchiver.archivedData(withRootObject: secrets) let updateDictionary = [kSecValueData as String: secretData] - let status: OSStatus = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) - let code = CelyStorageError(status: status) - if code == .noError { - return .success(()) + let status = SecItemUpdate(baseQuery as CFDictionary, updateDictionary as CFDictionary) + let errorStatus = CelyStorageError(status: status) + guard errorStatus == .noError else { + throw errorStatus } - return .failure(code) } } diff --git a/Sources/Storage/CelySecureStorage.swift b/Sources/Storage/CelySecureStorage.swift index 35b5f56..c799b32 100644 --- a/Sources/Storage/CelySecureStorage.swift +++ b/Sources/Storage/CelySecureStorage.swift @@ -8,13 +8,13 @@ import Foundation -internal class CelySecureStorage { +internal class CelySecureStorage: CelyStorageProtocol { var store: [String: Any] = [:] - private let _celyKeychain = CelyKeychain() + private let celyKeychain = CelyKeychain() init() { do { - let currentProtectedData = try _celyKeychain.getProtectedData() + let currentProtectedData = try celyKeychain.getProtectedData() store = currentProtectedData } catch let error as CelyStorageError { // Expect this error to happen if first keychain is empty :) @@ -24,26 +24,16 @@ internal class CelySecureStorage { } } - @discardableResult func clearStorage() -> Result { - let result = _celyKeychain.clearKeychain() - if case .success = result { - store = [:] - return .success(()) - } - return result - } - - func set(_ value: Any, forKey key: String) -> Result { + func set(_ value: Any?, forKey key: String, securely _: Bool = true, persisted _: Bool = true) throws { var storeCopy = store storeCopy[key] = value - let result = _celyKeychain.set(storeCopy) - switch result { - case .success: - store[key] = value - return .success(()) - default: - return result - } + try celyKeychain.set(storeCopy) + store[key] = value + } + + func clearStorage() throws { + try celyKeychain.clearKeychain() + store = [:] } func get(_ key: String) -> Any? { diff --git a/Sources/Storage/CelyStorage.swift b/Sources/Storage/CelyStorage.swift index 15f35bb..8d15777 100644 --- a/Sources/Storage/CelyStorage.swift +++ b/Sources/Storage/CelyStorage.swift @@ -35,7 +35,9 @@ public class CelyStorage: CelyStorageProtocol { UserDefaults.standard.synchronize() // Clear Secure Storage - secureStore.clearStorage() + do { + try secureStore.clearStorage() + } catch {} } setupStorage() @@ -51,11 +53,11 @@ public class CelyStorage: CelyStorageProtocol { } /// Removes all data from both `secureStorage` and regular `storage` - public func removeAllData() { + public func clearStorage() throws { CelyStorage.sharedInstance.storage[kStore] = [:] UserDefaults.standard.setPersistentDomain(CelyStorage.sharedInstance.storage, forName: kCelyDomain) UserDefaults.standard.synchronize() - CelyStorage.sharedInstance.secureStore.clearStorage() + try CelyStorage.sharedInstance.secureStore.clearStorage() } /// Saves data to storage @@ -66,10 +68,10 @@ public class CelyStorage: CelyStorageProtocol { /// - parameter persisted: `Boolean`: Keep data after logout /// /// - returns: `Boolean` on whether or not it successfully saved - public func set(_ value: Any?, forKey key: String, securely secure: Bool = false, persisted: Bool = false) -> Result { - guard let val = value else { return .failure(.param) } + public func set(_ value: Any?, forKey key: String, securely secure: Bool = false, persisted: Bool = false) throws { + guard let val = value else { throw CelyStorageError.param } if secure { - return secureStore.set(val, forKey: key) + return try secureStore.set(val, forKey: key) } else { if persisted { CelyStorage.sharedInstance.storage[kPersisted]?[key] = val @@ -81,7 +83,6 @@ public class CelyStorage: CelyStorageProtocol { UserDefaults.standard.setPersistentDomain(CelyStorage.sharedInstance.storage, forName: kCelyDomain) UserDefaults.standard.synchronize() } - return .success(()) } /// Retrieve user data from key diff --git a/Tests/CelyStorageTests.swift b/Tests/CelyStorageTests.swift index 93d810b..072275d 100644 --- a/Tests/CelyStorageTests.swift +++ b/Tests/CelyStorageTests.swift @@ -98,9 +98,9 @@ class StorageTests: XCTestCase { func testSavingData() { dummyData.forEach { dummy in - let status = store.set(dummy.value, forKey: dummy.key, securely: dummy.storeSecurely, persisted: dummy.persisted) - if case .success = status { - } else { + do { + try store.set(dummy.value, forKey: dummy.key, securely: dummy.storeSecurely, persisted: dummy.persisted) + } catch { XCTFail(dummy.failedToSet()) } } @@ -135,7 +135,7 @@ class StorageTests: XCTestCase { XCTAssert(secureCount == 5, "Did not add all entries inside of 'secureStorage': \(secureCount)") XCTAssert(storageCount == 5, "Did not add all entries inside of 'storage': \(storageCount)") - store.removeAllData() + try! store.clearStorage() secureCount = store.secureStorage.count diff --git a/Tests/CelyTests.swift b/Tests/CelyTests.swift index 5485a8e..24eeb35 100644 --- a/Tests/CelyTests.swift +++ b/Tests/CelyTests.swift @@ -24,17 +24,16 @@ class DummyStorage: CelyStorageProtocol { static var successful_setCalls = 0 static var successful_removeCalls = 0 - func set(_ value: Any?, forKey _: String, securely _: Bool = true, persisted _: Bool = false) -> Result { - if value == nil { return .failure(.param) } + func set(_ value: Any?, forKey _: String, securely _: Bool = true, persisted _: Bool = false) throws { + if value == nil { throw CelyStorageError.param } DummyStorage.successful_setCalls += 1 - return .success(()) } func get(_ key: String) -> Any? { return dummyStorage[key] ?? nil } - func removeAllData() { + func clearStorage() { DummyStorage.successful_removeCalls += 1 } } From eb206a8543d9073f7ff295eb026c7e43acd2c88d Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Mon, 30 Sep 2019 21:24:36 -0500 Subject: [PATCH 10/17] Add cely credentials --- Cely Demo/AppDelegate.swift | 23 +++++- Cely Demo/Base.lproj/Main.storyboard | 27 ++++--- Cely Demo/SettingsViewController.swift | 16 +++- Cely.xcodeproj/project.pbxproj | 24 +++++- Sources/Cely.swift | 13 +--- Sources/Storage/CelyCredentialStore.swift | 73 ++++++++++++++++++ Sources/Storage/CelyKeychain.swift | 93 ++++++++++------------- Sources/Storage/CelySecureStorage.swift | 26 ++++--- Sources/Storage/CelyStorage.swift | 3 + Sources/Storage/CelyStorageError.swift | 6 +- Sources/Storage/KeychainObject.swift | 52 +++++++++++++ Tests/CelyCredentialStoreTests.swift | 83 ++++++++++++++++++++ Tests/CelyStorageErrorTests.swift | 44 +++++++++++ 13 files changed, 389 insertions(+), 94 deletions(-) create mode 100644 Sources/Storage/CelyCredentialStore.swift create mode 100644 Sources/Storage/KeychainObject.swift create mode 100644 Tests/CelyCredentialStoreTests.swift create mode 100644 Tests/CelyStorageErrorTests.swift diff --git a/Cely Demo/AppDelegate.swift b/Cely Demo/AppDelegate.swift index 1663baa..ee41bae 100644 --- a/Cely Demo/AppDelegate.swift +++ b/Cely Demo/AppDelegate.swift @@ -17,8 +17,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Cely.setup(with: window!, forModel: User(), requiredProperties: [.token], withOptions: [ .loginCompletionBlock: { (username: String, password: String) in if username == "asdf", password == "asdf" { - if case .success = User.save("FAKETOKEN:\(username)\(password)", as: .token) { - Cely.changeStatus(to: .loggedIn) + let tokenResult = User.save("FAKETOKEN:\(username)\(password)", as: .token) + switch tokenResult { + case .success: + let credentialResult = Cely.credentials.set( + username: username, + password: password, + server: "api.example.com", + accessibility: [ + .biometricsIfPossible, + .thisDeviceOnly, + ] + ) + + switch credentialResult { + case .success: + Cely.changeStatus(to: .loggedIn) + case let .failure(error): + print("Cely store credentials error: \(error)") + } + case let .failure(error): + print("tokenResult Error: \(error)") } } }, diff --git a/Cely Demo/Base.lproj/Main.storyboard b/Cely Demo/Base.lproj/Main.storyboard index 3177021..75391b4 100644 --- a/Cely Demo/Base.lproj/Main.storyboard +++ b/Cely Demo/Base.lproj/Main.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -22,7 +20,7 @@ + + + @@ -88,7 +97,7 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Cely Demo/BiometricLoginViewController.swift b/Cely Demo/BiometricLoginViewController.swift new file mode 100644 index 0000000..c3b532a --- /dev/null +++ b/Cely Demo/BiometricLoginViewController.swift @@ -0,0 +1,74 @@ +// +// BiometricLoginViewController.swift +// Cely Demo +// +// Created by Fabian Buentello on 10/5/19. +// Copyright © 2019 ChaiOne. All rights reserved. +// + +import Cely +import UIKit + +class BiometricLoginViewController: UIViewController, UITextFieldDelegate { + @IBOutlet weak var usernameField: UITextField? + @IBOutlet weak var passwordField: UITextField? + + @IBOutlet var textFields: [UITextField]? + + var credentialsExist = false + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + let credentialsResult = Cely.credentials.get() + if case let .success(creds) = credentialsResult { + print(creds) + credentialsExist = true + usernameField?.text = creds.username + passwordField?.text = creds.password + loginButtonPressed() + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + usernameField?.delegate = self + passwordField?.delegate = self + } + + @IBAction func loginButtonPressed() { + if let username = usernameField?.text, let password = passwordField?.text { + let tokenResult = User.save("FAKETOKEN:\(username)\(password)", as: .token) + if case let .failure(error) = tokenResult { + return print("tokenResult Error: \(error)") + } + + if !credentialsExist { + let credentialResult = Cely.credentials.set( + username: username, + password: password, + server: "api.example.com", + accessibility: [.biometricsIfPossible] + ) + + if case let .failure(error) = credentialResult { + return print("Cely store credentials error: \(error)") + } + } + + Cely.changeStatus(to: .loggedIn) + } + } + + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + let nextTag = textField.tag + 1 + + if let next = textFields?.filter({ $0.tag == nextTag }).first { + next.becomeFirstResponder() + return true + } + + textField.resignFirstResponder() + return true + } +} diff --git a/Cely Demo/Cely Demo.entitlements b/Cely Demo/Cely Demo.entitlements index ef507d9..0c67376 100644 --- a/Cely Demo/Cely Demo.entitlements +++ b/Cely Demo/Cely Demo.entitlements @@ -1,10 +1,5 @@ - - keychain-access-groups - - $(AppIdentifierPrefix)com.cely-tools.Cely-Demo - - + diff --git a/Cely Demo/Info.plist b/Cely Demo/Info.plist index 1e04636..d569257 100644 --- a/Cely Demo/Info.plist +++ b/Cely Demo/Info.plist @@ -2,6 +2,8 @@ + NSFaceIDUsageDescription + Cely Demo CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index b1d0d20..a768332 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -70,6 +70,7 @@ 31238F162331019400D6CBC3 /* Cely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; }; 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31238F1A233103D500D6CBC3 /* CelyStorageError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31238F19233103D500D6CBC3 /* CelyStorageError.swift */; }; + 31394AD223495B19007D16C6 /* BiometricLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31394AD123495B19007D16C6 /* BiometricLoginViewController.swift */; }; 317D983923416BC0008E2016 /* CelyCredentialStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317D983823416BC0008E2016 /* CelyCredentialStoreTests.swift */; }; 317D983B234239BE008E2016 /* KeychainObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317D983A234239BE008E2016 /* KeychainObject.swift */; }; 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */; }; @@ -159,6 +160,7 @@ 1F68B0441E8951AA001A0161 /* TestStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = TestStoryboard.storyboard; path = Frameworks/TestStoryboard.storyboard; sourceTree = ""; }; 1F9D24071E8D49C700FB4BE6 /* Cely Demo.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Cely Demo.entitlements"; sourceTree = ""; }; 31238F19233103D500D6CBC3 /* CelyStorageError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyStorageError.swift; sourceTree = ""; }; + 31394AD123495B19007D16C6 /* BiometricLoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BiometricLoginViewController.swift; sourceTree = ""; }; 317D983823416BC0008E2016 /* CelyCredentialStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyCredentialStoreTests.swift; sourceTree = ""; }; 317D983A234239BE008E2016 /* KeychainObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainObject.swift; sourceTree = ""; }; 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelySecureStorage.swift; sourceTree = ""; }; @@ -281,6 +283,7 @@ 1F2864371E89578700EE8180 /* Assets.xcassets */, 1F2864391E89578700EE8180 /* LaunchScreen.storyboard */, 1F28643C1E89578700EE8180 /* Info.plist */, + 31394AD123495B19007D16C6 /* BiometricLoginViewController.swift */, ); path = "Cely Demo"; sourceTree = ""; @@ -863,6 +866,7 @@ 1F28642E1E89578700EE8180 /* AppDelegate.swift in Sources */, 1F2864501E895C2100EE8180 /* LoginStyles.swift in Sources */, 1F28644F1E895C2100EE8180 /* ViewController.swift in Sources */, + 31394AD223495B19007D16C6 /* BiometricLoginViewController.swift in Sources */, 1F28644E1E895C2100EE8180 /* User.swift in Sources */, 1F2864511E895C2100EE8180 /* SettingsViewController.swift in Sources */, ); @@ -1010,13 +1014,16 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "Cely Demo/Cely Demo.entitlements"; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = H367AL682C; INFOPLIST_FILE = "Cely Demo/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely-Demo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.xcode.cely-tools.Cely-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = Default; }; name = Debug; @@ -1026,13 +1033,16 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = "Cely Demo/Cely Demo.entitlements"; + CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = H367AL682C; INFOPLIST_FILE = "Cely Demo/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely-Demo"; + PRODUCT_BUNDLE_IDENTIFIER = "com.xcode.cely-tools.Cely-Demo"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = Default; }; name = Release; diff --git a/Sources/Storage/CelyCredentialStore.swift b/Sources/Storage/CelyCredentialStore.swift index b9ec802..372a11e 100644 --- a/Sources/Storage/CelyCredentialStore.swift +++ b/Sources/Storage/CelyCredentialStore.swift @@ -14,9 +14,9 @@ public enum AccessibilityOptions { } public struct CelyCredentials { - let username: String - let password: String - let server: String + public let username: String + public let password: String + public let server: String } public struct CelyCredentialStore { @@ -37,14 +37,14 @@ public struct CelyCredentialStore { } @discardableResult - public func set(username: String, password: String, server: String, accessibility _: [AccessibilityOptions] = []) -> Result { + public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { guard let passwordData = password.data(using: .utf8) else { return .failure(CelyStorageError.invalidValue) } do { - let keychainQuery = KeychainObject(account: username, server: server, value: passwordData) - try setCredentialsLookupKey(keyDictionary: keychainQuery.toCFDictionary(withValue: false)) + let keychainQuery = KeychainObject(account: username, server: server, value: passwordData, accessibility: accessibility) + try setCredentialsLookupKey(keyDictionary: keychainQuery.toLookupMap()) try keychain.set(query: keychainQuery) return .success(()) } catch { diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index 51bcee8..ae45cc3 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -16,12 +16,7 @@ protocol KeychainProtocol { internal struct CelyKeychain: KeychainProtocol { func get(query: KeychainObject) -> Result { - let limitQuery: [CFString: Any] = [ - kSecMatchLimit: kSecMatchLimitOne, - kSecReturnAttributes: true, - kSecReturnData: true, - ] - let newQuery = query.toCFDictionary(withValue: false).merging(limitQuery) { _, new in new } + let newQuery = query.toGetMap() var someItem: RawDictionary? let status = SecItemCopyMatching(newQuery as CFDictionary, &someItem) guard status == errSecSuccess else { @@ -37,7 +32,7 @@ internal struct CelyKeychain: KeychainProtocol { func set(query: KeychainObject) throws { // try adding first - let newQuery = query.toCFDictionary(withValue: true) + let newQuery = query.toSetMap(withValue: true) let status: OSStatus = SecItemAdd(newQuery as CFDictionary, nil) let code = CelyStorageError(status: status) switch code { @@ -50,7 +45,7 @@ internal struct CelyKeychain: KeychainProtocol { private func update(_ query: KeychainObject) throws { guard let valueData = query.value as CFData? else { throw CelyStorageError.invalidValue } - let status: OSStatus = SecItemUpdate(query.toCFDictionary(withValue: false) as CFDictionary, [kSecValueData: valueData] as CFDictionary) + let status: OSStatus = SecItemUpdate(query.toSetMap(withValue: false) as CFDictionary, [kSecValueData: valueData] as CFDictionary) let code = CelyStorageError(status: status) guard code == .noError else { throw code @@ -58,7 +53,7 @@ internal struct CelyKeychain: KeychainProtocol { } func delete(query: KeychainObject) throws { - let status = SecItemDelete(query.toCFDictionary(withValue: false) as CFDictionary) + let status = SecItemDelete(query.toLookupMap() as CFDictionary) let errorStatus = CelyStorageError(status: status) guard errorStatus == .noError else { throw errorStatus diff --git a/Sources/Storage/KeychainObject.swift b/Sources/Storage/KeychainObject.swift index b121379..f0f2aa1 100644 --- a/Sources/Storage/KeychainObject.swift +++ b/Sources/Storage/KeychainObject.swift @@ -11,14 +11,21 @@ import Foundation typealias RawDictionary = AnyObject struct KeychainObject { + var baseQuery: [CFString: Any] = [ + kSecClass: kSecClassInternetPassword, + kSecAttrLabel: kCelySecureStoreLabel, + ] + let account: String? let server: String? let value: Data? + private let accessibilityOptions: [AccessibilityOptions] - init(account: String? = nil, server: String? = nil, value: Data? = nil) { + init(account: String? = nil, server: String? = nil, value: Data? = nil, accessibility: [AccessibilityOptions] = []) { self.account = account self.server = server self.value = value + accessibilityOptions = accessibility } static func buildFromKeychain(dictionary: RawDictionary) -> KeychainObject { @@ -29,24 +36,54 @@ struct KeychainObject { ) } - func toCFDictionary(withValue: Bool) -> [CFString: Any] { - var query: [CFString: Any] = [ - kSecClass: kSecClassInternetPassword, - kSecAttrLabel: kCelySecureStoreLabel, - ] + func toLookupMap() -> [CFString: Any] { + var lookupMap: [CFString: Any] = [:] if let account = account { - query[kSecAttrAccount] = account + lookupMap[kSecAttrAccount] = account } if let server = server { - query[kSecAttrServer] = server + lookupMap[kSecAttrServer] = server } + return baseQuery.merging(lookupMap) { _, new in new } + } + + func toGetMap() -> [CFString: Any] { + let limitQuery: [CFString: Any] = [ + kSecMatchLimit: kSecMatchLimitOne, + kSecReturnAttributes: true, + kSecReturnData: true, + ] + + let query = toLookupMap() + return query.merging(limitQuery) { _, new in new } + } + + func getAccessibility() -> CFString { + let isThisDeviceOnly = accessibilityOptions.contains(.thisDeviceOnly) + return isThisDeviceOnly ? kSecAttrAccessibleWhenUnlockedThisDeviceOnly : kSecAttrAccessibleWhenUnlocked + } + + func toSetMap(withValue: Bool) -> [CFString: Any] { + var userMap = toLookupMap() + if let value = value, withValue { - query[kSecValueData] = value + userMap[kSecValueData] = value + } + + if accessibilityOptions.contains(.biometricsIfPossible) { + let accessibility = getAccessibility() + var error: Unmanaged? + let access = SecAccessControlCreateWithFlags(nil, + accessibility, + .userPresence, + &error) + + userMap[kSecAttrAccessControl] = access } - return query + return baseQuery.merging(userMap) { _, new in new } } } diff --git a/Tests/CelyCredentialStoreTests.swift b/Tests/CelyCredentialStoreTests.swift index 767323b..2b733c2 100644 --- a/Tests/CelyCredentialStoreTests.swift +++ b/Tests/CelyCredentialStoreTests.swift @@ -79,5 +79,21 @@ class CelyCredentialStoreTests: XCTestCase { XCTAssert(error.localizedDescription == CelyStorageError.itemNotFound.description, "Should have received an `.itemNotFound`: \(error)") } - // TODO: test different `AcccessibilityOption` + func testIncludesBiometrics() { + let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, accessibility: [.biometricsIfPossible]) + let getMap = object.toSetMap(withValue: false) + let foundValue = getMap[kSecAttrAccessControl] + XCTAssert(foundValue != nil, "Failed to find biometrics flag") + let accessibility = object.getAccessibility() + XCTAssert(accessibility == kSecAttrAccessibleWhenUnlocked, "Failed to set correct `accessibility`: \(accessibility)") + } + + func testThisDeviceOnly() { + let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, accessibility: [.biometricsIfPossible, .thisDeviceOnly]) + let getMap = object.toSetMap(withValue: false) + let foundValue = getMap[kSecAttrAccessControl] + XCTAssert(foundValue != nil, "Failed to find biometrics flag") + let accessibility = object.getAccessibility() + XCTAssert(accessibility == kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "Failed to set correct `accessibility`: \(accessibility)") + } } From 5c89ae2c40168a5c0db079ca9e2f0e49b34e3bdc Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Mon, 13 Jan 2020 07:27:15 -0600 Subject: [PATCH 12/17] Fix bug when adding biometrics to existing keychain item Adding keychain items such as "limitOne", "returnData", "class", "server" was causing errors. --- Sources/Storage/CelyKeychain.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Storage/CelyKeychain.swift index ae45cc3..f98bc84 100644 --- a/Sources/Storage/CelyKeychain.swift +++ b/Sources/Storage/CelyKeychain.swift @@ -43,9 +43,13 @@ internal struct CelyKeychain: KeychainProtocol { } private func update(_ query: KeychainObject) throws { - guard let valueData = query.value as CFData? else { throw CelyStorageError.invalidValue } + guard let _ = query.value as CFData? else { throw CelyStorageError.invalidValue } + var newDictionary = query.toSetMap(withValue: true) + for key in query.toGetMap().keys { + newDictionary.removeValue(forKey: key) + } - let status: OSStatus = SecItemUpdate(query.toSetMap(withValue: false) as CFDictionary, [kSecValueData: valueData] as CFDictionary) + let status: OSStatus = SecItemUpdate(query.toLookupMap() as CFDictionary, newDictionary as CFDictionary) let code = CelyStorageError(status: status) guard code == .noError else { throw code From 3ddd778099d352248294e7dfe2c1e07428bab907 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Fri, 24 Jan 2020 22:44:41 -0600 Subject: [PATCH 13/17] improve documentation and set Cely properties to private setters --- Sources/Cely.swift | 9 +++++---- Sources/Storage/CelyCredentialStore.swift | 11 +++++++++-- Sources/Storage/CelyStorage.swift | 2 +- Sources/Storage/KeychainObject.swift | 1 + 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Sources/Cely.swift b/Sources/Cely.swift index 78cbaca..ef7ae85 100644 --- a/Sources/Cely.swift +++ b/Sources/Cely.swift @@ -13,15 +13,16 @@ public struct Cely { fileprivate init() {} public typealias CelyLoginCompletion = (_ username: String, _ password: String) -> Void /// Properties that are needed inorder for user to stay logged in. - public static var requiredProperties: [CelyProperty] = [] + public private(set) static var requiredProperties: [CelyProperty] = [] /// A `Storage` instance - public static var store: CelyStorageProtocol = CelyStorage.sharedInstance + public private(set) static var store: CelyStorageProtocol = CelyStorage.sharedInstance /// A Completion Block that is expecting a `username:String` and a `password:String` - public static var loginCompletionBlock: CelyLoginCompletion? + private(set) static var loginCompletionBlock: CelyLoginCompletion? - public static var credentials = CelyCredentialStore.sharedInstance + /// `CelyCredentialsStore` instance + public private(set) static var credentials = CelyCredentialStore.sharedInstance /// Sets up Cely within your application /// diff --git a/Sources/Storage/CelyCredentialStore.swift b/Sources/Storage/CelyCredentialStore.swift index 372a11e..22e69e4 100644 --- a/Sources/Storage/CelyCredentialStore.swift +++ b/Sources/Storage/CelyCredentialStore.swift @@ -19,6 +19,7 @@ public struct CelyCredentials { public let server: String } +/// CelyCredentialStore - object that stores user credentials public struct CelyCredentialStore { static let sharedInstance = CelyCredentialStore() @@ -36,8 +37,14 @@ public struct CelyCredentialStore { return Cely.get(key: kCelyCredentialsLookupKey) as? [CFString: Any] } - @discardableResult - public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { + + /// Set user credentials + /// - Parameters: + /// - username: username for user + /// - password: password for user + /// - server: api uri for account + /// - accessibility: Array of AccessibilityOptions for credentials to be saved with + @discardableResult public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { guard let passwordData = password.data(using: .utf8) else { return .failure(CelyStorageError.invalidValue) } diff --git a/Sources/Storage/CelyStorage.swift b/Sources/Storage/CelyStorage.swift index ef0e4f3..a7bdbfd 100644 --- a/Sources/Storage/CelyStorage.swift +++ b/Sources/Storage/CelyStorage.swift @@ -16,7 +16,7 @@ internal let kProtectedDataAccount = "cely.secure.store.protected.data" internal let kCelySecureStoreLabel = "cely.secure.store.key" internal let kCelyCredentialsLookupKey = "credentials-lookup" -public class CelyStorage: CelyStorageProtocol { +internal class CelyStorage: CelyStorageProtocol { // MARK: - Variables static let sharedInstance = CelyStorage() diff --git a/Sources/Storage/KeychainObject.swift b/Sources/Storage/KeychainObject.swift index f0f2aa1..80f1c59 100644 --- a/Sources/Storage/KeychainObject.swift +++ b/Sources/Storage/KeychainObject.swift @@ -74,6 +74,7 @@ struct KeychainObject { } if accessibilityOptions.contains(.biometricsIfPossible) { + // TODO: what happens if application doesnt have biometrics setup? does it error let accessibility = getAccessibility() var error: Unmanaged? let access = SecAccessControlCreateWithFlags(nil, From 80726ba06320930ef3f2146f198d4c7039ae3017 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Sat, 25 Jan 2020 14:24:11 -0600 Subject: [PATCH 14/17] Restructure project directory --- .gitignore | 1 + Cely Demo/LoginStyles.swift | 11 + Cely.xcodeproj/project.pbxproj | 54 +- .../xcshareddata/xcschemes/Cely Demo.xcscheme | 78 + Documentation/Reference/README.md | 33 + .../Reference/classes/CelyWindowManager.md | 33 + .../Reference/enums/AccessibilityOptions.md | 20 + Documentation/Reference/enums/CelyOptions.md | 46 + Documentation/Reference/enums/CelyStatus.md | 22 + .../Reference/enums/CelyStorageError.md | 2426 +++++++++++++++++ .../Reference/extensions/CelyStorageError.md | 29 + .../Reference/extensions/CelyStyle.md | 54 + .../Reference/extensions/UIWindow.md | 10 + .../Reference/protocols/CelyAnimator.md | 22 + .../protocols/CelyStorageProtocol.md | 28 + .../Reference/protocols/CelyStyle.md | 40 + Documentation/Reference/protocols/CelyUser.md | 9 + Documentation/Reference/structs/Cely.md | 137 + .../Reference/structs/CelyCredentialStore.md | 40 + .../Reference/structs/CelyCredentials.md | 26 + Sources/{ => Core}/Cely.swift | 2 +- Sources/{ => Core}/CelyConstants.swift | 7 +- Sources/{ => Core}/CelyProtocols.swift | 0 Sources/{ => Core}/CelyWindowManager.swift | 0 .../Storage/CelyCredentialStore.swift | 10 +- Sources/{ => Core}/Storage/CelyKeychain.swift | 0 .../Storage/CelySecureStorage.swift | 0 Sources/{ => Core}/Storage/CelyStorage.swift | 0 .../{ => Core}/Storage/CelyStorageError.swift | 0 .../{ => Core}/Storage/KeychainObject.swift | 0 Sources/{ => Supporting Files}/Cely.h | 0 .../CelyLoginViewController.swift | 0 .../{ => Supporting Files}/Info-tvOS.plist | 0 Sources/{ => Supporting Files}/Info.plist | 0 34 files changed, 3102 insertions(+), 36 deletions(-) create mode 100644 Cely.xcodeproj/xcshareddata/xcschemes/Cely Demo.xcscheme create mode 100644 Documentation/Reference/README.md create mode 100644 Documentation/Reference/classes/CelyWindowManager.md create mode 100644 Documentation/Reference/enums/AccessibilityOptions.md create mode 100644 Documentation/Reference/enums/CelyOptions.md create mode 100644 Documentation/Reference/enums/CelyStatus.md create mode 100644 Documentation/Reference/enums/CelyStorageError.md create mode 100644 Documentation/Reference/extensions/CelyStorageError.md create mode 100644 Documentation/Reference/extensions/CelyStyle.md create mode 100644 Documentation/Reference/extensions/UIWindow.md create mode 100644 Documentation/Reference/protocols/CelyAnimator.md create mode 100644 Documentation/Reference/protocols/CelyStorageProtocol.md create mode 100644 Documentation/Reference/protocols/CelyStyle.md create mode 100644 Documentation/Reference/protocols/CelyUser.md create mode 100644 Documentation/Reference/structs/Cely.md create mode 100644 Documentation/Reference/structs/CelyCredentialStore.md create mode 100644 Documentation/Reference/structs/CelyCredentials.md rename Sources/{ => Core}/Cely.swift (98%) rename Sources/{ => Core}/CelyConstants.swift (92%) rename Sources/{ => Core}/CelyProtocols.swift (100%) rename Sources/{ => Core}/CelyWindowManager.swift (100%) rename Sources/{ => Core}/Storage/CelyCredentialStore.swift (90%) rename Sources/{ => Core}/Storage/CelyKeychain.swift (100%) rename Sources/{ => Core}/Storage/CelySecureStorage.swift (100%) rename Sources/{ => Core}/Storage/CelyStorage.swift (100%) rename Sources/{ => Core}/Storage/CelyStorageError.swift (100%) rename Sources/{ => Core}/Storage/KeychainObject.swift (100%) rename Sources/{ => Supporting Files}/Cely.h (100%) rename Sources/{ => Supporting Files}/CelyLoginViewController.swift (100%) rename Sources/{ => Supporting Files}/Info-tvOS.plist (100%) rename Sources/{ => Supporting Files}/Info.plist (100%) diff --git a/.gitignore b/.gitignore index 9233438..d13c82d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ xcuserdata/ ## Other *.moved-aside *.xcuserstate +.vscode ## Obj-C/Swift specific *.hmap diff --git a/Cely Demo/LoginStyles.swift b/Cely Demo/LoginStyles.swift index 4113f2d..9eddcdc 100644 --- a/Cely Demo/LoginStyles.swift +++ b/Cely Demo/LoginStyles.swift @@ -15,6 +15,17 @@ struct LoginStyles: CelyStyle { } } +extension UIWindow { + func setCurrentViewController(to viewController: UIViewController?) { + let previousViewController = rootViewController + rootViewController = viewController + + if let previousViewController = previousViewController { + previousViewController.dismiss(animated: false) + } + } +} + struct CustomAnimator: CelyAnimator { func loginTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) { guard let snapshot = celyWindow.snapshotView(afterScreenUpdates: true) else { diff --git a/Cely.xcodeproj/project.pbxproj b/Cely.xcodeproj/project.pbxproj index a768332..3a83c85 100644 --- a/Cely.xcodeproj/project.pbxproj +++ b/Cely.xcodeproj/project.pbxproj @@ -17,7 +17,6 @@ 1F2864451E89593700EE8180 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F68B01C1E89519A001A0161 /* Main.storyboard */; }; 1F28644E1E895C2100EE8180 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F28644A1E895C2100EE8180 /* User.swift */; }; 1F28644F1E895C2100EE8180 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F28644B1E895C2100EE8180 /* ViewController.swift */; }; - 1F2864501E895C2100EE8180 /* LoginStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F28644C1E895C2100EE8180 /* LoginStyles.swift */; }; 1F2864511E895C2100EE8180 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F28644D1E895C2100EE8180 /* SettingsViewController.swift */; }; 1F2864531E895C4B00EE8180 /* TestStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1F2864521E895C4B00EE8180 /* TestStoryboard.storyboard */; }; 1F68AFDD1E89505A001A0161 /* Cely.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F68AFD41E89505A001A0161 /* Cely.swift */; }; @@ -71,6 +70,7 @@ 31238F172331019400D6CBC3 /* Cely.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3549BB211DA389CD00C63030 /* Cely.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 31238F1A233103D500D6CBC3 /* CelyStorageError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31238F19233103D500D6CBC3 /* CelyStorageError.swift */; }; 31394AD223495B19007D16C6 /* BiometricLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31394AD123495B19007D16C6 /* BiometricLoginViewController.swift */; }; + 3157AA5923DCD0B000E1EEA8 /* LoginStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F28644C1E895C2100EE8180 /* LoginStyles.swift */; }; 317D983923416BC0008E2016 /* CelyCredentialStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317D983823416BC0008E2016 /* CelyCredentialStoreTests.swift */; }; 317D983B234239BE008E2016 /* KeychainObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317D983A234239BE008E2016 /* KeychainObject.swift */; }; 31FAEB8022ECC4DD003EC60A /* CelySecureStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FAEB7F22ECC4DD003EC60A /* CelySecureStorage.swift */; }; @@ -150,7 +150,7 @@ 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyWindowManager.swift; sourceTree = ""; }; 1F68B0011E895069001A0161 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = "Supporting Files/Assets.xcassets"; sourceTree = ""; }; 1F68B0021E895069001A0161 /* Cely.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Cely.storyboard; path = "Supporting Files/Cely.storyboard"; sourceTree = ""; }; - 1F68B0031E895069001A0161 /* CelyLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyLoginViewController.swift; sourceTree = ""; }; + 1F68B0031E895069001A0161 /* CelyLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CelyLoginViewController.swift; path = "Supporting Files/CelyLoginViewController.swift"; sourceTree = ""; }; 1F68B0111E89519A001A0161 /* CelyStorageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyStorageTests.swift; sourceTree = ""; }; 1F68B0121E89519A001A0161 /* CelyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyTests.swift; sourceTree = ""; }; 1F68B0131E89519A001A0161 /* CelyWindowManagerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CelyWindowManagerTest.swift; sourceTree = ""; }; @@ -167,13 +167,13 @@ 31FEDF6B2342E4FC000DD646 /* CelyStorageErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyStorageErrorTests.swift; sourceTree = ""; }; 31FF19A9233FC22300B4B7F1 /* CelyCredentialStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyCredentialStore.swift; sourceTree = ""; }; 31FF19AD233FCE7100B4B7F1 /* CelyKeychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CelyKeychain.swift; sourceTree = ""; }; - 3549BB171DA3890B00C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 3549BB181DA3890B00C63030 /* Cely.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cely.h; sourceTree = ""; }; + 3549BB171DA3890B00C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "Supporting Files/Info.plist"; sourceTree = ""; }; + 3549BB181DA3890B00C63030 /* Cely.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Cely.h; path = "Supporting Files/Cely.h"; sourceTree = ""; }; 3549BB211DA389CD00C63030 /* Cely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cely.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3549BB2E1DA389DB00C63030 /* Cely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cely.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3549BB3B1DA389E800C63030 /* Cely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cely.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3549BB481DA389F300C63030 /* Cely.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cely.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 3549BB551DA38A5E00C63030 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; + 3549BB551DA38A5E00C63030 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Info-tvOS.plist"; path = "Supporting Files/Info-tvOS.plist"; sourceTree = ""; }; 3549BB571DA38A8800C63030 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; }; 3549BB581DA38A8800C63030 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 3549BB611DA38ADB00C63030 /* CelyTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "CelyTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -288,6 +288,18 @@ path = "Cely Demo"; sourceTree = ""; }; + 31186A4023DCCA7D00A66C3C /* Core */ = { + isa = PBXGroup; + children = ( + 311B5E3023310901002166E1 /* Storage */, + 1F68AFD41E89505A001A0161 /* Cely.swift */, + 1F68AFD51E89505A001A0161 /* CelyConstants.swift */, + 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */, + 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */, + ); + path = Core; + sourceTree = ""; + }; 311B5E3023310901002166E1 /* Storage */ = { isa = PBXGroup; children = ( @@ -331,7 +343,7 @@ 3549BB161DA3890B00C63030 /* Sources */ = { isa = PBXGroup; children = ( - 3549BB5C1DA38AA500C63030 /* Core */, + 31186A4023DCCA7D00A66C3C /* Core */, 3549BB541DA38A4000C63030 /* Supporting Files */, ); path = Sources; @@ -376,18 +388,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 3549BB5C1DA38AA500C63030 /* Core */ = { - isa = PBXGroup; - children = ( - 311B5E3023310901002166E1 /* Storage */, - 1F68AFD41E89505A001A0161 /* Cely.swift */, - 1F68AFD51E89505A001A0161 /* CelyConstants.swift */, - 1F68AFD61E89505A001A0161 /* CelyProtocols.swift */, - 1F68AFD81E89505A001A0161 /* CelyWindowManager.swift */, - ); - name = Core; - sourceTree = ""; - }; 357D954B1DA3F2B400AEC55F /* Frameworks */ = { isa = PBXGroup; children = ( @@ -864,11 +864,11 @@ buildActionMask = 2147483647; files = ( 1F28642E1E89578700EE8180 /* AppDelegate.swift in Sources */, - 1F2864501E895C2100EE8180 /* LoginStyles.swift in Sources */, 1F28644F1E895C2100EE8180 /* ViewController.swift in Sources */, 31394AD223495B19007D16C6 /* BiometricLoginViewController.swift in Sources */, 1F28644E1E895C2100EE8180 /* User.swift in Sources */, 1F2864511E895C2100EE8180 /* SettingsViewController.swift in Sources */, + 3157AA5923DCD0B000E1EEA8 /* LoginStyles.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1173,7 +1173,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1196,7 +1196,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1218,7 +1218,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; @@ -1243,7 +1243,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; @@ -1268,7 +1268,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; @@ -1293,7 +1293,7 @@ DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; FRAMEWORK_VERSION = A; - INFOPLIST_FILE = Sources/Info.plist; + INFOPLIST_FILE = "Sources/Supporting Files/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.10; @@ -1315,7 +1315,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Sources/Info-tvOS.plist"; + INFOPLIST_FILE = "Sources/Supporting Files/Info-tvOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; @@ -1339,7 +1339,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = "Sources/Info-tvOS.plist"; + INFOPLIST_FILE = "Sources/Supporting Files/Info-tvOS.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.cely-tools.Cely"; diff --git a/Cely.xcodeproj/xcshareddata/xcschemes/Cely Demo.xcscheme b/Cely.xcodeproj/xcshareddata/xcschemes/Cely Demo.xcscheme new file mode 100644 index 0000000..6da19ff --- /dev/null +++ b/Cely.xcodeproj/xcshareddata/xcschemes/Cely Demo.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Documentation/Reference/README.md b/Documentation/Reference/README.md new file mode 100644 index 0000000..3d4a199 --- /dev/null +++ b/Documentation/Reference/README.md @@ -0,0 +1,33 @@ +## Protocols + +- [CelyAnimator](protocols/CelyAnimator.md) +- [CelyStorageProtocol](protocols/CelyStorageProtocol.md) +- [CelyStyle](protocols/CelyStyle.md) +- [CelyUser](protocols/CelyUser.md) + +## Structs + +- [Cely](structs/Cely.md) +- [CelyCredentialStore](structs/CelyCredentialStore.md) +- [CelyCredentials](structs/CelyCredentials.md) + +## Classes + +- [CelyWindowManager](classes/CelyWindowManager.md) + +## Enums + +- [AccessibilityOptions](enums/AccessibilityOptions.md) +- [CelyOptions](enums/CelyOptions.md) +- [CelyStatus](enums/CelyStatus.md) +- [CelyStorageError](enums/CelyStorageError.md) + +## Extensions + +- [CelyStorageError](extensions/CelyStorageError.md) +- [CelyStyle](extensions/CelyStyle.md) +- [UIWindow](extensions/UIWindow.md) + +# Reference Documentation +This reference documentation was generated with +[SourceDocs](https://github.com/eneko/SourceDocs). \ No newline at end of file diff --git a/Documentation/Reference/classes/CelyWindowManager.md b/Documentation/Reference/classes/CelyWindowManager.md new file mode 100644 index 0000000..4c5d795 --- /dev/null +++ b/Documentation/Reference/classes/CelyWindowManager.md @@ -0,0 +1,33 @@ +**CLASS** + +# `CelyWindowManager` + +```swift +public class CelyWindowManager +``` + +## Properties +### `loginStyle` + +```swift +public var loginStyle: CelyStyle! +``` + +### `celyAnimator` + +```swift +public var celyAnimator: CelyAnimator! +``` + +## Methods +### `init()` + +```swift +public init() +``` + +### `deinit` + +```swift +deinit +``` diff --git a/Documentation/Reference/enums/AccessibilityOptions.md b/Documentation/Reference/enums/AccessibilityOptions.md new file mode 100644 index 0000000..f0bdae1 --- /dev/null +++ b/Documentation/Reference/enums/AccessibilityOptions.md @@ -0,0 +1,20 @@ +**ENUM** + +# `AccessibilityOptions` + +```swift +public enum AccessibilityOptions +``` + +## Cases +### `biometricsIfPossible` + +```swift +case biometricsIfPossible +``` + +### `thisDeviceOnly` + +```swift +case thisDeviceOnly +``` diff --git a/Documentation/Reference/enums/CelyOptions.md b/Documentation/Reference/enums/CelyOptions.md new file mode 100644 index 0000000..3ca9186 --- /dev/null +++ b/Documentation/Reference/enums/CelyOptions.md @@ -0,0 +1,46 @@ +**ENUM** + +# `CelyOptions` + +```swift +public enum CelyOptions +``` + +> Options that you can pass into Cely on `Cely.setup(_:)` + +## Cases +### `storage` + +```swift +case storage +``` + +### `homeViewController` + +```swift +case homeViewController +``` + +### `loginViewController` + +```swift +case loginViewController +``` + +### `loginCompletionBlock` + +```swift +case loginCompletionBlock +``` + +### `loginStyle` + +```swift +case loginStyle +``` + +### `celyAnimator` + +```swift +case celyAnimator +``` diff --git a/Documentation/Reference/enums/CelyStatus.md b/Documentation/Reference/enums/CelyStatus.md new file mode 100644 index 0000000..98e2080 --- /dev/null +++ b/Documentation/Reference/enums/CelyStatus.md @@ -0,0 +1,22 @@ +**ENUM** + +# `CelyStatus` + +```swift +public enum CelyStatus: CelyCommands +``` + +> Statuses for Cely to perform actions on + +## Cases +### `loggedIn` + +```swift +case loggedIn = "CelyStatus.loggedIn.user" +``` + +### `loggedOut` + +```swift +case loggedOut = "CelyStatus.loggedOut.user" +``` diff --git a/Documentation/Reference/enums/CelyStorageError.md b/Documentation/Reference/enums/CelyStorageError.md new file mode 100644 index 0000000..028ad1c --- /dev/null +++ b/Documentation/Reference/enums/CelyStorageError.md @@ -0,0 +1,2426 @@ +**ENUM** + +# `CelyStorageError` + +```swift +public enum CelyStorageError: OSStatus, Error +``` + +## Cases +### `noError` + +```swift +case noError = 0 +``` + +### `unimplemented` + +```swift +case unimplemented = -4 +``` + +### `diskFull` + +```swift +case diskFull = -34 +``` + +### `io` + +```swift +case io = -36 +``` + +### `opWr` + +```swift +case opWr = -49 +``` + +### `param` + +```swift +case param = -50 +``` + +### `wrPerm` + +```swift +case wrPerm = -61 +``` + +### `allocate` + +```swift +case allocate = -108 +``` + +### `userCanceled` + +```swift +case userCanceled = -128 +``` + +### `badReq` + +```swift +case badReq = -909 +``` + +### `internalComponent` + +```swift +case internalComponent = -2070 +``` + +### `notAvailable` + +```swift +case notAvailable = -25291 +``` + +### `readOnly` + +```swift +case readOnly = -25292 +``` + +### `authFailed` + +```swift +case authFailed = -25293 +``` + +### `noSuchKeychain` + +```swift +case noSuchKeychain = -25294 +``` + +### `invalidKeychain` + +```swift +case invalidKeychain = -25295 +``` + +### `duplicateKeychain` + +```swift +case duplicateKeychain = -25296 +``` + +### `duplicateCallback` + +```swift +case duplicateCallback = -25297 +``` + +### `invalidCallback` + +```swift +case invalidCallback = -25298 +``` + +### `duplicateItem` + +```swift +case duplicateItem = -25299 +``` + +### `itemNotFound` + +```swift +case itemNotFound = -25300 +``` + +### `bufferTooSmall` + +```swift +case bufferTooSmall = -25301 +``` + +### `dataTooLarge` + +```swift +case dataTooLarge = -25302 +``` + +### `noSuchAttr` + +```swift +case noSuchAttr = -25303 +``` + +### `invalidItemRef` + +```swift +case invalidItemRef = -25304 +``` + +### `invalidSearchRef` + +```swift +case invalidSearchRef = -25305 +``` + +### `noSuchClass` + +```swift +case noSuchClass = -25306 +``` + +### `noDefaultKeychain` + +```swift +case noDefaultKeychain = -25307 +``` + +### `interactionNotAllowed` + +```swift +case interactionNotAllowed = -25308 +``` + +### `readOnlyAttr` + +```swift +case readOnlyAttr = -25309 +``` + +### `wrongSecVersion` + +```swift +case wrongSecVersion = -25310 +``` + +### `keySizeNotAllowed` + +```swift +case keySizeNotAllowed = -25311 +``` + +### `noStorageModule` + +```swift +case noStorageModule = -25312 +``` + +### `noCertificateModule` + +```swift +case noCertificateModule = -25313 +``` + +### `noPolicyModule` + +```swift +case noPolicyModule = -25314 +``` + +### `interactionRequired` + +```swift +case interactionRequired = -25315 +``` + +### `dataNotAvailable` + +```swift +case dataNotAvailable = -25316 +``` + +### `dataNotModifiable` + +```swift +case dataNotModifiable = -25317 +``` + +### `createChainFailed` + +```swift +case createChainFailed = -25318 +``` + +### `invalidPrefsDomain` + +```swift +case invalidPrefsDomain = -25319 +``` + +### `inDarkWake` + +```swift +case inDarkWake = -25320 +``` + +### `aclNotSimple` + +```swift +case aclNotSimple = -25240 +``` + +### `policyNotFound` + +```swift +case policyNotFound = -25241 +``` + +### `invalidTrustSetting` + +```swift +case invalidTrustSetting = -25242 +``` + +### `noAccessForItem` + +```swift +case noAccessForItem = -25243 +``` + +### `invalidOwnerEdit` + +```swift +case invalidOwnerEdit = -25244 +``` + +### `trustNotAvailable` + +```swift +case trustNotAvailable = -25245 +``` + +### `unsupportedFormat` + +```swift +case unsupportedFormat = -25256 +``` + +### `unknownFormat` + +```swift +case unknownFormat = -25257 +``` + +### `keyIsSensitive` + +```swift +case keyIsSensitive = -25258 +``` + +### `multiplePrivKeys` + +```swift +case multiplePrivKeys = -25259 +``` + +### `passphraseRequired` + +```swift +case passphraseRequired = -25260 +``` + +### `invalidPasswordRef` + +```swift +case invalidPasswordRef = -25261 +``` + +### `invalidTrustSettings` + +```swift +case invalidTrustSettings = -25262 +``` + +### `noTrustSettings` + +```swift +case noTrustSettings = -25263 +``` + +### `pkcs12VerifyFailure` + +```swift +case pkcs12VerifyFailure = -25264 +``` + +### `invalidCertificate` + +```swift +case invalidCertificate = -26265 +``` + +### `notSigner` + +```swift +case notSigner = -26267 +``` + +### `policyDenied` + +```swift +case policyDenied = -26270 +``` + +### `invalidKey` + +```swift +case invalidKey = -26274 +``` + +### `decode` + +```swift +case decode = -26275 +``` + +### `internal` + +```swift +case `internal` = -26276 +``` + +### `unsupportedAlgorithm` + +```swift +case unsupportedAlgorithm = -26268 +``` + +### `unsupportedOperation` + +```swift +case unsupportedOperation = -26271 +``` + +### `unsupportedPadding` + +```swift +case unsupportedPadding = -26273 +``` + +### `itemInvalidKey` + +```swift +case itemInvalidKey = -34000 +``` + +### `itemInvalidKeyType` + +```swift +case itemInvalidKeyType = -34001 +``` + +### `itemInvalidValue` + +```swift +case itemInvalidValue = -34002 +``` + +### `itemClassMissing` + +```swift +case itemClassMissing = -34003 +``` + +### `itemMatchUnsupported` + +```swift +case itemMatchUnsupported = -34004 +``` + +### `useItemListUnsupported` + +```swift +case useItemListUnsupported = -34005 +``` + +### `useKeychainUnsupported` + +```swift +case useKeychainUnsupported = -34006 +``` + +### `useKeychainListUnsupported` + +```swift +case useKeychainListUnsupported = -34007 +``` + +### `returnDataUnsupported` + +```swift +case returnDataUnsupported = -34008 +``` + +### `returnAttributesUnsupported` + +```swift +case returnAttributesUnsupported = -34009 +``` + +### `returnRefUnsupported` + +```swift +case returnRefUnsupported = -34010 +``` + +### `returnPersitentRefUnsupported` + +```swift +case returnPersitentRefUnsupported = -34011 +``` + +### `valueRefUnsupported` + +```swift +case valueRefUnsupported = -34012 +``` + +### `valuePersistentRefUnsupported` + +```swift +case valuePersistentRefUnsupported = -34013 +``` + +### `returnMissingPointer` + +```swift +case returnMissingPointer = -34014 +``` + +### `matchLimitUnsupported` + +```swift +case matchLimitUnsupported = -34015 +``` + +### `itemIllegalQuery` + +```swift +case itemIllegalQuery = -34016 +``` + +### `waitForCallback` + +```swift +case waitForCallback = -34017 +``` + +### `missingEntitlement` + +```swift +case missingEntitlement = -34018 +``` + +### `upgradePending` + +```swift +case upgradePending = -34019 +``` + +### `mpSignatureInvalid` + +```swift +case mpSignatureInvalid = -25327 +``` + +### `otrTooOld` + +```swift +case otrTooOld = -25328 +``` + +### `otrIDTooNew` + +```swift +case otrIDTooNew = -25329 +``` + +### `serviceNotAvailable` + +```swift +case serviceNotAvailable = -67585 +``` + +### `insufficientClientID` + +```swift +case insufficientClientID = -67586 +``` + +### `deviceReset` + +```swift +case deviceReset = -67587 +``` + +### `deviceFailed` + +```swift +case deviceFailed = -67588 +``` + +### `appleAddAppACLSubject` + +```swift +case appleAddAppACLSubject = -67589 +``` + +### `applePublicKeyIncomplete` + +```swift +case applePublicKeyIncomplete = -67590 +``` + +### `appleSignatureMismatch` + +```swift +case appleSignatureMismatch = -67591 +``` + +### `appleInvalidKeyStartDate` + +```swift +case appleInvalidKeyStartDate = -67592 +``` + +### `appleInvalidKeyEndDate` + +```swift +case appleInvalidKeyEndDate = -67593 +``` + +### `conversionError` + +```swift +case conversionError = -67594 +``` + +### `appleSSLv2Rollback` + +```swift +case appleSSLv2Rollback = -67595 +``` + +### `quotaExceeded` + +```swift +case quotaExceeded = -67596 +``` + +### `fileTooBig` + +```swift +case fileTooBig = -67597 +``` + +### `invalidDatabaseBlob` + +```swift +case invalidDatabaseBlob = -67598 +``` + +### `invalidKeyBlob` + +```swift +case invalidKeyBlob = -67599 +``` + +### `incompatibleDatabaseBlob` + +```swift +case incompatibleDatabaseBlob = -67600 +``` + +### `incompatibleKeyBlob` + +```swift +case incompatibleKeyBlob = -67601 +``` + +### `hostNameMismatch` + +```swift +case hostNameMismatch = -67602 +``` + +### `unknownCriticalExtensionFlag` + +```swift +case unknownCriticalExtensionFlag = -67603 +``` + +### `noBasicConstraints` + +```swift +case noBasicConstraints = -67604 +``` + +### `noBasicConstraintsCA` + +```swift +case noBasicConstraintsCA = -67605 +``` + +### `invalidAuthorityKeyID` + +```swift +case invalidAuthorityKeyID = -67606 +``` + +### `invalidSubjectKeyID` + +```swift +case invalidSubjectKeyID = -67607 +``` + +### `invalidKeyUsageForPolicy` + +```swift +case invalidKeyUsageForPolicy = -67608 +``` + +### `invalidExtendedKeyUsage` + +```swift +case invalidExtendedKeyUsage = -67609 +``` + +### `invalidIDLinkage` + +```swift +case invalidIDLinkage = -67610 +``` + +### `pathLengthConstraintExceeded` + +```swift +case pathLengthConstraintExceeded = -67611 +``` + +### `invalidRoot` + +```swift +case invalidRoot = -67612 +``` + +### `crlExpired` + +```swift +case crlExpired = -67613 +``` + +### `crlNotValidYet` + +```swift +case crlNotValidYet = -67614 +``` + +### `crlNotFound` + +```swift +case crlNotFound = -67615 +``` + +### `crlServerDown` + +```swift +case crlServerDown = -67616 +``` + +### `crlBadURI` + +```swift +case crlBadURI = -67617 +``` + +### `unknownCertExtension` + +```swift +case unknownCertExtension = -67618 +``` + +### `unknownCRLExtension` + +```swift +case unknownCRLExtension = -67619 +``` + +### `crlNotTrusted` + +```swift +case crlNotTrusted = -67620 +``` + +### `crlPolicyFailed` + +```swift +case crlPolicyFailed = -67621 +``` + +### `idpFailure` + +```swift +case idpFailure = -67622 +``` + +### `smimeEmailAddressesNotFound` + +```swift +case smimeEmailAddressesNotFound = -67623 +``` + +### `smimeBadExtendedKeyUsage` + +```swift +case smimeBadExtendedKeyUsage = -67624 +``` + +### `smimeBadKeyUsage` + +```swift +case smimeBadKeyUsage = -67625 +``` + +### `smimeKeyUsageNotCritical` + +```swift +case smimeKeyUsageNotCritical = -67626 +``` + +### `smimeNoEmailAddress` + +```swift +case smimeNoEmailAddress = -67627 +``` + +### `smimeSubjAltNameNotCritical` + +```swift +case smimeSubjAltNameNotCritical = -67628 +``` + +### `sslBadExtendedKeyUsage` + +```swift +case sslBadExtendedKeyUsage = -67629 +``` + +### `ocspBadResponse` + +```swift +case ocspBadResponse = -67630 +``` + +### `ocspBadRequest` + +```swift +case ocspBadRequest = -67631 +``` + +### `ocspUnavailable` + +```swift +case ocspUnavailable = -67632 +``` + +### `ocspStatusUnrecognized` + +```swift +case ocspStatusUnrecognized = -67633 +``` + +### `endOfData` + +```swift +case endOfData = -67634 +``` + +### `incompleteCertRevocationCheck` + +```swift +case incompleteCertRevocationCheck = -67635 +``` + +### `networkFailure` + +```swift +case networkFailure = -67636 +``` + +### `ocspNotTrustedToAnchor` + +```swift +case ocspNotTrustedToAnchor = -67637 +``` + +### `recordModified` + +```swift +case recordModified = -67638 +``` + +### `ocspSignatureError` + +```swift +case ocspSignatureError = -67639 +``` + +### `ocspNoSigner` + +```swift +case ocspNoSigner = -67640 +``` + +### `ocspResponderMalformedReq` + +```swift +case ocspResponderMalformedReq = -67641 +``` + +### `ocspResponderInternalError` + +```swift +case ocspResponderInternalError = -67642 +``` + +### `ocspResponderTryLater` + +```swift +case ocspResponderTryLater = -67643 +``` + +### `ocspResponderSignatureRequired` + +```swift +case ocspResponderSignatureRequired = -67644 +``` + +### `ocspResponderUnauthorized` + +```swift +case ocspResponderUnauthorized = -67645 +``` + +### `ocspResponseNonceMismatch` + +```swift +case ocspResponseNonceMismatch = -67646 +``` + +### `codeSigningBadCertChainLength` + +```swift +case codeSigningBadCertChainLength = -67647 +``` + +### `codeSigningNoBasicConstraints` + +```swift +case codeSigningNoBasicConstraints = -67648 +``` + +### `codeSigningBadPathLengthConstraint` + +```swift +case codeSigningBadPathLengthConstraint = -67649 +``` + +### `codeSigningNoExtendedKeyUsage` + +```swift +case codeSigningNoExtendedKeyUsage = -67650 +``` + +### `codeSigningDevelopment` + +```swift +case codeSigningDevelopment = -67651 +``` + +### `resourceSignBadCertChainLength` + +```swift +case resourceSignBadCertChainLength = -67652 +``` + +### `resourceSignBadExtKeyUsage` + +```swift +case resourceSignBadExtKeyUsage = -67653 +``` + +### `trustSettingDeny` + +```swift +case trustSettingDeny = -67654 +``` + +### `invalidSubjectName` + +```swift +case invalidSubjectName = -67655 +``` + +### `unknownQualifiedCertStatement` + +```swift +case unknownQualifiedCertStatement = -67656 +``` + +### `mobileMeRequestQueued` + +```swift +case mobileMeRequestQueued = -67657 +``` + +### `mobileMeRequestRedirected` + +```swift +case mobileMeRequestRedirected = -67658 +``` + +### `mobileMeServerError` + +```swift +case mobileMeServerError = -67659 +``` + +### `mobileMeServerNotAvailable` + +```swift +case mobileMeServerNotAvailable = -67660 +``` + +### `mobileMeServerAlreadyExists` + +```swift +case mobileMeServerAlreadyExists = -67661 +``` + +### `mobileMeServerServiceErr` + +```swift +case mobileMeServerServiceErr = -67662 +``` + +### `mobileMeRequestAlreadyPending` + +```swift +case mobileMeRequestAlreadyPending = -67663 +``` + +### `mobileMeNoRequestPending` + +```swift +case mobileMeNoRequestPending = -67664 +``` + +### `mobileMeCSRVerifyFailure` + +```swift +case mobileMeCSRVerifyFailure = -67665 +``` + +### `mobileMeFailedConsistencyCheck` + +```swift +case mobileMeFailedConsistencyCheck = -67666 +``` + +### `notInitialized` + +```swift +case notInitialized = -67667 +``` + +### `invalidHandleUsage` + +```swift +case invalidHandleUsage = -67668 +``` + +### `pvcReferentNotFound` + +```swift +case pvcReferentNotFound = -67669 +``` + +### `functionIntegrityFail` + +```swift +case functionIntegrityFail = -67670 +``` + +### `internalError` + +```swift +case internalError = -67671 +``` + +### `memoryError` + +```swift +case memoryError = -67672 +``` + +### `invalidData` + +```swift +case invalidData = -67673 +``` + +### `mdsError` + +```swift +case mdsError = -67674 +``` + +### `invalidPointer` + +```swift +case invalidPointer = -67675 +``` + +### `selfCheckFailed` + +```swift +case selfCheckFailed = -67676 +``` + +### `functionFailed` + +```swift +case functionFailed = -67677 +``` + +### `moduleManifestVerifyFailed` + +```swift +case moduleManifestVerifyFailed = -67678 +``` + +### `invalidGUID` + +```swift +case invalidGUID = -67679 +``` + +### `invalidHandle` + +```swift +case invalidHandle = -67680 +``` + +### `invalidDBList` + +```swift +case invalidDBList = -67681 +``` + +### `invalidPassthroughID` + +```swift +case invalidPassthroughID = -67682 +``` + +### `invalidNetworkAddress` + +```swift +case invalidNetworkAddress = -67683 +``` + +### `crlAlreadySigned` + +```swift +case crlAlreadySigned = -67684 +``` + +### `invalidNumberOfFields` + +```swift +case invalidNumberOfFields = -67685 +``` + +### `verificationFailure` + +```swift +case verificationFailure = -67686 +``` + +### `unknownTag` + +```swift +case unknownTag = -67687 +``` + +### `invalidSignature` + +```swift +case invalidSignature = -67688 +``` + +### `invalidName` + +```swift +case invalidName = -67689 +``` + +### `invalidCertificateRef` + +```swift +case invalidCertificateRef = -67690 +``` + +### `invalidCertificateGroup` + +```swift +case invalidCertificateGroup = -67691 +``` + +### `tagNotFound` + +```swift +case tagNotFound = -67692 +``` + +### `invalidQuery` + +```swift +case invalidQuery = -67693 +``` + +### `invalidValue` + +```swift +case invalidValue = -67694 +``` + +### `callbackFailed` + +```swift +case callbackFailed = -67695 +``` + +### `aclDeleteFailed` + +```swift +case aclDeleteFailed = -67696 +``` + +### `aclReplaceFailed` + +```swift +case aclReplaceFailed = -67697 +``` + +### `aclAddFailed` + +```swift +case aclAddFailed = -67698 +``` + +### `aclChangeFailed` + +```swift +case aclChangeFailed = -67699 +``` + +### `invalidAccessCredentials` + +```swift +case invalidAccessCredentials = -67700 +``` + +### `invalidRecord` + +```swift +case invalidRecord = -67701 +``` + +### `invalidACL` + +```swift +case invalidACL = -67702 +``` + +### `invalidSampleValue` + +```swift +case invalidSampleValue = -67703 +``` + +### `incompatibleVersion` + +```swift +case incompatibleVersion = -67704 +``` + +### `privilegeNotGranted` + +```swift +case privilegeNotGranted = -67705 +``` + +### `invalidScope` + +```swift +case invalidScope = -67706 +``` + +### `pvcAlreadyConfigured` + +```swift +case pvcAlreadyConfigured = -67707 +``` + +### `invalidPVC` + +```swift +case invalidPVC = -67708 +``` + +### `emmLoadFailed` + +```swift +case emmLoadFailed = -67709 +``` + +### `emmUnloadFailed` + +```swift +case emmUnloadFailed = -67710 +``` + +### `addinLoadFailed` + +```swift +case addinLoadFailed = -67711 +``` + +### `invalidKeyRef` + +```swift +case invalidKeyRef = -67712 +``` + +### `invalidKeyHierarchy` + +```swift +case invalidKeyHierarchy = -67713 +``` + +### `addinUnloadFailed` + +```swift +case addinUnloadFailed = -67714 +``` + +### `libraryReferenceNotFound` + +```swift +case libraryReferenceNotFound = -67715 +``` + +### `invalidAddinFunctionTable` + +```swift +case invalidAddinFunctionTable = -67716 +``` + +### `invalidServiceMask` + +```swift +case invalidServiceMask = -67717 +``` + +### `moduleNotLoaded` + +```swift +case moduleNotLoaded = -67718 +``` + +### `invalidSubServiceID` + +```swift +case invalidSubServiceID = -67719 +``` + +### `attributeNotInContext` + +```swift +case attributeNotInContext = -67720 +``` + +### `moduleManagerInitializeFailed` + +```swift +case moduleManagerInitializeFailed = -67721 +``` + +### `moduleManagerNotFound` + +```swift +case moduleManagerNotFound = -67722 +``` + +### `eventNotificationCallbackNotFound` + +```swift +case eventNotificationCallbackNotFound = -67723 +``` + +### `inputLengthError` + +```swift +case inputLengthError = -67724 +``` + +### `outputLengthError` + +```swift +case outputLengthError = -67725 +``` + +### `privilegeNotSupported` + +```swift +case privilegeNotSupported = -67726 +``` + +### `deviceError` + +```swift +case deviceError = -67727 +``` + +### `attachHandleBusy` + +```swift +case attachHandleBusy = -67728 +``` + +### `notLoggedIn` + +```swift +case notLoggedIn = -67729 +``` + +### `algorithmMismatch` + +```swift +case algorithmMismatch = -67730 +``` + +### `keyUsageIncorrect` + +```swift +case keyUsageIncorrect = -67731 +``` + +### `keyBlobTypeIncorrect` + +```swift +case keyBlobTypeIncorrect = -67732 +``` + +### `keyHeaderInconsistent` + +```swift +case keyHeaderInconsistent = -67733 +``` + +### `unsupportedKeyFormat` + +```swift +case unsupportedKeyFormat = -67734 +``` + +### `unsupportedKeySize` + +```swift +case unsupportedKeySize = -67735 +``` + +### `invalidKeyUsageMask` + +```swift +case invalidKeyUsageMask = -67736 +``` + +### `unsupportedKeyUsageMask` + +```swift +case unsupportedKeyUsageMask = -67737 +``` + +### `invalidKeyAttributeMask` + +```swift +case invalidKeyAttributeMask = -67738 +``` + +### `unsupportedKeyAttributeMask` + +```swift +case unsupportedKeyAttributeMask = -67739 +``` + +### `invalidKeyLabel` + +```swift +case invalidKeyLabel = -67740 +``` + +### `unsupportedKeyLabel` + +```swift +case unsupportedKeyLabel = -67741 +``` + +### `invalidKeyFormat` + +```swift +case invalidKeyFormat = -67742 +``` + +### `unsupportedVectorOfBuffers` + +```swift +case unsupportedVectorOfBuffers = -67743 +``` + +### `invalidInputVector` + +```swift +case invalidInputVector = -67744 +``` + +### `invalidOutputVector` + +```swift +case invalidOutputVector = -67745 +``` + +### `invalidContext` + +```swift +case invalidContext = -67746 +``` + +### `invalidAlgorithm` + +```swift +case invalidAlgorithm = -67747 +``` + +### `invalidAttributeKey` + +```swift +case invalidAttributeKey = -67748 +``` + +### `missingAttributeKey` + +```swift +case missingAttributeKey = -67749 +``` + +### `invalidAttributeInitVector` + +```swift +case invalidAttributeInitVector = -67750 +``` + +### `missingAttributeInitVector` + +```swift +case missingAttributeInitVector = -67751 +``` + +### `invalidAttributeSalt` + +```swift +case invalidAttributeSalt = -67752 +``` + +### `missingAttributeSalt` + +```swift +case missingAttributeSalt = -67753 +``` + +### `invalidAttributePadding` + +```swift +case invalidAttributePadding = -67754 +``` + +### `missingAttributePadding` + +```swift +case missingAttributePadding = -67755 +``` + +### `invalidAttributeRandom` + +```swift +case invalidAttributeRandom = -67756 +``` + +### `missingAttributeRandom` + +```swift +case missingAttributeRandom = -67757 +``` + +### `invalidAttributeSeed` + +```swift +case invalidAttributeSeed = -67758 +``` + +### `missingAttributeSeed` + +```swift +case missingAttributeSeed = -67759 +``` + +### `invalidAttributePassphrase` + +```swift +case invalidAttributePassphrase = -67760 +``` + +### `missingAttributePassphrase` + +```swift +case missingAttributePassphrase = -67761 +``` + +### `invalidAttributeKeyLength` + +```swift +case invalidAttributeKeyLength = -67762 +``` + +### `missingAttributeKeyLength` + +```swift +case missingAttributeKeyLength = -67763 +``` + +### `invalidAttributeBlockSize` + +```swift +case invalidAttributeBlockSize = -67764 +``` + +### `missingAttributeBlockSize` + +```swift +case missingAttributeBlockSize = -67765 +``` + +### `invalidAttributeOutputSize` + +```swift +case invalidAttributeOutputSize = -67766 +``` + +### `missingAttributeOutputSize` + +```swift +case missingAttributeOutputSize = -67767 +``` + +### `invalidAttributeRounds` + +```swift +case invalidAttributeRounds = -67768 +``` + +### `missingAttributeRounds` + +```swift +case missingAttributeRounds = -67769 +``` + +### `invalidAlgorithmParms` + +```swift +case invalidAlgorithmParms = -67770 +``` + +### `missingAlgorithmParms` + +```swift +case missingAlgorithmParms = -67771 +``` + +### `invalidAttributeLabel` + +```swift +case invalidAttributeLabel = -67772 +``` + +### `missingAttributeLabel` + +```swift +case missingAttributeLabel = -67773 +``` + +### `invalidAttributeKeyType` + +```swift +case invalidAttributeKeyType = -67774 +``` + +### `missingAttributeKeyType` + +```swift +case missingAttributeKeyType = -67775 +``` + +### `invalidAttributeMode` + +```swift +case invalidAttributeMode = -67776 +``` + +### `missingAttributeMode` + +```swift +case missingAttributeMode = -67777 +``` + +### `invalidAttributeEffectiveBits` + +```swift +case invalidAttributeEffectiveBits = -67778 +``` + +### `missingAttributeEffectiveBits` + +```swift +case missingAttributeEffectiveBits = -67779 +``` + +### `invalidAttributeStartDate` + +```swift +case invalidAttributeStartDate = -67780 +``` + +### `missingAttributeStartDate` + +```swift +case missingAttributeStartDate = -67781 +``` + +### `invalidAttributeEndDate` + +```swift +case invalidAttributeEndDate = -67782 +``` + +### `missingAttributeEndDate` + +```swift +case missingAttributeEndDate = -67783 +``` + +### `invalidAttributeVersion` + +```swift +case invalidAttributeVersion = -67784 +``` + +### `missingAttributeVersion` + +```swift +case missingAttributeVersion = -67785 +``` + +### `invalidAttributePrime` + +```swift +case invalidAttributePrime = -67786 +``` + +### `missingAttributePrime` + +```swift +case missingAttributePrime = -67787 +``` + +### `invalidAttributeBase` + +```swift +case invalidAttributeBase = -67788 +``` + +### `missingAttributeBase` + +```swift +case missingAttributeBase = -67789 +``` + +### `invalidAttributeSubprime` + +```swift +case invalidAttributeSubprime = -67790 +``` + +### `missingAttributeSubprime` + +```swift +case missingAttributeSubprime = -67791 +``` + +### `invalidAttributeIterationCount` + +```swift +case invalidAttributeIterationCount = -67792 +``` + +### `missingAttributeIterationCount` + +```swift +case missingAttributeIterationCount = -67793 +``` + +### `invalidAttributeDLDBHandle` + +```swift +case invalidAttributeDLDBHandle = -67794 +``` + +### `missingAttributeDLDBHandle` + +```swift +case missingAttributeDLDBHandle = -67795 +``` + +### `invalidAttributeAccessCredentials` + +```swift +case invalidAttributeAccessCredentials = -67796 +``` + +### `missingAttributeAccessCredentials` + +```swift +case missingAttributeAccessCredentials = -67797 +``` + +### `invalidAttributePublicKeyFormat` + +```swift +case invalidAttributePublicKeyFormat = -67798 +``` + +### `missingAttributePublicKeyFormat` + +```swift +case missingAttributePublicKeyFormat = -67799 +``` + +### `invalidAttributePrivateKeyFormat` + +```swift +case invalidAttributePrivateKeyFormat = -67800 +``` + +### `missingAttributePrivateKeyFormat` + +```swift +case missingAttributePrivateKeyFormat = -67801 +``` + +### `invalidAttributeSymmetricKeyFormat` + +```swift +case invalidAttributeSymmetricKeyFormat = -67802 +``` + +### `missingAttributeSymmetricKeyFormat` + +```swift +case missingAttributeSymmetricKeyFormat = -67803 +``` + +### `invalidAttributeWrappedKeyFormat` + +```swift +case invalidAttributeWrappedKeyFormat = -67804 +``` + +### `missingAttributeWrappedKeyFormat` + +```swift +case missingAttributeWrappedKeyFormat = -67805 +``` + +### `stagedOperationInProgress` + +```swift +case stagedOperationInProgress = -67806 +``` + +### `stagedOperationNotStarted` + +```swift +case stagedOperationNotStarted = -67807 +``` + +### `verifyFailed` + +```swift +case verifyFailed = -67808 +``` + +### `querySizeUnknown` + +```swift +case querySizeUnknown = -67809 +``` + +### `blockSizeMismatch` + +```swift +case blockSizeMismatch = -67810 +``` + +### `publicKeyInconsistent` + +```swift +case publicKeyInconsistent = -67811 +``` + +### `deviceVerifyFailed` + +```swift +case deviceVerifyFailed = -67812 +``` + +### `invalidLoginName` + +```swift +case invalidLoginName = -67813 +``` + +### `alreadyLoggedIn` + +```swift +case alreadyLoggedIn = -67814 +``` + +### `invalidDigestAlgorithm` + +```swift +case invalidDigestAlgorithm = -67815 +``` + +### `invalidCRLGroup` + +```swift +case invalidCRLGroup = -67816 +``` + +### `certificateCannotOperate` + +```swift +case certificateCannotOperate = -67817 +``` + +### `certificateExpired` + +```swift +case certificateExpired = -67818 +``` + +### `certificateNotValidYet` + +```swift +case certificateNotValidYet = -67819 +``` + +### `certificateRevoked` + +```swift +case certificateRevoked = -67820 +``` + +### `certificateSuspended` + +```swift +case certificateSuspended = -67821 +``` + +### `insufficientCredentials` + +```swift +case insufficientCredentials = -67822 +``` + +### `invalidAction` + +```swift +case invalidAction = -67823 +``` + +### `invalidAuthority` + +```swift +case invalidAuthority = -67824 +``` + +### `verifyActionFailed` + +```swift +case verifyActionFailed = -67825 +``` + +### `invalidCertAuthority` + +```swift +case invalidCertAuthority = -67826 +``` + +### `invaldCRLAuthority` + +```swift +case invaldCRLAuthority = -67827 +``` + +### `invalidCRLEncoding` + +```swift +case invalidCRLEncoding = -67828 +``` + +### `invalidCRLType` + +```swift +case invalidCRLType = -67829 +``` + +### `invalidCRL` + +```swift +case invalidCRL = -67830 +``` + +### `invalidFormType` + +```swift +case invalidFormType = -67831 +``` + +### `invalidID` + +```swift +case invalidID = -67832 +``` + +### `invalidIdentifier` + +```swift +case invalidIdentifier = -67833 +``` + +### `invalidIndex` + +```swift +case invalidIndex = -67834 +``` + +### `invalidPolicyIdentifiers` + +```swift +case invalidPolicyIdentifiers = -67835 +``` + +### `invalidTimeString` + +```swift +case invalidTimeString = -67836 +``` + +### `invalidReason` + +```swift +case invalidReason = -67837 +``` + +### `invalidRequestInputs` + +```swift +case invalidRequestInputs = -67838 +``` + +### `invalidResponseVector` + +```swift +case invalidResponseVector = -67839 +``` + +### `invalidStopOnPolicy` + +```swift +case invalidStopOnPolicy = -67840 +``` + +### `invalidTuple` + +```swift +case invalidTuple = -67841 +``` + +### `multipleValuesUnsupported` + +```swift +case multipleValuesUnsupported = -67842 +``` + +### `notTrusted` + +```swift +case notTrusted = -67843 +``` + +### `noDefaultAuthority` + +```swift +case noDefaultAuthority = -67844 +``` + +### `rejectedForm` + +```swift +case rejectedForm = -67845 +``` + +### `requestLost` + +```swift +case requestLost = -67846 +``` + +### `requestRejected` + +```swift +case requestRejected = -67847 +``` + +### `unsupportedAddressType` + +```swift +case unsupportedAddressType = -67848 +``` + +### `unsupportedService` + +```swift +case unsupportedService = -67849 +``` + +### `invalidTupleGroup` + +```swift +case invalidTupleGroup = -67850 +``` + +### `invalidBaseACLs` + +```swift +case invalidBaseACLs = -67851 +``` + +### `invalidTupleCredendtials` + +```swift +case invalidTupleCredendtials = -67852 +``` + +### `invalidEncoding` + +```swift +case invalidEncoding = -67853 +``` + +### `invalidValidityPeriod` + +```swift +case invalidValidityPeriod = -67854 +``` + +### `invalidRequestor` + +```swift +case invalidRequestor = -67855 +``` + +### `requestDescriptor` + +```swift +case requestDescriptor = -67856 +``` + +### `invalidBundleInfo` + +```swift +case invalidBundleInfo = -67857 +``` + +### `invalidCRLIndex` + +```swift +case invalidCRLIndex = -67858 +``` + +### `noFieldValues` + +```swift +case noFieldValues = -67859 +``` + +### `unsupportedFieldFormat` + +```swift +case unsupportedFieldFormat = -67860 +``` + +### `unsupportedIndexInfo` + +```swift +case unsupportedIndexInfo = -67861 +``` + +### `unsupportedLocality` + +```swift +case unsupportedLocality = -67862 +``` + +### `unsupportedNumAttributes` + +```swift +case unsupportedNumAttributes = -67863 +``` + +### `unsupportedNumIndexes` + +```swift +case unsupportedNumIndexes = -67864 +``` + +### `unsupportedNumRecordTypes` + +```swift +case unsupportedNumRecordTypes = -67865 +``` + +### `fieldSpecifiedMultiple` + +```swift +case fieldSpecifiedMultiple = -67866 +``` + +### `incompatibleFieldFormat` + +```swift +case incompatibleFieldFormat = -67867 +``` + +### `invalidParsingModule` + +```swift +case invalidParsingModule = -67868 +``` + +### `databaseLocked` + +```swift +case databaseLocked = -67869 +``` + +### `datastoreIsOpen` + +```swift +case datastoreIsOpen = -67870 +``` + +### `missingValue` + +```swift +case missingValue = -67871 +``` + +### `unsupportedQueryLimits` + +```swift +case unsupportedQueryLimits = -67872 +``` + +### `unsupportedNumSelectionPreds` + +```swift +case unsupportedNumSelectionPreds = -67873 +``` + +### `unsupportedOperator` + +```swift +case unsupportedOperator = -67874 +``` + +### `invalidDBLocation` + +```swift +case invalidDBLocation = -67875 +``` + +### `invalidAccessRequest` + +```swift +case invalidAccessRequest = -67876 +``` + +### `invalidIndexInfo` + +```swift +case invalidIndexInfo = -67877 +``` + +### `invalidNewOwner` + +```swift +case invalidNewOwner = -67878 +``` + +### `invalidModifyMode` + +```swift +case invalidModifyMode = -67879 +``` + +### `missingRequiredExtension` + +```swift +case missingRequiredExtension = -67880 +``` + +### `extendedKeyUsageNotCritical` + +```swift +case extendedKeyUsageNotCritical = -67881 +``` + +### `timestampMissing` + +```swift +case timestampMissing = -67882 +``` + +### `timestampInvalid` + +```swift +case timestampInvalid = -67883 +``` + +### `timestampNotTrusted` + +```swift +case timestampNotTrusted = -67884 +``` + +### `timestampServiceNotAvailable` + +```swift +case timestampServiceNotAvailable = -67885 +``` + +### `timestampBadAlg` + +```swift +case timestampBadAlg = -67886 +``` + +### `timestampBadRequest` + +```swift +case timestampBadRequest = -67887 +``` + +### `timestampBadDataFormat` + +```swift +case timestampBadDataFormat = -67888 +``` + +### `timestampTimeNotAvailable` + +```swift +case timestampTimeNotAvailable = -67889 +``` + +### `timestampUnacceptedPolicy` + +```swift +case timestampUnacceptedPolicy = -67890 +``` + +### `timestampUnacceptedExtension` + +```swift +case timestampUnacceptedExtension = -67891 +``` + +### `timestampAddInfoNotAvailable` + +```swift +case timestampAddInfoNotAvailable = -67892 +``` + +### `timestampSystemFailure` + +```swift +case timestampSystemFailure = -67893 +``` + +### `signingTimeMissing` + +```swift +case signingTimeMissing = -67894 +``` + +### `timestampRejection` + +```swift +case timestampRejection = -67895 +``` + +### `timestampWaiting` + +```swift +case timestampWaiting = -67896 +``` + +### `timestampRevocationWarning` + +```swift +case timestampRevocationWarning = -67897 +``` + +### `timestampRevocationNotification` + +```swift +case timestampRevocationNotification = -67898 +``` + +### `unexpectedError` + +```swift +case unexpectedError = -99999 +``` diff --git a/Documentation/Reference/extensions/CelyStorageError.md b/Documentation/Reference/extensions/CelyStorageError.md new file mode 100644 index 0000000..44aa92f --- /dev/null +++ b/Documentation/Reference/extensions/CelyStorageError.md @@ -0,0 +1,29 @@ +**EXTENSION** + +# `CelyStorageError` + +## Properties +### `description` + +```swift +public var description: String +``` + +### `errorCode` + +```swift +public var errorCode: Int +``` + +### `errorUserInfo` + +```swift +public var errorUserInfo: [String: Any] +``` + +## Methods +### `init(status:)` + +```swift +public init(status: OSStatus) +``` diff --git a/Documentation/Reference/extensions/CelyStyle.md b/Documentation/Reference/extensions/CelyStyle.md new file mode 100644 index 0000000..8767895 --- /dev/null +++ b/Documentation/Reference/extensions/CelyStyle.md @@ -0,0 +1,54 @@ +**EXTENSION** + +# `CelyStyle` + +## Methods +### `backgroundColor()` + +```swift +func backgroundColor() -> UIColor +``` + +> Background Color for default login screen +> +> - returns: UIColor + +### `textFieldBackgroundColor()` + +```swift +func textFieldBackgroundColor() -> UIColor +``` + +> Background Color for textfields +> +> - returns: UIColor + +### `buttonBackgroundColor()` + +```swift +func buttonBackgroundColor() -> UIColor +``` + +> Background Color for login button +> +> - returns: UIColor + +### `buttonTextColor()` + +```swift +func buttonTextColor() -> UIColor +``` + +> Text Color for login button +> +> - returns: UIColor + +### `appLogo()` + +```swift +func appLogo() -> UIImage? +``` + +> App icon for default login screen +> +> - returns: UIImage? diff --git a/Documentation/Reference/extensions/UIWindow.md b/Documentation/Reference/extensions/UIWindow.md new file mode 100644 index 0000000..b6f2108 --- /dev/null +++ b/Documentation/Reference/extensions/UIWindow.md @@ -0,0 +1,10 @@ +**EXTENSION** + +# `UIWindow` + +## Methods +### `setCurrentViewController(to:)` + +```swift +func setCurrentViewController(to viewController: UIViewController?) +``` diff --git a/Documentation/Reference/protocols/CelyAnimator.md b/Documentation/Reference/protocols/CelyAnimator.md new file mode 100644 index 0000000..d1072ce --- /dev/null +++ b/Documentation/Reference/protocols/CelyAnimator.md @@ -0,0 +1,22 @@ +**PROTOCOL** + +# `CelyAnimator` + +```swift +public protocol CelyAnimator +``` + +> Handles Animations between Home and Login ViewControllers + +## Methods +### `loginTransition(to:with:)` + +```swift +func loginTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) +``` + +### `logoutTransition(to:with:)` + +```swift +func logoutTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) +``` diff --git a/Documentation/Reference/protocols/CelyStorageProtocol.md b/Documentation/Reference/protocols/CelyStorageProtocol.md new file mode 100644 index 0000000..73fcbfd --- /dev/null +++ b/Documentation/Reference/protocols/CelyStorageProtocol.md @@ -0,0 +1,28 @@ +**PROTOCOL** + +# `CelyStorageProtocol` + +```swift +public protocol CelyStorageProtocol +``` + +> Protocol a storage class must abide by in order for Cely to use it + +## Methods +### `set(_:forKey:securely:persisted:)` + +```swift +func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) throws +``` + +### `get(_:)` + +```swift +func get(_ key: String) -> Any? +``` + +### `clearStorage()` + +```swift +func clearStorage() throws +``` diff --git a/Documentation/Reference/protocols/CelyStyle.md b/Documentation/Reference/protocols/CelyStyle.md new file mode 100644 index 0000000..592e671 --- /dev/null +++ b/Documentation/Reference/protocols/CelyStyle.md @@ -0,0 +1,40 @@ +**PROTOCOL** + +# `CelyStyle` + +```swift +public protocol CelyStyle +``` + +> Protocol that allows styles to be applied to Cely's default LoginViewController + +## Methods +### `backgroundColor()` + +```swift +func backgroundColor() -> UIColor +``` + +### `textFieldBackgroundColor()` + +```swift +func textFieldBackgroundColor() -> UIColor +``` + +### `buttonBackgroundColor()` + +```swift +func buttonBackgroundColor() -> UIColor +``` + +### `buttonTextColor()` + +```swift +func buttonTextColor() -> UIColor +``` + +### `appLogo()` + +```swift +func appLogo() -> UIImage? +``` diff --git a/Documentation/Reference/protocols/CelyUser.md b/Documentation/Reference/protocols/CelyUser.md new file mode 100644 index 0000000..605f533 --- /dev/null +++ b/Documentation/Reference/protocols/CelyUser.md @@ -0,0 +1,9 @@ +**PROTOCOL** + +# `CelyUser` + +```swift +public protocol CelyUser +``` + +> Protocol for model class to implements diff --git a/Documentation/Reference/structs/Cely.md b/Documentation/Reference/structs/Cely.md new file mode 100644 index 0000000..e7f6447 --- /dev/null +++ b/Documentation/Reference/structs/Cely.md @@ -0,0 +1,137 @@ +**STRUCT** + +# `Cely` + +```swift +public struct Cely +``` + +## Methods +### `setup(with:forModel:requiredProperties:withOptions:)` + +```swift +public static func setup(with window: UIWindow?, forModel _: T, requiredProperties: [U] = [], withOptions options: [CelyOptions: Any?]? = [:]) where T.Property == U +``` + +> Sets up Cely within your application +> +> - parameter window: `UIWindow` of your application. +> - parameter forModel: The `Model` Cely will be storing. +> - parameter requiredProperties: `[CelyProperty]`: The properties that cely tests against to determine if a user is logged in. +> - parameter withOptions: Dictionary of options to pass into cely upon setup. Please refer to `CelyOptions` to view all options. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| window | `UIWindow` of your application. | +| forModel | The `Model` Cely will be storing. | +| requiredProperties | `[CelyProperty]`: The properties that cely tests against to determine if a user is logged in. | +| withOptions | Dictionary of options to pass into cely upon setup. Please refer to `CelyOptions` to view all options. | + +### `currentLoginStatus(requiredProperties:fromStorage:)` + +```swift +public static func currentLoginStatus(requiredProperties properties: [CelyProperty] = requiredProperties, fromStorage store: CelyStorageProtocol = store) -> CelyStatus +``` + +> Will return the `CelyStatus` of the current user. +> - Parameters: +> - properties: Array of required properties that need to be in store. +> - store: Storage `Cely` will be using. Defaulted to `Storage` +> - returns: `CelyStatus`. If `requiredProperties` are all in store, it will return `.LoggedIn`, else `.LoggedOut` + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| properties | Array of required properties that need to be in store. | +| store | Storage `Cely` will be using. Defaulted to `Storage` | + +### `get(key:fromStorage:)` + +```swift +public static func get(key: String, fromStorage store: CelyStorageProtocol = store) -> Any? +``` + +> Returns stored data for key. +> +> - parameter key: String +> - parameter store: Object that conforms to the CelyStorageProtocol protocol that `Cely` will be using. Defaulted to `Cely`'s instance of store +> +> - returns: Returns data as an optional `Any` + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| key | String | +| store | Object that conforms to the CelyStorageProtocol protocol that `Cely` will be using. Defaulted to `Cely`’s instance of store | + +### `save(_:forKey:toStorage:securely:persisted:)` + +```swift +public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result +``` + +> Saves data in store +> +> - parameter value: data you want to save +> - parameter key: String for the key +> - parameter store: Storage `Cely` will be using. Defaulted to `Storage` +> - parameter secure: `Boolean`: Store data securely +> - parameter persist: `Boolean`: Keep data after logout +> +> - returns: `Boolean`: Whether or not your value was successfully set. + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| value | data you want to save | +| key | String for the key | +| store | Storage `Cely` will be using. Defaulted to `Storage` | +| secure | `Boolean`: Store data securely | +| persist | `Boolean`: Keep data after logout | + +### `changeStatus(to:)` + +```swift +public static func changeStatus(to status: CelyStatus) +``` + +> Perform action like `LoggedIn` or `LoggedOut` +> +> - parameter status: CelyStatus + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| status | CelyStatus | + +### `logout(useStorage:)` + +```swift +public static func logout(useStorage store: CelyStorageProtocol = store) -> Result +``` + +> Log user out +> +> - parameter store: Storage `Cely` will be using. Defaulted to `CelyStorageProtocol` + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| store | Storage `Cely` will be using. Defaulted to `CelyStorageProtocol` | + +### `isLoggedIn()` + +```swift +public static func isLoggedIn() -> Bool +``` + +> Returns whether or not the user is logged in +> +> - returns: `Boolean` diff --git a/Documentation/Reference/structs/CelyCredentialStore.md b/Documentation/Reference/structs/CelyCredentialStore.md new file mode 100644 index 0000000..cc6e518 --- /dev/null +++ b/Documentation/Reference/structs/CelyCredentialStore.md @@ -0,0 +1,40 @@ +**STRUCT** + +# `CelyCredentialStore` + +```swift +public struct CelyCredentialStore +``` + +> CelyCredentialStore - object that stores user credentials + +## Methods +### `set(username:password:server:accessibility:)` + +```swift +public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result +``` + +> Set user credentials +> - Parameters: +> - username: username for user +> - password: password for user +> - server: api uri for account +> - accessibility: Array of AccessibilityOptions for credentials to be saved with + +#### Parameters + +| Name | Description | +| ---- | ----------- | +| username | username for user | +| password | password for user | +| server | api uri for account | +| accessibility | Array of AccessibilityOptions for credentials to be saved with | + +### `get()` + +```swift +public func get() -> Result +``` + +> Return credentials diff --git a/Documentation/Reference/structs/CelyCredentials.md b/Documentation/Reference/structs/CelyCredentials.md new file mode 100644 index 0000000..e30da1f --- /dev/null +++ b/Documentation/Reference/structs/CelyCredentials.md @@ -0,0 +1,26 @@ +**STRUCT** + +# `CelyCredentials` + +```swift +public struct CelyCredentials +``` + +## Properties +### `username` + +```swift +public let username: String +``` + +### `password` + +```swift +public let password: String +``` + +### `server` + +```swift +public let server: String +``` diff --git a/Sources/Cely.swift b/Sources/Core/Cely.swift similarity index 98% rename from Sources/Cely.swift rename to Sources/Core/Cely.swift index ef7ae85..d8e332c 100644 --- a/Sources/Cely.swift +++ b/Sources/Core/Cely.swift @@ -13,7 +13,7 @@ public struct Cely { fileprivate init() {} public typealias CelyLoginCompletion = (_ username: String, _ password: String) -> Void /// Properties that are needed inorder for user to stay logged in. - public private(set) static var requiredProperties: [CelyProperty] = [] + public internal(set) static var requiredProperties: [CelyProperty] = [] /// A `Storage` instance public private(set) static var store: CelyStorageProtocol = CelyStorage.sharedInstance diff --git a/Sources/CelyConstants.swift b/Sources/Core/CelyConstants.swift similarity index 92% rename from Sources/CelyConstants.swift rename to Sources/Core/CelyConstants.swift index b83fb03..6cce27a 100644 --- a/Sources/CelyConstants.swift +++ b/Sources/Core/CelyConstants.swift @@ -44,7 +44,7 @@ internal extension UITextField { } } -public extension UIWindow { +internal extension UIWindow { func setCurrentViewController(to viewController: UIViewController?) { let previousViewController = rootViewController rootViewController = viewController @@ -54,3 +54,8 @@ public extension UIWindow { } } } + +public enum AccessibilityOptions { + case biometricsIfPossible + case thisDeviceOnly +} diff --git a/Sources/CelyProtocols.swift b/Sources/Core/CelyProtocols.swift similarity index 100% rename from Sources/CelyProtocols.swift rename to Sources/Core/CelyProtocols.swift diff --git a/Sources/CelyWindowManager.swift b/Sources/Core/CelyWindowManager.swift similarity index 100% rename from Sources/CelyWindowManager.swift rename to Sources/Core/CelyWindowManager.swift diff --git a/Sources/Storage/CelyCredentialStore.swift b/Sources/Core/Storage/CelyCredentialStore.swift similarity index 90% rename from Sources/Storage/CelyCredentialStore.swift rename to Sources/Core/Storage/CelyCredentialStore.swift index 22e69e4..e146099 100644 --- a/Sources/Storage/CelyCredentialStore.swift +++ b/Sources/Core/Storage/CelyCredentialStore.swift @@ -8,11 +8,6 @@ import Foundation -public enum AccessibilityOptions { - case biometricsIfPossible - case thisDeviceOnly -} - public struct CelyCredentials { public let username: String public let password: String @@ -37,14 +32,14 @@ public struct CelyCredentialStore { return Cely.get(key: kCelyCredentialsLookupKey) as? [CFString: Any] } - /// Set user credentials /// - Parameters: /// - username: username for user /// - password: password for user /// - server: api uri for account /// - accessibility: Array of AccessibilityOptions for credentials to be saved with - @discardableResult public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { + @discardableResult + public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { guard let passwordData = password.data(using: .utf8) else { return .failure(CelyStorageError.invalidValue) } @@ -59,6 +54,7 @@ public struct CelyCredentialStore { } } + /// Return credentials public func get() -> Result { guard let lookupQuery = getCredentialsLookupKey() else { return .failure(CelyStorageError.unexpectedError) diff --git a/Sources/Storage/CelyKeychain.swift b/Sources/Core/Storage/CelyKeychain.swift similarity index 100% rename from Sources/Storage/CelyKeychain.swift rename to Sources/Core/Storage/CelyKeychain.swift diff --git a/Sources/Storage/CelySecureStorage.swift b/Sources/Core/Storage/CelySecureStorage.swift similarity index 100% rename from Sources/Storage/CelySecureStorage.swift rename to Sources/Core/Storage/CelySecureStorage.swift diff --git a/Sources/Storage/CelyStorage.swift b/Sources/Core/Storage/CelyStorage.swift similarity index 100% rename from Sources/Storage/CelyStorage.swift rename to Sources/Core/Storage/CelyStorage.swift diff --git a/Sources/Storage/CelyStorageError.swift b/Sources/Core/Storage/CelyStorageError.swift similarity index 100% rename from Sources/Storage/CelyStorageError.swift rename to Sources/Core/Storage/CelyStorageError.swift diff --git a/Sources/Storage/KeychainObject.swift b/Sources/Core/Storage/KeychainObject.swift similarity index 100% rename from Sources/Storage/KeychainObject.swift rename to Sources/Core/Storage/KeychainObject.swift diff --git a/Sources/Cely.h b/Sources/Supporting Files/Cely.h similarity index 100% rename from Sources/Cely.h rename to Sources/Supporting Files/Cely.h diff --git a/Sources/CelyLoginViewController.swift b/Sources/Supporting Files/CelyLoginViewController.swift similarity index 100% rename from Sources/CelyLoginViewController.swift rename to Sources/Supporting Files/CelyLoginViewController.swift diff --git a/Sources/Info-tvOS.plist b/Sources/Supporting Files/Info-tvOS.plist similarity index 100% rename from Sources/Info-tvOS.plist rename to Sources/Supporting Files/Info-tvOS.plist diff --git a/Sources/Info.plist b/Sources/Supporting Files/Info.plist similarity index 100% rename from Sources/Info.plist rename to Sources/Supporting Files/Info.plist From c84b4e7cea9507155f27943b575a168e7c415e59 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Sun, 26 Jan 2020 01:52:17 -0600 Subject: [PATCH 15/17] code clean up before PR --- Cely Demo/Info.plist | 4 +- Documentation/Reference/README.md | 33 - .../Reference/classes/CelyWindowManager.md | 33 - .../Reference/enums/AccessibilityOptions.md | 20 - Documentation/Reference/enums/CelyOptions.md | 46 - Documentation/Reference/enums/CelyStatus.md | 22 - .../Reference/enums/CelyStorageError.md | 2426 ----------------- .../Reference/extensions/CelyStorageError.md | 29 - .../Reference/extensions/CelyStyle.md | 54 - .../Reference/extensions/UIWindow.md | 10 - .../Reference/protocols/CelyAnimator.md | 22 - .../protocols/CelyStorageProtocol.md | 28 - .../Reference/protocols/CelyStyle.md | 40 - Documentation/Reference/protocols/CelyUser.md | 9 - Documentation/Reference/structs/Cely.md | 137 - .../Reference/structs/CelyCredentialStore.md | 40 - .../Reference/structs/CelyCredentials.md | 26 - Sources/Core/CelyConstants.swift | 4 + Sources/Core/Storage/KeychainObject.swift | 1 - 19 files changed, 6 insertions(+), 2978 deletions(-) delete mode 100644 Documentation/Reference/README.md delete mode 100644 Documentation/Reference/classes/CelyWindowManager.md delete mode 100644 Documentation/Reference/enums/AccessibilityOptions.md delete mode 100644 Documentation/Reference/enums/CelyOptions.md delete mode 100644 Documentation/Reference/enums/CelyStatus.md delete mode 100644 Documentation/Reference/enums/CelyStorageError.md delete mode 100644 Documentation/Reference/extensions/CelyStorageError.md delete mode 100644 Documentation/Reference/extensions/CelyStyle.md delete mode 100644 Documentation/Reference/extensions/UIWindow.md delete mode 100644 Documentation/Reference/protocols/CelyAnimator.md delete mode 100644 Documentation/Reference/protocols/CelyStorageProtocol.md delete mode 100644 Documentation/Reference/protocols/CelyStyle.md delete mode 100644 Documentation/Reference/protocols/CelyUser.md delete mode 100644 Documentation/Reference/structs/Cely.md delete mode 100644 Documentation/Reference/structs/CelyCredentialStore.md delete mode 100644 Documentation/Reference/structs/CelyCredentials.md diff --git a/Cely Demo/Info.plist b/Cely Demo/Info.plist index d569257..d63dc4d 100644 --- a/Cely Demo/Info.plist +++ b/Cely Demo/Info.plist @@ -2,8 +2,6 @@ - NSFaceIDUsageDescription - Cely Demo CFBundleDevelopmentRegion en CFBundleExecutable @@ -22,6 +20,8 @@ 1 LSRequiresIPhoneOS + NSFaceIDUsageDescription + Cely Demo UILaunchStoryboardName LaunchScreen UIMainStoryboardFile diff --git a/Documentation/Reference/README.md b/Documentation/Reference/README.md deleted file mode 100644 index 3d4a199..0000000 --- a/Documentation/Reference/README.md +++ /dev/null @@ -1,33 +0,0 @@ -## Protocols - -- [CelyAnimator](protocols/CelyAnimator.md) -- [CelyStorageProtocol](protocols/CelyStorageProtocol.md) -- [CelyStyle](protocols/CelyStyle.md) -- [CelyUser](protocols/CelyUser.md) - -## Structs - -- [Cely](structs/Cely.md) -- [CelyCredentialStore](structs/CelyCredentialStore.md) -- [CelyCredentials](structs/CelyCredentials.md) - -## Classes - -- [CelyWindowManager](classes/CelyWindowManager.md) - -## Enums - -- [AccessibilityOptions](enums/AccessibilityOptions.md) -- [CelyOptions](enums/CelyOptions.md) -- [CelyStatus](enums/CelyStatus.md) -- [CelyStorageError](enums/CelyStorageError.md) - -## Extensions - -- [CelyStorageError](extensions/CelyStorageError.md) -- [CelyStyle](extensions/CelyStyle.md) -- [UIWindow](extensions/UIWindow.md) - -# Reference Documentation -This reference documentation was generated with -[SourceDocs](https://github.com/eneko/SourceDocs). \ No newline at end of file diff --git a/Documentation/Reference/classes/CelyWindowManager.md b/Documentation/Reference/classes/CelyWindowManager.md deleted file mode 100644 index 4c5d795..0000000 --- a/Documentation/Reference/classes/CelyWindowManager.md +++ /dev/null @@ -1,33 +0,0 @@ -**CLASS** - -# `CelyWindowManager` - -```swift -public class CelyWindowManager -``` - -## Properties -### `loginStyle` - -```swift -public var loginStyle: CelyStyle! -``` - -### `celyAnimator` - -```swift -public var celyAnimator: CelyAnimator! -``` - -## Methods -### `init()` - -```swift -public init() -``` - -### `deinit` - -```swift -deinit -``` diff --git a/Documentation/Reference/enums/AccessibilityOptions.md b/Documentation/Reference/enums/AccessibilityOptions.md deleted file mode 100644 index f0bdae1..0000000 --- a/Documentation/Reference/enums/AccessibilityOptions.md +++ /dev/null @@ -1,20 +0,0 @@ -**ENUM** - -# `AccessibilityOptions` - -```swift -public enum AccessibilityOptions -``` - -## Cases -### `biometricsIfPossible` - -```swift -case biometricsIfPossible -``` - -### `thisDeviceOnly` - -```swift -case thisDeviceOnly -``` diff --git a/Documentation/Reference/enums/CelyOptions.md b/Documentation/Reference/enums/CelyOptions.md deleted file mode 100644 index 3ca9186..0000000 --- a/Documentation/Reference/enums/CelyOptions.md +++ /dev/null @@ -1,46 +0,0 @@ -**ENUM** - -# `CelyOptions` - -```swift -public enum CelyOptions -``` - -> Options that you can pass into Cely on `Cely.setup(_:)` - -## Cases -### `storage` - -```swift -case storage -``` - -### `homeViewController` - -```swift -case homeViewController -``` - -### `loginViewController` - -```swift -case loginViewController -``` - -### `loginCompletionBlock` - -```swift -case loginCompletionBlock -``` - -### `loginStyle` - -```swift -case loginStyle -``` - -### `celyAnimator` - -```swift -case celyAnimator -``` diff --git a/Documentation/Reference/enums/CelyStatus.md b/Documentation/Reference/enums/CelyStatus.md deleted file mode 100644 index 98e2080..0000000 --- a/Documentation/Reference/enums/CelyStatus.md +++ /dev/null @@ -1,22 +0,0 @@ -**ENUM** - -# `CelyStatus` - -```swift -public enum CelyStatus: CelyCommands -``` - -> Statuses for Cely to perform actions on - -## Cases -### `loggedIn` - -```swift -case loggedIn = "CelyStatus.loggedIn.user" -``` - -### `loggedOut` - -```swift -case loggedOut = "CelyStatus.loggedOut.user" -``` diff --git a/Documentation/Reference/enums/CelyStorageError.md b/Documentation/Reference/enums/CelyStorageError.md deleted file mode 100644 index 028ad1c..0000000 --- a/Documentation/Reference/enums/CelyStorageError.md +++ /dev/null @@ -1,2426 +0,0 @@ -**ENUM** - -# `CelyStorageError` - -```swift -public enum CelyStorageError: OSStatus, Error -``` - -## Cases -### `noError` - -```swift -case noError = 0 -``` - -### `unimplemented` - -```swift -case unimplemented = -4 -``` - -### `diskFull` - -```swift -case diskFull = -34 -``` - -### `io` - -```swift -case io = -36 -``` - -### `opWr` - -```swift -case opWr = -49 -``` - -### `param` - -```swift -case param = -50 -``` - -### `wrPerm` - -```swift -case wrPerm = -61 -``` - -### `allocate` - -```swift -case allocate = -108 -``` - -### `userCanceled` - -```swift -case userCanceled = -128 -``` - -### `badReq` - -```swift -case badReq = -909 -``` - -### `internalComponent` - -```swift -case internalComponent = -2070 -``` - -### `notAvailable` - -```swift -case notAvailable = -25291 -``` - -### `readOnly` - -```swift -case readOnly = -25292 -``` - -### `authFailed` - -```swift -case authFailed = -25293 -``` - -### `noSuchKeychain` - -```swift -case noSuchKeychain = -25294 -``` - -### `invalidKeychain` - -```swift -case invalidKeychain = -25295 -``` - -### `duplicateKeychain` - -```swift -case duplicateKeychain = -25296 -``` - -### `duplicateCallback` - -```swift -case duplicateCallback = -25297 -``` - -### `invalidCallback` - -```swift -case invalidCallback = -25298 -``` - -### `duplicateItem` - -```swift -case duplicateItem = -25299 -``` - -### `itemNotFound` - -```swift -case itemNotFound = -25300 -``` - -### `bufferTooSmall` - -```swift -case bufferTooSmall = -25301 -``` - -### `dataTooLarge` - -```swift -case dataTooLarge = -25302 -``` - -### `noSuchAttr` - -```swift -case noSuchAttr = -25303 -``` - -### `invalidItemRef` - -```swift -case invalidItemRef = -25304 -``` - -### `invalidSearchRef` - -```swift -case invalidSearchRef = -25305 -``` - -### `noSuchClass` - -```swift -case noSuchClass = -25306 -``` - -### `noDefaultKeychain` - -```swift -case noDefaultKeychain = -25307 -``` - -### `interactionNotAllowed` - -```swift -case interactionNotAllowed = -25308 -``` - -### `readOnlyAttr` - -```swift -case readOnlyAttr = -25309 -``` - -### `wrongSecVersion` - -```swift -case wrongSecVersion = -25310 -``` - -### `keySizeNotAllowed` - -```swift -case keySizeNotAllowed = -25311 -``` - -### `noStorageModule` - -```swift -case noStorageModule = -25312 -``` - -### `noCertificateModule` - -```swift -case noCertificateModule = -25313 -``` - -### `noPolicyModule` - -```swift -case noPolicyModule = -25314 -``` - -### `interactionRequired` - -```swift -case interactionRequired = -25315 -``` - -### `dataNotAvailable` - -```swift -case dataNotAvailable = -25316 -``` - -### `dataNotModifiable` - -```swift -case dataNotModifiable = -25317 -``` - -### `createChainFailed` - -```swift -case createChainFailed = -25318 -``` - -### `invalidPrefsDomain` - -```swift -case invalidPrefsDomain = -25319 -``` - -### `inDarkWake` - -```swift -case inDarkWake = -25320 -``` - -### `aclNotSimple` - -```swift -case aclNotSimple = -25240 -``` - -### `policyNotFound` - -```swift -case policyNotFound = -25241 -``` - -### `invalidTrustSetting` - -```swift -case invalidTrustSetting = -25242 -``` - -### `noAccessForItem` - -```swift -case noAccessForItem = -25243 -``` - -### `invalidOwnerEdit` - -```swift -case invalidOwnerEdit = -25244 -``` - -### `trustNotAvailable` - -```swift -case trustNotAvailable = -25245 -``` - -### `unsupportedFormat` - -```swift -case unsupportedFormat = -25256 -``` - -### `unknownFormat` - -```swift -case unknownFormat = -25257 -``` - -### `keyIsSensitive` - -```swift -case keyIsSensitive = -25258 -``` - -### `multiplePrivKeys` - -```swift -case multiplePrivKeys = -25259 -``` - -### `passphraseRequired` - -```swift -case passphraseRequired = -25260 -``` - -### `invalidPasswordRef` - -```swift -case invalidPasswordRef = -25261 -``` - -### `invalidTrustSettings` - -```swift -case invalidTrustSettings = -25262 -``` - -### `noTrustSettings` - -```swift -case noTrustSettings = -25263 -``` - -### `pkcs12VerifyFailure` - -```swift -case pkcs12VerifyFailure = -25264 -``` - -### `invalidCertificate` - -```swift -case invalidCertificate = -26265 -``` - -### `notSigner` - -```swift -case notSigner = -26267 -``` - -### `policyDenied` - -```swift -case policyDenied = -26270 -``` - -### `invalidKey` - -```swift -case invalidKey = -26274 -``` - -### `decode` - -```swift -case decode = -26275 -``` - -### `internal` - -```swift -case `internal` = -26276 -``` - -### `unsupportedAlgorithm` - -```swift -case unsupportedAlgorithm = -26268 -``` - -### `unsupportedOperation` - -```swift -case unsupportedOperation = -26271 -``` - -### `unsupportedPadding` - -```swift -case unsupportedPadding = -26273 -``` - -### `itemInvalidKey` - -```swift -case itemInvalidKey = -34000 -``` - -### `itemInvalidKeyType` - -```swift -case itemInvalidKeyType = -34001 -``` - -### `itemInvalidValue` - -```swift -case itemInvalidValue = -34002 -``` - -### `itemClassMissing` - -```swift -case itemClassMissing = -34003 -``` - -### `itemMatchUnsupported` - -```swift -case itemMatchUnsupported = -34004 -``` - -### `useItemListUnsupported` - -```swift -case useItemListUnsupported = -34005 -``` - -### `useKeychainUnsupported` - -```swift -case useKeychainUnsupported = -34006 -``` - -### `useKeychainListUnsupported` - -```swift -case useKeychainListUnsupported = -34007 -``` - -### `returnDataUnsupported` - -```swift -case returnDataUnsupported = -34008 -``` - -### `returnAttributesUnsupported` - -```swift -case returnAttributesUnsupported = -34009 -``` - -### `returnRefUnsupported` - -```swift -case returnRefUnsupported = -34010 -``` - -### `returnPersitentRefUnsupported` - -```swift -case returnPersitentRefUnsupported = -34011 -``` - -### `valueRefUnsupported` - -```swift -case valueRefUnsupported = -34012 -``` - -### `valuePersistentRefUnsupported` - -```swift -case valuePersistentRefUnsupported = -34013 -``` - -### `returnMissingPointer` - -```swift -case returnMissingPointer = -34014 -``` - -### `matchLimitUnsupported` - -```swift -case matchLimitUnsupported = -34015 -``` - -### `itemIllegalQuery` - -```swift -case itemIllegalQuery = -34016 -``` - -### `waitForCallback` - -```swift -case waitForCallback = -34017 -``` - -### `missingEntitlement` - -```swift -case missingEntitlement = -34018 -``` - -### `upgradePending` - -```swift -case upgradePending = -34019 -``` - -### `mpSignatureInvalid` - -```swift -case mpSignatureInvalid = -25327 -``` - -### `otrTooOld` - -```swift -case otrTooOld = -25328 -``` - -### `otrIDTooNew` - -```swift -case otrIDTooNew = -25329 -``` - -### `serviceNotAvailable` - -```swift -case serviceNotAvailable = -67585 -``` - -### `insufficientClientID` - -```swift -case insufficientClientID = -67586 -``` - -### `deviceReset` - -```swift -case deviceReset = -67587 -``` - -### `deviceFailed` - -```swift -case deviceFailed = -67588 -``` - -### `appleAddAppACLSubject` - -```swift -case appleAddAppACLSubject = -67589 -``` - -### `applePublicKeyIncomplete` - -```swift -case applePublicKeyIncomplete = -67590 -``` - -### `appleSignatureMismatch` - -```swift -case appleSignatureMismatch = -67591 -``` - -### `appleInvalidKeyStartDate` - -```swift -case appleInvalidKeyStartDate = -67592 -``` - -### `appleInvalidKeyEndDate` - -```swift -case appleInvalidKeyEndDate = -67593 -``` - -### `conversionError` - -```swift -case conversionError = -67594 -``` - -### `appleSSLv2Rollback` - -```swift -case appleSSLv2Rollback = -67595 -``` - -### `quotaExceeded` - -```swift -case quotaExceeded = -67596 -``` - -### `fileTooBig` - -```swift -case fileTooBig = -67597 -``` - -### `invalidDatabaseBlob` - -```swift -case invalidDatabaseBlob = -67598 -``` - -### `invalidKeyBlob` - -```swift -case invalidKeyBlob = -67599 -``` - -### `incompatibleDatabaseBlob` - -```swift -case incompatibleDatabaseBlob = -67600 -``` - -### `incompatibleKeyBlob` - -```swift -case incompatibleKeyBlob = -67601 -``` - -### `hostNameMismatch` - -```swift -case hostNameMismatch = -67602 -``` - -### `unknownCriticalExtensionFlag` - -```swift -case unknownCriticalExtensionFlag = -67603 -``` - -### `noBasicConstraints` - -```swift -case noBasicConstraints = -67604 -``` - -### `noBasicConstraintsCA` - -```swift -case noBasicConstraintsCA = -67605 -``` - -### `invalidAuthorityKeyID` - -```swift -case invalidAuthorityKeyID = -67606 -``` - -### `invalidSubjectKeyID` - -```swift -case invalidSubjectKeyID = -67607 -``` - -### `invalidKeyUsageForPolicy` - -```swift -case invalidKeyUsageForPolicy = -67608 -``` - -### `invalidExtendedKeyUsage` - -```swift -case invalidExtendedKeyUsage = -67609 -``` - -### `invalidIDLinkage` - -```swift -case invalidIDLinkage = -67610 -``` - -### `pathLengthConstraintExceeded` - -```swift -case pathLengthConstraintExceeded = -67611 -``` - -### `invalidRoot` - -```swift -case invalidRoot = -67612 -``` - -### `crlExpired` - -```swift -case crlExpired = -67613 -``` - -### `crlNotValidYet` - -```swift -case crlNotValidYet = -67614 -``` - -### `crlNotFound` - -```swift -case crlNotFound = -67615 -``` - -### `crlServerDown` - -```swift -case crlServerDown = -67616 -``` - -### `crlBadURI` - -```swift -case crlBadURI = -67617 -``` - -### `unknownCertExtension` - -```swift -case unknownCertExtension = -67618 -``` - -### `unknownCRLExtension` - -```swift -case unknownCRLExtension = -67619 -``` - -### `crlNotTrusted` - -```swift -case crlNotTrusted = -67620 -``` - -### `crlPolicyFailed` - -```swift -case crlPolicyFailed = -67621 -``` - -### `idpFailure` - -```swift -case idpFailure = -67622 -``` - -### `smimeEmailAddressesNotFound` - -```swift -case smimeEmailAddressesNotFound = -67623 -``` - -### `smimeBadExtendedKeyUsage` - -```swift -case smimeBadExtendedKeyUsage = -67624 -``` - -### `smimeBadKeyUsage` - -```swift -case smimeBadKeyUsage = -67625 -``` - -### `smimeKeyUsageNotCritical` - -```swift -case smimeKeyUsageNotCritical = -67626 -``` - -### `smimeNoEmailAddress` - -```swift -case smimeNoEmailAddress = -67627 -``` - -### `smimeSubjAltNameNotCritical` - -```swift -case smimeSubjAltNameNotCritical = -67628 -``` - -### `sslBadExtendedKeyUsage` - -```swift -case sslBadExtendedKeyUsage = -67629 -``` - -### `ocspBadResponse` - -```swift -case ocspBadResponse = -67630 -``` - -### `ocspBadRequest` - -```swift -case ocspBadRequest = -67631 -``` - -### `ocspUnavailable` - -```swift -case ocspUnavailable = -67632 -``` - -### `ocspStatusUnrecognized` - -```swift -case ocspStatusUnrecognized = -67633 -``` - -### `endOfData` - -```swift -case endOfData = -67634 -``` - -### `incompleteCertRevocationCheck` - -```swift -case incompleteCertRevocationCheck = -67635 -``` - -### `networkFailure` - -```swift -case networkFailure = -67636 -``` - -### `ocspNotTrustedToAnchor` - -```swift -case ocspNotTrustedToAnchor = -67637 -``` - -### `recordModified` - -```swift -case recordModified = -67638 -``` - -### `ocspSignatureError` - -```swift -case ocspSignatureError = -67639 -``` - -### `ocspNoSigner` - -```swift -case ocspNoSigner = -67640 -``` - -### `ocspResponderMalformedReq` - -```swift -case ocspResponderMalformedReq = -67641 -``` - -### `ocspResponderInternalError` - -```swift -case ocspResponderInternalError = -67642 -``` - -### `ocspResponderTryLater` - -```swift -case ocspResponderTryLater = -67643 -``` - -### `ocspResponderSignatureRequired` - -```swift -case ocspResponderSignatureRequired = -67644 -``` - -### `ocspResponderUnauthorized` - -```swift -case ocspResponderUnauthorized = -67645 -``` - -### `ocspResponseNonceMismatch` - -```swift -case ocspResponseNonceMismatch = -67646 -``` - -### `codeSigningBadCertChainLength` - -```swift -case codeSigningBadCertChainLength = -67647 -``` - -### `codeSigningNoBasicConstraints` - -```swift -case codeSigningNoBasicConstraints = -67648 -``` - -### `codeSigningBadPathLengthConstraint` - -```swift -case codeSigningBadPathLengthConstraint = -67649 -``` - -### `codeSigningNoExtendedKeyUsage` - -```swift -case codeSigningNoExtendedKeyUsage = -67650 -``` - -### `codeSigningDevelopment` - -```swift -case codeSigningDevelopment = -67651 -``` - -### `resourceSignBadCertChainLength` - -```swift -case resourceSignBadCertChainLength = -67652 -``` - -### `resourceSignBadExtKeyUsage` - -```swift -case resourceSignBadExtKeyUsage = -67653 -``` - -### `trustSettingDeny` - -```swift -case trustSettingDeny = -67654 -``` - -### `invalidSubjectName` - -```swift -case invalidSubjectName = -67655 -``` - -### `unknownQualifiedCertStatement` - -```swift -case unknownQualifiedCertStatement = -67656 -``` - -### `mobileMeRequestQueued` - -```swift -case mobileMeRequestQueued = -67657 -``` - -### `mobileMeRequestRedirected` - -```swift -case mobileMeRequestRedirected = -67658 -``` - -### `mobileMeServerError` - -```swift -case mobileMeServerError = -67659 -``` - -### `mobileMeServerNotAvailable` - -```swift -case mobileMeServerNotAvailable = -67660 -``` - -### `mobileMeServerAlreadyExists` - -```swift -case mobileMeServerAlreadyExists = -67661 -``` - -### `mobileMeServerServiceErr` - -```swift -case mobileMeServerServiceErr = -67662 -``` - -### `mobileMeRequestAlreadyPending` - -```swift -case mobileMeRequestAlreadyPending = -67663 -``` - -### `mobileMeNoRequestPending` - -```swift -case mobileMeNoRequestPending = -67664 -``` - -### `mobileMeCSRVerifyFailure` - -```swift -case mobileMeCSRVerifyFailure = -67665 -``` - -### `mobileMeFailedConsistencyCheck` - -```swift -case mobileMeFailedConsistencyCheck = -67666 -``` - -### `notInitialized` - -```swift -case notInitialized = -67667 -``` - -### `invalidHandleUsage` - -```swift -case invalidHandleUsage = -67668 -``` - -### `pvcReferentNotFound` - -```swift -case pvcReferentNotFound = -67669 -``` - -### `functionIntegrityFail` - -```swift -case functionIntegrityFail = -67670 -``` - -### `internalError` - -```swift -case internalError = -67671 -``` - -### `memoryError` - -```swift -case memoryError = -67672 -``` - -### `invalidData` - -```swift -case invalidData = -67673 -``` - -### `mdsError` - -```swift -case mdsError = -67674 -``` - -### `invalidPointer` - -```swift -case invalidPointer = -67675 -``` - -### `selfCheckFailed` - -```swift -case selfCheckFailed = -67676 -``` - -### `functionFailed` - -```swift -case functionFailed = -67677 -``` - -### `moduleManifestVerifyFailed` - -```swift -case moduleManifestVerifyFailed = -67678 -``` - -### `invalidGUID` - -```swift -case invalidGUID = -67679 -``` - -### `invalidHandle` - -```swift -case invalidHandle = -67680 -``` - -### `invalidDBList` - -```swift -case invalidDBList = -67681 -``` - -### `invalidPassthroughID` - -```swift -case invalidPassthroughID = -67682 -``` - -### `invalidNetworkAddress` - -```swift -case invalidNetworkAddress = -67683 -``` - -### `crlAlreadySigned` - -```swift -case crlAlreadySigned = -67684 -``` - -### `invalidNumberOfFields` - -```swift -case invalidNumberOfFields = -67685 -``` - -### `verificationFailure` - -```swift -case verificationFailure = -67686 -``` - -### `unknownTag` - -```swift -case unknownTag = -67687 -``` - -### `invalidSignature` - -```swift -case invalidSignature = -67688 -``` - -### `invalidName` - -```swift -case invalidName = -67689 -``` - -### `invalidCertificateRef` - -```swift -case invalidCertificateRef = -67690 -``` - -### `invalidCertificateGroup` - -```swift -case invalidCertificateGroup = -67691 -``` - -### `tagNotFound` - -```swift -case tagNotFound = -67692 -``` - -### `invalidQuery` - -```swift -case invalidQuery = -67693 -``` - -### `invalidValue` - -```swift -case invalidValue = -67694 -``` - -### `callbackFailed` - -```swift -case callbackFailed = -67695 -``` - -### `aclDeleteFailed` - -```swift -case aclDeleteFailed = -67696 -``` - -### `aclReplaceFailed` - -```swift -case aclReplaceFailed = -67697 -``` - -### `aclAddFailed` - -```swift -case aclAddFailed = -67698 -``` - -### `aclChangeFailed` - -```swift -case aclChangeFailed = -67699 -``` - -### `invalidAccessCredentials` - -```swift -case invalidAccessCredentials = -67700 -``` - -### `invalidRecord` - -```swift -case invalidRecord = -67701 -``` - -### `invalidACL` - -```swift -case invalidACL = -67702 -``` - -### `invalidSampleValue` - -```swift -case invalidSampleValue = -67703 -``` - -### `incompatibleVersion` - -```swift -case incompatibleVersion = -67704 -``` - -### `privilegeNotGranted` - -```swift -case privilegeNotGranted = -67705 -``` - -### `invalidScope` - -```swift -case invalidScope = -67706 -``` - -### `pvcAlreadyConfigured` - -```swift -case pvcAlreadyConfigured = -67707 -``` - -### `invalidPVC` - -```swift -case invalidPVC = -67708 -``` - -### `emmLoadFailed` - -```swift -case emmLoadFailed = -67709 -``` - -### `emmUnloadFailed` - -```swift -case emmUnloadFailed = -67710 -``` - -### `addinLoadFailed` - -```swift -case addinLoadFailed = -67711 -``` - -### `invalidKeyRef` - -```swift -case invalidKeyRef = -67712 -``` - -### `invalidKeyHierarchy` - -```swift -case invalidKeyHierarchy = -67713 -``` - -### `addinUnloadFailed` - -```swift -case addinUnloadFailed = -67714 -``` - -### `libraryReferenceNotFound` - -```swift -case libraryReferenceNotFound = -67715 -``` - -### `invalidAddinFunctionTable` - -```swift -case invalidAddinFunctionTable = -67716 -``` - -### `invalidServiceMask` - -```swift -case invalidServiceMask = -67717 -``` - -### `moduleNotLoaded` - -```swift -case moduleNotLoaded = -67718 -``` - -### `invalidSubServiceID` - -```swift -case invalidSubServiceID = -67719 -``` - -### `attributeNotInContext` - -```swift -case attributeNotInContext = -67720 -``` - -### `moduleManagerInitializeFailed` - -```swift -case moduleManagerInitializeFailed = -67721 -``` - -### `moduleManagerNotFound` - -```swift -case moduleManagerNotFound = -67722 -``` - -### `eventNotificationCallbackNotFound` - -```swift -case eventNotificationCallbackNotFound = -67723 -``` - -### `inputLengthError` - -```swift -case inputLengthError = -67724 -``` - -### `outputLengthError` - -```swift -case outputLengthError = -67725 -``` - -### `privilegeNotSupported` - -```swift -case privilegeNotSupported = -67726 -``` - -### `deviceError` - -```swift -case deviceError = -67727 -``` - -### `attachHandleBusy` - -```swift -case attachHandleBusy = -67728 -``` - -### `notLoggedIn` - -```swift -case notLoggedIn = -67729 -``` - -### `algorithmMismatch` - -```swift -case algorithmMismatch = -67730 -``` - -### `keyUsageIncorrect` - -```swift -case keyUsageIncorrect = -67731 -``` - -### `keyBlobTypeIncorrect` - -```swift -case keyBlobTypeIncorrect = -67732 -``` - -### `keyHeaderInconsistent` - -```swift -case keyHeaderInconsistent = -67733 -``` - -### `unsupportedKeyFormat` - -```swift -case unsupportedKeyFormat = -67734 -``` - -### `unsupportedKeySize` - -```swift -case unsupportedKeySize = -67735 -``` - -### `invalidKeyUsageMask` - -```swift -case invalidKeyUsageMask = -67736 -``` - -### `unsupportedKeyUsageMask` - -```swift -case unsupportedKeyUsageMask = -67737 -``` - -### `invalidKeyAttributeMask` - -```swift -case invalidKeyAttributeMask = -67738 -``` - -### `unsupportedKeyAttributeMask` - -```swift -case unsupportedKeyAttributeMask = -67739 -``` - -### `invalidKeyLabel` - -```swift -case invalidKeyLabel = -67740 -``` - -### `unsupportedKeyLabel` - -```swift -case unsupportedKeyLabel = -67741 -``` - -### `invalidKeyFormat` - -```swift -case invalidKeyFormat = -67742 -``` - -### `unsupportedVectorOfBuffers` - -```swift -case unsupportedVectorOfBuffers = -67743 -``` - -### `invalidInputVector` - -```swift -case invalidInputVector = -67744 -``` - -### `invalidOutputVector` - -```swift -case invalidOutputVector = -67745 -``` - -### `invalidContext` - -```swift -case invalidContext = -67746 -``` - -### `invalidAlgorithm` - -```swift -case invalidAlgorithm = -67747 -``` - -### `invalidAttributeKey` - -```swift -case invalidAttributeKey = -67748 -``` - -### `missingAttributeKey` - -```swift -case missingAttributeKey = -67749 -``` - -### `invalidAttributeInitVector` - -```swift -case invalidAttributeInitVector = -67750 -``` - -### `missingAttributeInitVector` - -```swift -case missingAttributeInitVector = -67751 -``` - -### `invalidAttributeSalt` - -```swift -case invalidAttributeSalt = -67752 -``` - -### `missingAttributeSalt` - -```swift -case missingAttributeSalt = -67753 -``` - -### `invalidAttributePadding` - -```swift -case invalidAttributePadding = -67754 -``` - -### `missingAttributePadding` - -```swift -case missingAttributePadding = -67755 -``` - -### `invalidAttributeRandom` - -```swift -case invalidAttributeRandom = -67756 -``` - -### `missingAttributeRandom` - -```swift -case missingAttributeRandom = -67757 -``` - -### `invalidAttributeSeed` - -```swift -case invalidAttributeSeed = -67758 -``` - -### `missingAttributeSeed` - -```swift -case missingAttributeSeed = -67759 -``` - -### `invalidAttributePassphrase` - -```swift -case invalidAttributePassphrase = -67760 -``` - -### `missingAttributePassphrase` - -```swift -case missingAttributePassphrase = -67761 -``` - -### `invalidAttributeKeyLength` - -```swift -case invalidAttributeKeyLength = -67762 -``` - -### `missingAttributeKeyLength` - -```swift -case missingAttributeKeyLength = -67763 -``` - -### `invalidAttributeBlockSize` - -```swift -case invalidAttributeBlockSize = -67764 -``` - -### `missingAttributeBlockSize` - -```swift -case missingAttributeBlockSize = -67765 -``` - -### `invalidAttributeOutputSize` - -```swift -case invalidAttributeOutputSize = -67766 -``` - -### `missingAttributeOutputSize` - -```swift -case missingAttributeOutputSize = -67767 -``` - -### `invalidAttributeRounds` - -```swift -case invalidAttributeRounds = -67768 -``` - -### `missingAttributeRounds` - -```swift -case missingAttributeRounds = -67769 -``` - -### `invalidAlgorithmParms` - -```swift -case invalidAlgorithmParms = -67770 -``` - -### `missingAlgorithmParms` - -```swift -case missingAlgorithmParms = -67771 -``` - -### `invalidAttributeLabel` - -```swift -case invalidAttributeLabel = -67772 -``` - -### `missingAttributeLabel` - -```swift -case missingAttributeLabel = -67773 -``` - -### `invalidAttributeKeyType` - -```swift -case invalidAttributeKeyType = -67774 -``` - -### `missingAttributeKeyType` - -```swift -case missingAttributeKeyType = -67775 -``` - -### `invalidAttributeMode` - -```swift -case invalidAttributeMode = -67776 -``` - -### `missingAttributeMode` - -```swift -case missingAttributeMode = -67777 -``` - -### `invalidAttributeEffectiveBits` - -```swift -case invalidAttributeEffectiveBits = -67778 -``` - -### `missingAttributeEffectiveBits` - -```swift -case missingAttributeEffectiveBits = -67779 -``` - -### `invalidAttributeStartDate` - -```swift -case invalidAttributeStartDate = -67780 -``` - -### `missingAttributeStartDate` - -```swift -case missingAttributeStartDate = -67781 -``` - -### `invalidAttributeEndDate` - -```swift -case invalidAttributeEndDate = -67782 -``` - -### `missingAttributeEndDate` - -```swift -case missingAttributeEndDate = -67783 -``` - -### `invalidAttributeVersion` - -```swift -case invalidAttributeVersion = -67784 -``` - -### `missingAttributeVersion` - -```swift -case missingAttributeVersion = -67785 -``` - -### `invalidAttributePrime` - -```swift -case invalidAttributePrime = -67786 -``` - -### `missingAttributePrime` - -```swift -case missingAttributePrime = -67787 -``` - -### `invalidAttributeBase` - -```swift -case invalidAttributeBase = -67788 -``` - -### `missingAttributeBase` - -```swift -case missingAttributeBase = -67789 -``` - -### `invalidAttributeSubprime` - -```swift -case invalidAttributeSubprime = -67790 -``` - -### `missingAttributeSubprime` - -```swift -case missingAttributeSubprime = -67791 -``` - -### `invalidAttributeIterationCount` - -```swift -case invalidAttributeIterationCount = -67792 -``` - -### `missingAttributeIterationCount` - -```swift -case missingAttributeIterationCount = -67793 -``` - -### `invalidAttributeDLDBHandle` - -```swift -case invalidAttributeDLDBHandle = -67794 -``` - -### `missingAttributeDLDBHandle` - -```swift -case missingAttributeDLDBHandle = -67795 -``` - -### `invalidAttributeAccessCredentials` - -```swift -case invalidAttributeAccessCredentials = -67796 -``` - -### `missingAttributeAccessCredentials` - -```swift -case missingAttributeAccessCredentials = -67797 -``` - -### `invalidAttributePublicKeyFormat` - -```swift -case invalidAttributePublicKeyFormat = -67798 -``` - -### `missingAttributePublicKeyFormat` - -```swift -case missingAttributePublicKeyFormat = -67799 -``` - -### `invalidAttributePrivateKeyFormat` - -```swift -case invalidAttributePrivateKeyFormat = -67800 -``` - -### `missingAttributePrivateKeyFormat` - -```swift -case missingAttributePrivateKeyFormat = -67801 -``` - -### `invalidAttributeSymmetricKeyFormat` - -```swift -case invalidAttributeSymmetricKeyFormat = -67802 -``` - -### `missingAttributeSymmetricKeyFormat` - -```swift -case missingAttributeSymmetricKeyFormat = -67803 -``` - -### `invalidAttributeWrappedKeyFormat` - -```swift -case invalidAttributeWrappedKeyFormat = -67804 -``` - -### `missingAttributeWrappedKeyFormat` - -```swift -case missingAttributeWrappedKeyFormat = -67805 -``` - -### `stagedOperationInProgress` - -```swift -case stagedOperationInProgress = -67806 -``` - -### `stagedOperationNotStarted` - -```swift -case stagedOperationNotStarted = -67807 -``` - -### `verifyFailed` - -```swift -case verifyFailed = -67808 -``` - -### `querySizeUnknown` - -```swift -case querySizeUnknown = -67809 -``` - -### `blockSizeMismatch` - -```swift -case blockSizeMismatch = -67810 -``` - -### `publicKeyInconsistent` - -```swift -case publicKeyInconsistent = -67811 -``` - -### `deviceVerifyFailed` - -```swift -case deviceVerifyFailed = -67812 -``` - -### `invalidLoginName` - -```swift -case invalidLoginName = -67813 -``` - -### `alreadyLoggedIn` - -```swift -case alreadyLoggedIn = -67814 -``` - -### `invalidDigestAlgorithm` - -```swift -case invalidDigestAlgorithm = -67815 -``` - -### `invalidCRLGroup` - -```swift -case invalidCRLGroup = -67816 -``` - -### `certificateCannotOperate` - -```swift -case certificateCannotOperate = -67817 -``` - -### `certificateExpired` - -```swift -case certificateExpired = -67818 -``` - -### `certificateNotValidYet` - -```swift -case certificateNotValidYet = -67819 -``` - -### `certificateRevoked` - -```swift -case certificateRevoked = -67820 -``` - -### `certificateSuspended` - -```swift -case certificateSuspended = -67821 -``` - -### `insufficientCredentials` - -```swift -case insufficientCredentials = -67822 -``` - -### `invalidAction` - -```swift -case invalidAction = -67823 -``` - -### `invalidAuthority` - -```swift -case invalidAuthority = -67824 -``` - -### `verifyActionFailed` - -```swift -case verifyActionFailed = -67825 -``` - -### `invalidCertAuthority` - -```swift -case invalidCertAuthority = -67826 -``` - -### `invaldCRLAuthority` - -```swift -case invaldCRLAuthority = -67827 -``` - -### `invalidCRLEncoding` - -```swift -case invalidCRLEncoding = -67828 -``` - -### `invalidCRLType` - -```swift -case invalidCRLType = -67829 -``` - -### `invalidCRL` - -```swift -case invalidCRL = -67830 -``` - -### `invalidFormType` - -```swift -case invalidFormType = -67831 -``` - -### `invalidID` - -```swift -case invalidID = -67832 -``` - -### `invalidIdentifier` - -```swift -case invalidIdentifier = -67833 -``` - -### `invalidIndex` - -```swift -case invalidIndex = -67834 -``` - -### `invalidPolicyIdentifiers` - -```swift -case invalidPolicyIdentifiers = -67835 -``` - -### `invalidTimeString` - -```swift -case invalidTimeString = -67836 -``` - -### `invalidReason` - -```swift -case invalidReason = -67837 -``` - -### `invalidRequestInputs` - -```swift -case invalidRequestInputs = -67838 -``` - -### `invalidResponseVector` - -```swift -case invalidResponseVector = -67839 -``` - -### `invalidStopOnPolicy` - -```swift -case invalidStopOnPolicy = -67840 -``` - -### `invalidTuple` - -```swift -case invalidTuple = -67841 -``` - -### `multipleValuesUnsupported` - -```swift -case multipleValuesUnsupported = -67842 -``` - -### `notTrusted` - -```swift -case notTrusted = -67843 -``` - -### `noDefaultAuthority` - -```swift -case noDefaultAuthority = -67844 -``` - -### `rejectedForm` - -```swift -case rejectedForm = -67845 -``` - -### `requestLost` - -```swift -case requestLost = -67846 -``` - -### `requestRejected` - -```swift -case requestRejected = -67847 -``` - -### `unsupportedAddressType` - -```swift -case unsupportedAddressType = -67848 -``` - -### `unsupportedService` - -```swift -case unsupportedService = -67849 -``` - -### `invalidTupleGroup` - -```swift -case invalidTupleGroup = -67850 -``` - -### `invalidBaseACLs` - -```swift -case invalidBaseACLs = -67851 -``` - -### `invalidTupleCredendtials` - -```swift -case invalidTupleCredendtials = -67852 -``` - -### `invalidEncoding` - -```swift -case invalidEncoding = -67853 -``` - -### `invalidValidityPeriod` - -```swift -case invalidValidityPeriod = -67854 -``` - -### `invalidRequestor` - -```swift -case invalidRequestor = -67855 -``` - -### `requestDescriptor` - -```swift -case requestDescriptor = -67856 -``` - -### `invalidBundleInfo` - -```swift -case invalidBundleInfo = -67857 -``` - -### `invalidCRLIndex` - -```swift -case invalidCRLIndex = -67858 -``` - -### `noFieldValues` - -```swift -case noFieldValues = -67859 -``` - -### `unsupportedFieldFormat` - -```swift -case unsupportedFieldFormat = -67860 -``` - -### `unsupportedIndexInfo` - -```swift -case unsupportedIndexInfo = -67861 -``` - -### `unsupportedLocality` - -```swift -case unsupportedLocality = -67862 -``` - -### `unsupportedNumAttributes` - -```swift -case unsupportedNumAttributes = -67863 -``` - -### `unsupportedNumIndexes` - -```swift -case unsupportedNumIndexes = -67864 -``` - -### `unsupportedNumRecordTypes` - -```swift -case unsupportedNumRecordTypes = -67865 -``` - -### `fieldSpecifiedMultiple` - -```swift -case fieldSpecifiedMultiple = -67866 -``` - -### `incompatibleFieldFormat` - -```swift -case incompatibleFieldFormat = -67867 -``` - -### `invalidParsingModule` - -```swift -case invalidParsingModule = -67868 -``` - -### `databaseLocked` - -```swift -case databaseLocked = -67869 -``` - -### `datastoreIsOpen` - -```swift -case datastoreIsOpen = -67870 -``` - -### `missingValue` - -```swift -case missingValue = -67871 -``` - -### `unsupportedQueryLimits` - -```swift -case unsupportedQueryLimits = -67872 -``` - -### `unsupportedNumSelectionPreds` - -```swift -case unsupportedNumSelectionPreds = -67873 -``` - -### `unsupportedOperator` - -```swift -case unsupportedOperator = -67874 -``` - -### `invalidDBLocation` - -```swift -case invalidDBLocation = -67875 -``` - -### `invalidAccessRequest` - -```swift -case invalidAccessRequest = -67876 -``` - -### `invalidIndexInfo` - -```swift -case invalidIndexInfo = -67877 -``` - -### `invalidNewOwner` - -```swift -case invalidNewOwner = -67878 -``` - -### `invalidModifyMode` - -```swift -case invalidModifyMode = -67879 -``` - -### `missingRequiredExtension` - -```swift -case missingRequiredExtension = -67880 -``` - -### `extendedKeyUsageNotCritical` - -```swift -case extendedKeyUsageNotCritical = -67881 -``` - -### `timestampMissing` - -```swift -case timestampMissing = -67882 -``` - -### `timestampInvalid` - -```swift -case timestampInvalid = -67883 -``` - -### `timestampNotTrusted` - -```swift -case timestampNotTrusted = -67884 -``` - -### `timestampServiceNotAvailable` - -```swift -case timestampServiceNotAvailable = -67885 -``` - -### `timestampBadAlg` - -```swift -case timestampBadAlg = -67886 -``` - -### `timestampBadRequest` - -```swift -case timestampBadRequest = -67887 -``` - -### `timestampBadDataFormat` - -```swift -case timestampBadDataFormat = -67888 -``` - -### `timestampTimeNotAvailable` - -```swift -case timestampTimeNotAvailable = -67889 -``` - -### `timestampUnacceptedPolicy` - -```swift -case timestampUnacceptedPolicy = -67890 -``` - -### `timestampUnacceptedExtension` - -```swift -case timestampUnacceptedExtension = -67891 -``` - -### `timestampAddInfoNotAvailable` - -```swift -case timestampAddInfoNotAvailable = -67892 -``` - -### `timestampSystemFailure` - -```swift -case timestampSystemFailure = -67893 -``` - -### `signingTimeMissing` - -```swift -case signingTimeMissing = -67894 -``` - -### `timestampRejection` - -```swift -case timestampRejection = -67895 -``` - -### `timestampWaiting` - -```swift -case timestampWaiting = -67896 -``` - -### `timestampRevocationWarning` - -```swift -case timestampRevocationWarning = -67897 -``` - -### `timestampRevocationNotification` - -```swift -case timestampRevocationNotification = -67898 -``` - -### `unexpectedError` - -```swift -case unexpectedError = -99999 -``` diff --git a/Documentation/Reference/extensions/CelyStorageError.md b/Documentation/Reference/extensions/CelyStorageError.md deleted file mode 100644 index 44aa92f..0000000 --- a/Documentation/Reference/extensions/CelyStorageError.md +++ /dev/null @@ -1,29 +0,0 @@ -**EXTENSION** - -# `CelyStorageError` - -## Properties -### `description` - -```swift -public var description: String -``` - -### `errorCode` - -```swift -public var errorCode: Int -``` - -### `errorUserInfo` - -```swift -public var errorUserInfo: [String: Any] -``` - -## Methods -### `init(status:)` - -```swift -public init(status: OSStatus) -``` diff --git a/Documentation/Reference/extensions/CelyStyle.md b/Documentation/Reference/extensions/CelyStyle.md deleted file mode 100644 index 8767895..0000000 --- a/Documentation/Reference/extensions/CelyStyle.md +++ /dev/null @@ -1,54 +0,0 @@ -**EXTENSION** - -# `CelyStyle` - -## Methods -### `backgroundColor()` - -```swift -func backgroundColor() -> UIColor -``` - -> Background Color for default login screen -> -> - returns: UIColor - -### `textFieldBackgroundColor()` - -```swift -func textFieldBackgroundColor() -> UIColor -``` - -> Background Color for textfields -> -> - returns: UIColor - -### `buttonBackgroundColor()` - -```swift -func buttonBackgroundColor() -> UIColor -``` - -> Background Color for login button -> -> - returns: UIColor - -### `buttonTextColor()` - -```swift -func buttonTextColor() -> UIColor -``` - -> Text Color for login button -> -> - returns: UIColor - -### `appLogo()` - -```swift -func appLogo() -> UIImage? -``` - -> App icon for default login screen -> -> - returns: UIImage? diff --git a/Documentation/Reference/extensions/UIWindow.md b/Documentation/Reference/extensions/UIWindow.md deleted file mode 100644 index b6f2108..0000000 --- a/Documentation/Reference/extensions/UIWindow.md +++ /dev/null @@ -1,10 +0,0 @@ -**EXTENSION** - -# `UIWindow` - -## Methods -### `setCurrentViewController(to:)` - -```swift -func setCurrentViewController(to viewController: UIViewController?) -``` diff --git a/Documentation/Reference/protocols/CelyAnimator.md b/Documentation/Reference/protocols/CelyAnimator.md deleted file mode 100644 index d1072ce..0000000 --- a/Documentation/Reference/protocols/CelyAnimator.md +++ /dev/null @@ -1,22 +0,0 @@ -**PROTOCOL** - -# `CelyAnimator` - -```swift -public protocol CelyAnimator -``` - -> Handles Animations between Home and Login ViewControllers - -## Methods -### `loginTransition(to:with:)` - -```swift -func loginTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) -``` - -### `logoutTransition(to:with:)` - -```swift -func logoutTransition(to destinationVC: UIViewController?, with celyWindow: UIWindow) -``` diff --git a/Documentation/Reference/protocols/CelyStorageProtocol.md b/Documentation/Reference/protocols/CelyStorageProtocol.md deleted file mode 100644 index 73fcbfd..0000000 --- a/Documentation/Reference/protocols/CelyStorageProtocol.md +++ /dev/null @@ -1,28 +0,0 @@ -**PROTOCOL** - -# `CelyStorageProtocol` - -```swift -public protocol CelyStorageProtocol -``` - -> Protocol a storage class must abide by in order for Cely to use it - -## Methods -### `set(_:forKey:securely:persisted:)` - -```swift -func set(_ value: Any?, forKey key: String, securely secure: Bool, persisted persist: Bool) throws -``` - -### `get(_:)` - -```swift -func get(_ key: String) -> Any? -``` - -### `clearStorage()` - -```swift -func clearStorage() throws -``` diff --git a/Documentation/Reference/protocols/CelyStyle.md b/Documentation/Reference/protocols/CelyStyle.md deleted file mode 100644 index 592e671..0000000 --- a/Documentation/Reference/protocols/CelyStyle.md +++ /dev/null @@ -1,40 +0,0 @@ -**PROTOCOL** - -# `CelyStyle` - -```swift -public protocol CelyStyle -``` - -> Protocol that allows styles to be applied to Cely's default LoginViewController - -## Methods -### `backgroundColor()` - -```swift -func backgroundColor() -> UIColor -``` - -### `textFieldBackgroundColor()` - -```swift -func textFieldBackgroundColor() -> UIColor -``` - -### `buttonBackgroundColor()` - -```swift -func buttonBackgroundColor() -> UIColor -``` - -### `buttonTextColor()` - -```swift -func buttonTextColor() -> UIColor -``` - -### `appLogo()` - -```swift -func appLogo() -> UIImage? -``` diff --git a/Documentation/Reference/protocols/CelyUser.md b/Documentation/Reference/protocols/CelyUser.md deleted file mode 100644 index 605f533..0000000 --- a/Documentation/Reference/protocols/CelyUser.md +++ /dev/null @@ -1,9 +0,0 @@ -**PROTOCOL** - -# `CelyUser` - -```swift -public protocol CelyUser -``` - -> Protocol for model class to implements diff --git a/Documentation/Reference/structs/Cely.md b/Documentation/Reference/structs/Cely.md deleted file mode 100644 index e7f6447..0000000 --- a/Documentation/Reference/structs/Cely.md +++ /dev/null @@ -1,137 +0,0 @@ -**STRUCT** - -# `Cely` - -```swift -public struct Cely -``` - -## Methods -### `setup(with:forModel:requiredProperties:withOptions:)` - -```swift -public static func setup(with window: UIWindow?, forModel _: T, requiredProperties: [U] = [], withOptions options: [CelyOptions: Any?]? = [:]) where T.Property == U -``` - -> Sets up Cely within your application -> -> - parameter window: `UIWindow` of your application. -> - parameter forModel: The `Model` Cely will be storing. -> - parameter requiredProperties: `[CelyProperty]`: The properties that cely tests against to determine if a user is logged in. -> - parameter withOptions: Dictionary of options to pass into cely upon setup. Please refer to `CelyOptions` to view all options. - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| window | `UIWindow` of your application. | -| forModel | The `Model` Cely will be storing. | -| requiredProperties | `[CelyProperty]`: The properties that cely tests against to determine if a user is logged in. | -| withOptions | Dictionary of options to pass into cely upon setup. Please refer to `CelyOptions` to view all options. | - -### `currentLoginStatus(requiredProperties:fromStorage:)` - -```swift -public static func currentLoginStatus(requiredProperties properties: [CelyProperty] = requiredProperties, fromStorage store: CelyStorageProtocol = store) -> CelyStatus -``` - -> Will return the `CelyStatus` of the current user. -> - Parameters: -> - properties: Array of required properties that need to be in store. -> - store: Storage `Cely` will be using. Defaulted to `Storage` -> - returns: `CelyStatus`. If `requiredProperties` are all in store, it will return `.LoggedIn`, else `.LoggedOut` - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| properties | Array of required properties that need to be in store. | -| store | Storage `Cely` will be using. Defaulted to `Storage` | - -### `get(key:fromStorage:)` - -```swift -public static func get(key: String, fromStorage store: CelyStorageProtocol = store) -> Any? -``` - -> Returns stored data for key. -> -> - parameter key: String -> - parameter store: Object that conforms to the CelyStorageProtocol protocol that `Cely` will be using. Defaulted to `Cely`'s instance of store -> -> - returns: Returns data as an optional `Any` - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| key | String | -| store | Object that conforms to the CelyStorageProtocol protocol that `Cely` will be using. Defaulted to `Cely`’s instance of store | - -### `save(_:forKey:toStorage:securely:persisted:)` - -```swift -public static func save(_ value: Any?, forKey key: String, toStorage store: CelyStorageProtocol = store, securely secure: Bool = false, persisted persist: Bool = false) -> Result -``` - -> Saves data in store -> -> - parameter value: data you want to save -> - parameter key: String for the key -> - parameter store: Storage `Cely` will be using. Defaulted to `Storage` -> - parameter secure: `Boolean`: Store data securely -> - parameter persist: `Boolean`: Keep data after logout -> -> - returns: `Boolean`: Whether or not your value was successfully set. - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| value | data you want to save | -| key | String for the key | -| store | Storage `Cely` will be using. Defaulted to `Storage` | -| secure | `Boolean`: Store data securely | -| persist | `Boolean`: Keep data after logout | - -### `changeStatus(to:)` - -```swift -public static func changeStatus(to status: CelyStatus) -``` - -> Perform action like `LoggedIn` or `LoggedOut` -> -> - parameter status: CelyStatus - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| status | CelyStatus | - -### `logout(useStorage:)` - -```swift -public static func logout(useStorage store: CelyStorageProtocol = store) -> Result -``` - -> Log user out -> -> - parameter store: Storage `Cely` will be using. Defaulted to `CelyStorageProtocol` - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| store | Storage `Cely` will be using. Defaulted to `CelyStorageProtocol` | - -### `isLoggedIn()` - -```swift -public static func isLoggedIn() -> Bool -``` - -> Returns whether or not the user is logged in -> -> - returns: `Boolean` diff --git a/Documentation/Reference/structs/CelyCredentialStore.md b/Documentation/Reference/structs/CelyCredentialStore.md deleted file mode 100644 index cc6e518..0000000 --- a/Documentation/Reference/structs/CelyCredentialStore.md +++ /dev/null @@ -1,40 +0,0 @@ -**STRUCT** - -# `CelyCredentialStore` - -```swift -public struct CelyCredentialStore -``` - -> CelyCredentialStore - object that stores user credentials - -## Methods -### `set(username:password:server:accessibility:)` - -```swift -public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result -``` - -> Set user credentials -> - Parameters: -> - username: username for user -> - password: password for user -> - server: api uri for account -> - accessibility: Array of AccessibilityOptions for credentials to be saved with - -#### Parameters - -| Name | Description | -| ---- | ----------- | -| username | username for user | -| password | password for user | -| server | api uri for account | -| accessibility | Array of AccessibilityOptions for credentials to be saved with | - -### `get()` - -```swift -public func get() -> Result -``` - -> Return credentials diff --git a/Documentation/Reference/structs/CelyCredentials.md b/Documentation/Reference/structs/CelyCredentials.md deleted file mode 100644 index e30da1f..0000000 --- a/Documentation/Reference/structs/CelyCredentials.md +++ /dev/null @@ -1,26 +0,0 @@ -**STRUCT** - -# `CelyCredentials` - -```swift -public struct CelyCredentials -``` - -## Properties -### `username` - -```swift -public let username: String -``` - -### `password` - -```swift -public let password: String -``` - -### `server` - -```swift -public let server: String -``` diff --git a/Sources/Core/CelyConstants.swift b/Sources/Core/CelyConstants.swift index 6cce27a..acd05cf 100644 --- a/Sources/Core/CelyConstants.swift +++ b/Sources/Core/CelyConstants.swift @@ -23,6 +23,10 @@ public enum CelyStatus: CelyCommands { /// Options that you can pass into Cely on `Cely.setup(_:)` public enum CelyOptions { case storage + @available(*, deprecated, renamed: "homeViewController", message: "We will no longer support UIStoryboard as a way to instantiate ViewControllers.") + case homeStoryboard + @available(*, deprecated, renamed: "loginViewController", message: "We will no longer support UIStoryboard as a way to instantiate ViewControllers.") + case loginStoryboard case homeViewController case loginViewController case loginCompletionBlock diff --git a/Sources/Core/Storage/KeychainObject.swift b/Sources/Core/Storage/KeychainObject.swift index 80f1c59..f0f2aa1 100644 --- a/Sources/Core/Storage/KeychainObject.swift +++ b/Sources/Core/Storage/KeychainObject.swift @@ -74,7 +74,6 @@ struct KeychainObject { } if accessibilityOptions.contains(.biometricsIfPossible) { - // TODO: what happens if application doesnt have biometrics setup? does it error let accessibility = getAccessibility() var error: Unmanaged? let access = SecAccessControlCreateWithFlags(nil, From 5e9c5ff0ad60bde358f3c6abe58992571618a917 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Sun, 23 Feb 2020 00:01:04 -0600 Subject: [PATCH 16/17] Address PR comments --- .gitignore | 2 -- Cely Demo/BiometricLoginViewController.swift | 2 +- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++++ Sources/Core/CelyConstants.swift | 2 +- Sources/Core/Storage/CelyCredentialStore.swift | 6 +++--- Sources/Core/Storage/KeychainObject.swift | 16 ++++++++-------- Tests/CelyCredentialStoreTests.swift | 12 ++++++------ 7 files changed, 27 insertions(+), 21 deletions(-) create mode 100644 Cely.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/.gitignore b/.gitignore index d13c82d..dd4cb7c 100644 --- a/.gitignore +++ b/.gitignore @@ -65,5 +65,3 @@ fastlane/Preview.html fastlane/screenshots fastlane/test_output docs/ - -Cely.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/Cely Demo/BiometricLoginViewController.swift b/Cely Demo/BiometricLoginViewController.swift index c3b532a..2ee422f 100644 --- a/Cely Demo/BiometricLoginViewController.swift +++ b/Cely Demo/BiometricLoginViewController.swift @@ -48,7 +48,7 @@ class BiometricLoginViewController: UIViewController, UITextFieldDelegate { username: username, password: password, server: "api.example.com", - accessibility: [.biometricsIfPossible] + options: [.biometricsIfPossible] ) if case let .failure(error) = credentialResult { diff --git a/Cely.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Cely.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Cely.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Sources/Core/CelyConstants.swift b/Sources/Core/CelyConstants.swift index acd05cf..c29e122 100644 --- a/Sources/Core/CelyConstants.swift +++ b/Sources/Core/CelyConstants.swift @@ -59,7 +59,7 @@ internal extension UIWindow { } } -public enum AccessibilityOptions { +public enum AccessControlOptions { case biometricsIfPossible case thisDeviceOnly } diff --git a/Sources/Core/Storage/CelyCredentialStore.swift b/Sources/Core/Storage/CelyCredentialStore.swift index e146099..de2c284 100644 --- a/Sources/Core/Storage/CelyCredentialStore.swift +++ b/Sources/Core/Storage/CelyCredentialStore.swift @@ -37,15 +37,15 @@ public struct CelyCredentialStore { /// - username: username for user /// - password: password for user /// - server: api uri for account - /// - accessibility: Array of AccessibilityOptions for credentials to be saved with + /// - options: Array of AccessControlOptions for credentials to be saved with @discardableResult - public func set(username: String, password: String, server: String, accessibility: [AccessibilityOptions] = []) -> Result { + public func set(username: String, password: String, server: String, options: [AccessControlOptions] = []) -> Result { guard let passwordData = password.data(using: .utf8) else { return .failure(CelyStorageError.invalidValue) } do { - let keychainQuery = KeychainObject(account: username, server: server, value: passwordData, accessibility: accessibility) + let keychainQuery = KeychainObject(account: username, server: server, value: passwordData, options: options) try setCredentialsLookupKey(keyDictionary: keychainQuery.toLookupMap()) try keychain.set(query: keychainQuery) return .success(()) diff --git a/Sources/Core/Storage/KeychainObject.swift b/Sources/Core/Storage/KeychainObject.swift index f0f2aa1..dc579a6 100644 --- a/Sources/Core/Storage/KeychainObject.swift +++ b/Sources/Core/Storage/KeychainObject.swift @@ -19,13 +19,13 @@ struct KeychainObject { let account: String? let server: String? let value: Data? - private let accessibilityOptions: [AccessibilityOptions] + private let accessControlOptions: [AccessControlOptions] - init(account: String? = nil, server: String? = nil, value: Data? = nil, accessibility: [AccessibilityOptions] = []) { + init(account: String? = nil, server: String? = nil, value: Data? = nil, options: [AccessControlOptions] = []) { self.account = account self.server = server self.value = value - accessibilityOptions = accessibility + accessControlOptions = options } static func buildFromKeychain(dictionary: RawDictionary) -> KeychainObject { @@ -61,8 +61,8 @@ struct KeychainObject { return query.merging(limitQuery) { _, new in new } } - func getAccessibility() -> CFString { - let isThisDeviceOnly = accessibilityOptions.contains(.thisDeviceOnly) + func getAccessControlOptions() -> CFString { + let isThisDeviceOnly = accessControlOptions.contains(.thisDeviceOnly) return isThisDeviceOnly ? kSecAttrAccessibleWhenUnlockedThisDeviceOnly : kSecAttrAccessibleWhenUnlocked } @@ -73,11 +73,11 @@ struct KeychainObject { userMap[kSecValueData] = value } - if accessibilityOptions.contains(.biometricsIfPossible) { - let accessibility = getAccessibility() + if accessControlOptions.contains(.biometricsIfPossible) { + let options = getAccessControlOptions() var error: Unmanaged? let access = SecAccessControlCreateWithFlags(nil, - accessibility, + options, .userPresence, &error) diff --git a/Tests/CelyCredentialStoreTests.swift b/Tests/CelyCredentialStoreTests.swift index 2b733c2..ad8cdd4 100644 --- a/Tests/CelyCredentialStoreTests.swift +++ b/Tests/CelyCredentialStoreTests.swift @@ -80,20 +80,20 @@ class CelyCredentialStoreTests: XCTestCase { } func testIncludesBiometrics() { - let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, accessibility: [.biometricsIfPossible]) + let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, options: [.biometricsIfPossible]) let getMap = object.toSetMap(withValue: false) let foundValue = getMap[kSecAttrAccessControl] XCTAssert(foundValue != nil, "Failed to find biometrics flag") - let accessibility = object.getAccessibility() - XCTAssert(accessibility == kSecAttrAccessibleWhenUnlocked, "Failed to set correct `accessibility`: \(accessibility)") + let options = object.getAccessControlOptions() + XCTAssert(options == kSecAttrAccessibleWhenUnlocked, "Failed to set correct `accessibility`: \(options)") } func testThisDeviceOnly() { - let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, accessibility: [.biometricsIfPossible, .thisDeviceOnly]) + let object = KeychainObject(account: "valid-username", server: "someserver.com", value: "valid-password".data(using: .utf8)!, options: [.biometricsIfPossible, .thisDeviceOnly]) let getMap = object.toSetMap(withValue: false) let foundValue = getMap[kSecAttrAccessControl] XCTAssert(foundValue != nil, "Failed to find biometrics flag") - let accessibility = object.getAccessibility() - XCTAssert(accessibility == kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "Failed to set correct `accessibility`: \(accessibility)") + let options = object.getAccessControlOptions() + XCTAssert(options == kSecAttrAccessibleWhenUnlockedThisDeviceOnly, "Failed to set correct `accessibility`: \(options)") } } From cee4c19a1d5799e9a6733783ee34fba7e35aa6b1 Mon Sep 17 00:00:00 2001 From: Fabian Buentello Date: Sun, 23 Feb 2020 01:25:27 -0600 Subject: [PATCH 17/17] Replace Cely team --- Cely Demo/BiometricLoginViewController.swift | 2 +- Sources/Core/Storage/CelyCredentialStore.swift | 2 +- Sources/Core/Storage/CelyKeychain.swift | 2 +- Sources/Core/Storage/KeychainObject.swift | 2 +- Tests/CelyCredentialStoreTests.swift | 2 +- Tests/CelyStorageErrorTests.swift | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cely Demo/BiometricLoginViewController.swift b/Cely Demo/BiometricLoginViewController.swift index 2ee422f..383d0a5 100644 --- a/Cely Demo/BiometricLoginViewController.swift +++ b/Cely Demo/BiometricLoginViewController.swift @@ -3,7 +3,7 @@ // Cely Demo // // Created by Fabian Buentello on 10/5/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // import Cely diff --git a/Sources/Core/Storage/CelyCredentialStore.swift b/Sources/Core/Storage/CelyCredentialStore.swift index de2c284..b5164f9 100644 --- a/Sources/Core/Storage/CelyCredentialStore.swift +++ b/Sources/Core/Storage/CelyCredentialStore.swift @@ -3,7 +3,7 @@ // Cely-iOS // // Created by Fabian Buentello on 9/28/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // import Foundation diff --git a/Sources/Core/Storage/CelyKeychain.swift b/Sources/Core/Storage/CelyKeychain.swift index f98bc84..32ea028 100644 --- a/Sources/Core/Storage/CelyKeychain.swift +++ b/Sources/Core/Storage/CelyKeychain.swift @@ -3,7 +3,7 @@ // Cely-iOS // // Created by Fabian Buentello on 9/28/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // import Foundation diff --git a/Sources/Core/Storage/KeychainObject.swift b/Sources/Core/Storage/KeychainObject.swift index dc579a6..ceb93a2 100644 --- a/Sources/Core/Storage/KeychainObject.swift +++ b/Sources/Core/Storage/KeychainObject.swift @@ -3,7 +3,7 @@ // Cely-iOS // // Created by Fabian Buentello on 9/30/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // import Foundation diff --git a/Tests/CelyCredentialStoreTests.swift b/Tests/CelyCredentialStoreTests.swift index ad8cdd4..50533c7 100644 --- a/Tests/CelyCredentialStoreTests.swift +++ b/Tests/CelyCredentialStoreTests.swift @@ -3,7 +3,7 @@ // CelyTests-iOS // // Created by Fabian Buentello on 9/29/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // @testable import Cely diff --git a/Tests/CelyStorageErrorTests.swift b/Tests/CelyStorageErrorTests.swift index ab612bc..ca94401 100644 --- a/Tests/CelyStorageErrorTests.swift +++ b/Tests/CelyStorageErrorTests.swift @@ -3,7 +3,7 @@ // CelyTests-iOS // // Created by Fabian Buentello on 9/30/19. -// Copyright © 2019 ChaiOne. All rights reserved. +// Copyright © 2019 Fabian Buentello. All rights reserved. // @testable import Cely