Skip to content

Conversation

@subhankarmaiti
Copy link
Contributor

@subhankarmaiti subhankarmaiti commented Dec 11, 2025

Adds authorizeWithRequestUri(requestURI:) method to WebAuth protocol for PAR (Pushed Authorization Request) flows that return the authorization code instead of credentials.

New API

// Async/await
let authCode = try await Auth0.webAuth().authorizeWithRequestUri(requestURI: "urn:ietf:params:oauth:request_uri:...")

// Callback
Auth0.webAuth().authorizeWithRequestUri(requestURI: requestURI) { result in
    // result contains AuthorizationCode with .code and optional .state
}

// Combine
Auth0.webAuth().authorizeWithRequestUri(requestURI: requestURI)

@subhankarmaiti subhankarmaiti requested a review from a team as a code owner December 11, 2025 05:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for PAR (Pushed Authorization Request) flows in the SDK, enabling Backend-For-Frontend (BFF) authentication patterns. The new startForCode(requestURI:) method returns only the authorization code instead of performing token exchange, allowing backends to handle the secure token exchange using their client secret.

Key changes:

  • Introduces new startForCode(requestURI:) API with callback, async/await, and Combine variants
  • Returns AuthorizationCode struct containing the code and optional state parameter
  • Implements PARCodeTransaction to handle the authorization flow without token exchange

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Auth0/WebAuth.swift Added protocol definitions for startForCode(requestURI:) methods with comprehensive documentation
Auth0/Auth0WebAuth.swift Implemented startForCode methods and PAR-specific authorize URL builder
Auth0/AuthorizationCode.swift New public struct to encapsulate authorization code and state from PAR callbacks
Auth0/PARCodeTransaction.swift New transaction handler for PAR code flows, similar to LoginTransaction but returns codes instead of credentials
Auth0Tests/PARCodeTransactionSpec.swift Comprehensive test coverage for PARCodeTransaction including success, error, and cancellation scenarios
EXAMPLES.md Added PAR usage documentation with examples for callback, async/await, and Combine patterns
Auth0.xcodeproj/project.pbxproj Updated project file to include new source files in build targets

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@subhankarmaiti subhankarmaiti changed the title feat: Add startForCode method for PAR-based authentication feat: Add authorizeWithRequestUri method for PAR-based authentication Dec 12, 2025
}

private func buildPARAuthorizeURL(requestURI: String) -> URL {
guard let authorize = self.overrideAuthorizeURL ?? URL(string: "authorize", relativeTo: self.url),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming can be authorizeURL

// Step 4: Send code to BFF to exchange for tokens
let credentials = try await yourBffClient.exchangeCode(authorizationCode.code)
credentialsManager.store(credentials: credentials)
} catch let error as WebAuthError where error.isUserCancelled {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error handling can be kept uniform across async await and combine example

let provider = self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL,
ephemeralSession: ephemeralSession,
headers: headers)
let userAgent = provider(authorizeURL) { [storage, barrier, onCloseCallback] result in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets update this to use weak self and refer to storage and barrier via self inside the closure. Capturing them strongly poses a risk of memory leaks. I’ve noticed that in some of the existing code we are capturing these strongly, so it would be great to do refactoring there too


private(set) var userAgent: WebAuthUserAgent?

let redirectURL: URL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: all of these data members could be private if they aint being called internally from other structs/classes.


let authorizeURL = self.buildPARAuthorizeURL(requestURI: requestURI)

let provider = self.provider ?? WebAuthentication.asProvider(redirectURL: redirectURL,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provider property can take headers as parameters. Are those header values something that we need to pass to the authorize end point ?

}

private func handleCallback(url: URL) -> Bool {
guard url.absoluteString.lowercased().hasPrefix(self.redirectURL.absoluteString.lowercased()),
Copy link
Contributor

@sanchitmehta94 sanchitmehta94 Dec 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: lets avoid lowercased() for the full uri here it would create false positives for this validation. we could have lowercased() for scheme and domain

Comment on lines +48 to +56
if let fragment = components.fragment {
let fragmentItems = fragment.split(separator: "&").compactMap { pair -> (String, String)? in
let parts = pair.split(separator: "=", maxSplits: 1)
guard parts.count == 2 else { return nil }
return (String(parts[0]), String(parts[1]))
}
fragmentItems.forEach { items[$0.0] = $0.1 }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could not find the usage of fragments in subsequent code flow. if we do need fragment parsing we can put a fragment parser in utility or else please remove this

Copy link
Contributor

@sanchitmehta94 sanchitmehta94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@sanchitmehta94 sanchitmehta94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@sanchitmehta94 sanchitmehta94 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants