LCOV - code coverage report
Current view: top level - SwiftySimpleKeychain - SwiftySimpleKeychain.swift (source / functions) Hit Total Coverage
Test: lcov.info Lines: 30 30 100.0 %
Date: 2022-03-29 11:59:53 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // SwiftySimpleKeychain
       3             : // SwiftySimpleKeychain
       4             : //
       5             : // Copyright (c) 2022 Ezequiel (Kimi) Aceto (https://eaceto.dev). Based on Auth0's SimpleKeychain
       6             : //
       7             : // Permission is hereby granted, free of charge, to any person obtaining a copy
       8             : // of this software and associated documentation files (the "Software"), to deal
       9             : // in the Software without restriction, including without limitation the rights
      10             : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      11             : // copies of the Software, and to permit persons to whom the Software is
      12             : // furnished to do so, subject to the following conditions:
      13             : //
      14             : // The above copyright notice and this permission notice shall be included in
      15             : // all copies or substantial portions of the Software.
      16             : //
      17             : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      18             : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      19             : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      20             : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      21             : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      22             : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      23             : // THE SOFTWARE.
      24             : 
      25             : #if canImport(Foundation)
      26             : import Foundation
      27             : #endif
      28             : 
      29             : #if canImport(LocalAuthentication)
      30             : import LocalAuthentication
      31             : #endif
      32             : 
      33             : #if swift(<5.3)
      34             : #error("Alamofire doesn't support Swift versions below 5.3")
      35             : #endif
      36             : 
      37             : /**
      38             :  *  A simple helper class to deal with storing and retrieving values from  Keychain.
      39             :  *  It has support for sharing keychain items using Access Group and ffine grained accesibility
      40             :  *  over a specific Kyechain Item (Using Access Control).
      41             :  *  The support is only available for iOS and macOS, otherwise it will default using the coarse grained accesibility field.
      42             :  *  When a `NSString` or `NSData` is stored using Access Control and the accesibility flag
      43             :  *  `SwiftySimpleKeychainItem.accessibleAfterFirstUnlock`, iOS / macOS will prompt the user for
      44             :  *  it's passcode or pass a TouchID challenge (if available).
      45             :  */
      46             : public class SwiftySimpleKeychain {
      47             : 
      48             :     /**
      49             :      *  Service name under all items are saved. Default value is Bundle Identifier or "default" if not available
      50             :      */
      51             :     private(set) var service: String
      52             : 
      53             :     /**
      54             :      *  Access Group for Keychain item sharing. If it's nil no keychain sharing is possible. Default value is nil.
      55             :      */
      56             :     private(set) var accessGroup: String?
      57             : 
      58             :     /**
      59             :      *  What type of accessibility the items stored will have. 
      60             :      *  All values are translated to `kSecAttrAccessible` constants.
      61             :      *  Default value is A0SimpleKeychainItemAccessibleAfterFirstUnlock.
      62             :      *  @see kSecAttrAccessible
      63             :      */
      64             :     private(set) var defaultAccessiblity: SwiftySimpleKeychainItemAccessible
      65             : 
      66             :     /**
      67             :      *  Tells SwiftySimpleKeychain to use `kSecAttrAccessControl` instead of `kSecAttrAccessible`.
      68             :      *  It will work only in iOS 8+, defaulting to `kSecAttrAccessible` on lower version.
      69             :      *  Default value is False.
      70             :      */
      71             :     private(set) var useAccessControl: Bool
      72             : 
      73             :     /**
      74             :     *  LocalAuthenticationContext used to access items. Default value is a new LAContext object
      75             :     */
      76             :     #if canImport(LocalAuthentication)
      77             :     private(set) var localAuthenticationContext: LAContext
      78             :     #endif
      79             : 
      80             :     /**
      81             :      * Instantiates a SwiftySimpleKeychain
      82             :      *
      83             :      * Usage:
      84             :      * ```swift
      85             :      *  keychain = SwiftySimpleKeychain(with: "service-name")
      86             :      * ```
      87             :      *
      88             :      * - Parameter service: **Service name** under all items are saved. Defaults to `default`
      89             :      * - Parameter accessGroup: an **Access Group** for Keychain item sharing. Defaults to `nil`
      90             :      */
      91          42 :     public init(with service: String = "default", accessGroup: String? = nil) {
      92          42 :         self.service = service
      93          42 :         self.accessGroup = accessGroup
      94          42 :         self.defaultAccessiblity = .afterFirstUnlock
      95          42 :         self.useAccessControl = false
      96          42 : 
      97          42 :         // This does not apply to watchOS, tvOS and Linux
      98          42 :         // and all future platforms where LocalAuthentication is not available
      99          42 :         #if canImport(LocalAuthentication)
     100          42 :         localAuthenticationContext = LAContext()
     101          42 :         localAuthenticationContext.touchIDAuthenticationAllowableReuseDuration = 0
     102          42 :         #endif
     103          42 :     }
     104             : 
     105             :     /**
     106             :      * Sets the TouchID Authentication allowable reuse time
     107             :      *
     108             :      * Usage:
     109             :      * ```swift
     110             :      *  keychain.setTouchIDAuthenticationAllowableReuse(0) // do not reuse authentication
     111             :      * ```
     112             :      *
     113             :      * - Parameter duration: a TimeInterval that represents the allowable reuse time
     114             :      */
     115           3 :     func setTouchIDAuthenticationAllowableReuse(duration: TimeInterval) {
     116           3 :         // This does not apply to watchOS, tvOS and Linux
     117           3 :         // and all future platforms where LocalAuthentication is not available
     118           3 :         #if canImport(LocalAuthentication)
     119           3 :         if duration <= 0 {
     120           2 :             localAuthenticationContext.touchIDAuthenticationAllowableReuseDuration = 0
     121           3 :         } else if duration >= LATouchIDAuthenticationMaximumAllowableReuseDuration {
     122           1 :             localAuthenticationContext.touchIDAuthenticationAllowableReuseDuration
     123           1 :                 = LATouchIDAuthenticationMaximumAllowableReuseDuration
     124           3 :         } else {
     125           2 :             localAuthenticationContext.touchIDAuthenticationAllowableReuseDuration = duration
     126           3 :         }
     127           3 :         #endif
     128           3 :     }
     129             : }
     130             : 
     131             : public extension SwiftySimpleKeychain {
     132             :     
     133             :     /**
     134             :      * Instantiates a SwiftySimpleKeychain
     135             :      *
     136             :      * Usage:
     137             :      * ```swift
     138             :      *  keychain = SwiftySimpleKeychain.with("service-name")
     139             :      * ```
     140             :      *
     141             :      * - Parameter service: **Service name** under all items are saved. Defaults to `default`
     142             :      * - Parameter accessGroup: an **Access Group** for Keychain item sharing. Defaults to `nil`
     143             :      */
     144           3 :     static func with(_ service: String = "default", accessGroup: String? = nil) -> SwiftySimpleKeychain {
     145           3 :         return SwiftySimpleKeychain(with: service, accessGroup: accessGroup)
     146           3 :     }
     147             : }

Generated by: LCOV version 1.15