diff --git a/SmartcarAuth.xcodeproj/project.pbxproj b/SmartcarAuth.xcodeproj/project.pbxproj index 9a70b76..01f29e5 100644 --- a/SmartcarAuth.xcodeproj/project.pbxproj +++ b/SmartcarAuth.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 278B07A92248E2E000474A10 /* VehicleInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278B07A82248E2DF00474A10 /* VehicleInfo.swift */; }; + 535F0D9C362B52F39D5CCCF7 /* Pods_SmartcarAuth.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F1C77FCC7CB1C6991212F8 /* Pods_SmartcarAuth.framework */; }; A644ADEA238861F60036CE46 /* SCUrlBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = A644ADE9238861F60036CE46 /* SCUrlBuilder.swift */; }; A644ADEC238862810036CE46 /* SCUrlBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A644ADEB238862810036CE46 /* SCUrlBuilderTests.swift */; }; A69F57AB2374EAB9005971D2 /* AuthorizationErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A69F57AA2374EAB9005971D2 /* AuthorizationErrorTests.swift */; }; @@ -33,6 +34,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 19F1C77FCC7CB1C6991212F8 /* Pods_SmartcarAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SmartcarAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 278B07A82248E2DF00474A10 /* VehicleInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleInfo.swift; sourceTree = ""; }; 41E81CE39269597B8418C7C0 /* Pods-SmartcarAuth.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SmartcarAuth.release.xcconfig"; path = "Pods/Target Support Files/Pods-SmartcarAuth/Pods-SmartcarAuth.release.xcconfig"; sourceTree = ""; }; 4C65C9D0D291B77BE47281A0 /* Pods_SmartcarAuthTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SmartcarAuthTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -59,6 +61,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 535F0D9C362B52F39D5CCCF7 /* Pods_SmartcarAuth.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -78,6 +81,7 @@ isa = PBXGroup; children = ( 4C65C9D0D291B77BE47281A0 /* Pods_SmartcarAuthTests.framework */, + 19F1C77FCC7CB1C6991212F8 /* Pods_SmartcarAuth.framework */, ); name = Frameworks; sourceTree = ""; @@ -204,7 +208,6 @@ TargetAttributes = { F8F928801E2B2F6A009F07E5 = { CreatedOnToolsVersion = 8.2; - DevelopmentTeam = EE32J27TKP; LastSwiftMigration = 1120; ProvisioningStyle = Automatic; }; @@ -465,9 +468,10 @@ baseConfigurationReference = 8364B99DE3988F4714D06ED1 /* Pods-SmartcarAuth.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = EE32J27TKP; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -479,6 +483,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.smartcar.SmartCarOAuthSDK; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = On; @@ -491,9 +496,10 @@ baseConfigurationReference = 41E81CE39269597B8418C7C0 /* Pods-SmartcarAuth.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = EE32J27TKP; + DEVELOPMENT_TEAM = ""; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; @@ -505,6 +511,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.smartcar.SmartCarOAuthSDK; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 5.0; diff --git a/SmartcarAuth/SCUrlBuilder.swift b/SmartcarAuth/SCUrlBuilder.swift index 8fe604e..f45ab56 100644 --- a/SmartcarAuth/SCUrlBuilder.swift +++ b/SmartcarAuth/SCUrlBuilder.swift @@ -32,9 +32,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - clientId: The application's client ID - redirectUri: The application's redirect URI - scope: An array of authorization scopes - - testMode: Optional, launch the Smartcar auth flow in test mode when set to true. Defaults to false. + - authMode: Launch the Smartcar auth flow with the corresponding mode. Defaults to test mode. */ - public init(clientId: String, redirectUri: String, scope: [String], testMode: Bool) { + public init(clientId: String, redirectUri: String, scope: [String], authMode: SmartcarAuthMode) { self.components = URLComponents() self.components.scheme = "https" self.components.host = "connect.smartcar.com" @@ -43,7 +43,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. self.queryItems.append(contentsOf: [ URLQueryItem(name: "client_id", value: clientId), URLQueryItem(name: "response_type", value: "code"), - URLQueryItem(name: "mode", value: testMode ? "test" : "live") + URLQueryItem(name: "mode", value: authMode.rawValue) ]) if let redirectUri = redirectUri.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { diff --git a/SmartcarAuth/SmartcarAuth.swift b/SmartcarAuth/SmartcarAuth.swift index 6bbbe04..9b4fe7d 100644 --- a/SmartcarAuth/SmartcarAuth.swift +++ b/SmartcarAuth/SmartcarAuth.swift @@ -26,17 +26,23 @@ import SafariServices import AuthenticationServices #endif +public enum SmartcarAuthMode: String { + case live + case test + case simulated +} /** Smartcar Authentication SDK for iOS written in Swift 5. - Facilitates the authorization flow to launch the flow and retrieve an authorization code */ @objcMembers public class SmartcarAuth: NSObject { + var clientId: String var redirectUri: String var scope: [String] var completionHandler: (_ code: String?, _ state: String?, _ error: AuthorizationError?) -> Void - var testMode: Bool + var authMode: SmartcarAuthMode // SFAuthenticationSession/ASWebAuthenticationSession require a strong reference to the session so that the system doesn't deallocate the session before the user finishes authenticating private var session: Session? @@ -47,14 +53,14 @@ Smartcar Authentication SDK for iOS written in Swift 5. - clientId: The application's client ID - redirectUri: The application's redirect URI - scope: An array of authorization scopes - - testMode: Optional, launch the Smartcar auth flow in test mode when set to true. Defaults to false. + - authMode: Launch the Smartcar auth flow with the corresponding mode. Defaults to test mode. - completion: Callback function called upon the completion of the Smartcar Connect */ - public init(clientId: String, redirectUri: String, scope: [String], completionHandler: @escaping (String?, String?, AuthorizationError?) -> Void, testMode: Bool = false) { + public init(clientId: String, redirectUri: String, scope: [String], completionHandler: @escaping (String?, String?, AuthorizationError?) -> Void, authMode: SmartcarAuthMode = .test) { self.clientId = clientId self.redirectUri = redirectUri self.scope = scope - self.testMode = testMode + self.authMode = authMode self.completionHandler = completionHandler } @@ -63,7 +69,7 @@ Smartcar Authentication SDK for iOS written in Swift 5. See `SCURLBuilder` for a full list of query parameters that can be set on the authorization URL */ public func authUrlBuilder() -> SCUrlBuilder { - return SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + return SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) } /** diff --git a/SmartcarAuthTests/SCUrlBuilderTests.swift b/SmartcarAuthTests/SCUrlBuilderTests.swift index 8dd4210..76588be 100644 --- a/SmartcarAuthTests/SCUrlBuilderTests.swift +++ b/SmartcarAuthTests/SCUrlBuilderTests.swift @@ -18,7 +18,7 @@ class SCUrlBuilderTests: XCTestCase { let make = "TESLA" let vin = "12345678901234567" let flags = ["country:DE", "flag:suboption"] - var testMode = false + var authMode = SmartcarAuthMode.live override func setUp() { // Put setup code here. This method is called before the invocation of each test method in the class. @@ -31,16 +31,16 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderBaseUrlLiveMode() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer" - let baseUrl = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode).build() + let baseUrl = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode).build() expect(baseUrl).to(equal(expectedUrl)) } func testSCUrlBuilderBaseUrlTestMode() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=test&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer" - self.testMode = true + self.authMode = .test - let baseUrl = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode).build() + let baseUrl = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode).build() expect(baseUrl).to(equal(expectedUrl)) } @@ -48,7 +48,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetState() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&state=" + state - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setState(state: state) .build() @@ -58,7 +58,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetForcePromptTrue() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&approval_prompt=force" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setForcePrompt(forcePrompt: true) .build() @@ -68,7 +68,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetForcePromptFalse() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&approval_prompt=auto" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setForcePrompt(forcePrompt: false) .build() @@ -78,7 +78,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetMakeBypass() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&make=TESLA" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setMakeBypass(make: make) .build() @@ -88,7 +88,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetSingleSelectTrue() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&single_select=true" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setSingleSelect(singleSelect: true) .build() @@ -98,7 +98,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetSingleSelectFalse() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&single_select=false" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setSingleSelect(singleSelect: false) .build() @@ -108,7 +108,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetSingleSelectVin() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&single_select=true&single_select_vin=12345678901234567" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setSingleSelect(singleSelect: true) .setSingleSelectVin(vin: vin) .build() @@ -119,7 +119,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetFlags() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&flags=country:DE%20flag:suboption" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setFlags(flags: flags) .build() @@ -129,7 +129,7 @@ class SCUrlBuilderTests: XCTestCase { func testSCUrlBuilderSetAllParameters() { let expectedUrl = "https://connect.smartcar.com/oauth/authorize?client_id=" + clientId + "&response_type=code&mode=live&redirect_uri=" + redirectUri + "&scope=read_vehicle_info%20read_odometer&state=" + state + "&approval_prompt=force&make=TESLA&single_select=true&single_select_vin=12345678901234567&flags=country:DE%20flag:suboption" - let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, testMode: testMode) + let urlWithState = SCUrlBuilder(clientId: clientId, redirectUri: redirectUri, scope: scope, authMode: authMode) .setState(state: state) .setForcePrompt(forcePrompt: true) .setMakeBypass(make: make)