This is an automated email from the ASF dual-hosted git repository.
rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new abdf2e6c702 fix(home): redirect users without an ID before rendering
(#44456)
abdf2e6c702 is described below
commit abdf2e6c702503a83294e0f3aefeb604163d1087
Author: Bexultan <[email protected]>
AuthorDate: Fri Oct 2 05:49:38 2026 +0500
fix(home): redirect users without an ID before rendering (#44456)
---
docs/docs/quickstart.mdx | 3 ++
superset-frontend/src/pages/Home/Home.test.tsx | 45 +++++++++++++++++++++++---
superset-frontend/src/pages/Home/index.tsx | 20 +++++++++++-
3 files changed, 63 insertions(+), 5 deletions(-)
diff --git a/docs/docs/quickstart.mdx b/docs/docs/quickstart.mdx
index 22a6c2e667a..1bc6f96cf90 100644
--- a/docs/docs/quickstart.mdx
+++ b/docs/docs/quickstart.mdx
@@ -54,6 +54,9 @@ username: admin
password: admin
```
+The personalized Home page requires you to sign in. Opening Home from the login
+page or a public dashboard redirects you to the login page first.
+
#### 🎉 Congratulations! Superset is now up and running on your machine! 🎉
### Wrapping Up
diff --git a/superset-frontend/src/pages/Home/Home.test.tsx
b/superset-frontend/src/pages/Home/Home.test.tsx
index 75dc4ee0c75..bbe2419f90e 100644
--- a/superset-frontend/src/pages/Home/Home.test.tsx
+++ b/superset-frontend/src/pages/Home/Home.test.tsx
@@ -30,6 +30,8 @@ import {
import { isFeatureEnabled, getExtensionsRegistry } from '@superset-ui/core';
import Welcome from 'src/pages/Home';
import setupCodeOverrides from 'src/setup/setupCodeOverrides';
+import { redirect } from 'src/utils/navigationUtils';
+import { RoutePaths } from 'src/views/routePaths';
const chartsEndpoint = 'glob:*/api/v1/chart/?*';
const chartInfoEndpoint = 'glob:*/api/v1/chart/_info?*';
@@ -150,6 +152,11 @@ jest.mock('@superset-ui/core', () => ({
isFeatureEnabled: jest.fn(),
}));
+jest.mock('src/utils/navigationUtils', () => ({
+ ...jest.requireActual('src/utils/navigationUtils'),
+ redirect: jest.fn(),
+}));
+
// Mock useBreakpoint to return desktop breakpoints (prevents mobile rendering)
jest.mock('antd', () => mockAntdWithDesktopBreakpoint());
@@ -165,12 +172,42 @@ const renderWelcome = (props = mockedProps) =>
afterEach(() => {
fetchMock.clearHistory();
+ jest.mocked(redirect).mockClear();
});
-test('With sql role - renders', async () => {
- await renderWelcome();
- expect(await screen.findByText('Dashboards')).toBeInTheDocument();
-});
+test.each([
+ ['anonymous', { roles: { Public: [] }, permissions: {}, groups: [] }],
+ ['guest', { ...mockedProps.user, userId: undefined }],
+ ['missing', undefined],
+])(
+ 'Redirects the %s user through the server without fetching Home data',
+ async (_, user) => {
+ render(<Welcome user={user} />, { useRedux: true, useRouter: true });
+
+ await waitFor(() =>
expect(redirect).toHaveBeenCalledWith(RoutePaths.HOME));
+ [
+ chartsEndpoint,
+ dashboardsEndpoint,
+ recentActivityEndpoint,
+ savedQueryEndpoint,
+ ].forEach(endpoint => {
+ expect(fetchMock.callHistory.calls(endpoint)).toHaveLength(0);
+ });
+ expect(screen.queryByText('Dashboards')).not.toBeInTheDocument();
+ },
+);
+
+test.each([0, mockedProps.user.userId])(
+ 'With sql role and user ID %s - renders',
+ async userId => {
+ await renderWelcome({
+ ...mockedProps,
+ user: { ...mockedProps.user, userId },
+ });
+ expect(await screen.findByText('Dashboards')).toBeInTheDocument();
+ expect(redirect).not.toHaveBeenCalled();
+ },
+);
test('With sql role - renders all panels on the page on page load', async ()
=> {
await renderWelcome();
diff --git a/superset-frontend/src/pages/Home/index.tsx
b/superset-frontend/src/pages/Home/index.tsx
index 7c88a627b4a..82ff403b81e 100644
--- a/superset-frontend/src/pages/Home/index.tsx
+++ b/superset-frontend/src/pages/Home/index.tsx
@@ -48,6 +48,8 @@ import {
} from 'src/views/CRUD/utils';
import { Switch } from '@superset-ui/core/components/Switch';
import getBootstrapData from 'src/utils/getBootstrapData';
+import { redirect } from 'src/utils/navigationUtils';
+import { RoutePaths } from 'src/views/routePaths';
import { TableTab } from 'src/views/CRUD/types';
import SubMenu, { SubMenuProps } from 'src/features/home/SubMenu';
import { userHasPermission } from 'src/dashboard/util/permissionUtils';
@@ -448,4 +450,20 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
);
}
-export default withToasts(Welcome);
+function WelcomePage({
+ user,
+ ...props
+}: Omit<WelcomeProps, 'user'> & { user?: UserWithPermissionsAndRoles }) {
+ const hasUserId = user?.userId != null;
+
+ useEffect(() => {
+ if (!hasUserId) {
+ // SPA navigation can bypass the welcome view's server-side login check.
+ redirect(RoutePaths.HOME);
+ }
+ }, [hasUserId]);
+
+ return hasUserId ? <Welcome {...props} user={user} /> : null;
+}
+
+export default withToasts(WelcomePage);