diff --git a/package-lock.json b/package-lock.json
index e6e60a6d1b..8287c7e6c8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1745,11 +1745,11 @@
}
},
"node_modules/@babel/plugin-syntax-jsx": {
- "version": "7.24.6",
- "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.6.tgz",
- "integrity": "sha512-lWfvAIFNWMlCsU0DRUun2GpFwZdGTukLaHJqRh1JRb80NdAP5Sb1HDHB5X9P9OtgZHQl089UzQkpYlBq2VTPRw==",
+ "version": "7.24.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz",
+ "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.6"
+ "@babel/helper-plugin-utils": "^7.24.7"
},
"engines": {
"node": ">=6.9.0"
@@ -11927,9 +11927,9 @@
}
},
"node_modules/@types/babel__traverse": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
- "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
"dependencies": {
"@babel/types": "^7.20.7"
}
diff --git a/packages/web-main/src/components/Navbar/UserDropdown.tsx b/packages/web-main/src/components/Navbar/UserDropdown.tsx
index 58694463d9..5e7f76db40 100644
--- a/packages/web-main/src/components/Navbar/UserDropdown.tsx
+++ b/packages/web-main/src/components/Navbar/UserDropdown.tsx
@@ -56,18 +56,15 @@ const Name = styled.div`
`;
export const UserDropdown = () => {
- const { session } = useAuth();
const { logOut } = useAuth();
const navigate = useNavigate();
-
const { data, isPending } = useQuery(userMeQueryOptions());
const hasMultipleDomains = isPending === false && data && data.domains && data.domains.length > 1 ? true : false;
- // TODO: this should be a fallback component, to stil try to logout.
- if (session === null) return
could not get session
;
+ if (!data) return could not get user information
;
- const { name, email } = session;
+ const { name, email } = data.user;
return (
diff --git a/packages/web-main/src/components/Navbar/index.tsx b/packages/web-main/src/components/Navbar/index.tsx
index c3fd1c6497..fc57706f02 100644
--- a/packages/web-main/src/components/Navbar/index.tsx
+++ b/packages/web-main/src/components/Navbar/index.tsx
@@ -53,7 +53,7 @@ const domainLinks: NavbarLink[] = [
{
label: 'Players',
linkProps: {
- to: '/players' as any,
+ to: '/players',
},
icon: ,
requiredPermissions: [PERMISSIONS.ReadPlayers],
@@ -61,7 +61,7 @@ const domainLinks: NavbarLink[] = [
{
label: 'Users',
linkProps: {
- to: '/users' as any,
+ to: '/users',
},
icon: ,
requiredPermissions: [PERMISSIONS.ReadUsers],
@@ -112,8 +112,6 @@ export interface NavbarLink {
export const renderLink = ({ linkProps, icon, label, requiredPermissions }: NavbarLink) => (
- {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment*/}
- {/* @ts-ignore reusable link */}
{cloneElement(icon, { size: 20, key: `icon-${linkProps.to}` })}
diff --git a/packages/web-main/src/components/PermissionsGuard.tsx b/packages/web-main/src/components/PermissionsGuard.tsx
index 1e60c596cc..900a5856fe 100644
--- a/packages/web-main/src/components/PermissionsGuard.tsx
+++ b/packages/web-main/src/components/PermissionsGuard.tsx
@@ -1,7 +1,7 @@
import { PERMISSIONS } from '@takaro/apiclient';
import { PermissionsGuard as Guard } from '@takaro/lib-components';
import { RequiredPermissions } from '@takaro/lib-components';
-import { useAuth } from 'hooks/useAuth';
+import { useSession } from 'hooks/useSession';
import { FC, PropsWithChildren, ReactElement, useMemo } from 'react';
interface PermissionsGuardProps {
@@ -14,7 +14,7 @@ export const PermissionsGuard: FC> = ({
children,
fallback,
}) => {
- const { session } = useAuth();
+ const { session } = useSession();
const userPermissions = useMemo(() => {
if (!session) {
diff --git a/packages/web-main/src/hooks/useAuth.tsx b/packages/web-main/src/hooks/useAuth.tsx
index e27813c1b4..3efdad53a3 100644
--- a/packages/web-main/src/hooks/useAuth.tsx
+++ b/packages/web-main/src/hooks/useAuth.tsx
@@ -1,11 +1,10 @@
import { useQueryClient } from '@tanstack/react-query';
import { UserOutputWithRolesDTO } from '@takaro/apiclient';
-import { createContext, useCallback, useContext, useEffect, useState } from 'react';
+import { createContext, useCallback, useContext } from 'react';
import { useOry } from './useOry';
import * as Sentry from '@sentry/react';
import { DateTime } from 'luxon';
import { getApiClient } from 'util/getApiClient';
-import { redirect } from '@tanstack/react-router';
const SESSION_EXPIRES_AFTER_MINUTES = 5;
@@ -16,8 +15,7 @@ interface ExpirableSession {
export interface IAuthContext {
logOut: () => Promise;
- isAuthenticated: boolean;
- session: UserOutputWithRolesDTO;
+ getSession: () => Promise;
login: (user: UserOutputWithRolesDTO) => void;
}
@@ -35,19 +33,27 @@ function getLocalSession() {
return expirableSession.session;
}
+function setLocalSession(session: UserOutputWithRolesDTO | null) {
+ if (session) {
+ const expirableSession: ExpirableSession = {
+ session,
+ expiresAt: DateTime.now().plus({ minutes: SESSION_EXPIRES_AFTER_MINUTES }).toISO(),
+ };
+ localStorage.setItem('session', JSON.stringify(expirableSession));
+ } else {
+ localStorage.removeItem('session');
+ }
+}
+
export const AuthContext = createContext(null);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const queryClient = useQueryClient();
const { oryClient } = useOry();
- const [user, setUser] = useState(getLocalSession());
-
- const isAuthenticated = !!user;
const logOut = useCallback(async () => {
const logoutFlowRes = await oryClient.createBrowserLogoutFlow();
- setStoredSession(null);
- setUser(null);
+ setLocalSession(null);
queryClient.clear();
window.location.href = logoutFlowRes.data.logout_url;
// Extra clean up is done in /logout-return
@@ -55,29 +61,11 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
}, [oryClient, queryClient]);
const login = useCallback((session: UserOutputWithRolesDTO) => {
- setStoredSession(session);
+ setLocalSession(session);
Sentry.setUser({ id: session.id, email: session.email, username: session.name });
- setUser(session);
}, []);
- const refreshSession = useCallback(async () => {
- try {
- const response = await getApiClient().user.userControllerMe({
- headers: {
- 'Cache-Control': 'no-cache',
- },
- });
- const newSession = response.data.data.user;
- login(newSession);
- } catch (error) {
- setStoredSession(null);
- setUser(null);
- queryClient.clear();
- redirect({ to: '/login' });
- }
- }, [login, queryClient]);
-
- const getSession = useCallback(async (): Promise => {
+ const getSession = async function (): Promise {
const session = getLocalSession();
if (session) {
@@ -85,45 +73,31 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
}
try {
- await refreshSession();
- return JSON.parse(localStorage.getItem('session')!).session;
+ const newSession = (
+ await getApiClient().user.userControllerMe({
+ headers: {
+ 'Cache-Control': 'no-cache',
+ },
+ })
+ ).data.data.user;
+ setLocalSession(session);
+ return newSession;
} catch (error) {
+ // logout if session is invalid
localStorage.removeItem('session');
- return null;
- }
- }, [refreshSession]);
-
- useEffect(() => {
- async function fetchSession() {
- const storedSession = await getSession();
- if (!storedSession) {
- refreshSession();
- } else {
- setUser(storedSession);
- }
- }
- fetchSession();
- }, [getSession, refreshSession]);
-
- function setStoredSession(session: UserOutputWithRolesDTO | null) {
- if (session) {
- const expirableSession: ExpirableSession = {
- session,
- expiresAt: DateTime.now().plus({ minutes: SESSION_EXPIRES_AFTER_MINUTES }).toISO(),
- };
- localStorage.setItem('session', JSON.stringify(expirableSession));
- } else {
- localStorage.removeItem('session');
+ setLocalSession(null);
+ queryClient.clear();
+ window.location.href = '/login';
+ throw 'should not have no session and not be redirected to login';
}
- }
+ };
return (
{children}
diff --git a/packages/web-main/src/hooks/useHasPermission.tsx b/packages/web-main/src/hooks/useHasPermission.tsx
index 47e93e9816..b97f5de709 100644
--- a/packages/web-main/src/hooks/useHasPermission.tsx
+++ b/packages/web-main/src/hooks/useHasPermission.tsx
@@ -2,10 +2,10 @@ import { useMemo } from 'react';
import { RequiredPermissions } from '@takaro/lib-components';
import { hasPermissionHelper } from '@takaro/lib-components/src/components/other/PermissionsGuard';
import { PERMISSIONS, UserOutputWithRolesDTO } from '@takaro/apiclient';
-import { useAuth } from 'hooks/useAuth';
+import { useSession } from './useSession';
export const useHasPermission = (requiredPermissions: RequiredPermissions) => {
- const { session } = useAuth();
+ const { session } = useSession();
const userPermissions = useMemo(() => {
if (!session) {
diff --git a/packages/web-main/src/hooks/useSession.tsx b/packages/web-main/src/hooks/useSession.tsx
new file mode 100644
index 0000000000..7eacd34eec
--- /dev/null
+++ b/packages/web-main/src/hooks/useSession.tsx
@@ -0,0 +1,16 @@
+import { UserOutputWithRolesDTO } from '@takaro/apiclient';
+import { createContext, useContext } from 'react';
+
+export interface ISessionContext {
+ session: UserOutputWithRolesDTO;
+}
+
+export const SessionContext = createContext({} as any);
+
+export function useSession() {
+ const context = useContext(SessionContext);
+ if (!context) {
+ throw new Error('useAuth must be used within an AuthProvider');
+ }
+ return context;
+}
diff --git a/packages/web-main/src/queryClient.ts b/packages/web-main/src/queryClient.ts
index 5e9cbb65aa..c67e50aff6 100644
--- a/packages/web-main/src/queryClient.ts
+++ b/packages/web-main/src/queryClient.ts
@@ -14,7 +14,6 @@ const options = {
Sentry.setTag('traceId', traceId);
}
}
-
Sentry.captureException(error);
return true;
}
diff --git a/packages/web-main/src/router.tsx b/packages/web-main/src/router.tsx
index c96b9e8569..ee605118ba 100644
--- a/packages/web-main/src/router.tsx
+++ b/packages/web-main/src/router.tsx
@@ -2,8 +2,9 @@ import { queryClient } from './queryClient';
import { routeTree } from './routeTree.gen';
import { createRouter } from '@tanstack/react-router';
import { QueryClient } from '@tanstack/react-query';
-import { IAuthContext } from 'hooks/useAuth';
import { DefaultErrorComponent } from 'components/ErrorComponent';
+import { IAuthContext } from 'hooks/useAuth';
+import { UserOutputWithRolesDTO } from '@takaro/apiclient';
export interface RouterContext {
queryClient: QueryClient;
@@ -14,10 +15,9 @@ export const router = createRouter({
routeTree,
context: {
auth: {
- isAuthenticated: false,
logOut: async () => {},
- session: undefined!,
login: () => {},
+ getSession: async () => ({} as Promise),
},
queryClient: queryClient,
},
diff --git a/packages/web-main/src/routes/_auth.tsx b/packages/web-main/src/routes/_auth.tsx
index be23a6f0ab..7f93c2f879 100644
--- a/packages/web-main/src/routes/_auth.tsx
+++ b/packages/web-main/src/routes/_auth.tsx
@@ -1,11 +1,27 @@
import { Outlet, createFileRoute, redirect } from '@tanstack/react-router';
+import { SessionContext } from 'hooks/useSession';
export const Route = createFileRoute('/_auth')({
- beforeLoad: ({ context }) => {
- if (context.auth.isAuthenticated === false) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!session) {
const redirectPath = location.pathname === '/login' ? '/' : location.pathname;
throw redirect({ to: '/login', search: { redirect: redirectPath } });
}
},
- component: () => ,
+
+ loader: async ({ context }) => {
+ return await context.auth.getSession();
+ },
+ component: Component,
});
+
+function Component() {
+ const session = Route.useLoaderData();
+
+ return (
+
+
+
+ );
+}
diff --git a/packages/web-main/src/routes/_auth/_global/dashboard.tsx b/packages/web-main/src/routes/_auth/_global/dashboard.tsx
index 28919ebd1e..6d54a05bf7 100644
--- a/packages/web-main/src/routes/_auth/_global/dashboard.tsx
+++ b/packages/web-main/src/routes/_auth/_global/dashboard.tsx
@@ -13,7 +13,8 @@ import { PlayersOnlineStatsQueryOptions, ActivityStatsQueryOptions } from 'queri
export const Route = createFileRoute('/_auth/_global/dashboard')({
beforeLoad: async ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_EVENTS'])) {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_EVENTS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/events.tsx b/packages/web-main/src/routes/_auth/_global/events.tsx
index 170ad6ae27..7dc852fdbf 100644
--- a/packages/web-main/src/routes/_auth/_global/events.tsx
+++ b/packages/web-main/src/routes/_auth/_global/events.tsx
@@ -143,7 +143,8 @@ type EventSearch = z.infer;
export const Route = createFileRoute('/_auth/_global/events')({
validateSearch: eventSearchSchema,
beforeLoad: async ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_EVENTS', 'READ_GAMESERVERS', 'READ_PLAYERS', 'READ_USERS'])) {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_EVENTS', 'READ_GAMESERVERS', 'READ_PLAYERS', 'READ_USERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/gameservers.create.import.tsx b/packages/web-main/src/routes/_auth/_global/gameservers.create.import.tsx
index fb4c983e39..b29fc72053 100644
--- a/packages/web-main/src/routes/_auth/_global/gameservers.create.import.tsx
+++ b/packages/web-main/src/routes/_auth/_global/gameservers.create.import.tsx
@@ -14,8 +14,9 @@ export interface IFormInputs {
}
export const Route = createFileRoute('/_auth/_global/gameservers/create/import')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_GAMESERVERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_GAMESERVERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/gameservers.create.index.tsx b/packages/web-main/src/routes/_auth/_global/gameservers.create.index.tsx
index 72ef0cd793..f9adcd2520 100644
--- a/packages/web-main/src/routes/_auth/_global/gameservers.create.index.tsx
+++ b/packages/web-main/src/routes/_auth/_global/gameservers.create.index.tsx
@@ -8,8 +8,9 @@ import { GameServerCreateDTOTypeEnum } from '@takaro/apiclient';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/gameservers/create/')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_GAMESERVERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_GAMESERVERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/gameservers.tsx b/packages/web-main/src/routes/_auth/_global/gameservers.tsx
index b87dcaa5ab..731f4a9d81 100644
--- a/packages/web-main/src/routes/_auth/_global/gameservers.tsx
+++ b/packages/web-main/src/routes/_auth/_global/gameservers.tsx
@@ -11,8 +11,9 @@ import { Fragment } from 'react';
import { PERMISSIONS } from '@takaro/apiclient';
export const Route = createFileRoute('/_auth/_global/gameservers')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_GAMESERVERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_GAMESERVERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/gameservers.update.$gameServerId.tsx b/packages/web-main/src/routes/_auth/_global/gameservers.update.$gameServerId.tsx
index bff4afb2e6..8e19d4639e 100644
--- a/packages/web-main/src/routes/_auth/_global/gameservers.update.$gameServerId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/gameservers.update.$gameServerId.tsx
@@ -8,8 +8,9 @@ import { IFormInputs } from './-gameservers/validationSchema';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/gameservers/update/$gameServerId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_GAMESERVERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_GAMESERVERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/index.tsx b/packages/web-main/src/routes/_auth/_global/index.tsx
index 40bb2a5e75..29be253884 100644
--- a/packages/web-main/src/routes/_auth/_global/index.tsx
+++ b/packages/web-main/src/routes/_auth/_global/index.tsx
@@ -4,17 +4,14 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { getUserPermissions, hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/')({
- beforeLoad: ({ context, location }) => {
- if (context.auth.isAuthenticated === false) {
- throw redirect({ to: '/login', search: { redirect: location.pathname } });
- }
-
- if (hasPermission(context.auth.session, [PERMISSIONS.ReadEvents])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (hasPermission(session, [PERMISSIONS.ReadEvents])) {
throw redirect({ to: '/dashboard' });
}
/* if user has no permissions at all, so can't see any page, redirect to forbidden */
- if (getUserPermissions(context.auth.session).length === 0) {
+ if (getUserPermissions(session).length === 0) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.copy.tsx b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.copy.tsx
index 8437898856..e1a66b4288 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.copy.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.copy.tsx
@@ -7,8 +7,9 @@ import { useState } from 'react';
import { CopyModuleForm } from 'components/CopyModuleForm';
export const Route = createFileRoute('/_auth/_global/modules/$moduleId/copy')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.update.tsx b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.update.tsx
index b35015629e..d7e78ee0f4 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.update.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.update.tsx
@@ -5,8 +5,9 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/modules/$moduleId/update')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.view.tsx b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.view.tsx
index ebd3234151..bfb0d68cba 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.$moduleId.view.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.$moduleId.view.tsx
@@ -5,8 +5,9 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/modules/$moduleId/view')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.create.import.tsx b/packages/web-main/src/routes/_auth/_global/modules.create.import.tsx
index 4bc5bc219d..e1034e9904 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.create.import.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.create.import.tsx
@@ -4,8 +4,9 @@ import { ModuleImportForm, IFormInputs } from './-modules/ModuleImportForm';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/modules/create/import')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.create.index.tsx b/packages/web-main/src/routes/_auth/_global/modules.create.index.tsx
index 34cfca6c47..5c66144b0c 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.create.index.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.create.index.tsx
@@ -4,8 +4,9 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/modules/create/')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/modules.tsx b/packages/web-main/src/routes/_auth/_global/modules.tsx
index b4c9710ace..04b0094e11 100644
--- a/packages/web-main/src/routes/_auth/_global/modules.tsx
+++ b/packages/web-main/src/routes/_auth/_global/modules.tsx
@@ -20,8 +20,9 @@ const SubText = styled.p`
`;
export const Route = createFileRoute('/_auth/_global/modules')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, [PERMISSIONS.ReadModules])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, [PERMISSIONS.ReadModules])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/player.$playerId.tsx b/packages/web-main/src/routes/_auth/_global/player.$playerId.tsx
index 90dd9486ee..55361a8a6b 100644
--- a/packages/web-main/src/routes/_auth/_global/player.$playerId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/player.$playerId.tsx
@@ -8,8 +8,9 @@ import { ErrorBoundary } from 'components/ErrorBoundary';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/player/$playerId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_PLAYERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_PLAYERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/players.tsx b/packages/web-main/src/routes/_auth/_global/players.tsx
index 5cd384b75a..b34185acba 100644
--- a/packages/web-main/src/routes/_auth/_global/players.tsx
+++ b/packages/web-main/src/routes/_auth/_global/players.tsx
@@ -40,8 +40,9 @@ export const StyledDialogBody = styled(Dialog.Body)`
}
`;
export const Route = createFileRoute('/_auth/_global/players')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_PLAYERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_PLAYERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/roles.create.tsx b/packages/web-main/src/routes/_auth/_global/roles.create.tsx
index c4955f3852..438704bcad 100644
--- a/packages/web-main/src/routes/_auth/_global/roles.create.tsx
+++ b/packages/web-main/src/routes/_auth/_global/roles.create.tsx
@@ -8,8 +8,9 @@ import { RoleForm, IFormInputs } from './-roles/RoleCreateUpdateForm';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/roles/create')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_ROLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_ROLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/roles.tsx b/packages/web-main/src/routes/_auth/_global/roles.tsx
index f0e186d706..0f04f53f18 100644
--- a/packages/web-main/src/routes/_auth/_global/roles.tsx
+++ b/packages/web-main/src/routes/_auth/_global/roles.tsx
@@ -9,8 +9,9 @@ import { useInfiniteQuery } from '@tanstack/react-query';
import { InfiniteScroll } from '@takaro/lib-components';
export const Route = createFileRoute('/_auth/_global/roles')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_ROLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_ROLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/roles.update.$roleId.tsx b/packages/web-main/src/routes/_auth/_global/roles.update.$roleId.tsx
index 2acb7797d4..f416e7ba17 100644
--- a/packages/web-main/src/routes/_auth/_global/roles.update.$roleId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/roles.update.$roleId.tsx
@@ -7,8 +7,9 @@ import { createFileRoute, redirect, useNavigate } from '@tanstack/react-router';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/roles/update/$roleId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_ROLES', 'MANAGE_ROLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_ROLES', 'MANAGE_ROLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/roles.view.$roleId.tsx b/packages/web-main/src/routes/_auth/_global/roles.view.$roleId.tsx
index c103fc360e..e415b0e34f 100644
--- a/packages/web-main/src/routes/_auth/_global/roles.view.$roleId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/roles.view.$roleId.tsx
@@ -5,8 +5,9 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/roles/view/$roleId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_ROLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_ROLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/settings.tsx b/packages/web-main/src/routes/_auth/_global/settings.tsx
index b8eaa39cde..99e808b8bf 100644
--- a/packages/web-main/src/routes/_auth/_global/settings.tsx
+++ b/packages/web-main/src/routes/_auth/_global/settings.tsx
@@ -4,8 +4,9 @@ import { ErrorBoundary } from 'components/ErrorBoundary';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/settings')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_SETTINGS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_SETTINGS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/settings/-discord/LoginDiscordCard.tsx b/packages/web-main/src/routes/_auth/_global/settings/-discord/LoginDiscordCard.tsx
index 2edb50a821..9a6c6eeb27 100644
--- a/packages/web-main/src/routes/_auth/_global/settings/-discord/LoginDiscordCard.tsx
+++ b/packages/web-main/src/routes/_auth/_global/settings/-discord/LoginDiscordCard.tsx
@@ -1,8 +1,8 @@
import { FC } from 'react';
-import { useAuth } from 'hooks/useAuth';
import { Card, Button, styled, useTheme } from '@takaro/lib-components';
import { FaDiscord as DiscordIcon } from 'react-icons/fa';
import { getConfigVar } from 'util/getConfigVar';
+import { useSession } from 'hooks/useSession';
const Body = styled.div`
display: flex;
@@ -12,10 +12,10 @@ const Body = styled.div`
`;
export const LoginDiscordCard: FC = () => {
- const { session } = useAuth();
+ const { session } = useSession();
const { colors } = useTheme();
- const hasLinkedDiscord = !!session?.discordId;
+ const hasLinkedDiscord = !!session.discordId;
return (
diff --git a/packages/web-main/src/routes/_auth/_global/settings/gameservers.tsx b/packages/web-main/src/routes/_auth/_global/settings/gameservers.tsx
index ea7b0667a2..05388c3628 100644
--- a/packages/web-main/src/routes/_auth/_global/settings/gameservers.tsx
+++ b/packages/web-main/src/routes/_auth/_global/settings/gameservers.tsx
@@ -11,8 +11,9 @@ import { hasPermission, useHasPermission } from 'hooks/useHasPermission';
import { createFileRoute, redirect } from '@tanstack/react-router';
export const Route = createFileRoute('/_auth/_global/settings/gameservers')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_SETTINGS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_SETTINGS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/user.$userId.role.assign.tsx b/packages/web-main/src/routes/_auth/_global/user.$userId.role.assign.tsx
index 84f4a8f3b7..6445bd2ef8 100644
--- a/packages/web-main/src/routes/_auth/_global/user.$userId.role.assign.tsx
+++ b/packages/web-main/src/routes/_auth/_global/user.$userId.role.assign.tsx
@@ -36,8 +36,9 @@ const roleAssignValidationSchema = z.object({
type IFormInputs = z.infer;
export const Route = createFileRoute('/_auth/_global/user/$userId/role/assign')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_ROLES', 'MANAGE_ROLES', 'READ_USERS', 'MANAGE_USERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_ROLES', 'MANAGE_ROLES', 'READ_USERS', 'MANAGE_USERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/user.$userId.tsx b/packages/web-main/src/routes/_auth/_global/user.$userId.tsx
index f13fedfa91..01338d2679 100644
--- a/packages/web-main/src/routes/_auth/_global/user.$userId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/user.$userId.tsx
@@ -10,8 +10,9 @@ import { hasPermission } from 'hooks/useHasPermission';
import { useQuery } from '@tanstack/react-query';
export const Route = createFileRoute('/_auth/_global/user/$userId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_USERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_USERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/users.tsx b/packages/web-main/src/routes/_auth/_global/users.tsx
index 0b6ad79a7c..9225abbfef 100644
--- a/packages/web-main/src/routes/_auth/_global/users.tsx
+++ b/packages/web-main/src/routes/_auth/_global/users.tsx
@@ -26,8 +26,9 @@ import { createFileRoute, useNavigate, Link, redirect } from '@tanstack/react-ro
import { useQuery } from '@tanstack/react-query';
export const Route = createFileRoute('/_auth/_global/users')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_USERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_USERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/variables.create.tsx b/packages/web-main/src/routes/_auth/_global/variables.create.tsx
index 1c7e159005..1a0bae05e2 100644
--- a/packages/web-main/src/routes/_auth/_global/variables.create.tsx
+++ b/packages/web-main/src/routes/_auth/_global/variables.create.tsx
@@ -5,8 +5,9 @@ import { hasPermission } from 'hooks/useHasPermission';
import { useEffect } from 'react';
export const Route = createFileRoute('/_auth/_global/variables/create')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_VARIABLES', 'MANAGE_VARIABLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_VARIABLES', 'MANAGE_VARIABLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/variables.tsx b/packages/web-main/src/routes/_auth/_global/variables.tsx
index 5e8cd6f595..0663b9aaab 100644
--- a/packages/web-main/src/routes/_auth/_global/variables.tsx
+++ b/packages/web-main/src/routes/_auth/_global/variables.tsx
@@ -22,8 +22,9 @@ import { useQuery } from '@tanstack/react-query';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/_global/variables')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_VARIABLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_VARIABLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/_global/variables.update.$variableId.tsx b/packages/web-main/src/routes/_auth/_global/variables.update.$variableId.tsx
index 137253cd10..150f1e018a 100644
--- a/packages/web-main/src/routes/_auth/_global/variables.update.$variableId.tsx
+++ b/packages/web-main/src/routes/_auth/_global/variables.update.$variableId.tsx
@@ -9,8 +9,9 @@ import { hasPermission } from 'hooks/useHasPermission';
import { useEffect } from 'react';
export const Route = createFileRoute('/_auth/_global/variables/update/$variableId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_VARIABLES', 'MANAGE_VARIABLES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_VARIABLES', 'MANAGE_VARIABLES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId.tsx
index ac0df963d0..e72d39147c 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId.tsx
@@ -5,8 +5,9 @@ import { gameServerQueryOptions } from 'queries/gameserver';
import { BaseLayout } from 'components/BaseLayout';
export const Route = createFileRoute('/_auth/gameserver/$gameServerId')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['READ_GAMESERVERS'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['READ_GAMESERVERS'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/dashboard.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/dashboard.tsx
index 48bb3566d1..10e66850c6 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/dashboard.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/dashboard.tsx
@@ -6,8 +6,9 @@ import { hasPermission } from 'hooks/useHasPermission';
import { PERMISSIONS } from '@takaro/apiclient';
export const Route = createFileRoute('/_auth/gameserver/$gameServerId/dashboard')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, [PERMISSIONS.ReadGameservers])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, [PERMISSIONS.ReadGameservers])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.tsx
index a8186d36fb..283578eb38 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.tsx
@@ -5,8 +5,9 @@ import { InstallModuleForm } from './-InstallModuleForm';
import { hasPermission } from 'hooks/useHasPermission';
export const Route = createFileRoute('/_auth/gameserver/$gameServerId/modules/$moduleId/install')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, ['MANAGE_MODULES'])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.view.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.view.tsx
index 7b22aecfcb..316b764a16 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.view.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.$moduleId.install.view.tsx
@@ -6,8 +6,9 @@ import { hasPermission } from 'hooks/useHasPermission';
import { PERMISSIONS } from '@takaro/apiclient';
export const Route = createFileRoute('/_auth/gameserver/$gameServerId/modules/$moduleId/install/view')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, [PERMISSIONS.ReadModules])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, [PERMISSIONS.ReadModules])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.tsx
index acc0df7878..7a1c983391 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/modules.tsx
@@ -13,8 +13,9 @@ const SubHeader = styled.h2`
`;
export const Route = createFileRoute('/_auth/gameserver/$gameServerId/modules')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, [PERMISSIONS.ReadModules])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, [PERMISSIONS.ReadModules])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/settings.tsx b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/settings.tsx
index 14962d4bdd..7fc4272335 100644
--- a/packages/web-main/src/routes/_auth/gameserver.$gameServerId/settings.tsx
+++ b/packages/web-main/src/routes/_auth/gameserver.$gameServerId/settings.tsx
@@ -15,8 +15,9 @@ import { createFileRoute, redirect } from '@tanstack/react-router';
import { useQueries } from '@tanstack/react-query';
export const Route = createFileRoute('/_auth/gameserver/$gameServerId/settings')({
- beforeLoad: ({ context }) => {
- if (!hasPermission(context.auth.session, [PERMISSIONS.ReadSettings])) {
+ beforeLoad: async ({ context }) => {
+ const session = await context.auth.getSession();
+ if (!hasPermission(session, [PERMISSIONS.ReadSettings])) {
throw redirect({ to: '/forbidden' });
}
},
diff --git a/packages/web-main/src/routes/studio.$moduleId.tsx b/packages/web-main/src/routes/studio.$moduleId.tsx
index ed784456b6..b6ca4e3a93 100644
--- a/packages/web-main/src/routes/studio.$moduleId.tsx
+++ b/packages/web-main/src/routes/studio.$moduleId.tsx
@@ -9,6 +9,7 @@ import { StudioInner } from './-studio/StudioInner';
import { hasPermission } from 'hooks/useHasPermission';
import { FileMap, FileType, StudioProvider } from './-studio/useStudioStore';
import { z } from 'zod';
+import { getApiClient } from 'util/getApiClient';
const Flex = styled.div`
display: flex;
@@ -27,12 +28,13 @@ const LoadingContainer = styled.div`
`;
export const Route = createFileRoute('/studio/$moduleId')({
- beforeLoad: ({ context, location }) => {
- if (context.auth.isAuthenticated === false) {
- throw redirect({ to: '/login', search: { redirect: location.pathname } });
- }
-
- if (!hasPermission(context.auth.session, ['MANAGE_MODULES'])) {
+ beforeLoad: async ({}) => {
+ try {
+ const me = (await getApiClient().user.userControllerMe()).data.data;
+ if (!hasPermission(me.user, ['MANAGE_MODULES'])) {
+ throw redirect({ to: '/forbidden' });
+ }
+ } catch {
throw redirect({ to: '/forbidden' });
}
},