mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
fix(console): adapt callback and current tenant id logic (#4206)
* fix(console): adapt callback and current tenant id logic * fix(console): fix cache and onboarding route * fix(console): fix cache and onboarding route
This commit is contained in:
parent
437be82a27
commit
f8e11b1b34
6 changed files with 45 additions and 15 deletions
|
@ -1,6 +1,7 @@
|
|||
import { Route, Routes } from 'react-router-dom';
|
||||
|
||||
import ProtectedRoutes from '@/containers/ProtectedRoutes';
|
||||
import { GlobalAnonymousRoute } from '@/contexts/TenantsProvider';
|
||||
import Callback from '@/pages/Callback';
|
||||
|
||||
import * as styles from './AppRoutes.module.scss';
|
||||
|
@ -12,11 +13,10 @@ function AppRoutes() {
|
|||
return (
|
||||
<div className={styles.app}>
|
||||
<Routes>
|
||||
<Route path="/callback" element={<Callback />} />
|
||||
<Route path="/social-demo-callback" element={<SocialDemoCallback />} />
|
||||
<Route path="/:tenantId/callback" element={<Callback />} />
|
||||
<Route path={GlobalAnonymousRoute.Callback} element={<Callback />} />
|
||||
<Route path={GlobalAnonymousRoute.SocialDemoCallback} element={<SocialDemoCallback />} />
|
||||
<Route element={<ProtectedRoutes />}>
|
||||
<Route path="*" element={<Main />} />
|
||||
<Route index element={<Main />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</div>
|
||||
|
|
|
@ -59,7 +59,7 @@ export default function TenantAccess() {
|
|||
* We need to exclude the `me` key because it's not tenant-aware. If don't, we
|
||||
* need to manually revalidate the `me` key to make console work again.
|
||||
*/
|
||||
void mutate((key) => key !== 'me', undefined, false);
|
||||
void mutate((key) => key !== 'me', undefined, { rollbackOnError: false, throwOnError: false });
|
||||
}, [mutate, currentTenantId]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -7,6 +7,23 @@ import { useMatch, useNavigate } from 'react-router-dom';
|
|||
|
||||
import { isCloud } from '@/consts/env';
|
||||
|
||||
/**
|
||||
* The routes don't start with a tenant ID.
|
||||
*
|
||||
* @remarks
|
||||
* It's important to keep this single source of truth for all anonymous routes
|
||||
* because we need to check if the current route is anonymous or not to decide
|
||||
* if the current tenant ID is available.
|
||||
*
|
||||
* This should be more clear once we refactor the file structure and the routes.
|
||||
*/
|
||||
export enum GlobalAnonymousRoute {
|
||||
Callback = '/callback',
|
||||
SocialDemoCallback = '/social-demo-callback',
|
||||
}
|
||||
|
||||
const anonymousRoutes: Readonly<string[]> = Object.freeze(Object.values(GlobalAnonymousRoute));
|
||||
|
||||
/**
|
||||
* The current tenant status of access validation. When it's `validated`, it indicates that a
|
||||
* valid Access Token for the current tenant is available.
|
||||
|
@ -83,12 +100,19 @@ function TenantsProvider({ children }: Props) {
|
|||
const [tenants, setTenants] = useState(initialTenants);
|
||||
/** @see {@link initialTenants} */
|
||||
const [isInitComplete, setIsInitComplete] = useState(!isCloud);
|
||||
const matched = useMatch('/:tenantId/*');
|
||||
const match = useMatch('/:tenantId/*');
|
||||
const navigate = useNavigate();
|
||||
const currentTenantId = useMemo(
|
||||
() => (isCloud ? matched?.params.tenantId ?? '' : defaultTenantId),
|
||||
[matched]
|
||||
);
|
||||
const currentTenantId = useMemo(() => {
|
||||
if (!isCloud) {
|
||||
return defaultTenantId;
|
||||
}
|
||||
|
||||
if (!match || anonymousRoutes.includes(match.pathname)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return match.params.tenantId ?? '';
|
||||
}, [match]);
|
||||
const [currentTenantStatus, setCurrentTenantStatus] = useState<CurrentTenantStatus>('pending');
|
||||
|
||||
const navigateTenant = useCallback(
|
||||
|
|
|
@ -23,9 +23,8 @@ function Congrats() {
|
|||
const { update } = useUserOnboardingData();
|
||||
const { navigateTenant, currentTenantId } = useContext(TenantsContext);
|
||||
|
||||
const enterAdminConsole = () => {
|
||||
void update({ isOnboardingDone: true });
|
||||
// Note: navigate to the admin console page directly instead of using the router
|
||||
const enterAdminConsole = async () => {
|
||||
await update({ isOnboardingDone: true });
|
||||
navigateTenant(currentTenantId);
|
||||
};
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ function Callback() {
|
|||
return;
|
||||
}
|
||||
|
||||
navigate(getTo('/'), { replace: true });
|
||||
navigate('/', { replace: true });
|
||||
});
|
||||
|
||||
return <AppLoading />;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Component, GeneralEvent } from '@logto/app-insights/custom-event';
|
||||
import { TrackOnce } from '@logto/app-insights/react';
|
||||
import { Outlet, Route, Routes } from 'react-router-dom';
|
||||
import { ossConsolePath } from '@logto/schemas';
|
||||
import { Navigate, Outlet, Route, Routes } from 'react-router-dom';
|
||||
import { SWRConfig } from 'swr';
|
||||
|
||||
import { isCloud, isProduction } from '@/consts/env';
|
||||
|
@ -35,6 +36,12 @@ function Layout() {
|
|||
export function ConsoleRoutes() {
|
||||
return (
|
||||
<Routes>
|
||||
{/**
|
||||
* OSS doesn't have a tenant concept nor root path handling component, but it may
|
||||
* navigate to the root path in frontend. In this case, we redirect it to the OSS
|
||||
* console path to trigger the console routes.
|
||||
*/}
|
||||
{!isCloud && <Route path="/" element={<Navigate to={ossConsolePath} />} />}
|
||||
<Route path="/:tenantId" element={<Layout />}>
|
||||
<Route path="callback" element={<Callback />} />
|
||||
<Route path="welcome" element={<Welcome />} />
|
||||
|
|
Loading…
Reference in a new issue