diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d7fec8b..2e992f2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to - 🐛(service-worker) Fix useOffline Maximum update depth exceeded #1196 - 🐛(helm) charts generate invalid YAML for collaboration API / WS #890 +- 🐛(frontend) 401 redirection overridden #1214 ## [3.4.2] - 2025-07-18 diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts index 83845be0..6f8eb7c6 100644 --- a/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-routing.spec.ts @@ -9,6 +9,7 @@ import { mockedDocument, verifyDocName, } from './utils-common'; +import { createRootSubPage } from './utils-sub-pages'; test.describe('Doc Routing', () => { test.beforeEach(async ({ page }) => { @@ -60,16 +61,20 @@ test.describe('Doc Routing', () => { }); test('checks 401 on docs/[id] page', async ({ page, browserName }) => { - const [docTitle] = await createDoc(page, '401-doc', browserName, 1); + const [docTitle] = await createDoc(page, '401-doc-parent', browserName, 1); await verifyDocName(page, docTitle); + await createRootSubPage(page, browserName, '401-doc-child'); + + await page.locator('.ProseMirror.bn-editor').fill('Hello World'); + const responsePromise = page.route( - /.*\/link-configuration\/$|users\/me\/$/, + /.*\/documents\/.*\/$|users\/me\/$/, async (route) => { const request = route.request(); if ( - request.method().includes('PUT') || + request.method().includes('PATCH') || request.method().includes('GET') ) { await route.fulfill({ @@ -84,11 +89,7 @@ test.describe('Doc Routing', () => { }, ); - await page.getByRole('button', { name: 'Share' }).click(); - - const selectVisibility = page.getByLabel('Visibility', { exact: true }); - await selectVisibility.click(); - await page.getByLabel('Connected').click(); + await page.getByRole('link', { name: '401-doc-parent' }).click(); await responsePromise; diff --git a/src/frontend/apps/impress/src/core/AppProvider.tsx b/src/frontend/apps/impress/src/core/AppProvider.tsx index 9f18e114..b52f8fd2 100644 --- a/src/frontend/apps/impress/src/core/AppProvider.tsx +++ b/src/frontend/apps/impress/src/core/AppProvider.tsx @@ -1,5 +1,9 @@ import { CunninghamProvider } from '@openfun/cunningham-react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { + MutationCache, + QueryClient, + QueryClientProvider, +} from '@tanstack/react-query'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; @@ -24,8 +28,24 @@ const defaultOptions = { retry: DEFAULT_QUERY_RETRY, }, }; + +let globalRouterReplace: ((url: string) => void) | null = null; + const queryClient = new QueryClient({ defaultOptions, + mutationCache: new MutationCache({ + onError: (error) => { + if (error instanceof Error && 'status' in error && error.status === 401) { + void queryClient.resetQueries({ + queryKey: [KEY_AUTH], + }); + setAuthUrl(); + if (globalRouterReplace) { + void globalRouterReplace('/401'); + } + } + }, + }), }); export function AppProvider({ children }: { children: React.ReactNode }) { @@ -40,25 +60,14 @@ export function AppProvider({ children }: { children: React.ReactNode }) { return initializeResizeListener(); }, [initializeResizeListener]); + /** + * Update the global router replace function + * This allows us to use the router replace function globally + */ useEffect(() => { - queryClient.setDefaultOptions({ - ...defaultOptions, - mutations: { - onError: (error) => { - if ( - error instanceof Error && - 'status' in error && - error.status === 401 - ) { - void queryClient.resetQueries({ - queryKey: [KEY_AUTH], - }); - setAuthUrl(); - void replace(`/401`); - } - }, - }, - }); + globalRouterReplace = (url: string) => { + void replace(url); + }; }, [replace]); return ( diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx b/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx index 12a87367..d63283e2 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-management/api/useUpdateDoc.tsx @@ -52,10 +52,16 @@ export function useUpdateDoc(queryConfig?: UseUpdateDoc) { void queryConfig.onSuccess(data, variables, context); } }, - onError: () => { + onError: (error, variables, context) => { + // If error it means the user is probably not allowed to edit the doc + // so we invalidate the canEdit query to update the UI accordingly void queryClient.invalidateQueries({ queryKey: [KEY_CAN_EDIT], }); + + if (queryConfig?.onError) { + queryConfig.onError(error, variables, context); + } }, }); }