fix(ui): undefined permissions passed in create-first-user view (#13671)
### What?
In the create-first-user view, fields like `richText` were being marked
as `readOnly: true` because they had no permissions entry in the
permissions map.
### Why?
The view was passing an incomplete `docPermissions` object.
When a field had no entry in `docPermissions.fields`, `renderField`
received `permissions: undefined`, which was interpreted as denied
access.
This caused fields (notably `richText`) to default to read-only even
though the user should have full access when creating the first user.
### How?
- Updated the create-first-user view to always pass a complete
`docPermissions` object.
- Default all fields in the user collection to `{ create: true, read:
true, update: true }`.
- Ensures every field is explicitly granted full access during the
first-user flow.
- Keeps the `renderField` logic unchanged and aligned with Payload’s
permission model.
Fixes #13612
---
- To see the specific tasks where the Asana app for GitHub is being
used, see below:
- https://app.asana.com/0/0/1211211792037939
This commit is contained in:
@@ -75,6 +75,10 @@ export default buildConfigWithDefaults({
|
||||
label: 'Named Save To JWT',
|
||||
saveToJWT: saveToJWTKey,
|
||||
},
|
||||
{
|
||||
name: 'richText',
|
||||
type: 'richText',
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
|
||||
@@ -124,6 +124,33 @@ describe('Auth', () => {
|
||||
.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT })
|
||||
.not.toContain('create-first-user')
|
||||
})
|
||||
|
||||
test('richText field should should not be readOnly in create first user view', async () => {
|
||||
const {
|
||||
admin: {
|
||||
routes: { createFirstUser: createFirstUserRoute },
|
||||
},
|
||||
routes: { admin: adminRoute },
|
||||
} = getRoutes({})
|
||||
|
||||
// wait for create first user route
|
||||
await page.goto(serverURL + `${adminRoute}${createFirstUserRoute}`)
|
||||
|
||||
await expect(page.locator('.create-first-user')).toBeVisible()
|
||||
|
||||
await waitForVisibleAuthFields()
|
||||
|
||||
const richTextRoot = page
|
||||
.locator('.rich-text-lexical .ContentEditable__root[data-lexical-editor="true"]')
|
||||
.first()
|
||||
|
||||
// ensure editor is present
|
||||
await expect(richTextRoot).toBeVisible()
|
||||
|
||||
// core read-only checks
|
||||
await expect(richTextRoot).toHaveAttribute('contenteditable', 'true')
|
||||
await expect(richTextRoot).not.toHaveAttribute('aria-readonly', 'true')
|
||||
})
|
||||
})
|
||||
|
||||
describe('non create first user', () => {
|
||||
|
||||
@@ -243,6 +243,21 @@ export interface User {
|
||||
adminOnlyField?: string | null;
|
||||
roles: ('admin' | 'editor' | 'moderator' | 'user' | 'viewer')[];
|
||||
namedSaveToJWT?: string | null;
|
||||
richText?: {
|
||||
root: {
|
||||
type: string;
|
||||
children: {
|
||||
type: string;
|
||||
version: number;
|
||||
[k: string]: unknown;
|
||||
}[];
|
||||
direction: ('ltr' | 'rtl') | null;
|
||||
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
|
||||
indent: number;
|
||||
version: number;
|
||||
};
|
||||
[k: string]: unknown;
|
||||
} | null;
|
||||
group?: {
|
||||
liftedSaveToJWT?: string | null;
|
||||
};
|
||||
@@ -503,6 +518,7 @@ export interface UsersSelect<T extends boolean = true> {
|
||||
adminOnlyField?: T;
|
||||
roles?: T;
|
||||
namedSaveToJWT?: T;
|
||||
richText?: T;
|
||||
group?:
|
||||
| T
|
||||
| {
|
||||
|
||||
Reference in New Issue
Block a user