@@ -756,33 +756,32 @@ public final class AuthClient: Sendable {
756756 /// Gets the session data from a OAuth2 callback URL.
757757 @discardableResult
758758 public func session( from url: URL ) async throws -> Session {
759- logger? . debug ( " received \( url) " )
759+ logger? . debug ( " Received URL: \( url) " )
760760
761761 let params = extractParams ( from: url)
762762
763- if configuration. flowType == . implicit, !isImplicitGrantFlow( params: params) {
764- throw AuthError . implicitGrantRedirect ( message: " Not a valid implicit grant flow url: \( url) " )
765- }
766-
767- if configuration. flowType == . pkce, !isPKCEFlow( params: params) {
768- throw AuthError . pkceGrantCodeExchange ( message: " Not a valid PKCE flow url: \( url) " )
769- }
770-
771- if isPKCEFlow ( params: params) {
772- guard let code = params [ " code " ] else {
773- throw AuthError . pkceGrantCodeExchange ( message: " No code detected. " )
763+ switch configuration. flowType {
764+ case . implicit:
765+ guard isImplicitGrantFlow ( params: params) else {
766+ throw AuthError . implicitGrantRedirect (
767+ message: " Not a valid implicit grant flow URL: \( url) " )
774768 }
769+ return try await handleImplicitGrantFlow ( params: params)
775770
776- let session = try await exchangeCodeForSession ( authCode: code)
777- return session
771+ case . pkce:
772+ guard isPKCEFlow ( params: params) else {
773+ throw AuthError . pkceGrantCodeExchange ( message: " Not a valid PKCE flow URL: \( url) " )
774+ }
775+ return try await handlePKCEFlow ( params: params)
778776 }
777+ }
779778
780- if params [ " error " ] != nil || params [ " error_description " ] != nil || params [ " error_code " ] != nil {
781- throw AuthError . pkceGrantCodeExchange (
782- message : params [ " error_description " ] ?? " Error in URL with unspecified error_description. " ,
783- error : params [ " error " ] ?? " unspecified_error " ,
784- code : params [ " error_code " ] ?? " unspecified_code "
785- )
779+ private func handleImplicitGrantFlow ( params: [ String : String ] ) async throws -> Session {
780+ precondition ( configuration . flowType == . implicit , " Method only allowed for implicit flow. " )
781+
782+ if let errorDescription = params [ " error_description " ] {
783+ throw AuthError . implicitGrantRedirect (
784+ message : errorDescription . replacingOccurrences ( of : " + " , with : " " ) )
786785 }
787786
788787 guard
@@ -827,6 +826,25 @@ public final class AuthClient: Sendable {
827826 return session
828827 }
829828
829+ private func handlePKCEFlow( params: [ String : String ] ) async throws -> Session {
830+ precondition ( configuration. flowType == . pkce, " Method only allowed for PKCE flow. " )
831+
832+ if params [ " error " ] != nil || params [ " error_description " ] != nil || params [ " error_code " ] != nil {
833+ throw AuthError . pkceGrantCodeExchange (
834+ message: params [ " error_description " ] ? . replacingOccurrences ( of: " + " , with: " " )
835+ ?? " Error in URL with unspecified error_description. " ,
836+ error: params [ " error " ] ?? " unspecified_error " ,
837+ code: params [ " error_code " ] ?? " unspecified_code "
838+ )
839+ }
840+
841+ guard let code = params [ " code " ] else {
842+ throw AuthError . pkceGrantCodeExchange ( message: " No code detected. " )
843+ }
844+
845+ return try await exchangeCodeForSession ( authCode: code)
846+ }
847+
830848 /// Sets the session data from the current session. If the current session is expired, setSession
831849 /// will take care of refreshing it to obtain a new session.
832850 ///
@@ -1304,7 +1322,8 @@ public final class AuthClient: Sendable {
13041322
13051323 private func isPKCEFlow( params: [ String : String ] ) -> Bool {
13061324 let currentCodeVerifier = codeVerifierStorage. get ( )
1307- return params [ " code " ] != nil && currentCodeVerifier != nil
1325+ return params [ " code " ] != nil || params [ " error_description " ] != nil || params [ " error " ] != nil
1326+ || params [ " error_code " ] != nil && currentCodeVerifier != nil
13081327 }
13091328
13101329 private func getURLForProvider(
0 commit comments