Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion Sources/AuthFoundation/JWT/Protocols/Claim.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import Foundation

/// Indicates a type that can be used as an enum value for the ``HasClaims/ClaimType`` associated type.
public protocol IsClaim: RawRepresentable<String> {}
public protocol IsClaim: RawRepresentable<String>, Sendable, Hashable, Equatable {}

/// Used by classes that contains OAuth2 claims.
///
Expand Down
50 changes: 28 additions & 22 deletions Sources/BrowserSignin/BrowserSignin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,25 @@ public final class BrowserSignin {
scope: ClaimCollection<[String]>,
redirectUri: URL,
logoutRedirectUri: URL? = nil,
additionalParameters: [String: any APIRequestArgument]? = nil) throws
additionalParameters: [String: any APIRequestArgument]? = nil)
{
let client = OAuth2Client(issuerURL: issuerURL,
clientId: clientId,
scope: scope,
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri)
try self.init(client: client, additionalParameters: additionalParameters)
let loginFlow = AuthorizationCodeFlow(issuerURL: issuerURL,
clientId: clientId,
scope: scope,
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri,
additionalParameters: additionalParameters)
let client = loginFlow.client

let logoutFlow: SessionLogoutFlow?
if client.configuration.logoutRedirectUri != nil {
logoutFlow = SessionLogoutFlow(client: client,
additionalParameters: additionalParameters)
} else {
logoutFlow = nil
}

self.init(loginFlow: loginFlow, logoutFlow: logoutFlow)
}

@_documentation(visibility: private)
Expand All @@ -241,34 +252,29 @@ public final class BrowserSignin {
scope: some WhitespaceSeparated,
redirectUri: URL,
logoutRedirectUri: URL? = nil,
additionalParameters: [String: any APIRequestArgument]? = nil) throws
additionalParameters: [String: any APIRequestArgument]? = nil)
{
let client = OAuth2Client(issuerURL: issuerURL,
clientId: clientId,
scope: scope,
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri)
try self.init(client: client, additionalParameters: additionalParameters)
self.init(issuerURL: issuerURL,
clientId: clientId,
scope: .init(wrappedValue: scope.whitespaceSeparated),
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri,
additionalParameters: additionalParameters)
}

convenience init(_ config: OAuth2Client.PropertyListConfiguration) throws {
try self.init(client: OAuth2Client(config),
additionalParameters: config.additionalParameters)
}

convenience init(client: OAuth2Client, additionalParameters: [String: any APIRequestArgument]?) throws {
let client = try OAuth2Client(config)
let loginFlow = try AuthorizationCodeFlow(client: client,
additionalParameters: additionalParameters)
additionalParameters: config.additionalParameters)
let logoutFlow: SessionLogoutFlow?
if client.configuration.logoutRedirectUri != nil {
logoutFlow = SessionLogoutFlow(client: client,
additionalParameters: additionalParameters)
additionalParameters: config.additionalParameters)
} else {
logoutFlow = nil
}

self.init(loginFlow: loginFlow, logoutFlow: logoutFlow)

}

Comment thread
AlexNachbaur marked this conversation as resolved.
/// Initializes a web authentication session using the supplied AuthorizationCodeFlow and optional context.
Expand Down
9 changes: 7 additions & 2 deletions Sources/OAuth2Auth/Authentication/AuthorizationCodeFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,21 @@ public actor AuthorizationCodeFlow: AuthenticationFlow {
/// - clientId: The client ID.
/// - scope: The scopes to request.
/// - redirectUri: The redirect URI for the client.
/// - logoutRedirectUri: The logout URI for the client, if applicable.
/// - additionalParameters: Optional additional query string parameters you would like to supply to the authorization server.
@inlinable
public init(issuerURL: URL,
clientId: String,
scope: ClaimCollection<[String]>,
redirectUri: URL,
logoutRedirectUri: URL? = nil,
additionalParameters: [String: any APIRequestArgument]? = nil)
{
self.init(verifiedClient: OAuth2Client(issuerURL: issuerURL,
clientId: clientId,
scope: scope,
redirectUri: redirectUri),
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri),
additionalParameters: additionalParameters)
}

Expand All @@ -109,12 +112,14 @@ public actor AuthorizationCodeFlow: AuthenticationFlow {
clientId: String,
scope: some WhitespaceSeparated,
redirectUri: URL,
logoutRedirectUri: URL? = nil,
additionalParameters: [String: any APIRequestArgument]? = nil)
{
self.init(verifiedClient: OAuth2Client(issuerURL: issuerURL,
clientId: clientId,
scope: .init(wrappedValue: scope.whitespaceSeparated),
redirectUri: redirectUri),
redirectUri: redirectUri,
logoutRedirectUri: logoutRedirectUri),
additionalParameters: additionalParameters)
}

Expand Down
18 changes: 11 additions & 7 deletions Tests/BrowserSigninTests/BrowserSigninFlowTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ class BrowserSigninFlowTests: XCTestCase {

@MainActor
func testStart() async throws {
let webAuth = try BrowserSignin(client: client,
additionalParameters: ["testName": name])
let loginFlow = try AuthorizationCodeFlow(client: client,
additionalParameters: ["testName": name])
let webAuth = BrowserSignin(loginFlow: loginFlow, logoutFlow: nil)

try await BrowserSigninProviderFactoryMock.register(
result: .success(URL(string: "com.example:/callback?state=qwe&code=the_auth_code")!),
Expand All @@ -87,8 +88,11 @@ class BrowserSigninFlowTests: XCTestCase {

@MainActor
func testLogout() async throws {
let webAuth = try BrowserSignin(client: client,
additionalParameters: ["testName": name])
let loginFlow = try AuthorizationCodeFlow(client: client,
additionalParameters: ["testName": name])
let logoutFlow = SessionLogoutFlow(client: loginFlow.client,
additionalParameters: loginFlow.additionalParameters)
let webAuth = BrowserSignin(loginFlow: loginFlow, logoutFlow: logoutFlow)

try await BrowserSigninProviderFactoryMock.register(
result: .success(URL(string: "com.example:/logout?state=qwe")!),
Expand All @@ -114,9 +118,9 @@ class BrowserSigninFlowTests: XCTestCase {
}

func testCancel() async throws {
let webAuth = try await BrowserSignin(
client: client,
additionalParameters: ["testName": name])
let loginFlow = try AuthorizationCodeFlow(client: client,
additionalParameters: ["testName": name])
let webAuth = await BrowserSignin(loginFlow: loginFlow, logoutFlow: nil)

try await BrowserSigninProviderFactoryMock.register(
result: .failure(NSError(domain: ASWebAuthenticationSessionErrorDomain,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class BrowserSigninInitializerTests: XCTestCase {
private let logoutRedirectUri = URL(string: "com.example:/logout")!

func testInitializer() async throws {
let auth = try await BrowserSignin(
let auth = await BrowserSignin(
issuerURL: issuer,
clientId: "client_id",
scope: "openid profile",
Expand Down
Loading