|
12 | 12 | /** |
13 | 13 | * External user agent that uses the iOS 17.4+ ASWebAuthenticationSession https callback |
14 | 14 | * (ASWebAuthenticationSessionCallback callbackWithHTTPSHost:path:). With an https |
15 | | - * (universal link) redirect URI, AppAuth-iOS passes "https" as the callbackURLScheme — |
16 | | - * which ASWebAuthenticationSession does not support — so the session never intercepts |
| 15 | + * (universal link) redirect URI, AppAuth-iOS passes "https" as the callbackURLScheme - |
| 16 | + * which ASWebAuthenticationSession does not support - so the session never intercepts |
17 | 17 | * the redirect and the flow has to rely on the universal link opening the app, which is |
18 | 18 | * not triggered by server redirects/JS navigation inside the session and is sporadically |
19 | 19 | * dropped, leaving authorize() pending forever (#987, #932; openid/AppAuth-iOS#367). |
|
22 | 22 | * Requires the callback host to be an associated domain with the webcredentials service |
23 | 23 | * type (entitlement + apple-app-site-association). When the association is missing the |
24 | 24 | * agent transparently falls back to the legacy callbackURLScheme session, preserving |
25 | | - * AppAuth's default behavior. |
| 25 | + * AppAuth default behavior. |
26 | 26 | */ |
27 | 27 | API_AVAILABLE(ios(17.4)) |
28 | 28 | @interface RNAppAuthHTTPSExternalUserAgent : NSObject <OIDExternalUserAgent, ASWebAuthenticationPresentationContextProviding> |
@@ -845,8 +845,8 @@ - (void)rejectPromise:(RCTPromiseRejectBlock)reject |
845 | 845 | @end |
846 | 846 |
|
847 | 847 | /** |
848 | | - * Implementation modeled on AppAuth's OIDExternalUserAgentIOS, but built with |
849 | | - * [ASWebAuthenticationSessionCallback callbackWithHTTPSHost:path:] so the session |
| 848 | + * Implementation modeled on AppAuth's OIDExternalUserAgentIOS, but built |
| 849 | + * with [ASWebAuthenticationSessionCallback callbackWithHTTPSHost:path:] so the session |
850 | 850 | * intercepts the https redirect itself (iOS 17.4+). |
851 | 851 | */ |
852 | 852 | @implementation RNAppAuthHTTPSExternalUserAgent { |
@@ -923,10 +923,13 @@ - (ASWebAuthenticationSession *)authenticationSessionWithHTTPSCallback:(BOOL)use |
923 | 923 | [strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL]; |
924 | 924 | return; |
925 | 925 | } |
926 | | - BOOL isUserCancel = [error.domain isEqualToString:ASWebAuthenticationSessionErrorDomain] && |
927 | | - error.code == ASWebAuthenticationSessionErrorCodeCanceledLogin; |
928 | | - if (useHTTPSCallback && !isUserCancel && [strongSelf startLegacyFallbackSession]) { |
929 | | - // Missing/unvalidated webcredentials association — legacy session took over |
| 926 | + // A missing webcredentials association is reported with the SAME error code as a |
| 927 | + // user cancellation (ASWebAuthenticationSessionErrorCodeCanceledLogin) — but it |
| 928 | + // carries an NSLocalizedFailureReason ("...requires Associated Domains using the |
| 929 | + // `webcredentials` service type..."), which genuine user cancellations do not. |
| 930 | + NSString *failureReason = error.userInfo[NSLocalizedFailureReasonErrorKey]; |
| 931 | + if (useHTTPSCallback && failureReason.length > 0 && [strongSelf startLegacyFallbackSession]) { |
| 932 | + // Association missing/unvalidated — legacy session took over |
930 | 933 | return; |
931 | 934 | } |
932 | 935 | NSError *safariError = |
|
0 commit comments