Skip to content

Commit 8113d3b

Browse files
authored
fix(next): exclude permissions from page response when unauthenticated (#13796)
Similar spirit as #13714. Permissions are embedded into the page response, exposing some field names to unauthenticated users. For example, when setting `read: () => false` on a field, that field's name is now included in the response due to its presence in the permissions object. We now search the HTML source directly in the test, similar to "view source" in the browser, which will be much effective at preventing regression going forward. --- - To see the specific tasks where the Asana app for GitHub is being used, see below: - https://app.asana.com/0/0/1211347942663256
1 parent e2632c8 commit 8113d3b

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

packages/next/src/layouts/Root/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export const RootLayout = async ({
122122
languageCode={languageCode}
123123
languageOptions={languageOptions}
124124
locale={req.locale}
125-
permissions={permissions}
125+
permissions={req.user ? permissions : null}
126126
serverFunction={serverFunction}
127127
switchLanguageServerAction={switchLanguageServerAction}
128128
theme={theme}

test/auth/config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,14 @@ export default buildConfigWithDefaults({
190190
label: 'Auth Debug',
191191
},
192192
{
193+
// This is a uniquely identifiable field that we use to ensure it doesn't appear in the page source when unauthenticated
194+
// E.g. if the user is authenticated, it will appear in the both the client config
193195
name: 'shouldNotShowInClientConfigUnlessAuthenticated',
194196
type: 'text',
197+
access: {
198+
// Setting this forces the field to show up in the permissions object
199+
read: () => true,
200+
},
195201
},
196202
],
197203
},

test/auth/e2e.spec.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,17 @@ describe('Auth', () => {
182182
await saveDocAndAssert(page, '#action-save')
183183
})
184184

185-
test('should protect the client config behind authentication', async () => {
185+
test('should protect field schemas behind authentication', async () => {
186186
await logout(page, serverURL)
187187

188-
// This element is absolutely positioned and `opacity: 0`
188+
// Inspect the page source (before authentication)
189+
const loginPageRes = await page.goto(`${serverURL}/admin/login`)
190+
const loginPageSource = await loginPageRes?.text()
191+
expect(loginPageSource).not.toContain('shouldNotShowInClientConfigUnlessAuthenticated')
192+
193+
// Inspect the client config (before authentication)
189194
await expect(page.locator('#unauthenticated-client-config')).toBeAttached()
190195

191-
// Search for our uniquely identifiable field name
192196
await expect(
193197
page.locator('#unauthenticated-client-config', {
194198
hasText: 'shouldNotShowInClientConfigUnlessAuthenticated',
@@ -199,13 +203,19 @@ describe('Auth', () => {
199203

200204
await page.goto(serverURL + '/admin')
201205

206+
// Inspect the client config (after authentication)
202207
await expect(page.locator('#authenticated-client-config')).toBeAttached()
203208

204209
await expect(
205210
page.locator('#authenticated-client-config', {
206211
hasText: 'shouldNotShowInClientConfigUnlessAuthenticated',
207212
}),
208213
).toHaveCount(1)
214+
215+
// Inspect the page source (after authentication)
216+
const dashboardPageRes = await page.goto(`${serverURL}/admin`)
217+
const dashboardPageSource = await dashboardPageRes?.text()
218+
expect(dashboardPageSource).toContain('shouldNotShowInClientConfigUnlessAuthenticated')
209219
})
210220

211221
test('should allow change password', async () => {

0 commit comments

Comments
 (0)