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:
Patrik
2025-09-03 17:16:49 -04:00
committed by GitHub
parent d9e183242c
commit 5146fc865f
4 changed files with 69 additions and 10 deletions

View File

@@ -75,6 +75,10 @@ export default buildConfigWithDefaults({
label: 'Named Save To JWT',
saveToJWT: saveToJWTKey,
},
{
name: 'richText',
type: 'richText',
},
{
name: 'group',
type: 'group',

View File

@@ -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', () => {

View File

@@ -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
| {