fix(ui): updates auth fields UI to reflect access control (#12745)
### What? Reflects any access control restrictions applied to Auth fields in the UI. I.e. if `email` has `update: () => false` the field should be displayed as read-only. ### Why? Currently any access control that is applied to auth fields is functional but is not matched within the UI. For example: - `password` that does not have read access will not return data, but the field will still be shown when it should be hidden - `email` that does not have update access, updating the field and saving the doc will **not** update the data, but it should be displayed as read-only so nothing can be filled out and the updating restriction is made clear ### How? Passes field permissions through to the Auth fields UI and adds docs with instructions on how to override auth field access. #### Testing Use `access-control` test suite and `auth` collection. Tests added to `access-control` e2e. Fixes #11569
This commit is contained in:
@@ -6,7 +6,7 @@ import { devUser } from 'credentials.js'
|
||||
import { openDocControls } from 'helpers/e2e/openDocControls.js'
|
||||
import { openNav } from 'helpers/e2e/toggleNav.js'
|
||||
import path from 'path'
|
||||
import { wait } from 'payload/shared'
|
||||
import { email, wait } from 'payload/shared'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
||||
@@ -25,6 +25,7 @@ import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
||||
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
||||
import { POLL_TOPASS_TIMEOUT, TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
||||
import {
|
||||
authSlug,
|
||||
createNotUpdateCollectionSlug,
|
||||
disabledSlug,
|
||||
docLevelAccessSlug,
|
||||
@@ -53,7 +54,7 @@ const dirname = path.dirname(filename)
|
||||
* Repeat all above for globals
|
||||
*/
|
||||
|
||||
const { beforeAll, describe } = test
|
||||
const { beforeAll, beforeEach, describe } = test
|
||||
let payload: PayloadTestSDK<Config>
|
||||
describe('Access Control', () => {
|
||||
let page: Page
|
||||
@@ -71,6 +72,7 @@ describe('Access Control', () => {
|
||||
let serverURL: string
|
||||
let context: BrowserContext
|
||||
let logoutURL: string
|
||||
let authFields: AdminUrlUtil
|
||||
|
||||
beforeAll(async ({ browser }, testInfo) => {
|
||||
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
||||
@@ -87,6 +89,7 @@ describe('Access Control', () => {
|
||||
userRestrictedCollectionURL = new AdminUrlUtil(serverURL, userRestrictedCollectionSlug)
|
||||
userRestrictedGlobalURL = new AdminUrlUtil(serverURL, userRestrictedGlobalSlug)
|
||||
disabledFields = new AdminUrlUtil(serverURL, disabledSlug)
|
||||
authFields = new AdminUrlUtil(serverURL, authSlug)
|
||||
|
||||
context = await browser.newContext()
|
||||
page = await context.newPage()
|
||||
@@ -228,7 +231,7 @@ describe('Access Control', () => {
|
||||
/**
|
||||
* This reproduces a bug where certain fields were incorrectly marked as read-only
|
||||
*/
|
||||
// eslint-disable-next-line playwright/expect-expect
|
||||
|
||||
test('ensure complex collection config fields show up in correct read-only state', async () => {
|
||||
const regression1URL = new AdminUrlUtil(serverURL, 'regression1')
|
||||
await page.goto(regression1URL.list)
|
||||
@@ -272,7 +275,7 @@ describe('Access Control', () => {
|
||||
/**
|
||||
* This reproduces a bug where certain fields were incorrectly marked as read-only
|
||||
*/
|
||||
// eslint-disable-next-line playwright/expect-expect
|
||||
|
||||
test('ensure complex collection config fields show up in correct read-only state 2', async () => {
|
||||
const regression2URL = new AdminUrlUtil(serverURL, 'regression2')
|
||||
await page.goto(regression2URL.list)
|
||||
@@ -733,6 +736,33 @@ describe('Access Control', () => {
|
||||
await expect(page.locator('#field-array__0__text')).toBeDisabled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('restricting update access to auth fields', () => {
|
||||
let existingDoc: ReadOnlyCollection
|
||||
beforeAll(async () => {
|
||||
existingDoc = await payload.create({
|
||||
collection: authSlug,
|
||||
data: {
|
||||
email: 'test@payloadcms.com',
|
||||
password: 'test',
|
||||
},
|
||||
})
|
||||
})
|
||||
test('should show email as readonly when user does not have update permission', async () => {
|
||||
await page.goto(authFields.edit(existingDoc.id))
|
||||
const emailField = page.locator('#field-email')
|
||||
await expect(emailField).toBeVisible()
|
||||
await expect(emailField).toBeDisabled()
|
||||
})
|
||||
|
||||
test('should hide Change Password button when user does not have update permission', async () => {
|
||||
await page.goto(authFields.edit(existingDoc.id))
|
||||
const passwordField = page.locator('#field-password')
|
||||
await expect(passwordField).toBeHidden()
|
||||
const changePasswordButton = page.locator('#change-password')
|
||||
await expect(changePasswordButton).toBeHidden()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
async function createDoc(data: any): Promise<Record<string, unknown> & TypeWithID> {
|
||||
|
||||
Reference in New Issue
Block a user