Replace session with user in various files

This change mainly involves replacing 'session' with 'user' in various files in several applications. The function calls related to 'session' have been refactored to reflect 'user'. The '@supabase/supabase-js' package dependency has
This commit is contained in:
giancarlo
2024-03-28 21:14:12 +08:00
parent 15d4533949
commit 348eec8495
14 changed files with 50 additions and 117 deletions

View File

@@ -38,7 +38,6 @@ export function AppSidebar(props: {
account: string;
accounts: AccountModel[];
collapsed: boolean;
session: Session | null;
}) {
return (
<Sidebar collapsed={props.collapsed}>
@@ -48,7 +47,6 @@ export function AppSidebar(props: {
setCollapsed={setCollapsed}
account={props.account}
accounts={props.accounts}
session={props.session}
/>
)}
</Sidebar>
@@ -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: {
<div className={'absolute bottom-4 left-0 w-full'}>
<SidebarContent>
<ProfileAccountDropdownContainer
session={props.session}
collapsed={props.collapsed}
/>
<ProfileAccountDropdownContainer collapsed={props.collapsed} />
<AppSidebarFooterMenu
collapsed={props.collapsed}

View File

@@ -25,12 +25,10 @@ export const loadTeamWorkspace = cache(async (accountSlug: string) => {
});
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,
};
});

View File

@@ -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({
<AppSidebar
collapsed={sidebarCollapsed}
account={params.account}
session={session}
accounts={accounts}
/>
}
@@ -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;
}

View File

@@ -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 (
<Sidebar collapsed={collapsed}>
@@ -25,10 +25,7 @@ export function HomeSidebar() {
<div className={'absolute bottom-4 left-0 w-full'}>
<SidebarContent>
<ProfileAccountDropdownContainer
session={session}
collapsed={collapsed}
/>
<ProfileAccountDropdownContainer collapsed={collapsed} />
</SidebarContent>
</div>
</Sidebar>

View File

@@ -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 (
<div className={props.collapsed ? '' : 'w-full'}>
@@ -25,7 +22,7 @@ export function ProfileAccountDropdownContainer(props: {
}}
className={'w-full'}
showProfileName={!props.collapsed}
session={props.session}
user={user.data ?? null}
signOutRequested={() => signOut.mutateAsync()}
/>
</div>

View File

@@ -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();

View File

@@ -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 <AuthButtons />;
}
return <SuspendedPersonalAccountDropdown session={props.session} />;
return <SuspendedPersonalAccountDropdown user={props.user} />;
}
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 (
<If condition={userSession.data} fallback={<AuthButtons />}>
{(session) => (
<If condition={user.data} fallback={<AuthButtons />}>
{(data) => (
<PersonalAccountDropdown
paths={{
home: pathsConfig.app.home,
@@ -42,7 +43,7 @@ function SuspendedPersonalAccountDropdown(props: { session: Session | null }) {
features={{
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
}}
session={session}
user={data}
signOutRequested={() => signOut.mutateAsync()}
/>
)}

View File

@@ -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 (
<div className={'container mx-auto'}>
<div className="flex h-16 items-center justify-between">
@@ -23,7 +23,7 @@ export function SiteHeader(props: { session?: Session | null }) {
<ModeToggle />
</div>
<SiteHeaderAccountSection session={props.session ?? null} />
<SiteHeaderAccountSection user={props.user ?? null} />
</div>
</div>
</div>

View File

@@ -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 (
<>
<SiteHeader session={session} />
<SiteHeader user={user} />
{props.children}

View File

@@ -19,12 +19,12 @@ const NotFoundPage = async () => {
const client = getSupabaseServerComponentClient();
const {
data: { session },
} = await client.auth.getSession();
data: { user },
} = await client.auth.getUser();
return (
<div className={'flex h-screen flex-1 flex-col'}>
<SiteHeader session={session} />
<SiteHeader user={user} />
<div
className={

View File

@@ -23,17 +23,13 @@ export async function middleware(request: NextRequest) {
// apply CSRF and session middleware
const csrfResponse = await withCsrfMiddleware(request, response);
const sessionResponse = await sessionMiddleware(request, csrfResponse);
// handle patterns for specific routes
const handlePattern = matchUrlPattern(request.url);
// if a pattern handler exists, call it
if (handlePattern) {
const patternHandlerResponse = await handlePattern(
request,
sessionResponse,
);
const patternHandlerResponse = await handlePattern(request, csrfResponse);
// if a pattern handler returns a response, return it
if (patternHandlerResponse) {
@@ -42,15 +38,7 @@ export async function middleware(request: NextRequest) {
}
// if no pattern handler returned a response, return the session response
return sessionResponse;
}
async function sessionMiddleware(req: NextRequest, res: NextResponse) {
const supabase = createMiddlewareClient(req, res);
await supabase.auth.getSession();
return res;
return csrfResponse;
}
async function withCsrfMiddleware(
@@ -127,14 +115,14 @@ function getPatterns() {
pattern: new URLPattern({ pathname: '/auth*' }),
handler: async (req: NextRequest, res: NextResponse) => {
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}`;

View File

@@ -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",

View File

@@ -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 (
<DropdownMenu>
@@ -79,7 +78,7 @@ export function PersonalAccountDropdown({
)}
>
<ProfileAvatar
displayName={displayName ?? authUser?.email ?? ''}
displayName={displayName ?? user?.email ?? ''}
pictureUrl={personalAccountData?.picture_url}
/>

View File

@@ -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,
});
}