Skip to content

Connect events and next= on the OAuth door - #295

Merged
czpython merged 1 commit into
mainfrom
oauth-events
Aug 21, 2026
Merged

Connect events and next= on the OAuth door#295
czpython merged 1 commit into
mainfrom
oauth-events

Conversation

@czpython

@czpython czpython commented Aug 21, 2026

Copy link
Copy Markdown
Owner

Two additions to the Connections flow.

Connect events

Extensions that keep per-connection state (a sync cursor, an enable flag)
had no way to hear about a new sign-in — the callback stored the row and
rendered a terminal page, leaving apps to sweep list_for_provider on a
cron. The platform now publishes on the existing signal machinery:

  • oauth.connected — after the callback stores a connection, both
    branches; reconsent is true when it replaced an existing connection's
    tokens. Fields: provider, connection_id, account_id, reconsent.
  • oauth.disconnected — when a connection dies: revoked from the
    Connections page, or purged because the service's client credentials
    were replaced. Same fields, no reconsent.
@subscribe("oauth.connected", provider="acme")
async def adopt_sign_in(
    provider: str, connection_id: str, account_id: str, reconsent: bool
) -> None:
    ...

next= on the connect door

GET /api/oauth/{name}/connect?next=/app/night_watch/accounts rides
the pending-state stash; a successful callback redirects there instead of
rendering the "connected" page, so an app's sign-in button lands the user
back on its own page. Only a bare same-origin path is accepted — it must
start with / and anything host-shaped (//…, /\…, a scheme) is
rejected with 422, so the door cannot become an open redirect.

Both are documented next to the connections section in
writing-an-extension.md.

@czpython czpython changed the title Connect events and return_to on the OAuth door Connect events and next= on the OAuth door Aug 21, 2026
@czpython
czpython force-pushed the oauth-events branch 2 times, most recently from ef8aaa2 to a52cd93 Compare August 21, 2026 06:14
… user back

The platform publishes oauth.connected when a consent completes (reconsent
marks a token replacement) and oauth.disconnected when a connection dies —
revoked, or purged by a client-credential replacement. An extension that
keeps per-connection state subscribes instead of sweeping the table on a
cron.

The connect door takes next, a bare same-origin path that rides the state
stash; a successful callback redirects there instead of rendering the
terminal page, so an app's own sign-in button lands the user back on its
page. Anything host-shaped is rejected — the door is not an open
redirect.
@czpython
czpython merged commit fb310fd into main Aug 21, 2026
1 check passed
@czpython
czpython deleted the oauth-events branch August 21, 2026 06:19
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