Skip to content

[flutter_appauth] macOS: also resume the authorization flow from the app lifecycle - #672

Open
cristianmgm7 wants to merge 1 commit into
MaikuB:masterfrom
PhononX:fix/macos-resume-via-app-lifecycle-master
Open

[flutter_appauth] macOS: also resume the authorization flow from the app lifecycle#672
cristianmgm7 wants to merge 1 commit into
MaikuB:masterfrom
PhononX:fix/macos-resume-via-app-lifecycle-master

Conversation

@cristianmgm7

Copy link
Copy Markdown

On macOS the plugin installs a kAEGetURL Apple Event handler so an authorization redirect delivered from outside the app's own browser session can resume the pending flow. In a large class of host apps that handler never runs.

NSAppleEventManager setEventHandler: replaces any existing handler for the event. AppKit installs its own during finishLaunching — the one that drives application:openURLs: — and plugin registration happens earlier, during nib loading. So AppKit's registration wins and handleGetURLEvent: is silently dead in any app whose delegate implements application:openURLs:, which is any app with deep links.

The symptom is a login that hangs with no error and no cancellation: the redirect reaches the host app, the plugin never sees it, and the pending OIDExternalUserAgentSession is never resumed. It shows up with flows whose redirect legitimately returns through a different browser — an emailed magic link, where the user opens the link from their mail client.

The change: also register the plugin with addApplicationDelegate: and implement handleOpenURLs:, so the resume happens on whichever path actually delivers the URL. The two paths are safe together — the flow is cleared after the first successful resume, and handleOpenURLs: returns YES only when a pending flow accepted the URL, leaving unrelated deep links to the host app. The macOS header declares FlutterAppLifecycleDelegate conformance, which addApplicationDelegate: requires.

Verified on macOS against a Keycloak realm: without this the flow hangs indefinitely; with it the authorization completes normally. iOS already registers via addApplicationDelegate: and is untouched by this change.

…fecycle too

`registerWithRegistrar:` installs a kAEGetURL handler so an authorization
redirect delivered from outside the app's own browser session can resume
the pending flow. That handler never runs in a large class of host apps.

`NSAppleEventManager setEventHandler:` replaces any existing handler for
that event, and AppKit installs its own during `finishLaunching` — the one
that drives `application:openURLs:`. Plugin registration happens earlier,
during nib loading, so AppKit's registration wins and the plugin's handler
is silently dead in every app whose delegate implements
`application:openURLs:`. That is any app with deep links.

The symptom is a login that hangs with no error and no cancellation: the
redirect reaches the host app, the plugin never sees it, and the pending
`OIDExternalUserAgentSession` is never resumed. It shows up with flows
whose redirect legitimately comes back through a different browser — an
emailed magic link, for example, where the user opens the link from their
mail client.

Registering the plugin as a `FlutterAppLifecycleDelegate` makes
`FlutterAppDelegate` forward `application:openURLs:` to it as well, so the
resume happens on whichever path actually delivers the URL. The two paths
are safe together: the flow is cleared after the first successful resume,
and `handleOpenURLs:` returns YES only when a pending flow accepted the
URL, leaving unrelated deep links to the host app.

Verified on macOS against a Keycloak realm: without this the flow hangs
indefinitely; with it the authorization completes normally. iOS already
registers via `addApplicationDelegate:` and is unaffected.
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.

1 participant