Skip to content

[web-browser] Add support for auth universal links callback#42695

Merged
gabrieldonadel merged 4 commits intomainfrom
@gabrieldonadel/web-browser-universal-links
Feb 24, 2026
Merged

[web-browser] Add support for auth universal links callback#42695
gabrieldonadel merged 4 commits intomainfrom
@gabrieldonadel/web-browser-universal-links

Conversation

@gabrieldonadel
Copy link
Copy Markdown
Member

@gabrieldonadel gabrieldonadel commented Jan 29, 2026

Why

openAuthSessionAsync currently uses ASWebAuthenticationSession with callbackURLScheme, which only supports custom URL scheme callbacks. Starting with iOS 17.4/macOS 14.4, Apple introduced a new callback API (.https(host:path:)) that supports HTTPS universal link callbacks, enabling more secure auth flows without relying on custom URL schemes.

How

  • On iOS 17.4+/macOS 14.4+, when the redirect URL has an https scheme with a non-empty host, WebAuthSession now uses the new ASWebAuthenticationSession(url:callback:completionHandler:) initializer with .https(host:path:) callback matching. On older OS versions or when using custom scheme redirect URLs, keep using the existing callbackURLScheme API.
  • Updated the NCL OpenAuthSessionAsyncDemo to use real GitHub OAuth instead of fake-auth.netlify.com, which was no longer working.
  • Configured bare-expo with associated domains (applinks + webcredentials for bare-expo.expo.app) to enable HTTPS callback testing.

Test Plan

  • Open the WebBrowser screen in NCL/bare-expo
  • In the openAuthSessionAsync section, select Custom Scheme redirect URL → tap GitHub → verify the GitHub OAuth page opens and the auth flow completes with a success result
  • Switch to HTTPS (Universal Link) redirect URL → tap GitHub → verify the auth flow works using the HTTPS callback path (requires associated domains to be properly configured for bare-expo.expo.app)

Checklist

@expo-bot expo-bot added the bot: suggestions ExpoBot has some suggestions label Jan 29, 2026
@expo-bot
Copy link
Copy Markdown
Collaborator

expo-bot commented Jan 29, 2026

The Pull Request introduced fingerprint changes against the base commit: 796c709

