Skip to content

Commit

Permalink
BREAKING CHANGE: add virtualKeyUrl to completion handler arguments (#76)
Browse files Browse the repository at this point in the history
* BREAKING CHANGE: add virtualKeyUrl to completion handler arguments

* chore: update docs

---------

Co-authored-by: Smartcar <[email protected]>
  • Loading branch information
allisonc07 and smartcar-ops authored Dec 4, 2023
1 parent 6964c98 commit 27d1b1d
Show file tree
Hide file tree
Showing 30 changed files with 96 additions and 74 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ fastlane/test_output

# Docs
docs/undocumented.json
docs/docsets/SmartcarAuth.docset/Contents/Resources/Documents/undocumented.json

# Other
.DS_Store
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Then, initiate the SmartcarAuth object in the UIViewController.
```swift
let appDelegate = UIApplication.shared.delegate as! AppDelegate

func completionHandler(code: String?, state: String?, err: AuthorizationError?,) -> Void {
func completionHandler(code: String?, state: String?, virtualKeyUrl: String?, err: AuthorizationError?,) -> Void {
// Receive authorization code
}

Expand Down
2 changes: 1 addition & 1 deletion SmartcarAuth.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'SmartcarAuth'
s.version = '4.3.1'
s.version = '5.3.1'
s.summary = 'Smartcar Authentication SDK for iOS written in Swift 5.'

s.description = <<-DESC
Expand Down
3 changes: 3 additions & 0 deletions SmartcarAuth.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@
};
F8F928891E2B2F6B009F07E5 = {
CreatedOnToolsVersion = 8.2;
DevelopmentTeam = KP52A6LHWC;
LastSwiftMigration = 1120;
ProvisioningStyle = Automatic;
};
Expand Down Expand Up @@ -516,6 +517,7 @@
baseConfigurationReference = BD668AF997F2B3DDFDBE6656 /* Pods-SmartcarAuthTests.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
DEVELOPMENT_TEAM = KP52A6LHWC;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
INFOPLIST_FILE = SmartcarAuthTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
Expand All @@ -531,6 +533,7 @@
baseConfigurationReference = B06E3582ED1597AA5389FE57 /* Pods-SmartcarAuthTests.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
DEVELOPMENT_TEAM = KP52A6LHWC;
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
INFOPLIST_FILE = SmartcarAuthTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
Expand Down
18 changes: 10 additions & 8 deletions SmartcarAuth/SmartcarAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Smartcar Authentication SDK for iOS written in Swift 5.
var clientId: String
var redirectUri: String
var scope: [String]
var completionHandler: (_ code: String?, _ state: String?, _ error: AuthorizationError?) -> Void
var completionHandler: (_ code: String?, _ state: String?, _ virtualKeyUrl: String?, _ error: AuthorizationError?) -> Void
var mode: SCMode?
@available(*, deprecated, message: "Use mode instead")
var testMode: Bool
Expand All @@ -58,7 +58,7 @@ Smartcar Authentication SDK for iOS written in Swift 5.
clientId: String,
redirectUri: String,
scope: [String],
completionHandler: @escaping (String?, String?, AuthorizationError?) -> Void,
completionHandler: @escaping (String?, String?, String?, AuthorizationError?) -> Void,
testMode: Bool = false,
mode: SCMode? = nil
) {
Expand Down Expand Up @@ -146,13 +146,13 @@ Smartcar Authentication SDK for iOS written in Swift 5.
default:
authorizationError = AuthorizationError(type: .unknownError)
}
return self.completionHandler(nil, nil, authorizationError)
return self.completionHandler(nil, nil, nil, authorizationError)
}
handleCallback(callbackUrl: callback)
}

/**
Authorization callback function. Verifies that no error occured during the OAuth process and extracts the auth code and state string upon success. Invokes the completion function with either the code or an error (and state if included).
Authorization callback function. Verifies that no error occured during the OAuth process and extracts the auth code, state string, and virtualKeyUrl upon success. Invokes the completion function with either the code or an error (and state and/or virtualKeyUrl if included).
- parameters:
- url: callback URL containing authorization code or an error
*/
Expand All @@ -162,7 +162,7 @@ Smartcar Authentication SDK for iOS written in Swift 5.
let urlComp = URLComponents(url: callbackUrl, resolvingAgainstBaseURL: false)
guard let query = urlComp?.queryItems else {
authorizationError = AuthorizationError(type: .missingQueryParameters, errorDescription: nil, vehicleInfo: nil)
return self.completionHandler(nil, nil, authorizationError)
return self.completionHandler(nil, nil, nil, authorizationError)
}

let queryState = query.filter({$0.name == "state"}).first?.value!
Expand Down Expand Up @@ -198,15 +198,17 @@ Smartcar Authentication SDK for iOS written in Swift 5.
default:
authorizationError = AuthorizationError(type: .unknownError, errorDescription: errorDescription)
}
return self.completionHandler(nil, queryState, authorizationError)
return self.completionHandler(nil, queryState, nil, authorizationError)
}

let virtualKeyUrl = query.filter({$0.name == "virtual_key_url"}).first?.value!

guard let code = query.filter({$0.name == "code"}).first?.value else {
let authorizationError = AuthorizationError(type: .missingAuthCode, errorDescription: nil, vehicleInfo: nil)
return self.completionHandler(nil, queryState, authorizationError)
return self.completionHandler(nil, queryState, nil, authorizationError)
}

return self.completionHandler(code, queryState, nil)
return self.completionHandler(code, queryState, virtualKeyUrl, nil)
}

}
Expand Down
40 changes: 28 additions & 12 deletions SmartcarAuthTests/SmartcarAuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ class SmartcarAuthTests: XCTestCase {
let make = "Tesla"
let vin = "12345678901234"
let code = UUID().uuidString
let virtualKeyUrl = "https://www.tesla.com/_ak/smartcar.com"

func completion(code: String?, state: String?, err: AuthorizationError?) -> Void {
func completion(code: String?, state: String?, virtualKeyUrl: String?, err: AuthorizationError?) -> Void {
}

override func setUp() {
Expand All @@ -32,23 +33,24 @@ class SmartcarAuthTests: XCTestCase {
}

func testSmartcarAuthGenerateAuthUrl() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: completion(code:state:err:))
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: completion(code:state:virtualKeyUrl:err:))

let builder = smartcar.authUrlBuilder()

expect(builder).to(beAnInstanceOf(SCUrlBuilder.self))
}

func testHandleCallbackSuccess() {
func completionCheck(code: String?, state: String?, err: AuthorizationError?) -> Void {
func completionCheck(code: String?, state: String?, virtualKeyUrl: String?, err: AuthorizationError?) -> Void {
expect(code).to(equal(self.code))
expect(state).to(beNil())
expect(err).to(beNil())
}

let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(equal(self.code))
expect(state).to(beNil())
expect(virtualKeyUrl).to(beNil())
expect(err).to(beNil())
})

Expand All @@ -60,7 +62,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackSuccessWithState() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(equal(self.code))
expect(state).to(equal(self.state))
expect(err).to(beNil())
Expand All @@ -73,8 +75,22 @@ class SmartcarAuthTests: XCTestCase {
smartcar.handleCallback(callbackUrl: url)
}

func testHandleCallbackSuccessWithVirtualKeyUrl() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(equal(self.code))
expect(virtualKeyUrl).to(equal(self.virtualKeyUrl))
expect(err).to(beNil())
})

let urlString = redirectUri + "?code=" + code + "&virtual_key_url=" + virtualKeyUrl

let url = URL(string: urlString)!

smartcar.handleCallback(callbackUrl: url)
}

func testHandleCallbackAccessDenied() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -91,7 +107,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackVehicleIncompatible() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -112,7 +128,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackInvalidSubscription() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -129,7 +145,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackUnrecognizedError() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -146,7 +162,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackMissingQueryParameters() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -163,7 +179,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testHandleCallbackNoCode() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
expect(code).to(beNil())
expect(state).to(beNil())

Expand All @@ -180,7 +196,7 @@ class SmartcarAuthTests: XCTestCase {
}

func testLaunchAuthFlow() {
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, err in
let smartcar = SmartcarAuth(clientId: clientId, redirectUri: redirectUri, scope: scope, completionHandler: { code, state, virtualKeyUrl, err in
fail("Callback should not have been called")
})

Expand Down
4 changes: 2 additions & 2 deletions docs/Classes.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a title="Classes Reference"></a>
<header>
<div class="content-wrapper">
<p><a href="index.html">SmartcarAuth 4.3.0 Docs</a> (62% documented)</p>
<p><a href="index.html">SmartcarAuth 5.3.1 Docs</a> (61% documented)</p>
<div class="header-right">
<form role="search" action="search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
Expand Down Expand Up @@ -200,7 +200,7 @@ <h4>Declaration</h4>
</section>
</section>
<section id="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-14)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-30)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</article>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/AuthorizationError.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a title="AuthorizationError Class Reference"></a>
<header>
<div class="content-wrapper">
<p><a href="../index.html">SmartcarAuth 4.3.0 Docs</a> (62% documented)</p>
<p><a href="../index.html">SmartcarAuth 5.3.1 Docs</a> (61% documented)</p>
<div class="header-right">
<form role="search" action="../search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
Expand Down Expand Up @@ -170,7 +170,7 @@ <h4>Declaration</h4>
</section>
</section>
<section id="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-14)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-30)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</article>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/AuthorizationError/ErrorType.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a title="ErrorType Enumeration Reference"></a>
<header>
<div class="content-wrapper">
<p><a href="../../index.html">SmartcarAuth 4.3.0 Docs</a> (62% documented)</p>
<p><a href="../../index.html">SmartcarAuth 5.3.1 Docs</a> (61% documented)</p>
<div class="header-right">
<form role="search" action="../../search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
Expand Down Expand Up @@ -276,7 +276,7 @@ <h4>Declaration</h4>
</section>
</section>
<section id="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-14)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-30)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</article>
Expand Down
4 changes: 2 additions & 2 deletions docs/Classes/SCUrlBuilder.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a title="SCUrlBuilder Class Reference"></a>
<header>
<div class="content-wrapper">
<p><a href="../index.html">SmartcarAuth 4.3.0 Docs</a> (62% documented)</p>
<p><a href="../index.html">SmartcarAuth 5.3.1 Docs</a> (61% documented)</p>
<div class="header-right">
<form role="search" action="../search.json">
<input type="text" placeholder="Search documentation" data-typeahead>
Expand Down Expand Up @@ -539,7 +539,7 @@ <h4>Return Value</h4>
</section>
</section>
<section id="footer">
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-14)</p>
<p>&copy; 2023 <a class="link" href="https://github.com/smartcar/ios-sdk" target="_blank" rel="external noopener">Smartcar Inc.</a>. All rights reserved. (Last updated: 2023-11-30)</p>
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.4</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
</section>
</article>
Expand Down
Loading

0 comments on commit 27d1b1d

Please sign in to comment.