diff --git a/apps/web/app/(dashboard)/home/[account]/_components/app-sidebar.tsx b/apps/web/app/(dashboard)/home/[account]/_components/app-sidebar.tsx index 455743b29..a2a9646cc 100644 --- a/apps/web/app/(dashboard)/home/[account]/_components/app-sidebar.tsx +++ b/apps/web/app/(dashboard)/home/[account]/_components/app-sidebar.tsx @@ -38,7 +38,6 @@ export function AppSidebar(props: { account: string; accounts: AccountModel[]; collapsed: boolean; - session: Session | null; }) { return ( @@ -48,7 +47,6 @@ export function AppSidebar(props: { setCollapsed={setCollapsed} account={props.account} accounts={props.accounts} - session={props.session} /> )} @@ -58,7 +56,6 @@ export function AppSidebar(props: { function SidebarContainer(props: { account: string; accounts: AccountModel[]; - session: Session | null; collapsed: boolean; setCollapsed: (collapsed: boolean) => void; }) { @@ -89,10 +86,7 @@ function SidebarContainer(props: {
- + { }); const accountsPromise = client.from('user_accounts').select('*'); - const userSessionPromise = client.auth.getSession(); - const [accountResult, accountsResult, sessionResult] = await Promise.all([ + const [accountResult, accountsResult] = await Promise.all([ accountPromise, accountsPromise, - userSessionPromise, ]); if (accountResult.error) { @@ -53,13 +51,8 @@ export const loadTeamWorkspace = cache(async (accountSlug: string) => { throw accountsResult.error; } - if (sessionResult.error ?? !sessionResult.data.session?.user) { - throw new Error('User session not found'); - } - return { account: accountData, accounts: accountsResult.data, - user: sessionResult.data.session.user, }; }); diff --git a/apps/web/app/(dashboard)/home/[account]/layout.tsx b/apps/web/app/(dashboard)/home/[account]/layout.tsx index 5f88f62b8..7aa761e67 100644 --- a/apps/web/app/(dashboard)/home/[account]/layout.tsx +++ b/apps/web/app/(dashboard)/home/[account]/layout.tsx @@ -2,7 +2,6 @@ import { use } from 'react'; import { parseSidebarStateCookie } from '@kit/shared/cookies/sidebar-state.cookie'; import { parseThemeCookie } from '@kit/shared/cookies/theme.cookie'; -import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; import { Page } from '@kit/ui/page'; import { AppSidebar } from '~/(dashboard)/home/[account]/_components/app-sidebar'; @@ -19,10 +18,7 @@ function TeamWorkspaceLayout({ }: React.PropsWithChildren<{ params: Params; }>) { - const [data, session] = use( - Promise.all([loadTeamWorkspace(params.account), loadSession()]), - ); - + const data = use(loadTeamWorkspace(params.account)); const ui = getUIStateCookies(); const sidebarCollapsed = ui.sidebarState === 'collapsed'; @@ -38,7 +34,6 @@ function TeamWorkspaceLayout({ } @@ -56,18 +51,3 @@ function getUIStateCookies() { sidebarState: parseSidebarStateCookie(), }; } - -async function loadSession() { - const client = getSupabaseServerComponentClient(); - - const { - data: { session }, - error, - } = await client.auth.getSession(); - - if (error) { - throw error; - } - - return session; -} diff --git a/apps/web/app/(dashboard)/home/_components/home-sidebar.tsx b/apps/web/app/(dashboard)/home/_components/home-sidebar.tsx index 458e8eae0..d5f39eae5 100644 --- a/apps/web/app/(dashboard)/home/_components/home-sidebar.tsx +++ b/apps/web/app/(dashboard)/home/_components/home-sidebar.tsx @@ -11,7 +11,7 @@ import { personalAccountSidebarConfig } from '~/config/personal-account-sidebar. export function HomeSidebar() { const collapsed = getSidebarCollapsed(); - const { session, accounts } = use(loadUserWorkspace()); + const { accounts } = use(loadUserWorkspace()); return ( @@ -25,10 +25,7 @@ export function HomeSidebar() {
- +
diff --git a/apps/web/app/(dashboard)/home/_components/personal-account-dropdown.tsx b/apps/web/app/(dashboard)/home/_components/personal-account-dropdown.tsx index dc1ee9f1d..00b252f76 100644 --- a/apps/web/app/(dashboard)/home/_components/personal-account-dropdown.tsx +++ b/apps/web/app/(dashboard)/home/_components/personal-account-dropdown.tsx @@ -1,18 +1,15 @@ 'use client'; -import type { Session } from '@supabase/supabase-js'; - import { PersonalAccountDropdown } from '@kit/accounts/personal-account-dropdown'; import { useSignOut } from '@kit/supabase/hooks/use-sign-out'; +import { useUser } from '@kit/supabase/hooks/use-user'; import featuresFlagConfig from '~/config/feature-flags.config'; import pathsConfig from '~/config/paths.config'; -export function ProfileAccountDropdownContainer(props: { - collapsed: boolean; - session: Session | null; -}) { +export function ProfileAccountDropdownContainer(props: { collapsed: boolean }) { const signOut = useSignOut(); + const user = useUser(); return (
@@ -25,7 +22,7 @@ export function ProfileAccountDropdownContainer(props: { }} className={'w-full'} showProfileName={!props.collapsed} - session={props.session} + user={user.data ?? null} signOutRequested={() => signOut.mutateAsync()} />
diff --git a/apps/web/app/(dashboard)/home/_lib/load-user-workspace.ts b/apps/web/app/(dashboard)/home/_lib/load-user-workspace.ts index eee102a8a..6d7feb0fc 100644 --- a/apps/web/app/(dashboard)/home/_lib/load-user-workspace.ts +++ b/apps/web/app/(dashboard)/home/_lib/load-user-workspace.ts @@ -3,32 +3,13 @@ import { cache } from 'react'; import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client'; export const loadUserWorkspace = cache(async () => { - const [accounts, session] = await Promise.all([ - loadUserAccounts(), - loadSession(), - ]); + const accounts = await loadUserAccounts(); return { accounts, - session, }; }); -async function loadSession() { - const client = getSupabaseServerComponentClient(); - - const { - data: { session }, - error, - } = await client.auth.getSession(); - - if (error) { - throw error; - } - - return session; -} - async function loadUserAccounts() { const client = getSupabaseServerComponentClient(); diff --git a/apps/web/app/(marketing)/_components/site-header-account-section.tsx b/apps/web/app/(marketing)/_components/site-header-account-section.tsx index 02abd90f0..f6fb20fb4 100644 --- a/apps/web/app/(marketing)/_components/site-header-account-section.tsx +++ b/apps/web/app/(marketing)/_components/site-header-account-section.tsx @@ -2,12 +2,13 @@ import Link from 'next/link'; -import type { Session } from '@supabase/supabase-js'; +import { Session, User } from '@supabase/supabase-js'; import { ChevronRight } from 'lucide-react'; import { PersonalAccountDropdown } from '@kit/accounts/personal-account-dropdown'; import { useSignOut } from '@kit/supabase/hooks/use-sign-out'; +import { useUser } from '@kit/supabase/hooks/use-user'; import { useUserSession } from '@kit/supabase/hooks/use-user-session'; import { Button } from '@kit/ui/button'; import { If } from '@kit/ui/if'; @@ -18,23 +19,23 @@ import pathsConfig from '~/config/paths.config'; export function SiteHeaderAccountSection( props: React.PropsWithChildren<{ - session: Session | null; + user: User | null; }>, ) { - if (!props.session) { + if (!props.user) { return ; } - return ; + return ; } -function SuspendedPersonalAccountDropdown(props: { session: Session | null }) { +function SuspendedPersonalAccountDropdown(props: { user: User | null }) { const signOut = useSignOut(); - const userSession = useUserSession(props.session); + const user = useUser(props.user); return ( - }> - {(session) => ( + }> + {(data) => ( signOut.mutateAsync()} /> )} diff --git a/apps/web/app/(marketing)/_components/site-header.tsx b/apps/web/app/(marketing)/_components/site-header.tsx index d24c8a0fb..2a05e4776 100644 --- a/apps/web/app/(marketing)/_components/site-header.tsx +++ b/apps/web/app/(marketing)/_components/site-header.tsx @@ -1,4 +1,4 @@ -import type { Session } from '@supabase/supabase-js'; +import type { User } from '@supabase/supabase-js'; import { ModeToggle } from '@kit/ui/mode-toggle'; @@ -6,7 +6,7 @@ import { SiteHeaderAccountSection } from '~/(marketing)/_components/site-header- import { SiteNavigation } from '~/(marketing)/_components/site-navigation'; import { AppLogo } from '~/components/app-logo'; -export function SiteHeader(props: { session?: Session | null }) { +export function SiteHeader(props: { user?: User | null }) { return (
@@ -23,7 +23,7 @@ export function SiteHeader(props: { session?: Session | null }) {
- +
diff --git a/apps/web/app/(marketing)/layout.tsx b/apps/web/app/(marketing)/layout.tsx index b5d4546c6..c6916d2d3 100644 --- a/apps/web/app/(marketing)/layout.tsx +++ b/apps/web/app/(marketing)/layout.tsx @@ -8,12 +8,12 @@ async function SiteLayout(props: React.PropsWithChildren) { const client = getSupabaseServerComponentClient(); const { - data: { session }, - } = await client.auth.getSession(); + data: { user }, + } = await client.auth.getUser(); return ( <> - + {props.children} diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx index 5e98a7dcb..5f29d906d 100644 --- a/apps/web/app/not-found.tsx +++ b/apps/web/app/not-found.tsx @@ -19,12 +19,12 @@ const NotFoundPage = async () => { const client = getSupabaseServerComponentClient(); const { - data: { session }, - } = await client.auth.getSession(); + data: { user }, + } = await client.auth.getUser(); return (
- +
{ const supabase = createMiddlewareClient(req, res); - const { data } = await supabase.auth.getSession(); + const { data: user } = await supabase.auth.getUser(); // check if we need to verify MFA (user is authenticated but needs to verify MFA) const isVerifyMfa = req.nextUrl.pathname === pathsConfig.auth.verifyMfa; // If user is logged in and does not need to verify MFA, // redirect to home page. - if (data.session && !isVerifyMfa) { + if (user && !isVerifyMfa) { return NextResponse.redirect( new URL(pathsConfig.app.home, req.nextUrl.origin).href, ); @@ -145,12 +133,12 @@ function getPatterns() { pattern: new URLPattern({ pathname: '/home*' }), handler: async (req: NextRequest, res: NextResponse) => { const supabase = createMiddlewareClient(req, res); - const { data, error } = await supabase.auth.getSession(); + const { data: user, error } = await supabase.auth.getUser(); const origin = req.nextUrl.origin; const next = req.nextUrl.pathname; // If user is not logged in, redirect to sign in page. - if (!data.session || error) { + if (!user || error) { const signIn = pathsConfig.auth.signIn; const redirectPath = `${signIn}?next=${next}`; diff --git a/apps/web/package.json b/apps/web/package.json index 90acc8279..9809afbaa 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -7,7 +7,7 @@ "analyze": "ANALYZE=true pnpm run build", "build": "pnpm with-env next build", "clean": "git clean -xdf .next .turbo node_modules", - "dev": "pnpm with-env next dev --turbo", + "dev": "pnpm with-env next dev", "lint": "next lint", "format": "prettier --check \"**/*.{js,cjs,mjs,ts,tsx,md,json}\"", "start": "pnpm with-env next start", diff --git a/packages/features/accounts/src/components/personal-account-dropdown.tsx b/packages/features/accounts/src/components/personal-account-dropdown.tsx index e0cc39f3c..7dd22030b 100644 --- a/packages/features/accounts/src/components/personal-account-dropdown.tsx +++ b/packages/features/accounts/src/components/personal-account-dropdown.tsx @@ -4,7 +4,7 @@ import { useMemo } from 'react'; import Link from 'next/link'; -import type { Session } from '@supabase/gotrue-js'; +import type { User } from '@supabase/supabase-js'; import { EllipsisVertical, @@ -31,14 +31,14 @@ import { usePersonalAccountData } from '../hooks/use-personal-account-data'; export function PersonalAccountDropdown({ className, - session, + user, signOutRequested, showProfileName, paths, features, }: { className?: string; - session: Session | null; + user: User | null; signOutRequested: () => unknown; showProfileName?: boolean; paths: { @@ -49,20 +49,19 @@ export function PersonalAccountDropdown({ }; }) { const { data: personalAccountData } = usePersonalAccountData(); - const authUser = session?.user; const signedInAsLabel = useMemo(() => { - const email = authUser?.email ?? undefined; - const phone = authUser?.phone ?? undefined; + const email = user?.email ?? undefined; + const phone = user?.phone ?? undefined; return email ?? phone; - }, [authUser?.email, authUser?.phone]); + }, [user?.email, user?.phone]); - const displayName = personalAccountData?.name ?? authUser?.email ?? ''; + const displayName = personalAccountData?.name ?? user?.email ?? ''; const isSuperAdmin = useMemo(() => { - return authUser?.app_metadata.role === 'super-admin'; - }, [authUser]); + return user?.app_metadata.role === 'super-admin'; + }, [user]); return ( @@ -79,7 +78,7 @@ export function PersonalAccountDropdown({ )} > diff --git a/packages/supabase/src/hooks/use-user.ts b/packages/supabase/src/hooks/use-user.ts index be26aeb22..3217c9653 100644 --- a/packages/supabase/src/hooks/use-user.ts +++ b/packages/supabase/src/hooks/use-user.ts @@ -1,10 +1,12 @@ import { useRouter } from 'next/navigation'; +import type { User } from '@supabase/supabase-js'; + import { useQuery } from '@tanstack/react-query'; import { useSupabase } from './use-supabase'; -export function useUser() { +export function useUser(initialData?: User | null) { const client = useSupabase(); const router = useRouter(); const queryKey = ['supabase:user']; @@ -27,5 +29,6 @@ export function useUser() { return useQuery({ queryFn, queryKey, + initialData, }); }