Fingerprint diff
[
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "../../packages/expo-web-browser/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "377da013f61c00aa6fbab8be357e544069e7d80a"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "../../packages/expo-web-browser/ios",
      "reasons": [
        "expoAutolinkingIos"
      ],
      "hash": "bd92089ca320b28e8d2c9ecb067df7800023678e"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "8f1093c6ad5769f033f75abeba93ed394cc71b0a"
    },
    "afterSource": {
      "type": "dir",
      "filePath": "ios",
      "reasons": [
        "bareNativeDir"
      ],
      "hash": "43f0145c0a069a2cde40267b394ed6337398faaa"
    }
  },
  {
    "op": "changed",
    "beforeSource": {
      "type": "contents",
      "id": "expoConfig",
      "contents": "{\"android\":{\"adaptiveIcon\":{\"backgroundColor\":\"#000020\",\"foregroundImage\":\"./assets/adaptive-icon.png\"},\"package\":\"dev.expo.payments\",\"permissions\":[\"android.permission.ACCESS_BACKGROUND_LOCATION\",\"android.permission.ACCESS_COARSE_LOCATION\",\"android.permission.ACCESS_FINE_LOCATION\",\"android.permission.FOREGROUND_SERVICE\",\"android.permission.FOREGROUND_SERVICE_LOCATION\",\"android.permission.RECEIVE_BOOT_COMPLETED\",\"android.permission.WAKE_LOCK\",\"com.google.android.gms.permission.AD_ID\"],\"scheme\":[\"com.googleusercontent.apps.29635966244-knmlpr1upnv6rs4bumqea7hpit4o7kg2\"]},\"extra\":{\"eas\":{\"projectId\":\"2c28de10-a2cd-11e6-b8ce-59d1587e6774\"}},\"facebookAppId\":\"629712900716487\",\"facebookDisplayName\":\"Expo APIs\",\"facebookScheme\":\"fb629712900716487\",\"icon\":\"./assets/icon.png\",\"ios\":{\"bundleIdentifier\":\"dev.expo.Payments\",\"entitlements\":{\"com.apple.security.application-groups\":[\"group.dev.expo.Payments\"]},\"requireFullScreen\":false,\"scheme\":[\"com.googleusercontent.apps.29635966244-v8mbqt2mtno71thelt7f2i6pob104f6e\",\"msauth.dev.expo.Payments\"],\"supportsTablet\":true},\"name\":\"BareExpo\",\"notification\":{\"serviceWorkerPath\":\"/expo-service-worker.js\",\"vapidPublicKey\":\"BNHvR05XkY5LH9GdN0GreLx2wZnK9IwNJGVmo3jujIkFni4of26E3U3fnt9nUrZfM7h0omdIHKM0eshkzTSFOWQ\"},\"platforms\":[\"android\",\"ios\",\"web\"],\"plugins\":[\"./plugins/withAndroidNetworkSecurityConfig\",\"./plugins/withBenchmarkModules\",\"expo-background-fetch\",\"expo-video\",[\"expo-build-properties\",{\"android\":{\"enableMinifyInReleaseBuilds\":true}}],[\"expo-font\",{\"fonts\":[\"./assets/icomoon.ttf\"]}],[\"expo-location\",{\"androidForegroundServiceIcon\":\"./assets/location_service_icon.png\",\"isAndroidBackgroundLocationEnabled\":true,\"isIosBackgroundLocationEnabled\":true}],[\"expo-notifications\",{\"color\":\"#4630EB\",\"icon\":\"./assets/ic_stat_notifications.png\",\"sounds\":[\"./assets/notification.wav\"]}],[\"expo-tracking-transparency\",{\"userTrackingPermission\":\"Allow Expo projects to use data for tracking the user or the device\"}]],\"privacy\":\"unlisted\",\"runtimeVersion\":\"1.0.0\",\"scheme\":\"bareexpo\",\"sdkVersion\":\"55.0.0\",\"slug\":\"bare-expo\",\"splash\":{\"backgroundColor\":\"#000020\",\"image\":\"./assets/splash.png\",\"resizeMode\":\"cover\"},\"updates\":{\"url\":\"https://u.expo.dev/2c28de10-a2cd-11e6-b8ce-59d1587e6774\"},\"userInterfaceStyle\":\"automatic\",\"version\":\"1.0.0\",\"web\":{\"bundler\":\"metro\"}}",
      "reasons": [
        "expoConfig"
      ],
      "hash": "ebc86ae046f23b0ccc2b3e4fc3282a63a1b84091"
    },
    "afterSource": {
      "type": "contents",
      "id": "expoConfig",
      "contents": "{\"android\":{\"adaptiveIcon\":{\"backgroundColor\":\"#000020\",\"foregroundImage\":\"./assets/adaptive-icon.png\"},\"package\":\"dev.expo.payments\",\"permissions\":[\"android.permission.ACCESS_BACKGROUND_LOCATION\",\"android.permission.ACCESS_COARSE_LOCATION\",\"android.permission.ACCESS_FINE_LOCATION\",\"android.permission.FOREGROUND_SERVICE\",\"android.permission.FOREGROUND_SERVICE_LOCATION\",\"android.permission.RECEIVE_BOOT_COMPLETED\",\"android.permission.WAKE_LOCK\",\"com.google.android.gms.permission.AD_ID\"],\"scheme\":[\"com.googleusercontent.apps.29635966244-knmlpr1upnv6rs4bumqea7hpit4o7kg2\"]},\"extra\":{\"eas\":{\"projectId\":\"2c28de10-a2cd-11e6-b8ce-59d1587e6774\"}},\"facebookAppId\":\"629712900716487\",\"facebookDisplayName\":\"Expo APIs\",\"facebookScheme\":\"fb629712900716487\",\"icon\":\"./assets/icon.png\",\"ios\":{\"associatedDomains\":[\"applinks:bare-expo.expo.app\",\"webcredentials:bare-expo.expo.app\"],\"bundleIdentifier\":\"dev.expo.Payments\",\"entitlements\":{\"com.apple.security.application-groups\":[\"group.dev.expo.Payments\"]},\"requireFullScreen\":false,\"scheme\":[\"com.googleusercontent.apps.29635966244-v8mbqt2mtno71thelt7f2i6pob104f6e\",\"msauth.dev.expo.Payments\"],\"supportsTablet\":true},\"name\":\"BareExpo\",\"notification\":{\"serviceWorkerPath\":\"/expo-service-worker.js\",\"vapidPublicKey\":\"BNHvR05XkY5LH9GdN0GreLx2wZnK9IwNJGVmo3jujIkFni4of26E3U3fnt9nUrZfM7h0omdIHKM0eshkzTSFOWQ\"},\"platforms\":[\"android\",\"ios\",\"web\"],\"plugins\":[\"./plugins/withAndroidNetworkSecurityConfig\",\"./plugins/withBenchmarkModules\",\"expo-background-fetch\",\"expo-video\",[\"expo-build-properties\",{\"android\":{\"enableMinifyInReleaseBuilds\":true}}],[\"expo-font\",{\"fonts\":[\"./assets/icomoon.ttf\"]}],[\"expo-location\",{\"androidForegroundServiceIcon\":\"./assets/location_service_icon.png\",\"isAndroidBackgroundLocationEnabled\":true,\"isIosBackgroundLocationEnabled\":true}],[\"expo-notifications\",{\"color\":\"#4630EB\",\"icon\":\"./assets/ic_stat_notifications.png\",\"sounds\":[\"./assets/notification.wav\"]}],[\"expo-tracking-transparency\",{\"userTrackingPermission\":\"Allow Expo projects to use data for tracking the user or the device\"}]],\"privacy\":\"unlisted\",\"runtimeVersion\":\"1.0.0\",\"scheme\":\"bareexpo\",\"sdkVersion\":\"55.0.0\",\"slug\":\"bare-expo\",\"splash\":{\"backgroundColor\":\"#000020\",\"image\":\"./assets/splash.png\",\"resizeMode\":\"cover\"},\"updates\":{\"url\":\"https://u.expo.dev/2c28de10-a2cd-11e6-b8ce-59d1587e6774\"},\"userInterfaceStyle\":\"automatic\",\"version\":\"1.0.0\",\"web\":{\"bundler\":\"metro\"}}",
      "reasons": [
        "expoConfig"
      ],
      "hash": "630d49569edfc74a216aaebf41cff3e9fd49abba"
    }
  }
]

