Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convex Auth consumes pages that have "code" as search param #145

Open
tomredman opened this issue Dec 19, 2024 · 5 comments
Open

Convex Auth consumes pages that have "code" as search param #145

tomredman opened this issue Dec 19, 2024 · 5 comments

Comments

@tomredman
Copy link

Came across this curious case recently:

  • A user is created and authenticated through Convex Auth, no problem, no sweat.
  • As a business rule, that user needs to be able to connect a Mailchimp account to their profile (entirely independent of Convex Auth)
  • Kick off Mailchimp's oauth flow and upon success, it redirects back to my app, where we're using Convex Auth (e.g. https://my-sick-app.com/app/integrations/mailchimp/connect?code=12345)
image

After some head scratching, I realized my ConvexAuthProvider was snatching up the ?code=12345 portion of my URL, attempting to authenticate it as if it were a sanctioned auth provider, failing, clearing my locally stored auth tokens, ultimately leaving me in a logged-out state.

Unfortunately this all happens prior to my /integrations/mailchimp/connect page loading, so I can't "block" it there, or do anything in that place.

I'm sure I can find a workaround, but it'd be great to somehow (not sure how!) tell Convex Auth not to worry about this ?code, I got it.

image
@thomasballinger
Copy link
Contributor

thomasballinger commented Dec 19, 2024

Sounds like we should be using state= param to the auth request to GitHub, etc. Looking into this now.

@thomasballinger
Copy link
Contributor

Today the Convex Auth middleware sees the ?code= query parameter and assumes the request is intended to be a new login.

I wonder if we can use a more specific query parameter than ?code= to distinguish this, say convexAuthCode=. The OAuth provider's specified redirect (which must contain a ?code= query parameter) sends the browser to the Convex backend, so skips this middleware completely. The code query parameter for the next redirect this is specific to this library.

I need to confirm this, there are other flows but they might all be able to use a different name.

If this doesn't work, we could register certain routes and not oauth-redirectable-to and those routes don't slurp up ?code=
or register certain routes as oauth-redirectable-to and only those routes can be redirected to, checking at runtime so there's a clear error if you do.

@tomredman
Copy link
Author

tomredman commented Dec 20, 2024

Oh, that's good news then @thomasballinger. For now, I have a simple hack that is working well by rewriting the search param in berforeLoad, so there is no urgency on my end.

Trying to do this in the most TanStacky way (vs brute-forcing the param change in the URL):

export const Route = createFileRoute("/_authenticated/integrations/mailchimp")({
  beforeLoad: ({ search }) => {
    if (search.code) {
      const mailchimpCode = search.code;
      delete search.code;
      throw redirect({
        to: "/integrations/mailchimp",
        search: {
          ...search,
          mailchimpCode,
        },
      });
    }
  },
  component: MailchimpComponent,
  validateSearch: (search: Record<string, unknown>): MailchimpSearch => {
    return {
      code: (search.code as string) || undefined,
      mailchimpCode: (search.mailchimpCode as string) || undefined,
    };
  },
});

@thomasballinger
Copy link
Contributor

After some investigation here, the name of the code= query parameter is out of our hands for things like Resend verification emails, which we want to be able to send you back your site URL instead of your Convex backend site URL so that SPA auth flows work well.

The most pragmatic thing seems to be a list of URL patterns to ignore or a callback to examine the request in middleware to know to skip it. This would be a change to middleware, a callback or pattern you pass in that returns true or matches when the ?code= query parameter should be ignored, but normal auth logic should still apply (the Next.js route should still be protected, an user not signed in will still be e.g. redirected to /sign-in).

Any design thoughts welcome, I'm going to hit some more urgent auth things first but if this blocking anyone else please let me know and we can reprioritize.

@sshader
Copy link
Contributor

sshader commented Dec 23, 2024

the name of the code= query parameter is out of our hands for things like Resend verification emails

I don't think this is true -- we're just hardcoding that the parameter is named code without allowing any customization here

So an alternative option here would be allowing the name of the query param to be customizable (but still intercepting the query param on every request). But I think it might be more straightforward to allow configuring which routes should expect a code query param and which to leave alone.

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

No branches or pull requests

3 participants