From 5b2fe2f6c9cd5df060a573025ccb322c3076f8fd Mon Sep 17 00:00:00 2001 From: Michael Dausmann Date: Sat, 1 Apr 2023 16:53:47 +1100 Subject: [PATCH] Signup flow + switch to serverSupabaseUser in context (fixes token refresh issue)+ lib upgrades for nuxt/supabase and nuxt/trpc --- README.md | 12 +- components/AppFooter.vue | 4 +- components/AppHeader.vue | 16 +- lib/services/user.account.service.ts | 2 +- lib/services/util.service.ts | 17 + package-lock.json | 828 +++++++++++++++------------ package.json | 4 +- pages/index.vue | 3 +- pages/pricing.vue | 23 +- pages/signin.vue | 42 ++ pages/signup.vue | 42 ++ pages/success.vue | 2 +- server/trpc/context.ts | 16 +- 13 files changed, 604 insertions(+), 407 deletions(-) create mode 100644 pages/signin.vue create mode 100644 pages/signup.vue diff --git a/README.md b/README.md index 88fa99a..910288f 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,12 @@ pnpm install --shamefully-hoist ## Development Server +Start the Stripe thingy + +```bash +stripe listen --forward-to localhost:3000/webhook +``` + Start the development server on http://localhost:3000 ```bash @@ -77,7 +83,7 @@ npm run dev -- -o ## Setup Supabase To setup supabase and middleware, loosely follow instructions from https://www.youtube.com/watch?v=IcaL1RfnU44 - +remember to update email template Supabase - new account (free tier), used github oath for supabase account ``` @@ -139,8 +145,8 @@ I set up a Stripe account with a couple of 'Products' with a single price each t -- add a pricing page....should be the default redirect from signup if the user has no active plan.. not sure whether to use a 'blank' plan or make plan nullable (basic pricing page is done - decided on 'no plan' plan) -- figure out what to do with Plan Name. Could add Plan Name to account record and copy over at time of account creation or updation. could pull from the Plan record for display.... but makes it difficult to change... should be loosely coupled, maybe use first approach (done) -- figure out when/how plan changes.. is it triggered by webhook? (Done, webhook looks up product info on plan record and updates plan info) --- Plan info is all over the place... product id is on the plan record in the db, pricing id's are on the pricing page template. would it be too crazy to have an admin page to administer pricing and plan/product info? --- What to do with pricing page? should probably change depending on current account information i.e. buttons say 'upgrade' for plans > current and maybe 'downgrade' for plans < current? +-- Plan info is all over the place... product id is on the plan record in the db, pricing id's are on the pricing page template. would it be too crazy to have an admin page to administer pricing and plan/product info? (scratch, current system works ok) +-- What to do with pricing page? should probably change depending on current account information i.e. buttons say 'upgrade' for plans > current and maybe 'downgrade' for plans < current? (Add an 'order' to the plan... basically an integer indicating how 'good' the plan is so that if your current account plan order (yes it's also copied onto the account), is lower than the plan on the pricing page, it says 'upgrade', otherwise 'downgrade'... on second thought, maybe just use plan name and if it's not == to your current plan, say 'switch to plan') # Admin Functions Scenario (shitty test) Pre-condition User 3 (encumbent id=3) - Owner of own single user account. Admin of Team account diff --git a/components/AppFooter.vue b/components/AppFooter.vue index 8741e6d..ef7c5f9 100644 --- a/components/AppFooter.vue +++ b/components/AppFooter.vue @@ -1,5 +1,7 @@ diff --git a/components/AppHeader.vue b/components/AppHeader.vue index 353d35a..b5353aa 100644 --- a/components/AppHeader.vue +++ b/components/AppHeader.vue @@ -23,15 +23,15 @@ \ No newline at end of file diff --git a/server/trpc/context.ts b/server/trpc/context.ts index e410404..fe7813b 100644 --- a/server/trpc/context.ts +++ b/server/trpc/context.ts @@ -1,36 +1,30 @@ import { inferAsyncReturnType, TRPCError } from '@trpc/server' import { H3Event } from 'h3'; -import { serverSupabaseClient } from '#supabase/server'; -import SupabaseClient from '@supabase/supabase-js/dist/module/SupabaseClient'; +import { serverSupabaseUser } from '#supabase/server' import { User } from '@supabase/supabase-js'; import UserAccountService, { FullDBUser } from '~~/lib/services/user.account.service'; -let supabase: SupabaseClient | undefined - export async function createContext(event: H3Event){ let user: User | null = null; let dbUser: FullDBUser | null = null; - if (!supabase) { - supabase = serverSupabaseClient(event) - } if (!user) { - ({data: { user }} = await supabase.auth.getUser()); + user = await serverSupabaseUser(event); } if (!dbUser && user) { const userService = new UserAccountService(); dbUser = await userService.getFullUserBySupabaseId(user.id); if (!dbUser && user) { - dbUser = await userService.createUser( user.id, user.user_metadata.full_name, user.email?user.email:"no@email.supplied" ); - console.log(`\n Created user \n ${JSON.stringify(dbUser)}\n`); + dbUser = await userService.createUser(user.id, user.user_metadata.full_name?user.user_metadata.full_name:"no name supplied", user.email?user.email:"no@email.supplied" ); + console.log(`\n Created DB User \n ${JSON.stringify(dbUser)}\n`); } } if(!user || !dbUser) { throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', - message: `Unable to fetch user data, please try again later. Missing ->[supabase:${(!supabase)},user:${(!user)},dbUser:${(!dbUser)}]`, + message: `Unable to fetch user data, please try again later. Missing ->[user:${(!user)},dbUser:${(!dbUser)}]`, }); }