Skip to content

Commit

Permalink
WebView behavior update.
Browse files Browse the repository at this point in the history
  • Loading branch information
borut-t committed Sep 28, 2023
1 parent 6522544 commit d0982da
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
30 changes: 27 additions & 3 deletions Sources/LinkedIn/LinkedInAuthenticator+Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public extension LinkedInAuthenticator {
let redirectUrl: URL
var authEndpoint: URL = "https://www.linkedin.com/oauth/v2/authorization"
var authCancel: URL = "https://www.linkedin.com/oauth/v2/login-cancel"
var audience: String?
public var codeVerifier: String?
var codeChallenge: String?
var codeChallengeMethod: String?

public init(
clientId: String,
Expand All @@ -35,26 +39,46 @@ public extension LinkedInAuthenticator {
permissions: String,
redirectUrl: URL,
authEndpoint: URL,
authCancel: URL
authCancel: URL,
audience: String?,
codeVerifier: String?,
codeChallenge: String?,
codeChallengeMethod: String?
) {
self.clientId = clientId
self.clientSecret = clientSecret
self.permissions = permissions
self.redirectUrl = redirectUrl
self.authEndpoint = authEndpoint
self.authCancel = authCancel
self.audience = audience
self.codeVerifier = codeVerifier
self.codeChallenge = codeChallenge
self.codeChallengeMethod = codeChallengeMethod
}

func authorizationUrl(state: String) -> URL? {
public func authorizationUrl(state: String) -> URL? {
guard var urlComponents = URLComponents(url: authEndpoint, resolvingAgainstBaseURL: false) else { return nil }
urlComponents.queryItems = [
var queryItems: [URLQueryItem] = [
.init(name: "response_type", value: "code"),
.init(name: "connection", value: "linkedin"),
.init(name: "client_id", value: clientId),
.init(name: "redirect_uri", value: redirectUrl.absoluteString),
.init(name: "state", value: state),
.init(name: "scope", value: permissions)
]

if let audience {
queryItems.append(.init(name: "audience", value: audience))
}
if let codeChallenge {
queryItems.append(.init(name: "code_challenge", value: codeChallenge))
}
if let codeChallengeMethod {
queryItems.append(.init(name: "code_challenge_method", value: codeChallengeMethod))
}

urlComponents.queryItems = queryItems
return urlComponents.url
}
}
Expand Down
27 changes: 9 additions & 18 deletions Sources/LinkedIn/WebView/LinkedInWebView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ public struct LinkedInWebView: UIViewRepresentable {
webView = WKWebView(frame: .zero, configuration: config)
self.onSuccess = onSuccess
self.onFailure = onFailure

webView.navigationDelegate = makeCoordinator()
}

public func makeUIView(context: Context) -> some UIView {
Expand Down Expand Up @@ -69,33 +67,26 @@ public extension LinkedInWebView {
public func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
// if authCancel endpoint was called, dismiss the view
if let url = navigationAction.request.url,
url.absoluteString.hasPrefix(parent.configuration.authCancel.absoluteString) {
decisionHandler(.cancel)
parent.dismiss()
return
}

guard let url = webView.url, url.host == parent.configuration.redirectUrl.host else {
decisionHandler(.allow)
return
}

// extract the authorization code
let components = URLComponents(string: url.absoluteString)
guard let state = components?.queryItems?.first(where: { $0.name == "state" }),
let code = components?.queryItems?.first(where: { $0.name == "code" }) else {
// extract the authorization code from the redirect url
guard let url = webView.url,
url.host == parent.configuration.redirectUrl.host,
let components = URLComponents(string: url.absoluteString),
let state = components.queryItems?.first(where: { $0.name == "state" })?.value,
requestState == state,
let code = components.queryItems?.first(where: { $0.name == "code" }) else {
decisionHandler(.allow)
return
}
guard requestState == state.value ?? "" else {
parent.onFailure?()
decisionHandler(.allow)
parent.dismiss()
return
}
parent.onSuccess?((code.value ?? "", parent.requestState))
decisionHandler(.allow)
decisionHandler(.cancel)
parent.dismiss()
}
}
Expand Down

0 comments on commit d0982da

Please sign in to comment.