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

Server-side auth system #280

Closed
wants to merge 104 commits into from
Closed

Conversation

chriscarrollsmith
Copy link
Contributor

Since we haven't heard from @dalkommatt for over a week, I figure instead of waiting for him to approve my chained PR, I will just open this PR directly to the Vercel repo. Since his edits are still in the commit history, he will still get credit for his work.

Implements:

  • Fully server-side auth flow for all but OAuth (which unfortunately can't be done fully server-side)
  • Dropping the AuthUI dependency (which in addition to being buggy is not compatible with SSR)
  • Working password recovery (which has been broken in AuthUI for quite some time)
  • Simple boolean switches in utils/auth-helpers.ts to control which sign-in methods to allow
  • Preferred sign-in view "saved" in a cookie
  • Toast handling of success and error messages via providing URL query parameters to next/navigation redirect (server-side) or router (client-side)
  • Database reconciliation in the event that Stripe and Supabase customer records get out of sync
  • Stripe webhook error handling and prevention of race condition that sometimes prevented propagation of prices and products from Stripe to Supabase
  • Cascading user deletion through Supabase tables
  • Full update of all dependencies to latest versions
  • Sensible refactoring of some of the file structure and informative comments to make code more interpretable
  • More robust URL handling with improved getUrl function
  • npm run stripe:fixtures command

Closes #278, closes #262, closes #252, closes #254, closes #249, closes #244, closes #236, closes #222, closes #200, closes #190, closes #115

Fixes #269, fixes #267, fixes #265, fixes #255, fixes #248, fixes #241, fixes #225, fixes #224, fixes #184, fixes #170, fixes #80

IMO, the highest priority future update is to implement Supabase foreign data wrappers. A theming system would go a long way toward making this template more usable too. But hopefully this PR is a strong start.

chriscarrollsmith and others added 30 commits November 14, 2023 15:04
Handle empty as well as missing env variables
Re-added comments
Reduced line length and restored chaining operators just in case there's a good reason for including them.
workflows for creating supabase client
constraint, change trial handling per stripe docs
simplified some error message handling on the account page
Throw error if Stripe webhook secret is missing to prevent failure during compile
@Raspber
Copy link

Raspber commented Jan 15, 2024

Contributor

I want to thank you for all your contribution. Thanks for keeping up witht the repo, currently, when a user subcribes i can get the payment to go through using the CLI, but when the user completes the subscription the supabase subscription isnt update. i know i can create a handle and trigger on supabase or i can edit the code in the files. Just wondering what if the best way you recommend. Did you use the supabase create types to get that information? I think if we updated the checkoutwith strip function to include a quick update on the supbase subcription trable as well. I guess i just need a way to input the auth user id into the subscription when its true,

Did you turn on the stripe listener before running the transaction? Open up a terminal and use the command 'pnpm run stripe:listen'. Then run your development server in a separate terminal, and try again. You need the listener running in order to receive events from the Stripe webhook.

thank you for your quick reply. i am using ./stripe listen --forward-to localhost:3000/api/webhooks

update:it is working. Thank you! Im learning and trying to pick up all the changes you made and seeing how its all working.

@chriscarrollsmith
Copy link
Contributor Author

chriscarrollsmith commented Jan 15, 2024 via email

@Raspber
Copy link

Raspber commented Jan 15, 2024

If you've got that running, then you should see the subscription events logged in both that terminal and in the terminal where you're running the development server. When you complete checkout, do you see those event logs? You can also check the Stripe dashboard to make sure it is sending these webhook events and is receiving a success code from your webhook. The subscription update is handled from app/webhook/api/route.ts.

On Sun, Jan 14, 2024, 10:03 PM Hauvert @.> wrote: Contributor I want to thank you for all your contribution. Thanks for keeping up witht the repo, currently, when a user subcribes i can get the payment to go through using the CLI, but when the user completes the subscription the supabase subscription isnt update. i know i can create a handle and trigger on supabase or i can edit the code in the files. Just wondering what if the best way you recommend. Did you use the supabase create types to get that information? I think if we updated the checkoutwith strip function to include a quick update on the supbase subcription trable as well. I guess i just need a way to input the auth user id into the subscription when its true, Did you turn on the stripe listener before running the transaction? Open up a terminal and use the command 'pnpm run stripe:listen'. Then run your development server in a separate terminal, and try again. You need the listener running in order to receive events from the Stripe webhook. thank you for your quick reply. just i am using ./stripe listen --forward-to localhost:3000/api/webhooks — Reply to this email directly, view it on GitHub <#280 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASCYPGNVPRASFPQAFAFQYM3YOSMBDAVCNFSM6AAAAABAOH6B2CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJRGIZTCMJRGU . You are receiving this because you were mentioned.Message ID: @.>

Yes, thank you for your help. Amazing website btw.

@chriscarrollsmith
Copy link
Contributor Author

Thank you!

(now migrates database schema changes from local to remote rather than the other way around
@Raspber
Copy link

Raspber commented Jan 15, 2024

Thank you!

Can you further explain how the webhook are being called? im trying to see how it all works together. I know when you click the subscribe the "handleStripeCheckout" function runs and calls "checkoutWithStripe" us the currentPath how it is activated? Sorry i am a newer dev so this is a bit advanced for me. I would like to use this for my project but only if i can understand how it works because I want to be able to explain.

@chriscarrollsmith
Copy link
Contributor Author

Basically, your webhook is an API endpoint that is always listening.

When we call checkoutWithStripe, basically what happens under the hood is that Stripe spins up a special gateway on their server and gives us a secure link to that gateway, and we redirect the user to that link. Now all the magic happens on the Stripe server; we don't have to worry about taking payment, because they will do it for us.

When the checkout session completes, Stripe sends a webhook event to our webhook API to let us know what happened during the checkout session. They're not actually going to complete the transaction unless they get a success code from us to let them know we received and successfully handled this event. So we receive the event, and we update our database according to the information they sent us. Then, if the database update is successful, we send them a success code. If it fails, we send them an error code.

Once Stripe gets that success or error code, they will let the customer know whether or not the transaction was successful, and then they will redirect them back to our website.

@chriscarrollsmith
Copy link
Contributor Author

By the way, the webhook still needs some work. There are some Stripe events related to subscription/checkout changes (e.g., subscription paused, subscription resumed, session expired) and customer changes (e.g., customer deleted) that we need to support. If you should happen to do that work, feel free to open a PR to my branch.

@Raspber
Copy link

Raspber commented Jan 15, 2024

By the way, the webhook still needs some work. There are some Stripe events related to subscription/checkout changes (e.g., subscription paused, subscription resumed, session expired) and customer changes (e.g., customer deleted) that we need to support. If you should happen to do that work, feel free to open a PR to my branch.

I see. I appreciate the more in depth explanation. I am wondering if this is when/where the webhooks are called
WM-c0074ebc-c8b5-4505-86e5-daaf1024e3db

I am starting to better understand how this is all working. If i can contribute to those improvements you mentioned I will open a PR on your branch like you mentioned.

@Raspber
Copy link

Raspber commented Jan 15, 2024

By the way, the webhook still needs some work. There are some Stripe events related to subscription/checkout changes (e.g., subscription paused, subscription resumed, session expired) and customer changes (e.g., customer deleted) that we need to support. If you should happen to do that work, feel free to open a PR to my branch.

update: I made my way to stripe developers section and see how the you are getting the events. I will try my best to contribute. I appreciate and thank you for your time. Its not often I get replies to questions.

chriscarrollsmith and others added 14 commits February 4, 2024 16:25
if logged in with cookie for user deleted from database
- use turbo for local dev
- fix confirmation email status
- trim user input
- prevent user from updating to same name or email
- fix nextjs logo size on mobile
- fix logo cloud spacing on mobile
- fix navigation buttons not showing on mobile
- bump packages
- improve sign in wording clarity
- drop name requirement on sign up (supabase will collect the name data if the user runs the schema sql)
- re-add schema.sql (why was this dropped?)
- add trimming to form data
@ehowey
Copy link

ehowey commented Feb 11, 2024

This is probably something that could go in a seperate PR. But one of the confusing things I find using this code is how every client is named createClient. I renamed mine to createServerClient, createBrowserClient, createAdminClient and createMiddlewareClient.

This comes into play when working with more complex real life server actions. There are situations like deleting users where you need the admin client. I just find it much easier and clearer with a naming convention like this.

@leerob
Copy link
Member

leerob commented Feb 12, 2024

#278

@leerob leerob closed this Feb 12, 2024
@leerob
Copy link
Member

leerob commented Feb 12, 2024

#278

@chriscarrollsmith chriscarrollsmith deleted the pr278 branch March 8, 2024 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment