fix: do not display field if read permission is false - admin panel ui (#3949)
This commit is contained in:
@@ -48,23 +48,24 @@ export const filterFields = (args: {
|
||||
}
|
||||
|
||||
const isFieldAffectingData = fieldAffectsData(field)
|
||||
|
||||
const fieldPermissions = isFieldAffectingData ? permissions?.[field.name] : permissions
|
||||
|
||||
// if the user cannot read the field, then filter it out
|
||||
if (fieldPermissions?.read?.permission === false) {
|
||||
return acc
|
||||
}
|
||||
|
||||
// readOnly from field config
|
||||
let readOnly = field.admin && 'readOnly' in field.admin ? field.admin.readOnly : undefined
|
||||
|
||||
// if parent field is readOnly
|
||||
// but this field is `readOnly: false`
|
||||
// the field should be editable
|
||||
if (readOnlyOverride && readOnly !== false) readOnly = true
|
||||
|
||||
if (
|
||||
(isFieldAffectingData && permissions?.[field?.name]?.read?.permission !== false) ||
|
||||
!isFieldAffectingData
|
||||
) {
|
||||
if (
|
||||
isFieldAffectingData &&
|
||||
permissions?.[field?.name]?.[operation]?.permission === false
|
||||
) {
|
||||
readOnly = true
|
||||
}
|
||||
// unless the user does not pass access control
|
||||
if (fieldPermissions?.[operation]?.permission === false) {
|
||||
readOnly = true
|
||||
}
|
||||
|
||||
if (FieldComponent) {
|
||||
|
||||
@@ -52,7 +52,22 @@ export default buildConfigWithDefaults({
|
||||
setTimeout(resolve, 50, true) // set to 'true' or 'false' here to simulate the response
|
||||
}),
|
||||
},
|
||||
fields: [],
|
||||
fields: [
|
||||
{
|
||||
name: 'roles',
|
||||
type: 'select',
|
||||
hasMany: true,
|
||||
options: ['admin', 'user'],
|
||||
defaultValue: ['user'],
|
||||
access: {
|
||||
create: ({ req }) => req.user?.roles?.includes('admin'),
|
||||
read: () => false,
|
||||
update: ({ req }) => {
|
||||
return req.user?.roles?.includes('admin')
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug,
|
||||
|
||||
@@ -125,6 +125,14 @@ describe('access control', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('restricted fields', () => {
|
||||
test('should not show field without permission', async () => {
|
||||
await page.goto(url.account)
|
||||
await wait(500)
|
||||
await expect(page.locator('#field-roles')).toBeHidden()
|
||||
})
|
||||
})
|
||||
|
||||
describe('read-only collection', () => {
|
||||
let existingDoc: ReadOnlyCollection
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* This file was automatically generated by Payload.
|
||||
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
|
||||
@@ -9,92 +10,156 @@ export interface Config {
|
||||
collections: {
|
||||
users: User
|
||||
posts: Post
|
||||
unrestricted: Unrestricted
|
||||
restricted: Restricted
|
||||
'read-only-collection': ReadOnlyCollection
|
||||
'user-restricted': UserRestricted
|
||||
'restricted-versions': RestrictedVersion
|
||||
'sibling-data': SiblingDatum
|
||||
'rely-on-request-headers': RelyOnRequestHeader
|
||||
'doc-level-access': DocLevelAccess
|
||||
'hidden-fields': HiddenField
|
||||
'hidden-access': HiddenAccess
|
||||
'payload-preferences': PayloadPreference
|
||||
'payload-migrations': PayloadMigration
|
||||
}
|
||||
globals: {}
|
||||
}
|
||||
export interface User {
|
||||
id: string
|
||||
email?: string
|
||||
resetPasswordToken?: string
|
||||
resetPasswordExpiration?: string
|
||||
loginAttempts?: number
|
||||
lockUntil?: string
|
||||
createdAt: string
|
||||
roles?: ('admin' | 'user')[] | null
|
||||
updatedAt: string
|
||||
password?: string
|
||||
createdAt: string
|
||||
email: string
|
||||
resetPasswordToken?: string | null
|
||||
resetPasswordExpiration?: string | null
|
||||
salt?: string | null
|
||||
hash?: string | null
|
||||
loginAttempts?: number | null
|
||||
lockUntil?: string | null
|
||||
password: string | null
|
||||
}
|
||||
export interface Post {
|
||||
id: string
|
||||
restrictedField?: string
|
||||
restrictedField?: string | null
|
||||
group?: {
|
||||
restrictedGroupText?: string
|
||||
restrictedGroupText?: string | null
|
||||
}
|
||||
restrictedRowText?: string
|
||||
restrictedCollapsibleText?: string
|
||||
createdAt: string
|
||||
restrictedRowText?: string | null
|
||||
restrictedCollapsibleText?: string | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface Unrestricted {
|
||||
id: string
|
||||
name?: string | null
|
||||
userRestrictedDocs?: (string | UserRestricted)[] | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface UserRestricted {
|
||||
id: string
|
||||
name?: string | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface Restricted {
|
||||
id: string
|
||||
name?: string
|
||||
createdAt: string
|
||||
name?: string | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface ReadOnlyCollection {
|
||||
id: string
|
||||
name?: string
|
||||
createdAt: string
|
||||
name?: string | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface RestrictedVersion {
|
||||
id: string
|
||||
name?: string
|
||||
createdAt: string
|
||||
name?: string | null
|
||||
hidden?: boolean | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface SiblingDatum {
|
||||
id: string
|
||||
array?: {
|
||||
allowPublicReadability?: boolean
|
||||
text?: string
|
||||
id?: string
|
||||
}[]
|
||||
createdAt: string
|
||||
array?:
|
||||
| {
|
||||
allowPublicReadability?: boolean | null
|
||||
text?: string | null
|
||||
id?: string | null
|
||||
}[]
|
||||
| null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface RelyOnRequestHeader {
|
||||
id: string
|
||||
name?: string
|
||||
createdAt: string
|
||||
name?: string | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface DocLevelAccess {
|
||||
id: string
|
||||
approvedForRemoval?: boolean
|
||||
approvedTitle?: string
|
||||
lockTitle?: boolean
|
||||
createdAt: string
|
||||
approvedForRemoval?: boolean | null
|
||||
approvedTitle?: string | null
|
||||
lockTitle?: boolean | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface HiddenField {
|
||||
id: string
|
||||
title?: string
|
||||
title?: string | null
|
||||
partiallyHiddenGroup?: {
|
||||
name?: string
|
||||
value?: string
|
||||
name?: string | null
|
||||
value?: string | null
|
||||
}
|
||||
partiallyHiddenArray?: {
|
||||
name?: string
|
||||
value?: string
|
||||
id?: string
|
||||
}[]
|
||||
createdAt: string
|
||||
partiallyHiddenArray?:
|
||||
| {
|
||||
name?: string | null
|
||||
value?: string | null
|
||||
id?: string | null
|
||||
}[]
|
||||
| null
|
||||
hidden?: boolean | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface HiddenAccess {
|
||||
id: string
|
||||
title: string
|
||||
hidden?: boolean | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface PayloadPreference {
|
||||
id: string
|
||||
user: {
|
||||
relationTo: 'users'
|
||||
value: string | User
|
||||
}
|
||||
key?: string | null
|
||||
value?:
|
||||
| {
|
||||
[k: string]: unknown
|
||||
}
|
||||
| unknown[]
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
export interface PayloadMigration {
|
||||
id: string
|
||||
name?: string | null
|
||||
batch?: number | null
|
||||
updatedAt: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
declare module 'payload' {
|
||||
export interface GeneratedTypes extends Config {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user