fix(next): login redirect crashes page (#13786)
## Problem When logging in with a `?redirect=`, the target page may crash. This happens because the update from `SyncClientConfig` is applied in a `useEffect`, which runs **_after_** the target page's client components render. As a result, those components read the unauthenticated client config on first render - even though they expect the authenticated one. ## Steps To Reproduce 1. logout 2. login with ?redirect= 3. document client component incorrectly still receives unauthenticated client config on render 4. THEN the SyncClientConfig useEffect runs. Too late 5. Potential error (depending on the page, e.g. document view) - document client component expects sth to be there, but it is not ## Solution This PR replaces `SyncClientConfig` with a `RootPageConfigProvider`. This new provider shadows the root layout’s `ConfigProvider` and ensures the correct client config is available **_immediately_**. It still updates the config using `useEffect` (the same way`SyncClientConfig` did), but with one key difference: - During the brief window between the redirect and the effect running, it overrides the root layout’s config and provides the fresh, authenticated config from the root page via the `RootConfigContext`. This guarantees that client components on the target page receive the correct config on first render, preventing errors caused by reading the outdated unauthenticated config. ## Additional change - get rid of `UnsanitizedClientConfig` and `sanitizeClientConfig` Those functions added unnecessary complexity, just to build the blocksMap. I removed those and perform the building of the `blocksMap` server-side - directly in `createClientConfig`. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211334752795621
This commit is contained in:
@@ -52,6 +52,7 @@ describe('Auth', () => {
|
||||
page = await context.newPage()
|
||||
initPageConsoleErrorCatch(page)
|
||||
})
|
||||
|
||||
describe('create first user', () => {
|
||||
beforeAll(async () => {
|
||||
await reInitializeDB({
|
||||
@@ -386,6 +387,36 @@ describe('Auth', () => {
|
||||
|
||||
await saveDocAndAssert(page)
|
||||
})
|
||||
|
||||
test('ensure login page with redirect to users document redirects properly after login, without client error', async () => {
|
||||
await page.goto(url.admin)
|
||||
|
||||
await page.goto(`${serverURL}/admin/logout`)
|
||||
|
||||
await expect(page.locator('.login')).toBeVisible()
|
||||
|
||||
const users = await payload.find({
|
||||
collection: slug,
|
||||
limit: 1,
|
||||
})
|
||||
const userDocumentRoute = `${serverURL}/admin/collections/users/${users?.docs?.[0]?.id}`
|
||||
|
||||
await page.goto(userDocumentRoute)
|
||||
|
||||
await expect(page.locator('#field-email')).toBeVisible()
|
||||
await expect(page.locator('#field-password')).toBeVisible()
|
||||
|
||||
await page.locator('.form-submit > button').click()
|
||||
|
||||
// Expect to be redirected to the correct page
|
||||
await expect
|
||||
.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT })
|
||||
.toBe(userDocumentRoute)
|
||||
|
||||
// Previously, this would crash the page with a "Cannot read properties of undefined (reading 'match')" error
|
||||
|
||||
await expect(page.locator('#field-roles')).toBeVisible()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user