Skip to content

Commit

Permalink
+1
Browse files Browse the repository at this point in the history
  • Loading branch information
borut-t committed Sep 4, 2023
1 parent edf6596 commit 2977bcc
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 47 deletions.
4 changes: 3 additions & 1 deletion Sources/LinkedIn/LinkedInAuthenticator+Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ public extension LinkedInAuthenticator {
let clientId: String
let clientSecret: String
let permissions: String
let code: String
let redirectUrl: URL
let authEndpoint: URL = "https://www.linkedin.com/oauth/v2/authorization"
let authCancel: URL = "https://www.linkedin.com/oauth/v2/authorization-cancel"

public init(clientId: String, clientSecret: String, permissions: String, redirectUrl: URL) {
public init(clientId: String, clientSecret: String, permissions: String, code: String, redirectUrl: URL) {
self.clientId = clientId
self.clientSecret = clientSecret
self.permissions = permissions
self.code = code
self.redirectUrl = redirectUrl
}

Expand Down
74 changes: 28 additions & 46 deletions Sources/LinkedIn/LinkedInAuthenticator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@

import Foundation
import PovioKitAuthCore
import PovioKitPromise
//import PovioKitPromise
import SwiftUI

@available(iOS 15.0, *)
public final class LinkedInAuthenticator {
@State private var openWebView = false
private let linkedInAPI: LinkedInAPI

public init(linkedInAPI: LinkedInAPI = .init()) {
Expand All @@ -27,27 +26,27 @@ extension LinkedInAuthenticator: Authenticator {
/// SignIn user.
///
/// Will return promise with the `Response` object on success or with `Error` on error.
@MainActor
public func signIn(from view: any View,
with configuration: Configuration,
additionalScopes: [String]? = .none) -> Promise<Response> {
openWebView.toggle()
return Promise { seal in
_ = view.sheet(isPresented: $openWebView) {
LinkedInWebView(with: configuration) { data in
Task {
do {
let response = try await self.loadData(code: data.code, with: configuration)
seal.resolve(with: response)
} catch {
seal.reject(with: error)
}
}
} onFailure: {
seal.reject(with: Error.unhandledAuthorization)
}
}
}
public func signIn(with configuration: Configuration) async throws -> Response {
// try await loadData(with: configuration)

let authRequest: LinkedInAPI.LinkedInAuthRequest = .init(
code: configuration.code,
redirectUri: configuration.redirectUrl.absoluteString,
clientId: configuration.clientId,
clientSecret: configuration.clientSecret
)
let authResponse = try await linkedInAPI.login(with: authRequest)
let profileResponse = try await linkedInAPI.loadProfile(with: .init(token: authResponse.accessToken))
let emailResponse = try await linkedInAPI.loadEmail(with: .init(token: authResponse.accessToken))

let name = [profileResponse.localizedFirstName, profileResponse.localizedLastName].joined(separator: " ")
return Response(
userId: profileResponse.id,
token: authResponse.accessToken,
name: name,
email: emailResponse.emailAddress,
expiresAt: authResponse.expiresIn
)
}

/// Clears the signIn footprint and logs out the user immediatelly.
Expand All @@ -72,34 +71,17 @@ extension LinkedInAuthenticator: Authenticator {
@available(iOS 15.0, *)
public extension LinkedInAuthenticator {
enum Error: Swift.Error {
// case system(_ error: Swift.Error)
// case cancelled
// case system(_ error: Swift.Error)
// case cancelled
case unhandledAuthorization
// case alreadySignedIn
// case alreadySignedIn
}
}

// MARK: - Private Extension
@available(iOS 15.0, *)
private extension LinkedInAuthenticator {
func loadData(code: String, with configuration: Configuration) async throws -> Response {
let authRequest: LinkedInAPI.LinkedInAuthRequest = .init(
code: code,
redirectUri: configuration.redirectUrl.absoluteString,
clientId: configuration.clientId,
clientSecret: configuration.clientSecret
)
let authResponse = try await linkedInAPI.login(with: authRequest)
let profileResponse = try await linkedInAPI.loadProfile(with: .init(token: authResponse.accessToken))
let emailResponse = try await linkedInAPI.loadEmail(with: .init(token: authResponse.accessToken))

let name = [profileResponse.localizedFirstName, profileResponse.localizedLastName].joined(separator: " ")
return Response(
userId: profileResponse.id,
token: authResponse.accessToken,
name: name,
email: emailResponse.emailAddress,
expiresAt: authResponse.expiresIn
)
}
// func loadData(with configuration: Configuration) async throws -> Response {
//
// }
}
35 changes: 35 additions & 0 deletions Sources/LinkedIn/WebView/LinkedInSheet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// File.swift
//
//
// Created by Borut Tomazin on 04/09/2023.
//

import SwiftUI

//struct LinkedInSheet: ViewModifier {
// typealias SuccessHandler = (Bool) -> Void
// typealias ErrorHandler = (Error) -> Void
// let isPresented: Binding<Bool>
// let onSuccess: SuccessHandler?
// let onError: ErrorHandler?
//
// func body(content: Content) -> some View {
// content
// .sheet(isPresented: isPresented) {
// LinkedInWebView { data in
// // Task { await viewModel.signInWithLinkedIn() }
// } onFailure: {
// // viewModel.error = .general
// }
// }
// }
//}
//
//extension View {
// func linkedInSheet(isPresented: Binding<Bool>,
// onSuccess: LinkedInSheet.SuccessHandler? = nil,
// onError: LinkedInSheet.ErrorHandler? = nil) -> some View {
// modifier(LinkedInSheet(isPresented: isPresented, onSuccess: onSuccess, onError: onError))
// }
//}

0 comments on commit 2977bcc

Please sign in to comment.