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

Lucia branch: ERROR: Failed to produce a Cloudflare Pages build from the project. The route /oauth/[provider] was not configured to run with the Edge Runtime #129

Open
Boscop opened this issue Dec 28, 2023 · 15 comments

Comments

@Boscop
Copy link

Boscop commented Dec 28, 2023

When I run the CF-deploy GH action

- name: Publish to Cloudflare Pages

I get this error:

⚡️ Completed bunx vercel build.

⚡️ ERROR: Failed to produce a Cloudflare Pages build from the project.
⚡️
⚡️ The following routes were not configured to run with the Edge Runtime:
⚡️ - /oauth/[provider]
⚡️
⚡️ Please make sure that all your non-static routes export the following edge runtime route segment config:
⚡️ export const runtime = 'edge';
⚡️
⚡️ You can read more about the Edge Runtime on the Next.js documentation:
⚡️ https://nextjs.org/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes

Any idea why? It didn't happen when I tried deploying the master branch a month ago..

@Boscop
Copy link
Author

Boscop commented Dec 28, 2023

It seems to work when I add export const runtime = 'experimental-edge'; to apps/next/pages/oauth/[provider].tsx.

Is this really necessary / is this the right solution?

Why did it work without it for you before? (I.e. why didn't you have this issue so far when deploying the lucia branch?)

@timothymiller
Copy link
Owner

I've been trying to track this issue down this past week.

Does it work when you set the runtime to 'experimental-edge'?

@timothymiller
Copy link
Owner

The long term solution is going to be moving this server side code to an API endpoint, outside of next.js

@Boscop
Copy link
Author

Boscop commented Dec 28, 2023

Does it work when you set the runtime to 'experimental-edge'?

Yes (like I wrote above in my reply).

I'm just not sure if I should set the runtime to 'experimental-edge' only for this route or for all (in apps/next/next.config.js)..

@rmarscher
Copy link
Contributor

rmarscher commented Dec 28, 2023

Sorry about this. I recently added handling apple oauth form posts and apparently never tested deploying to cloudflare. I must have only been running it locally.

I added some comments to the code to explain what it is doing there. Apple will POST form data to the redirect URI when scopes have been requested. https://developer.apple.com/documentation/sign_in_with_apple/request_an_authorization_to_the_sign_in_with_apple_server

@timothymiller
Copy link
Owner

Does it work when you set the runtime to 'experimental-edge'?

Yes (like I wrote above in my reply).

I'm just not sure if I should set the runtime to 'experimental-edge' only for this route or for all (in apps/next/next.config.js)..

Do you have a deployed example we can test?

When I've deployed this with experimental-edge set, I receive this error server side:
"Error: Some functionality, such as asynchronous I/O, timeouts, and generating random values, can only be performed while handling a request."

@Boscop
Copy link
Author

Boscop commented Dec 28, 2023

Does it work when you set the runtime to 'experimental-edge'?

Yes (like I wrote above in my reply).
I'm just not sure if I should set the runtime to 'experimental-edge' only for this route or for all (in apps/next/next.config.js)..

Do you have a deployed example we can test?

When I've deployed this with experimental-edge set, I receive this error server side: "Error: Some functionality, such as asynchronous I/O, timeouts, and generating random values, can only be performed while handling a request."

I literally just appended export const runtime = 'experimental-edge'; at the bottom of apps/next/pages/oauth/[provider].tsx and it seems to be working.
(I didn't change the config in apps/next/next.config.js.)
Where do you see this server-side error btw? :)

@timothymiller
Copy link
Owner

When signing in with Apple, the redirect will take you to /oauth/apple with some query params. It's on this route that the client displays "internal server error", and if you check the cloudflare logs, you will see the above error.

After I removed the Tamagui provider and components from the route, the getServerSideProps call was able to complete.

@timothymiller
Copy link
Owner

Btw, I'm a big fan of your work on rust bindings for webview 😃

@Boscop
Copy link
Author

Boscop commented Dec 28, 2023

Ah. I didn't setup any oauth providers yet, I only tested with email auth so far.
(And with that, looking at the log stream under Real-time Logs in my worker, I only see successful responses.)

@timothymiller
Copy link
Owner

Email works well. Lmk how signing in with apple works for you.

If someone else can reproduce this error, I'll do a PR for moving the oauth provider logic to an api route.

@rmarscher
Copy link
Contributor

rmarscher commented Dec 29, 2023

Running in the iOS simulator on my #136 branch, I get

email: "[email protected]"
email_verified: "true"

in the parsed ID token payload. For the use case of the current simple auth, that is enough. So maybe implementing the apple form_post handler isn't that important.

@timothymiller
Copy link
Owner

timothymiller commented Dec 29, 2023

Cool! So maybe we can do the getServerSideProps code client side?

@rmarscher
Copy link
Contributor

It already does most of the processing on the client side. The server code is just for making the POST data available somehow for the client. The middleware.ts function works fine with cloudflare so that's another option instead of a nextjs pages api route. It could redirect the browser and include json encoded apple user data in the browser url hash and then the client could grab it and rewrite browser history to take it out. That leaks that user data a bit by sending it in a url request though. A more secure option would be to create a new d1 table to hold authorization code <> user data pairs with an expiration time and write to that from the server when it receives the post data. And then when the client calls sign in, the api server can look up the authorization code in the db and get the additional user data and delete it out of that table. A clean up process would need to be run once in a while to clean up old data in that table. A kv store with expiration or something like that would also work.

@timothymiller
Copy link
Owner

I like the idea of handling it in middleware and returning the value as a cookie that can be deleted once processed client side

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