Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ struct ContentView: View {
}
}
}
.onChange(of: oauth.state) {
handle(state: oauth.state)
.onChange(of: oauth.state) { state, _ in
handle(state: state)
}
}

Expand Down Expand Up @@ -101,15 +101,15 @@ If you want to customize your OAuth environment or are using modules in your app


```swift
let oauth: OAuth = .init(.module)
let oauth: OAuth = await .init(.module)
```

If you are building your OAuth Providers programatically (recommended for production applications via a CI build pipeline for security purposes), you can pass providers and options as well.

```swift
let providers: [OAuth.Provider] = ...
let options: [OAuth.Option: Sendable] = [.applicationTag: "com.bundle.identifier"]
let oauth: OAuth = .init(providers: providers, options: options)
let oauth: OAuth = await .init(providers: providers, options: options)
```


Expand Down
3 changes: 2 additions & 1 deletion Sources/OAuthKit/Extensions/Collection+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import Foundation

extension Collection {

/// Returns true if the collection is not empty.
@inlinable
public var isNotEmpty: Bool {
return !isEmpty
!isEmpty
}
}
3 changes: 1 addition & 2 deletions Sources/OAuthKit/OAuth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,7 @@ public final class OAuth: NSObject {
/// The url session to use for communicating with providers.
@ObservationIgnored
private lazy var urlSession: URLSession = {
let configuration = URLSessionConfiguration.default
return URLSession(configuration: URLSessionConfiguration.default)
.init(configuration: .default)
}()

@ObservationIgnored
Expand Down
2 changes: 1 addition & 1 deletion Sources/OAuthKit/Views/OAWebViewCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class OAWebViewCoordinator: NSObject {

/// The oauth reference.
var oauth: OAuth {
return webView.oauth
webView.oauth
}

/// Initializer
Expand Down
28 changes: 28 additions & 0 deletions Tests/OAuthKitTests/CodableTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// CodeableTests.swift
// OAuthKit
//
// Created by Kevin McKee
//

import Foundation
@testable import OAuthKit
import Testing

@Suite("Codable Tests")
struct CodableTests {

private let encoder: JSONEncoder = .init()
private let decoder: JSONDecoder = .init()

@Test("Encoding and Decoding Tokens")
func whenEncodingDecodingTokens() async throws {

let token: OAuth.Token = .init(accessToken: UUID().uuidString, refreshToken: UUID().uuidString, expiresIn: 3600, state: "xyz", type: "bearer")

let data = try encoder.encode(token)
let decoded: OAuth.Token = try decoder.decode(OAuth.Token.self, from: data)
#expect(token == decoded)
}

}
4 changes: 2 additions & 2 deletions Tests/OAuthKitTests/KeychainTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ final class KeychainTests {
func whenStoring() async throws {
let keychain = Keychain.default
let key = "Github"
let token = OAuth.Token(accessToken: "1234", refreshToken: nil, expiresIn: 3600, state: "x", type: "bearer")
let token: OAuth.Token = .init(accessToken: "1234", refreshToken: nil, expiresIn: 3600, state: "x", type: "bearer")

let inserted = try! keychain.set(token, for: key)
#expect(inserted == true)

let found: OAuth.Token = try! keychain.get(key: key)!

#expect(token.accessToken != nil)
#expect(token.accessToken.isNotEmpty)
#expect(token.accessToken == found.accessToken)
#expect(token.expiresIn == found.expiresIn)
#expect(token.state == found.state)
Expand Down
31 changes: 30 additions & 1 deletion Tests/OAuthKitTests/OAuthTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,16 @@ import Testing
@Suite("OAuth Tests", .tags(.oauth))
final class OAuthTests {

let oauth: OAuth

/// Initializer.
init() async throws {
oauth = await .init(.module)
}

/// Tests the init method using a custom bundle.
@Test("Initializing providers")
func whenInitializing() async throws {
let oauth: OAuth = await .init(.module)
let providers = await oauth.providers
#expect(providers.isNotEmpty)
}
Expand All @@ -29,4 +35,27 @@ final class OAuthTests {
let timeInterval = expiration - Date.now
#expect(timeInterval < 0)
}

/// Tests the authorization request parameters.
@Test("Building Authorization Request")
func whenBuildingAuthorizationRequest() async throws {
let provider = await oauth.providers[0]
let request = provider.request(grantType: .authorizationCode)
#expect(request != nil)
#expect(request!.url!.absoluteString.contains("client_id="))
#expect(request!.url!.absoluteString.contains("redirect_uri=\(provider.redirectURI!)"))
#expect(request!.url!.absoluteString.contains("response_type=code"))
}

/// Tests the refresh token request parameters.
@Test("Building Refresh Token Request")
func whenBuildingRefreshTokenRequest() async throws {
let provider = await oauth.providers[0]
let token: OAuth.Token = .init(accessToken: UUID().uuidString, refreshToken: UUID().uuidString, expiresIn: 3600, state: nil, type: "bearer")
let request = provider.request(grantType: .refreshToken, token: token)
#expect(request != nil)
#expect(request!.url!.absoluteString.contains("client_id="))
#expect(request!.url!.absoluteString.contains("grant_type=refresh_token"))
#expect(request!.url!.absoluteString.contains("refresh_token=\(token.refreshToken!)"))
}
}