Skip to content

Commit 69ada97

Browse files
authored
fix(ui): apiKey field not being customisable and field access control not being updated with correct data (#7591)
You can now override the apiKey field with access control by adding this field to your auth collection: ```ts { name: 'apiKey', type: 'text', access: { update: ({ req }) => req.user.role === 'admin', } } ``` Translated labels are now also supported. Note that `siblingData` isn't working still in FieldAccess control and `data` only works in non-dynamic fields, eg. fields not in an array or block for now.
1 parent 81e7355 commit 69ada97

File tree

2 files changed

+46
-17
lines changed

2 files changed

+46
-17
lines changed

packages/next/src/views/Edit/Default/Auth/APIKey.tsx

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
'use client'
2-
import type { PayloadRequest } from 'payload'
2+
import type { FieldMap, PayloadRequest } from 'payload'
33

4+
import { getTranslation } from '@payloadcms/translations'
45
import {
56
CopyToClipboard,
7+
FieldDescription,
68
FieldLabel,
79
GenerateConfirmation,
10+
useComponentMap,
811
useConfig,
12+
useDocumentInfo,
913
useField,
1014
useFormFields,
1115
useTranslation,
@@ -18,16 +22,24 @@ const path = 'apiKey'
1822
const baseClass = 'api-key'
1923
const fieldBaseClass = 'field-type'
2024

21-
export const APIKey: React.FC<{ enabled: boolean; readOnly?: boolean }> = ({
25+
export const APIKey: React.FC<{ readonly enabled: boolean; readonly readOnly?: boolean }> = ({
2226
enabled,
2327
readOnly,
2428
}) => {
2529
const [initialAPIKey] = useState(uuidv4())
2630
const [highlightedField, setHighlightedField] = useState(false)
27-
const { t } = useTranslation()
31+
const { i18n, t } = useTranslation()
2832
const config = useConfig()
29-
3033
const apiKey = useFormFields(([fields]) => (fields && fields[path]) || null)
34+
const { collectionSlug, docPermissions } = useDocumentInfo()
35+
36+
const { getFieldMap } = useComponentMap()
37+
38+
const fieldMap: FieldMap = getFieldMap({
39+
collectionSlug,
40+
})
41+
42+
const apiKeyField = fieldMap.find((field) => 'name' in field && field.name === 'apiKey')
3143

3244
const validate = (val) =>
3345
text(val, {
@@ -48,15 +60,30 @@ export const APIKey: React.FC<{ enabled: boolean; readOnly?: boolean }> = ({
4860

4961
const apiKeyValue = apiKey?.value
5062

51-
const APIKeyLabel = useMemo(
52-
() => (
63+
const apiKeyLabel = useMemo(() => {
64+
let label: Record<string, string> | string = 'API Key'
65+
66+
if (apiKeyField && apiKeyField.fieldComponentProps.label) {
67+
label = apiKeyField.fieldComponentProps.label
68+
}
69+
70+
return getTranslation(label, i18n)
71+
}, [apiKeyField, i18n])
72+
73+
const APIKeyLabelComponent = useMemo(() => {
74+
return (
5375
<div className={`${baseClass}__label`}>
54-
<span>API Key</span>
76+
<span>{apiKeyLabel}</span>
5577
<CopyToClipboard value={apiKeyValue as string} />
5678
</div>
57-
),
58-
[apiKeyValue],
59-
)
79+
)
80+
}, [apiKeyLabel, apiKeyValue])
81+
82+
const canUpdateAPIKey = useMemo(() => {
83+
if (docPermissions && docPermissions?.fields?.apiKey) {
84+
return docPermissions.fields.apiKey.update.permission
85+
}
86+
}, [docPermissions])
6087

6188
const fieldType = useField({
6289
path: 'apiKey',
@@ -98,9 +125,9 @@ export const APIKey: React.FC<{ enabled: boolean; readOnly?: boolean }> = ({
98125
return (
99126
<React.Fragment>
100127
<div className={[fieldBaseClass, 'api-key', 'read-only'].filter(Boolean).join(' ')}>
101-
<FieldLabel CustomLabel={APIKeyLabel} htmlFor={path} />
128+
<FieldLabel CustomLabel={APIKeyLabelComponent} htmlFor={path} />
102129
<input
103-
aria-label="API Key"
130+
aria-label={apiKeyLabel}
104131
className={highlightedField ? 'highlight' : undefined}
105132
disabled
106133
id="apiKey"
@@ -109,7 +136,7 @@ export const APIKey: React.FC<{ enabled: boolean; readOnly?: boolean }> = ({
109136
value={(value as string) || ''}
110137
/>
111138
</div>
112-
{!readOnly && (
139+
{!readOnly && canUpdateAPIKey && (
113140
<GenerateConfirmation highlightField={highlightField} setKey={() => setValue(uuidv4())} />
114141
)}
115142
</React.Fragment>

packages/ui/src/providers/DocumentInfo/index.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,25 +276,27 @@ const DocumentInfo: React.FC<
276276

277277
if (docAccessURL) {
278278
const res = await fetch(`${serverURL}${api}${docAccessURL}?${qs.stringify(params)}`, {
279+
body: JSON.stringify(data),
279280
credentials: 'include',
280281
headers: {
281282
'Accept-Language': i18n.language,
283+
'Content-Type': 'application/json',
282284
},
285+
method: 'post',
283286
})
284287

285288
const json: DocumentPermissions = await res.json()
286289
const publishedAccessJSON = await fetch(
287290
`${serverURL}${api}${docAccessURL}?${qs.stringify(params)}`,
288291
{
289292
body: JSON.stringify({
290-
data: {
291-
...(data || {}),
292-
_status: 'published',
293-
},
293+
...(data || {}),
294+
_status: 'published',
294295
}),
295296
credentials: 'include',
296297
headers: {
297298
'Accept-Language': i18n.language,
299+
'Content-Type': 'application/json',
298300
},
299301
method: 'POST',
300302
},

0 commit comments

Comments
 (0)