Generated by PR labeler 🤖

@KimmoHernborg
Copy link
Copy Markdown

Hi, we are experiencing issues when moving to Universal / App links (see this link for more information why: https://auth0.com/docs/secure/security-guidance/measures-against-app-impersonation). Just wanted to say that this pull request is of high importance to us.

@gabrieldonadel gabrieldonadel force-pushed the @gabrieldonadel/web-browser-universal-links branch from 8663207 to 98b3e3b Compare February 16, 2026 22:31
@gabrieldonadel gabrieldonadel force-pushed the @gabrieldonadel/web-browser-universal-links branch from 7e5893b to e38c5f0 Compare February 24, 2026 12:35
@gabrieldonadel gabrieldonadel force-pushed the @gabrieldonadel/web-browser-universal-links branch from e38c5f0 to 1a32267 Compare February 24, 2026 19:53
@gabrieldonadel gabrieldonadel marked this pull request as ready for review February 24, 2026 20:00
@github-actions
Copy link
Copy Markdown
Contributor

Subscribed to pull request

File Patterns Mentions
packages/expo-web-browser/** @alanjhughes

Generated by CodeMention

gabrieldonadel and others added 2 commits February 24, 2026 21:32
Co-authored-by: Alan Hughes <30924086+alanjhughes@users.noreply.github.com>
@expo-bot expo-bot added bot: passed checks ExpoBot has nothing to complain about and removed bot: suggestions ExpoBot has some suggestions labels Feb 24, 2026
@gabrieldonadel gabrieldonadel merged commit f9de901 into main Feb 24, 2026
23 of 24 checks passed
@gabrieldonadel gabrieldonadel deleted the @gabrieldonadel/web-browser-universal-links branch February 24, 2026 23:20
gabrieldonadel added a commit that referenced this pull request Feb 26, 2026
`openAuthSessionAsync` currently uses `ASWebAuthenticationSession` with
`callbackURLScheme`, which only supports custom URL scheme callbacks.
Starting with iOS 17.4/macOS 14.4, Apple introduced a new callback API
(`.https(host:path:)`) that supports HTTPS universal link callbacks,
enabling more secure auth flows without relying on custom URL schemes.

- On iOS 17.4+/macOS 14.4+, when the redirect URL has an `https` scheme
with a non-empty host, `WebAuthSession` now uses the new
`ASWebAuthenticationSession(url:callback:completionHandler:)`
initializer with `.https(host:path:)` callback matching. On older OS
versions or when using custom scheme redirect URLs, keep using the
existing `callbackURLScheme` API.
- Updated the NCL `OpenAuthSessionAsyncDemo` to use real GitHub OAuth
instead of `fake-auth.netlify.com`, which was no longer working.
- Configured `bare-expo` with associated domains (`applinks` +
`webcredentials` for `bare-expo.expo.app`) to enable HTTPS callback
testing.

- Open the WebBrowser screen in NCL/bare-expo
- In the `openAuthSessionAsync` section, select **Custom Scheme**
redirect URL → tap **GitHub** → verify the GitHub OAuth page opens and
the auth flow completes with a `success` result
- Switch to **HTTPS (Universal Link)** redirect URL → tap **GitHub** →
verify the auth flow works using the HTTPS callback path (requires
associated domains to be properly configured for `bare-expo.expo.app`)

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Alan Hughes <30924086+alanjhughes@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot: fingerprint changed bot: passed checks ExpoBot has nothing to complain about

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants