0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -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:
Gao Sun 2023-07-24 11:11:06 +08:00 committed by GitHub
parent 437be82a27
commit f8e11b1b34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 15 deletions

View file

@ -1,6 +1,7 @@
import { Route, Routes } from 'react-router-dom'; import { Route, Routes } from 'react-router-dom';
import ProtectedRoutes from '@/containers/ProtectedRoutes'; import ProtectedRoutes from '@/containers/ProtectedRoutes';
import { GlobalAnonymousRoute } from '@/contexts/TenantsProvider';
import Callback from '@/pages/Callback'; import Callback from '@/pages/Callback';
import * as styles from './AppRoutes.module.scss'; import * as styles from './AppRoutes.module.scss';
@ -12,11 +13,10 @@ function AppRoutes() {
return ( return (
<div className={styles.app}> <div className={styles.app}>
<Routes> <Routes>
<Route path="/callback" element={<Callback />} /> <Route path={GlobalAnonymousRoute.Callback} element={<Callback />} />
<Route path="/social-demo-callback" element={<SocialDemoCallback />} /> <Route path={GlobalAnonymousRoute.SocialDemoCallback} element={<SocialDemoCallback />} />
<Route path="/:tenantId/callback" element={<Callback />} />
<Route element={<ProtectedRoutes />}> <Route element={<ProtectedRoutes />}>
<Route path="*" element={<Main />} /> <Route index element={<Main />} />
</Route> </Route>
</Routes> </Routes>
</div> </div>

View file

@ -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 * 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. * 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]); }, [mutate, currentTenantId]);
useEffect(() => { useEffect(() => {

View file

@ -7,6 +7,23 @@ import { useMatch, useNavigate } from 'react-router-dom';
import { isCloud } from '@/consts/env'; 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 * The current tenant status of access validation. When it's `validated`, it indicates that a
* valid Access Token for the current tenant is available. * valid Access Token for the current tenant is available.
@ -83,12 +100,19 @@ function TenantsProvider({ children }: Props) {
const [tenants, setTenants] = useState(initialTenants); const [tenants, setTenants] = useState(initialTenants);
/** @see {@link initialTenants} */ /** @see {@link initialTenants} */
const [isInitComplete, setIsInitComplete] = useState(!isCloud); const [isInitComplete, setIsInitComplete] = useState(!isCloud);
const matched = useMatch('/:tenantId/*'); const match = useMatch('/:tenantId/*');
const navigate = useNavigate(); const navigate = useNavigate();
const currentTenantId = useMemo( const currentTenantId = useMemo(() => {
() => (isCloud ? matched?.params.tenantId ?? '' : defaultTenantId), if (!isCloud) {
[matched] return defaultTenantId;
); }
if (!match || anonymousRoutes.includes(match.pathname)) {
return '';
}
return match.params.tenantId ?? '';
}, [match]);
const [currentTenantStatus, setCurrentTenantStatus] = useState<CurrentTenantStatus>('pending'); const [currentTenantStatus, setCurrentTenantStatus] = useState<CurrentTenantStatus>('pending');
const navigateTenant = useCallback( const navigateTenant = useCallback(

View file

@ -23,9 +23,8 @@ function Congrats() {
const { update } = useUserOnboardingData(); const { update } = useUserOnboardingData();
const { navigateTenant, currentTenantId } = useContext(TenantsContext); const { navigateTenant, currentTenantId } = useContext(TenantsContext);
const enterAdminConsole = () => { const enterAdminConsole = async () => {
void update({ isOnboardingDone: true }); await update({ isOnboardingDone: true });
// Note: navigate to the admin console page directly instead of using the router
navigateTenant(currentTenantId); navigateTenant(currentTenantId);
}; };

View file

@ -19,7 +19,7 @@ function Callback() {
return; return;
} }
navigate(getTo('/'), { replace: true }); navigate('/', { replace: true });
}); });
return <AppLoading />; return <AppLoading />;

View file

@ -1,6 +1,7 @@
import { Component, GeneralEvent } from '@logto/app-insights/custom-event'; import { Component, GeneralEvent } from '@logto/app-insights/custom-event';
import { TrackOnce } from '@logto/app-insights/react'; 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 { SWRConfig } from 'swr';
import { isCloud, isProduction } from '@/consts/env'; import { isCloud, isProduction } from '@/consts/env';
@ -35,6 +36,12 @@ function Layout() {
export function ConsoleRoutes() { export function ConsoleRoutes() {
return ( return (
<Routes> <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="/:tenantId" element={<Layout />}>
<Route path="callback" element={<Callback />} /> <Route path="callback" element={<Callback />} />
<Route path="welcome" element={<Welcome />} /> <Route path="welcome" element={<Welcome />} />