diff --git a/apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts b/apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts
index f9f471956..76d415c8c 100644
--- a/apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts
+++ b/apps/web/app/home/[account]/members/_lib/server/members-page.loader.ts
@@ -19,7 +19,6 @@ export async function loadMembersPageData(
loadTeamWorkspace(slug),
loadAccountMembers(client, slug),
loadInvitations(client, slug),
- loadUser(client),
canAddMember,
]);
}
@@ -38,16 +37,6 @@ async function canAddMember() {
return Promise.resolve(true);
}
-async function loadUser(client: SupabaseClient
) {
- const { data, error } = await client.auth.getUser();
-
- if (error) {
- throw error;
- }
-
- return data.user;
-}
-
/**
* Load account members
* @param client
diff --git a/apps/web/app/home/[account]/members/page.tsx b/apps/web/app/home/[account]/members/page.tsx
index 4a51b92b3..7f76e45b3 100644
--- a/apps/web/app/home/[account]/members/page.tsx
+++ b/apps/web/app/home/[account]/members/page.tsx
@@ -18,6 +18,7 @@ import { If } from '@kit/ui/if';
import { PageBody } from '@kit/ui/page';
import { Trans } from '@kit/ui/trans';
+import { loadTeamWorkspace } from '~/home/[account]/_lib/server/team-account-workspace.loader';
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
import { withI18n } from '~/lib/i18n/with-i18n';
@@ -43,7 +44,9 @@ export const generateMetadata = async () => {
async function TeamAccountMembersPage({ params }: Params) {
const client = getSupabaseServerComponentClient();
- const [{ account }, members, invitations, user, canAddMember] =
+ const { user } = await loadTeamWorkspace(params.account);
+
+ const [{ account }, members, invitations, canAddMember] =
await loadMembersPageData(client, params.account);
const canManageRoles = account.permissions.includes('roles.manage');
diff --git a/apps/web/components/personal-account-dropdown-container.tsx b/apps/web/components/personal-account-dropdown-container.tsx
index 4bb727804..407e7dcc8 100644
--- a/apps/web/components/personal-account-dropdown-container.tsx
+++ b/apps/web/components/personal-account-dropdown-container.tsx
@@ -19,7 +19,7 @@ const features = {
export function ProfileAccountDropdownContainer(props: {
collapsed: boolean;
- user: User | null;
+ user: User;
account?: {
id: string | null;
@@ -29,7 +29,7 @@ export function ProfileAccountDropdownContainer(props: {
}) {
const signOut = useSignOut();
const user = useUser(props.user);
- const userData = user.data ?? props.user ?? null;
+ const userData = user.data as User;
return (
diff --git a/apps/web/lib/root-metdata.ts b/apps/web/lib/root-metdata.ts
index d8aea6fcc..d5c41a15b 100644
--- a/apps/web/lib/root-metdata.ts
+++ b/apps/web/lib/root-metdata.ts
@@ -22,11 +22,6 @@ export const rootMetadata: Metadata = {
},
icons: {
icon: '/images/favicon/favicon.ico',
- shortcut: '/shortcut-icon.png',
apple: '/images/favicon/apple-touch-icon.png',
- other: {
- rel: 'apple-touch-icon-precomposed',
- url: '/apple-touch-icon-precomposed.png',
- },
},
};
diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts
index ed1d784d2..ef9d74cbf 100644
--- a/apps/web/middleware.ts
+++ b/apps/web/middleware.ts
@@ -1,8 +1,6 @@
import type { NextRequest } from 'next/server';
import { NextResponse, URLPattern } from 'next/server';
-import type { UserResponse } from '@supabase/supabase-js';
-
import { CsrfError, createCsrfProtect } from '@edge-csrf/nextjs';
import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa';
@@ -15,17 +13,17 @@ const CSRF_SECRET_COOKIE = 'csrfSecret';
const NEXT_ACTION_HEADER = 'next-action';
export const config = {
- matcher: [
- '/((?!_next/static|_next/image|favicon.ico|locales|assets|api/*).*)',
- ],
+ matcher: ['/((?!_next/static|_next/image|images|locales|assets|api/*).*)'],
+};
+
+const getUser = (request: NextRequest, response: NextResponse) => {
+ const supabase = createMiddlewareClient(request, response);
+
+ return supabase.auth.getUser();
};
export async function middleware(request: NextRequest) {
const response = NextResponse.next();
- const supabase = createMiddlewareClient(request, response);
-
- // get the user from the session (no matter if it's logged in or not)
- const userResponse = await supabase.auth.getUser();
// set a unique request ID for each request
// this helps us log and trace requests
@@ -39,11 +37,7 @@ export async function middleware(request: NextRequest) {
// if a pattern handler exists, call it
if (handlePattern) {
- const patternHandlerResponse = await handlePattern(
- request,
- csrfResponse,
- userResponse,
- );
+ const patternHandlerResponse = await handlePattern(request, csrfResponse);
// if a pattern handler returns a response, return it
if (patternHandlerResponse) {
@@ -95,18 +89,14 @@ function isServerAction(request: NextRequest) {
return headers.has(NEXT_ACTION_HEADER);
}
-function adminMiddleware(
- request: NextRequest,
- response: NextResponse,
- userResponse: UserResponse,
-) {
+async function adminMiddleware(request: NextRequest, response: NextResponse) {
const isAdminPath = request.nextUrl.pathname.startsWith('/admin');
if (!isAdminPath) {
return response;
}
- const { data, error } = userResponse;
+ const { data, error } = await getUser(request, response);
// If user is not logged in, redirect to sign in page.
// This should never happen, but just in case.
@@ -138,12 +128,8 @@ function getPatterns() {
},
{
pattern: new URLPattern({ pathname: '/auth*' }),
- handler: (
- req: NextRequest,
- _: NextResponse,
- userResponse: UserResponse,
- ) => {
- const user = userResponse.data.user;
+ handler: async (req: NextRequest, res: NextResponse) => {
+ const { data: user } = await getUser(req, res);
// the user is logged out, so we don't need to do anything
if (!user) {
@@ -164,14 +150,8 @@ function getPatterns() {
},
{
pattern: new URLPattern({ pathname: '/home*' }),
- handler: async (
- req: NextRequest,
- res: NextResponse,
- userResponse: UserResponse,
- ) => {
- const {
- data: { user },
- } = userResponse;
+ handler: async (req: NextRequest, res: NextResponse) => {
+ const { data: user } = await getUser(req, res);
const origin = req.nextUrl.origin;
const next = req.nextUrl.pathname;
diff --git a/packages/features/accounts/src/components/account-selector.tsx b/packages/features/accounts/src/components/account-selector.tsx
index 81f8426b3..309031cea 100644
--- a/packages/features/accounts/src/components/account-selector.tsx
+++ b/packages/features/accounts/src/components/account-selector.tsx
@@ -36,6 +36,7 @@ interface AccountSelectorProps {
enableTeamCreation: boolean;
};
+ userId: string;
selectedAccount?: string;
collapsed?: boolean;
className?: string;
@@ -49,6 +50,7 @@ export function AccountSelector({
accounts,
selectedAccount,
onAccountChange,
+ userId,
className,
features = {
enableTeamCreation: true,
@@ -63,7 +65,7 @@ export function AccountSelector({
);
const { t } = useTranslation('teams');
- const personalData = usePersonalAccountData();
+ const personalData = usePersonalAccountData(userId);
useEffect(() => {
setValue(selectedAccount ?? PERSONAL_ACCOUNT_SLUG);
diff --git a/packages/features/accounts/src/components/personal-account-dropdown.tsx b/packages/features/accounts/src/components/personal-account-dropdown.tsx
index 38f1a1b42..f066e4789 100644
--- a/packages/features/accounts/src/components/personal-account-dropdown.tsx
+++ b/packages/features/accounts/src/components/personal-account-dropdown.tsx
@@ -38,8 +38,7 @@ export function PersonalAccountDropdown({
features,
account,
}: {
- className?: string;
- user: User | null;
+ user: User;
account?: {
id: string | null;
@@ -48,7 +47,6 @@ export function PersonalAccountDropdown({
};
signOutRequested: () => unknown;
- showProfileName?: boolean;
paths: {
home: string;
@@ -57,8 +55,14 @@ export function PersonalAccountDropdown({
features: {
enableThemeToggle: boolean;
};
+
+ className?: string;
+ showProfileName?: boolean;
}) {
- const { data: personalAccountData } = usePersonalAccountData(account);
+ const { data: personalAccountData } = usePersonalAccountData(
+ user.id,
+ account,
+ );
const signedInAsLabel = useMemo(() => {
const email = user?.email ?? undefined;
diff --git a/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx b/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx
index 633d2460b..37f3325ff 100644
--- a/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx
+++ b/packages/features/accounts/src/components/personal-account-settings/account-settings-container.tsx
@@ -24,6 +24,8 @@ import { UpdateAccountImageContainer } from './update-account-image-container';
export function PersonalAccountSettingsContainer(
props: React.PropsWithChildren<{
+ userId: string;
+
features: {
enableAccountDeletion: boolean;
};
@@ -34,7 +36,7 @@ export function PersonalAccountSettingsContainer(
}>,
) {
const supportsLanguageSelection = useSupportMultiLanguage();
- const user = usePersonalAccountData();
+ const user = usePersonalAccountData(props.userId);
if (!user.data || user.isPending) {
return ;
diff --git a/packages/features/accounts/src/hooks/use-personal-account-data.ts b/packages/features/accounts/src/hooks/use-personal-account-data.ts
index e2a48effb..15d96fa49 100644
--- a/packages/features/accounts/src/hooks/use-personal-account-data.ts
+++ b/packages/features/accounts/src/hooks/use-personal-account-data.ts
@@ -3,9 +3,9 @@ import { useCallback } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useSupabase } from '@kit/supabase/hooks/use-supabase';
-import { useUser } from '@kit/supabase/hooks/use-user';
export function usePersonalAccountData(
+ userId: string,
partialAccount?:
| {
id: string | null;
@@ -15,9 +15,6 @@ export function usePersonalAccountData(
| undefined,
) {
const client = useSupabase();
- const user = useUser();
- const userId = user.data?.id;
-
const queryKey = ['account:data', userId];
const queryFn = async () => {
diff --git a/packages/features/team-accounts/src/server/api.ts b/packages/features/team-accounts/src/server/api.ts
index 2fb4e16c2..1fdaa0bee 100644
--- a/packages/features/team-accounts/src/server/api.ts
+++ b/packages/features/team-accounts/src/server/api.ts
@@ -78,16 +78,9 @@ export class TeamAccountsApi {
const accountsPromise = this.client.from('user_accounts').select('*');
- const [
- accountResult,
- accountsResult,
- {
- data: { user },
- },
- ] = await Promise.all([
+ const [accountResult, accountsResult] = await Promise.all([
accountPromise,
accountsPromise,
- this.client.auth.getUser(),
]);
if (accountResult.error) {
@@ -104,13 +97,6 @@ export class TeamAccountsApi {
};
}
- if (!user) {
- return {
- error: new Error('User is not logged in'),
- data: null,
- };
- }
-
const accountData = accountResult.data[0];
if (!accountData) {
@@ -124,7 +110,6 @@ export class TeamAccountsApi {
data: {
account: accountData,
accounts: accountsResult.data,
- user,
},
error: null,
};
diff --git a/packages/supabase/src/hooks/use-user.ts b/packages/supabase/src/hooks/use-user.ts
index 0972999e2..198005b38 100644
--- a/packages/supabase/src/hooks/use-user.ts
+++ b/packages/supabase/src/hooks/use-user.ts
@@ -24,10 +24,15 @@ export function useUser(initialData?: User | null) {
return Promise.reject('Unexpected result format');
};
+ // update staleTime to 5 minutes
+ const staleTime = 1000 * 60 * 5;
+
return useQuery({
queryFn,
queryKey,
initialData,
+ staleTime,
+ refetchInterval: false,
refetchOnMount: false,
refetchOnWindowFocus: false,
});