diff --git a/apps/ui-library/content/docs/tanstack/password-based-auth.mdx b/apps/ui-library/content/docs/tanstack/password-based-auth.mdx index 6e21f452006..5d648efa33f 100644 --- a/apps/ui-library/content/docs/tanstack/password-based-auth.mdx +++ b/apps/ui-library/content/docs/tanstack/password-based-auth.mdx @@ -9,23 +9,7 @@ description: Supabase client for Tanstack Start 1. Follow the steps in /ui/docs/tanstack/password-based-auth to setup your repo. -2. Add the following property to your `createRootRoute` function: - -```ts -import { fetchUser } from "@/lib/supabase/fetch-user-server-fn"; - -... - beforeLoad: async () => { - const user = await fetchUser(); - - return { - user, - }; - }, -... -``` - -3. Try to access the /info route, you should be redirected to login screen. If you create an account and try accessing the /info page, you should see your email. +2. Try to access the /info route, you should be redirected to login screen. If you create an account and login and try accessing the /info page, you should see your email. ## Folder structure diff --git a/apps/ui-library/public/r/password-based-auth-tanstack.json b/apps/ui-library/public/r/password-based-auth-tanstack.json index d77d3596bcc..814d13ef21e 100644 --- a/apps/ui-library/public/r/password-based-auth-tanstack.json +++ b/apps/ui-library/public/r/password-based-auth-tanstack.json @@ -29,7 +29,7 @@ }, { "path": "registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx", - "content": "import { createFileRoute, redirect } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/_protected')({\n beforeLoad: ({ context }) => {\n if (!context.user) {\n throw redirect({ to: '/login' })\n }\n },\n})\n", + "content": "import { fetchUser } from '@/registry/default/blocks/password-based-auth-tanstack/lib/supabase/fetch-user-server-fn'\nimport { createFileRoute, redirect } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/_protected')({\n beforeLoad: async () => {\n const user = await fetchUser()\n\n if (!user) {\n throw redirect({ to: '/login' })\n }\n\n return {\n user,\n }\n },\n})\n", "type": "registry:file", "target": "routes/_protected.tsx" }, @@ -41,7 +41,7 @@ }, { "path": "registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts", - "content": "import { createClient } from '@/registry/default/clients/tanstack/lib/supabase/server'\nimport { type EmailOtpType } from '@supabase/supabase-js'\nimport { createFileRoute, redirect } from '@tanstack/react-router'\nimport { createServerFn } from '@tanstack/react-start'\nimport { getWebRequest } from '@tanstack/react-start/server'\n\nconst confirmFn = createServerFn({ method: 'GET' })\n .validator((searchParams: unknown) => {\n if (\n searchParams &&\n typeof searchParams === 'object' &&\n 'token_hash' in searchParams &&\n 'type' in searchParams &&\n 'next' in searchParams\n ) {\n return searchParams\n }\n throw new Error('Invalid search params')\n })\n .handler(async (ctx) => {\n const request = getWebRequest()\n\n if (!request) {\n throw redirect({ to: `/auth/error`, params: { error: 'No request' } })\n }\n\n const searchParams = ctx.data\n const token_hash = searchParams['token_hash'] as string\n const type = searchParams['type'] as EmailOtpType | null\n const next = (searchParams['next'] ?? '/') as string\n\n if (token_hash && type) {\n const supabase = createClient()\n\n const { error } = await supabase.auth.verifyOtp({\n type,\n token_hash,\n })\n console.log(error?.message)\n if (!error) {\n // redirect user to specified redirect URL or root of app\n throw redirect({ href: next })\n } else {\n // redirect the user to an error page with some instructions\n throw redirect({\n to: `/auth/error`,\n params: { error: error?.message },\n })\n }\n }\n\n // redirect the user to an error page with some instructions\n throw redirect({\n to: `/auth/error`,\n params: { error: 'No token hash or type' },\n })\n })\n\nexport const Route = createFileRoute('/auth/confirm')({\n preload: false,\n loader: (opts) => confirmFn({ data: opts.location.search }),\n})\n", + "content": "import { createClient } from '@/registry/default/clients/tanstack/lib/supabase/server'\nimport { type EmailOtpType } from '@supabase/supabase-js'\nimport { createFileRoute, redirect } from '@tanstack/react-router'\nimport { createServerFn } from '@tanstack/react-start'\nimport { getWebRequest } from '@tanstack/react-start/server'\n\nconst confirmFn = createServerFn({ method: 'GET' })\n .validator((searchParams: unknown) => {\n if (\n searchParams &&\n typeof searchParams === 'object' &&\n 'token_hash' in searchParams &&\n 'type' in searchParams &&\n 'next' in searchParams\n ) {\n return searchParams\n }\n throw new Error('Invalid search params')\n })\n .handler(async (ctx) => {\n const request = getWebRequest()\n\n if (!request) {\n throw redirect({ to: `/auth/error`, search: { error: 'No request' } })\n }\n\n const searchParams = ctx.data\n const token_hash = searchParams['token_hash'] as string\n const type = searchParams['type'] as EmailOtpType | null\n const next = (searchParams['next'] ?? '/') as string\n\n if (token_hash && type) {\n const supabase = createClient()\n\n const { error } = await supabase.auth.verifyOtp({\n type,\n token_hash,\n })\n console.log(error?.message)\n if (!error) {\n // redirect user to specified redirect URL or root of app\n throw redirect({ href: next })\n } else {\n // redirect the user to an error page with some instructions\n throw redirect({\n to: `/auth/error`,\n search: { error: error?.message },\n })\n }\n }\n\n // redirect the user to an error page with some instructions\n throw redirect({\n to: `/auth/error`,\n search: { error: 'No token hash or type' },\n })\n })\n\nexport const Route = createFileRoute('/auth/confirm')({\n preload: false,\n loader: (opts) => confirmFn({ data: opts.location.search }),\n})\n", "type": "registry:file", "target": "routes/auth/confirm.ts" }, diff --git a/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx b/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx index 70ca25fb70c..d5fda348370 100644 --- a/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx +++ b/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx @@ -1,9 +1,16 @@ +import { fetchUser } from '@/registry/default/blocks/password-based-auth-tanstack/lib/supabase/fetch-user-server-fn' import { createFileRoute, redirect } from '@tanstack/react-router' export const Route = createFileRoute('/_protected')({ - beforeLoad: ({ context }) => { - if (!context.user) { + beforeLoad: async () => { + const user = await fetchUser() + + if (!user) { throw redirect({ to: '/login' }) } + + return { + user, + } }, }) diff --git a/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts b/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts index d19e254a339..8e72087fc68 100644 --- a/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts +++ b/apps/ui-library/registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts @@ -21,7 +21,7 @@ const confirmFn = createServerFn({ method: 'GET' }) const request = getWebRequest() if (!request) { - throw redirect({ to: `/auth/error`, params: { error: 'No request' } }) + throw redirect({ to: `/auth/error`, search: { error: 'No request' } }) } const searchParams = ctx.data @@ -44,7 +44,7 @@ const confirmFn = createServerFn({ method: 'GET' }) // redirect the user to an error page with some instructions throw redirect({ to: `/auth/error`, - params: { error: error?.message }, + search: { error: error?.message }, }) } } @@ -52,7 +52,7 @@ const confirmFn = createServerFn({ method: 'GET' }) // redirect the user to an error page with some instructions throw redirect({ to: `/auth/error`, - params: { error: 'No token hash or type' }, + search: { error: 'No token hash or type' }, }) })