Skip to content

handbook: clear the OAuth callback parameters off the Studio landing page - #5809

Merged
ZJvandeWeg merged 1 commit into
mainfrom
fix/studio-oauth-callback-params
Sep 15, 2026
Merged

ZJvandeWeg merged 1 commit into
mainfrom
fix/studio-oauth-callback-params

Conversation

@dimitrieh

@dimitrieh dimitrieh commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Description

After signing in to Studio, you land on a clean URL instead of one carrying GitHub's OAuth parameters.

URL you land on
Before /handbook/?code=4b55bf56c558e9767106&iss=https://github.com/login/oauth&state=phtnIFy-...
After /handbook/

Why it matters: state is different on every sign-in, so today each one reports its own $current_url to PostHog and the handbook's page stats split into a new row per sign-in. A spent authorization code also sits in the URL bar and browser history, and travels along if anyone copies the link.

Follow-up to #5690. Sign-in itself works and is unchanged.

Where the parameters come from

This host appends the request's own query string to every relative redirect Location. A junk parameter shows it:

$ curl -sSI 'https://flowfuse.com/_studio?zzz=test' | grep -i location
location: /__nuxt_studio/auth/github?zzz=test     # the handler emits no query of its own

GitHub returns to /__nuxt_studio/auth/github?code=&iss=&state=. That handler finishes by redirecting to the page you asked to edit, and the query it was called with rides along. Nothing reads the parameters by then.

How it is fixed

A small inline script in <head> drops the three parameters with history.replaceState.

Inline and in the head on purpose: it has to run before the PostHog snippet, which is appended at the end of <body>, and before Nuxt boots so the router starts from the cleaned URL.

It only acts when a code and GitHub's own iss value are both present, so an unrelated ?code= elsewhere on the site is untouched.

Testing

Against the deploy preview:

  • the reported URL lands as /handbook/, location.search empty, page rendered normally, and history.length unchanged so it replaces rather than adds an entry;
  • /handbook/?utm_source=slack&code=PROMO20 is left exactly as-is.

The snippet was also checked directly against a foreign iss, unrelated query parameters on the same landing (kept), and a hash fragment (kept).

Related Issue(s)

None.

Checklist

  • I have read the contribution guidelines
  • I have considered the performance impact of these changes
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
  • For blog PRs, an Art Request has been created (instructions)

@netlify

netlify Bot commented Sep 15, 2026

Copy link
Copy Markdown

Deploy Preview for flowfuse-website ready!

Name Link
🔨 Latest commit b9d1391
🔍 Latest deploy log https://app.netlify.com/projects/flowfuse-website/deploys/6aa9536dc4556900085d8425
😎 Deploy Preview https://deploy-preview-5809--flowfuse-website.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 39 (🟢 up 8 from production)
Accessibility: 95 (no change from production)
Best Practices: 92 (no change from production)
SEO: 92 (no change from production)
PWA: -
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

…page

Studio's GitHub sign-in returns to /__nuxt_studio/auth/github?code=&iss=&state=,
and that handler finishes by redirecting to the page you asked to edit. This host
appends the request's own query string to every relative redirect Location, so the
three OAuth parameters ride along and the landing URL reads

  https://flowfuse.com/handbook/?code=...&iss=https://github.com/login/oauth&state=...

Sign-in has already completed at that point and nothing reads them, but they leave a
spent authorization code in the URL bar and in browser history, and state is unique
per sign-in, so every landing also reports its own $current_url to PostHog instead of
the page's real URL.

A small inline script in <head> drops the three parameters with history.replaceState.
It is inline and in the head so it runs before the PostHog snippet appended at the end
of <body>, and before Nuxt boots, so the router starts from the cleaned URL. It only
acts when both a code and GitHub's own iss value are present.
@dimitrieh
dimitrieh force-pushed the fix/studio-oauth-callback-params branch from 1de2c39 to b9d1391 Compare September 15, 2026 14:17
@ZJvandeWeg
ZJvandeWeg merged commit a5f0d06 into main Sep 15, 2026
7 checks passed
@ZJvandeWeg
ZJvandeWeg deleted the fix/studio-oauth-callback-params branch September 15, 2026 17:47
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.

2 participants