@payloadcms/ui 3.89.0-internal.95c9cba → 3.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/dist/elements/BulkUpload/FormsManager/createFormData.d.ts +1 -1
  2. package/dist/elements/BulkUpload/FormsManager/createFormData.d.ts.map +1 -1
  3. package/dist/elements/BulkUpload/FormsManager/createFormData.js +7 -3
  4. package/dist/elements/BulkUpload/FormsManager/createFormData.js.map +1 -1
  5. package/dist/elements/BulkUpload/FormsManager/index.d.ts.map +1 -1
  6. package/dist/elements/BulkUpload/FormsManager/index.js +4 -2
  7. package/dist/elements/BulkUpload/FormsManager/index.js.map +1 -1
  8. package/dist/elements/PublishButton/ScheduleDrawer/buildUpcomingScheduleWhere.d.ts +13 -0
  9. package/dist/elements/PublishButton/ScheduleDrawer/buildUpcomingScheduleWhere.d.ts.map +1 -0
  10. package/dist/elements/PublishButton/ScheduleDrawer/buildUpcomingScheduleWhere.js +41 -0
  11. package/dist/elements/PublishButton/ScheduleDrawer/buildUpcomingScheduleWhere.js.map +1 -0
  12. package/dist/elements/PublishButton/ScheduleDrawer/index.d.ts.map +1 -1
  13. package/dist/elements/PublishButton/ScheduleDrawer/index.js +8 -54
  14. package/dist/elements/PublishButton/ScheduleDrawer/index.js.map +1 -1
  15. package/dist/elements/PublishButton/ScheduleDrawer/types.d.ts +1 -1
  16. package/dist/elements/PublishButton/ScheduleDrawer/types.d.ts.map +1 -1
  17. package/dist/elements/PublishButton/ScheduleDrawer/types.js.map +1 -1
  18. package/dist/elements/Spinner/index.d.ts +19 -0
  19. package/dist/elements/Spinner/index.d.ts.map +1 -0
  20. package/dist/elements/Spinner/index.js +51 -0
  21. package/dist/elements/Spinner/index.js.map +1 -0
  22. package/dist/elements/Spinner/index.scss +23 -0
  23. package/dist/exports/client/index.d.ts +4 -1
  24. package/dist/exports/client/index.d.ts.map +1 -1
  25. package/dist/exports/client/index.js +24 -24
  26. package/dist/exports/client/index.js.map +4 -4
  27. package/dist/fields/Tabs/index.d.ts.map +1 -1
  28. package/dist/fields/Tabs/index.js +109 -234
  29. package/dist/fields/Tabs/index.js.map +1 -1
  30. package/dist/fields/Tabs/resolveRestoredTabIndex.d.ts +19 -0
  31. package/dist/fields/Tabs/resolveRestoredTabIndex.d.ts.map +1 -0
  32. package/dist/fields/Tabs/resolveRestoredTabIndex.js +20 -0
  33. package/dist/fields/Tabs/resolveRestoredTabIndex.js.map +1 -0
  34. package/dist/fields/Tabs/resolveRestoredTabIndex.spec.js +53 -0
  35. package/dist/fields/Tabs/resolveRestoredTabIndex.spec.js.map +1 -0
  36. package/dist/forms/Form/index.d.ts.map +1 -1
  37. package/dist/forms/Form/index.js +6 -2
  38. package/dist/forms/Form/index.js.map +1 -1
  39. package/dist/forms/fieldSchemasToFormState/renderField.d.ts.map +1 -1
  40. package/dist/forms/fieldSchemasToFormState/renderField.js +3 -2
  41. package/dist/forms/fieldSchemasToFormState/renderField.js.map +1 -1
  42. package/dist/forms/fieldSchemasToFormState/serverFunctions/mergeAllowedFieldOverrides.d.ts +12 -0
  43. package/dist/forms/fieldSchemasToFormState/serverFunctions/mergeAllowedFieldOverrides.d.ts.map +1 -0
  44. package/dist/forms/fieldSchemasToFormState/serverFunctions/mergeAllowedFieldOverrides.js +32 -0
  45. package/dist/forms/fieldSchemasToFormState/serverFunctions/mergeAllowedFieldOverrides.js.map +1 -0
  46. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.d.ts +8 -6
  47. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.d.ts.map +1 -1
  48. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js +25 -9
  49. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.js.map +1 -1
  50. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.spec.js +179 -0
  51. package/dist/forms/fieldSchemasToFormState/serverFunctions/renderFieldServerFn.spec.js.map +1 -0
  52. package/dist/forms/fieldSchemasToFormState/types.d.ts +1 -0
  53. package/dist/forms/fieldSchemasToFormState/types.d.ts.map +1 -1
  54. package/dist/forms/fieldSchemasToFormState/types.js.map +1 -1
  55. package/dist/icons/Eye/index.scss +1 -1
  56. package/dist/icons/Refresh/index.d.ts +7 -0
  57. package/dist/icons/Refresh/index.d.ts.map +1 -0
  58. package/dist/icons/Refresh/index.js +35 -0
  59. package/dist/icons/Refresh/index.js.map +1 -0
  60. package/dist/icons/Refresh/index.scss +11 -0
  61. package/dist/icons/Spinner/index.d.ts +8 -0
  62. package/dist/icons/Spinner/index.d.ts.map +1 -0
  63. package/dist/icons/Spinner/index.js +34 -0
  64. package/dist/icons/Spinner/index.js.map +1 -0
  65. package/dist/icons/Spinner/index.scss +12 -0
  66. package/dist/providers/LivePreview/index.d.ts.map +1 -1
  67. package/dist/providers/LivePreview/index.js +13 -6
  68. package/dist/providers/LivePreview/index.js.map +1 -1
  69. package/dist/providers/ServerFunctions/index.d.ts +5 -1
  70. package/dist/providers/ServerFunctions/index.d.ts.map +1 -1
  71. package/dist/providers/ServerFunctions/index.js +15 -0
  72. package/dist/providers/ServerFunctions/index.js.map +1 -1
  73. package/dist/styles.css +1 -1
  74. package/dist/utilities/buildFormState.d.ts.map +1 -1
  75. package/dist/utilities/buildFormState.js +6 -2
  76. package/dist/utilities/buildFormState.js.map +1 -1
  77. package/dist/utilities/formatAbsoluteURL.d.ts +1 -1
  78. package/dist/utilities/formatAbsoluteURL.d.ts.map +1 -1
  79. package/dist/utilities/formatAbsoluteURL.js +18 -8
  80. package/dist/utilities/formatAbsoluteURL.js.map +1 -1
  81. package/dist/utilities/formatAbsoluteURL.spec.js +27 -0
  82. package/dist/utilities/formatAbsoluteURL.spec.js.map +1 -0
  83. package/dist/utilities/isAbsoluteURL.d.ts +3 -0
  84. package/dist/utilities/isAbsoluteURL.d.ts.map +1 -0
  85. package/dist/utilities/isAbsoluteURL.js +15 -0
  86. package/dist/utilities/isAbsoluteURL.js.map +1 -0
  87. package/dist/utilities/isAbsoluteURL.spec.js +11 -0
  88. package/dist/utilities/isAbsoluteURL.spec.js.map +1 -0
  89. package/dist/utilities/isHttpURL.d.ts +3 -0
  90. package/dist/utilities/isHttpURL.d.ts.map +1 -0
  91. package/dist/utilities/isHttpURL.js +12 -0
  92. package/dist/utilities/isHttpURL.js.map +1 -0
  93. package/dist/utilities/isHttpURL.spec.js +25 -0
  94. package/dist/utilities/isHttpURL.spec.js.map +1 -0
  95. package/dist/utilities/schedulePublishHandler.d.ts +8 -1
  96. package/dist/utilities/schedulePublishHandler.d.ts.map +1 -1
  97. package/dist/utilities/schedulePublishHandler.js +78 -5
  98. package/dist/utilities/schedulePublishHandler.js.map +1 -1
  99. package/dist/views/Edit/Auth/APIKey.d.ts +1 -1
  100. package/dist/views/Edit/Auth/APIKey.d.ts.map +1 -1
  101. package/dist/views/Edit/Auth/APIKey.js +216 -59
  102. package/dist/views/Edit/Auth/APIKey.js.map +1 -1
  103. package/dist/views/Edit/Auth/APIKeyGenerationModal.d.ts +11 -0
  104. package/dist/views/Edit/Auth/APIKeyGenerationModal.d.ts.map +1 -0
  105. package/dist/views/Edit/Auth/APIKeyGenerationModal.js +113 -0
  106. package/dist/views/Edit/Auth/APIKeyGenerationModal.js.map +1 -0
  107. package/dist/views/Edit/Auth/index.d.ts.map +1 -1
  108. package/dist/views/Edit/Auth/index.js +10 -30
  109. package/dist/views/Edit/Auth/index.js.map +1 -1
  110. package/dist/views/Edit/Auth/index.scss +73 -36
  111. package/dist/views/Edit/Auth/types.d.ts +1 -1
  112. package/dist/views/Edit/Auth/types.d.ts.map +1 -1
  113. package/dist/views/Edit/Auth/types.js.map +1 -1
  114. package/package.json +6 -5
  115. package/dist/elements/GenerateConfirmation/index.d.ts +0 -7
  116. package/dist/elements/GenerateConfirmation/index.d.ts.map +0 -1
  117. package/dist/elements/GenerateConfirmation/index.js +0 -95
  118. package/dist/elements/GenerateConfirmation/index.js.map +0 -1
@@ -1,41 +1,65 @@
1
1
  'use client';
2
2
 
3
3
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { useModal } from '@faceless-ui/modal';
4
5
  import { getTranslation } from '@payloadcms/translations';
5
- import { text } from 'payload/shared';
6
- import React, { useEffect, useMemo, useState } from 'react';
6
+ import { formatAdminURL, text } from 'payload/shared';
7
+ import React, { useEffect, useMemo, useRef, useState } from 'react';
8
+ import { toast } from 'sonner';
7
9
  import { v4 as uuidv4 } from 'uuid';
8
10
  import { Button } from '../../../elements/Button/index.js';
11
+ import { ConfirmationModal } from '../../../elements/ConfirmationModal/index.js';
9
12
  import { CopyToClipboard } from '../../../elements/CopyToClipboard/index.js';
10
- import { GenerateConfirmation } from '../../../elements/GenerateConfirmation/index.js';
11
- import { useFormFields } from '../../../forms/Form/context.js';
13
+ import { Spinner } from '../../../elements/Spinner/index.js';
14
+ import { FieldDescription } from '../../../fields/FieldDescription/index.js';
15
+ import { useFormFields, useFormModified } from '../../../forms/Form/context.js';
12
16
  import { useField } from '../../../forms/useField/index.js';
13
17
  import { EyeIcon } from '../../../icons/Eye/index.js';
18
+ import { RefreshIcon } from '../../../icons/Refresh/index.js';
14
19
  import { useConfig } from '../../../providers/Config/index.js';
15
20
  import { useDocumentInfo } from '../../../providers/DocumentInfo/index.js';
21
+ import { useLocale } from '../../../providers/Locale/index.js';
16
22
  import { useTranslation } from '../../../providers/Translation/index.js';
23
+ import { APIKeyGenerationModal } from './APIKeyGenerationModal.js';
17
24
  const path = 'apiKey';
18
25
  const baseClass = 'api-key';
19
26
  const fieldBaseClass = 'field-type';
27
+ const maskedAPIKey = '•'.repeat(24);
20
28
  export const APIKey = ({
21
- enabled,
22
- readOnly
29
+ readOnly,
30
+ reveal
23
31
  }) => {
24
- const [initialAPIKey] = useState(uuidv4());
25
32
  const [highlightedField, setHighlightedField] = useState(false);
33
+ const [hasUpdatedPersistedAPIKey, setHasUpdatedPersistedAPIKey] = useState(null);
34
+ const [isRevealing, setIsRevealing] = useState(false);
35
+ const [revealedKey, setRevealedKey] = useState(null);
36
+ const [showCopyWarning, setShowCopyWarning] = useState(false);
26
37
  const [showKey, setShowKey] = useState(false);
38
+ const modified = useFormModified();
39
+ const wasModified = useRef(modified);
27
40
  const {
28
41
  i18n,
29
42
  t
30
43
  } = useTranslation();
44
+ const {
45
+ toggleModal
46
+ } = useModal();
31
47
  const {
32
48
  config,
33
49
  getEntityConfig
34
50
  } = useConfig();
35
51
  const {
36
- collectionSlug
52
+ id,
53
+ collectionSlug,
54
+ setData,
55
+ setLastUpdateTime
37
56
  } = useDocumentInfo();
38
- const apiKey = useFormFields(([fields]) => fields && fields[path] || null);
57
+ const {
58
+ code: locale
59
+ } = useLocale();
60
+ const revokeModalSlug = `revoke-api-key-${id}`;
61
+ const hasAPIKey = useFormFields(([fields]) => fields && fields.hasAPIKey || null);
62
+ const dispatchFields_0 = useFormFields(([, dispatchFields]) => dispatchFields);
39
63
  const apiKeyField = getEntityConfig({
40
64
  collectionSlug
41
65
  })?.fields?.find(field => 'name' in field && field.name === 'apiKey');
@@ -59,7 +83,16 @@ export const APIKey = ({
59
83
  },
60
84
  siblingData: {}
61
85
  });
62
- const apiKeyValue = apiKey?.value;
86
+ const {
87
+ setValue,
88
+ value
89
+ } = useField({
90
+ path,
91
+ validate
92
+ });
93
+ const apiKeyValue = revealedKey || value;
94
+ const hasPersistedAPIKey = hasUpdatedPersistedAPIKey ?? Boolean(hasAPIKey?.value);
95
+ const canRevealPersistedAPIKey = reveal && hasPersistedAPIKey && !revealedKey;
63
96
  const apiKeyLabel = useMemo(() => {
64
97
  let label = 'API Key';
65
98
  if (apiKeyField?.label) {
@@ -67,77 +100,201 @@ export const APIKey = ({
67
100
  }
68
101
  return getTranslation(label, i18n);
69
102
  }, [apiKeyField, i18n]);
70
- const APIKeyLabel = useMemo(() => /*#__PURE__*/_jsxs("label", {
71
- className: `${baseClass}__label field-label`,
72
- htmlFor: "apiKey",
73
- children: [/*#__PURE__*/_jsx("span", {
74
- children: apiKeyLabel
75
- }), /*#__PURE__*/_jsx(CopyToClipboard, {
76
- value: apiKeyValue
77
- })]
78
- }), [apiKeyLabel, apiKeyValue]);
79
- const fieldType = useField({
80
- path: 'apiKey',
81
- validate
82
- });
83
103
  const highlightField = () => {
84
- if (highlightedField) {
85
- setHighlightedField(false);
104
+ setHighlightedField(true);
105
+ };
106
+ const updateKey = async apiKey => {
107
+ if (!id) {
108
+ return false;
109
+ }
110
+ try {
111
+ const response = await fetch(formatAdminURL({
112
+ apiRoute: config.routes.api,
113
+ path: `/${collectionSlug}/${encodeURIComponent(String(id))}?depth=0&fallback-locale=null&locale=${locale}`
114
+ }), {
115
+ body: JSON.stringify({
116
+ apiKey,
117
+ // The `enableAPIKey` field is for backward compatibility only and will be removed in v4.
118
+ enableAPIKey: Boolean(apiKey)
119
+ }),
120
+ headers: {
121
+ 'Content-Type': 'application/json'
122
+ },
123
+ method: 'PATCH'
124
+ });
125
+ if (!response.ok) {
126
+ throw new Error('API key update failed');
127
+ }
128
+ const result = await response.json();
129
+ setHasUpdatedPersistedAPIKey(Boolean(apiKey));
130
+ dispatchFields_0({
131
+ type: 'REMOVE',
132
+ path
133
+ });
134
+ // The `enableAPIKey` field is for backward compatibility only and will be removed in v4.
135
+ dispatchFields_0({
136
+ type: 'REMOVE',
137
+ path: 'enableAPIKey'
138
+ });
139
+ if (result.doc?.updatedAt) {
140
+ setData(result.doc);
141
+ setLastUpdateTime(new Date(result.doc.updatedAt).getTime());
142
+ }
143
+ return true;
144
+ } catch {
145
+ toast.error('Failed to update the API key.');
146
+ return false;
86
147
  }
87
- setTimeout(() => {
88
- setHighlightedField(true);
89
- }, 1);
90
148
  };
91
- const {
92
- setValue,
93
- value
94
- } = fieldType;
95
- useEffect(() => {
96
- if (!apiKeyValue && enabled) {
97
- setValue(initialAPIKey);
149
+ const generateKey = async () => {
150
+ const key = uuidv4();
151
+ if (!id) {
152
+ setValue(key, true);
153
+ setShowCopyWarning(true);
154
+ setShowKey(true);
155
+ highlightField();
156
+ return true;
98
157
  }
99
- if (!enabled && apiKeyValue) {
100
- setValue(null);
158
+ if (!(await updateKey(key))) {
159
+ return false;
101
160
  }
102
- }, [apiKeyValue, enabled, setValue, initialAPIKey]);
161
+ setRevealedKey(key);
162
+ setShowCopyWarning(true);
163
+ setShowKey(true);
164
+ highlightField();
165
+ return true;
166
+ };
167
+ const revokeKey = async () => {
168
+ if (!(await updateKey(null))) {
169
+ return;
170
+ }
171
+ setRevealedKey(null);
172
+ setHasUpdatedPersistedAPIKey(false);
173
+ setHighlightedField(false);
174
+ setShowCopyWarning(false);
175
+ setShowKey(false);
176
+ toast.success('API key revoked successfully.');
177
+ };
178
+ const revealKey = async () => {
179
+ if (isRevealing) {
180
+ return;
181
+ }
182
+ setIsRevealing(true);
183
+ try {
184
+ const response_0 = await fetch(formatAdminURL({
185
+ apiRoute: config.routes.api,
186
+ path: `/${collectionSlug}/${encodeURIComponent(String(id))}/api-key/reveal`
187
+ }), {
188
+ method: 'POST'
189
+ });
190
+ if (!response_0.ok) {
191
+ toast.error('Failed to reveal the API key.');
192
+ return;
193
+ }
194
+ const result_0 = await response_0.json();
195
+ setRevealedKey(result_0.apiKey);
196
+ setShowCopyWarning(false);
197
+ setShowKey(true);
198
+ } catch {
199
+ toast.error('Failed to reveal the API key.');
200
+ } finally {
201
+ setIsRevealing(false);
202
+ }
203
+ };
103
204
  useEffect(() => {
104
- if (highlightedField) {
105
- setTimeout(() => {
106
- setHighlightedField(false);
107
- }, 10000);
205
+ if (wasModified.current && !modified && apiKeyValue) {
206
+ setHasUpdatedPersistedAPIKey(true);
207
+ setHighlightedField(false);
208
+ setRevealedKey(null);
209
+ setShowCopyWarning(false);
210
+ dispatchFields_0({
211
+ type: 'REMOVE',
212
+ path
213
+ });
214
+ setShowKey(false);
108
215
  }
109
- }, [highlightedField]);
110
- if (!enabled) {
111
- return null;
112
- }
216
+ wasModified.current = modified;
217
+ }, [apiKeyValue, dispatchFields_0, modified]);
113
218
  return /*#__PURE__*/_jsxs(React.Fragment, {
114
219
  children: [/*#__PURE__*/_jsxs("div", {
115
220
  className: [fieldBaseClass, 'api-key', 'read-only'].filter(Boolean).join(' '),
116
- children: [APIKeyLabel, /*#__PURE__*/_jsxs("div", {
117
- className: `${baseClass}__input-wrap`,
221
+ children: [/*#__PURE__*/_jsxs("label", {
222
+ className: `${baseClass}__label field-label`,
223
+ htmlFor: "apiKey",
224
+ children: [/*#__PURE__*/_jsx("span", {
225
+ children: apiKeyLabel
226
+ }), apiKeyValue && /*#__PURE__*/_jsx(CopyToClipboard, {
227
+ value: apiKeyValue
228
+ })]
229
+ }), /*#__PURE__*/_jsxs("div", {
230
+ className: [`${baseClass}__input-wrap`, !readOnly && hasPersistedAPIKey && `${baseClass}__input-wrap--has-regenerate`, highlightedField && `${baseClass}__input-wrap--highlighted`].filter(Boolean).join(' '),
118
231
  children: [/*#__PURE__*/_jsx("input", {
119
232
  "aria-label": apiKeyLabel,
120
- className: highlightedField ? 'highlight' : undefined,
121
233
  disabled: true,
122
234
  id: "apiKey",
123
235
  name: "apiKey",
124
- type: showKey ? 'text' : 'password',
125
- value: value || ''
126
- }), /*#__PURE__*/_jsx("div", {
236
+ type: apiKeyValue && !showKey ? 'password' : 'text',
237
+ value: apiKeyValue || (hasPersistedAPIKey ? maskedAPIKey : '')
238
+ }), (apiKeyValue || canRevealPersistedAPIKey || !readOnly && hasPersistedAPIKey) && /*#__PURE__*/_jsxs("div", {
127
239
  className: `${baseClass}__toggle-button-wrap`,
128
- children: /*#__PURE__*/_jsx(Button, {
240
+ children: [(apiKeyValue || canRevealPersistedAPIKey) && /*#__PURE__*/_jsx(Button, {
241
+ "aria-label": canRevealPersistedAPIKey ? 'Reveal API key' : 'Toggle API key visibility',
129
242
  buttonStyle: "none",
130
- className: `${baseClass}__toggle-button`,
131
- icon: /*#__PURE__*/_jsx(EyeIcon, {
243
+ className: [`${baseClass}__visibility-button`, !readOnly && hasPersistedAPIKey && `${baseClass}__visibility-button--with-regenerate`].filter(Boolean).join(' '),
244
+ disabled: isRevealing,
245
+ extraButtonProps: {
246
+ 'aria-busy': isRevealing
247
+ },
248
+ icon: isRevealing ? /*#__PURE__*/_jsx(Spinner, {
249
+ loadingText: null,
250
+ size: "sm"
251
+ }) : /*#__PURE__*/_jsx(EyeIcon, {
132
252
  active: showKey
133
253
  }),
134
- onClick: () => setShowKey(prev => !prev)
135
- })
254
+ id: canRevealPersistedAPIKey ? 'reveal-api-key' : 'toggle-api-key-visibility',
255
+ onClick: canRevealPersistedAPIKey ? revealKey : () => setShowKey(previous => !previous)
256
+ }), !readOnly && hasPersistedAPIKey && /*#__PURE__*/_jsx(APIKeyGenerationModal, {
257
+ highlightField: highlightField,
258
+ icon: /*#__PURE__*/_jsx(RefreshIcon, {}),
259
+ id: "regenerate-api-key",
260
+ setKey: generateKey
261
+ })]
136
262
  })]
263
+ }), apiKeyValue && showCopyWarning && /*#__PURE__*/_jsx(FieldDescription, {
264
+ description: reveal ? 'Make sure to copy your API key. You may not have access to reveal it again.' : 'Make sure to copy your API key. It will not be displayed again.',
265
+ path: path
137
266
  })]
138
- }), !readOnly && /*#__PURE__*/_jsx(GenerateConfirmation, {
267
+ }), !readOnly && !apiKeyValue && !hasPersistedAPIKey && (id ? /*#__PURE__*/_jsx(APIKeyGenerationModal, {
139
268
  highlightField: highlightField,
140
- setKey: () => setValue(uuidv4())
269
+ id: "generate-api-key",
270
+ setKey: generateKey,
271
+ willInvalidateExistingKey: false
272
+ }) : /*#__PURE__*/_jsx(Button, {
273
+ buttonStyle: "secondary",
274
+ id: "generate-api-key",
275
+ onClick: () => void generateKey(),
276
+ size: "small",
277
+ children: t('authentication:generateNewAPIKey')
278
+ })), !readOnly && hasPersistedAPIKey && /*#__PURE__*/_jsxs("div", {
279
+ className: `${baseClass}__actions`,
280
+ children: [/*#__PURE__*/_jsx(Button, {
281
+ buttonStyle: "secondary",
282
+ className: `${baseClass}__revoke-button`,
283
+ id: "revoke-api-key",
284
+ onClick: () => toggleModal(revokeModalSlug),
285
+ size: "small",
286
+ children: "Revoke API key"
287
+ }), /*#__PURE__*/_jsx(ConfirmationModal, {
288
+ body: /*#__PURE__*/_jsxs("span", {
289
+ children: ["Are you sure you want to revoke the API key for user ", /*#__PURE__*/_jsx("strong", {
290
+ children: id
291
+ }), "? The key will no longer be usable, and this action cannot be undone."]
292
+ }),
293
+ confirmLabel: "Revoke",
294
+ heading: "Revoke API key?",
295
+ modalSlug: revokeModalSlug,
296
+ onConfirm: revokeKey
297
+ })]
141
298
  })]
142
299
  });
143
300
  };
@@ -1 +1 @@
1
- {"version":3,"file":"APIKey.js","names":["getTranslation","text","React","useEffect","useMemo","useState","v4","uuidv4","Button","CopyToClipboard","GenerateConfirmation","useFormFields","useField","EyeIcon","useConfig","useDocumentInfo","useTranslation","path","baseClass","fieldBaseClass","APIKey","enabled","readOnly","initialAPIKey","highlightedField","setHighlightedField","showKey","setShowKey","i18n","t","config","getEntityConfig","collectionSlug","apiKey","fields","apiKeyField","find","field","name","validate","val","type","blockData","data","event","maxLength","minLength","preferences","req","payload","siblingData","apiKeyValue","value","apiKeyLabel","label","APIKeyLabel","_jsxs","className","htmlFor","_jsx","fieldType","highlightField","setTimeout","setValue","Fragment","filter","Boolean","join","undefined","disabled","id","buttonStyle","icon","active","onClick","prev","setKey"],"sources":["../../../../src/views/Edit/Auth/APIKey.tsx"],"sourcesContent":["'use client'\nimport type { PayloadRequest, TextFieldClient } from 'payload'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { text } from 'payload/shared'\nimport React, { useEffect, useMemo, useState } from 'react'\nimport { v4 as uuidv4 } from 'uuid'\n\nimport { Button } from '../../../elements/Button/index.js'\nimport { CopyToClipboard } from '../../../elements/CopyToClipboard/index.js'\nimport { GenerateConfirmation } from '../../../elements/GenerateConfirmation/index.js'\nimport { useFormFields } from '../../../forms/Form/context.js'\nimport { useField } from '../../../forms/useField/index.js'\nimport { EyeIcon } from '../../../icons/Eye/index.js'\nimport { useConfig } from '../../../providers/Config/index.js'\nimport { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../../providers/Translation/index.js'\n\nconst path = 'apiKey'\nconst baseClass = 'api-key'\nconst fieldBaseClass = 'field-type'\n\nexport const APIKey: React.FC<{ readonly enabled: boolean; readonly readOnly?: boolean }> = ({\n enabled,\n readOnly,\n}) => {\n const [initialAPIKey] = useState(uuidv4())\n const [highlightedField, setHighlightedField] = useState(false)\n const [showKey, setShowKey] = useState(false)\n const { i18n, t } = useTranslation()\n const { config, getEntityConfig } = useConfig()\n const { collectionSlug } = useDocumentInfo()\n\n const apiKey = useFormFields(([fields]) => (fields && fields[path]) || null)\n\n const apiKeyField: TextFieldClient = getEntityConfig({ collectionSlug })?.fields?.find(\n (field) => 'name' in field && field.name === 'apiKey',\n ) as TextFieldClient\n\n const validate = (val) =>\n text(val, {\n name: 'apiKey',\n type: 'text',\n blockData: {},\n data: {},\n event: 'onChange',\n maxLength: 48,\n minLength: 24,\n path: ['apiKey'],\n preferences: { fields: {} },\n req: {\n payload: {\n config,\n },\n t,\n } as unknown as PayloadRequest,\n siblingData: {},\n })\n\n const apiKeyValue = apiKey?.value\n\n const apiKeyLabel = useMemo(() => {\n let label: Record<string, string> | string = 'API Key'\n\n if (apiKeyField?.label) {\n label = apiKeyField.label\n }\n\n return getTranslation(label, i18n)\n }, [apiKeyField, i18n])\n\n const APIKeyLabel = useMemo(\n () => (\n <label className={`${baseClass}__label field-label`} htmlFor=\"apiKey\">\n <span>{apiKeyLabel}</span>\n <CopyToClipboard value={apiKeyValue as string} />\n </label>\n ),\n [apiKeyLabel, apiKeyValue],\n )\n\n const fieldType = useField({\n path: 'apiKey',\n validate,\n })\n\n const highlightField = () => {\n if (highlightedField) {\n setHighlightedField(false)\n }\n setTimeout(() => {\n setHighlightedField(true)\n }, 1)\n }\n\n const { setValue, value } = fieldType\n\n useEffect(() => {\n if (!apiKeyValue && enabled) {\n setValue(initialAPIKey)\n }\n if (!enabled && apiKeyValue) {\n setValue(null)\n }\n }, [apiKeyValue, enabled, setValue, initialAPIKey])\n\n useEffect(() => {\n if (highlightedField) {\n setTimeout(() => {\n setHighlightedField(false)\n }, 10000)\n }\n }, [highlightedField])\n\n if (!enabled) {\n return null\n }\n\n return (\n <React.Fragment>\n <div className={[fieldBaseClass, 'api-key', 'read-only'].filter(Boolean).join(' ')}>\n {APIKeyLabel}\n <div className={`${baseClass}__input-wrap`}>\n <input\n aria-label={apiKeyLabel}\n className={highlightedField ? 'highlight' : undefined}\n disabled\n id=\"apiKey\"\n name=\"apiKey\"\n type={showKey ? 'text' : 'password'}\n value={(value as string) || ''}\n />\n <div className={`${baseClass}__toggle-button-wrap`}>\n <Button\n buttonStyle=\"none\"\n className={`${baseClass}__toggle-button`}\n icon={<EyeIcon active={showKey} />}\n onClick={() => setShowKey((prev) => !prev)}\n />\n </div>\n </div>\n </div>\n {!readOnly && (\n <GenerateConfirmation highlightField={highlightField} setKey={() => setValue(uuidv4())} />\n )}\n </React.Fragment>\n )\n}\n"],"mappings":"AAAA;;;AAGA,SAASA,cAAc,QAAQ;AAC/B,SAASC,IAAI,QAAQ;AACrB,OAAOC,KAAA,IAASC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ;AACpD,SAASC,EAAA,IAAMC,MAAM,QAAQ;AAE7B,SAASC,MAAM,QAAQ;AACvB,SAASC,eAAe,QAAQ;AAChC,SAASC,oBAAoB,QAAQ;AACrC,SAASC,aAAa,QAAQ;AAC9B,SAASC,QAAQ,QAAQ;AACzB,SAASC,OAAO,QAAQ;AACxB,SAASC,SAAS,QAAQ;AAC1B,SAASC,eAAe,QAAQ;AAChC,SAASC,cAAc,QAAQ;AAE/B,MAAMC,IAAA,GAAO;AACb,MAAMC,SAAA,GAAY;AAClB,MAAMC,cAAA,GAAiB;AAEvB,OAAO,MAAMC,MAAA,GAA+EA,CAAC;EAC3FC,OAAO;EACPC;AAAQ,CACT;EACC,MAAM,CAACC,aAAA,CAAc,GAAGlB,QAAA,CAASE,MAAA;EACjC,MAAM,CAACiB,gBAAA,EAAkBC,mBAAA,CAAoB,GAAGpB,QAAA,CAAS;EACzD,MAAM,CAACqB,OAAA,EAASC,UAAA,CAAW,GAAGtB,QAAA,CAAS;EACvC,MAAM;IAAEuB,IAAI;IAAEC;EAAC,CAAE,GAAGb,cAAA;EACpB,MAAM;IAAEc,MAAM;IAAEC;EAAe,CAAE,GAAGjB,SAAA;EACpC,MAAM;IAAEkB;EAAc,CAAE,GAAGjB,eAAA;EAE3B,MAAMkB,MAAA,GAAStB,aAAA,CAAc,CAAC,CAACuB,MAAA,CAAO,KAAKA,MAAC,IAAUA,MAAM,CAACjB,IAAA,CAAK,IAAK;EAEvE,MAAMkB,WAAA,GAA+BJ,eAAA,CAAgB;IAAEC;EAAe,IAAIE,MAAA,EAAQE,IAAA,CAC/EC,KAAA,IAAU,UAAUA,KAAA,IAASA,KAAA,CAAMC,IAAI,KAAK;EAG/C,MAAMC,QAAA,GAAYC,GAAA,IAChBvC,IAAA,CAAKuC,GAAA,EAAK;IACRF,IAAA,EAAM;IACNG,IAAA,EAAM;IACNC,SAAA,EAAW,CAAC;IACZC,IAAA,EAAM,CAAC;IACPC,KAAA,EAAO;IACPC,SAAA,EAAW;IACXC,SAAA,EAAW;IACX7B,IAAA,EAAM,CAAC,SAAS;IAChB8B,WAAA,EAAa;MAAEb,MAAA,EAAQ,CAAC;IAAE;IAC1Bc,GAAA,EAAK;MACHC,OAAA,EAAS;QACPnB;MACF;MACAD;IACF;IACAqB,WAAA,EAAa,CAAC;EAChB;EAEF,MAAMC,WAAA,GAAclB,MAAA,EAAQmB,KAAA;EAE5B,MAAMC,WAAA,GAAcjD,OAAA,CAAQ;IAC1B,IAAIkD,KAAA,GAAyC;IAE7C,IAAInB,WAAA,EAAamB,KAAA,EAAO;MACtBA,KAAA,GAAQnB,WAAA,CAAYmB,KAAK;IAC3B;IAEA,OAAOtD,cAAA,CAAesD,KAAA,EAAO1B,IAAA;EAC/B,GAAG,CAACO,WAAA,EAAaP,IAAA,CAAK;EAEtB,MAAM2B,WAAA,GAAcnD,OAAA,CAClB,mBACEoD,KAAA,CAAC;IAAMC,SAAA,EAAW,GAAGvC,SAAA,qBAA8B;IAAEwC,OAAA,EAAQ;4BAC3DC,IAAA,CAAC;gBAAMN;qBACPM,IAAA,CAAClD,eAAA;MAAgB2C,KAAA,EAAOD;;MAG5B,CAACE,WAAA,EAAaF,WAAA,CAAY;EAG5B,MAAMS,SAAA,GAAYhD,QAAA,CAAS;IACzBK,IAAA,EAAM;IACNsB;EACF;EAEA,MAAMsB,cAAA,GAAiBA,CAAA;IACrB,IAAIrC,gBAAA,EAAkB;MACpBC,mBAAA,CAAoB;IACtB;IACAqC,UAAA,CAAW;MACTrC,mBAAA,CAAoB;IACtB,GAAG;EACL;EAEA,MAAM;IAAEsC,QAAQ;IAAEX;EAAK,CAAE,GAAGQ,SAAA;EAE5BzD,SAAA,CAAU;IACR,IAAI,CAACgD,WAAA,IAAe9B,OAAA,EAAS;MAC3B0C,QAAA,CAASxC,aAAA;IACX;IACA,IAAI,CAACF,OAAA,IAAW8B,WAAA,EAAa;MAC3BY,QAAA,CAAS;IACX;EACF,GAAG,CAACZ,WAAA,EAAa9B,OAAA,EAAS0C,QAAA,EAAUxC,aAAA,CAAc;EAElDpB,SAAA,CAAU;IACR,IAAIqB,gBAAA,EAAkB;MACpBsC,UAAA,CAAW;QACTrC,mBAAA,CAAoB;MACtB,GAAG;IACL;EACF,GAAG,CAACD,gBAAA,CAAiB;EAErB,IAAI,CAACH,OAAA,EAAS;IACZ,OAAO;EACT;EAEA,oBACEmC,KAAA,CAACtD,KAAA,CAAM8D,QAAQ;4BACbR,KAAA,CAAC;MAAIC,SAAA,EAAW,CAACtC,cAAA,EAAgB,WAAW,YAAY,CAAC8C,MAAM,CAACC,OAAA,EAASC,IAAI,CAAC;iBAC3EZ,WAAA,E,aACDC,KAAA,CAAC;QAAIC,SAAA,EAAW,GAAGvC,SAAA,cAAuB;gCACxCyC,IAAA,CAAC;UACC,cAAYN,WAAA;UACZI,SAAA,EAAWjC,gBAAA,GAAmB,cAAc4C,SAAA;UAC5CC,QAAQ;UACRC,EAAA,EAAG;UACHhC,IAAA,EAAK;UACLG,IAAA,EAAMf,OAAA,GAAU,SAAS;UACzB0B,KAAA,EAAOA,KAAC,IAAoB;yBAE9BO,IAAA,CAAC;UAAIF,SAAA,EAAW,GAAGvC,SAAA,sBAA+B;oBAChD,aAAAyC,IAAA,CAACnD,MAAA;YACC+D,WAAA,EAAY;YACZd,SAAA,EAAW,GAAGvC,SAAA,iBAA0B;YACxCsD,IAAA,eAAMb,IAAA,CAAC9C,OAAA;cAAQ4D,MAAA,EAAQ/C;;YACvBgD,OAAA,EAASA,CAAA,KAAM/C,UAAA,CAAYgD,IAAA,IAAS,CAACA,IAAA;;;;QAK5C,CAACrD,QAAA,iBACAqC,IAAA,CAACjD,oBAAA;MAAqBmD,cAAA,EAAgBA,cAAA;MAAgBe,MAAA,EAAQA,CAAA,KAAMb,QAAA,CAASxD,MAAA;;;AAIrF","ignoreList":[]}
1
+ {"version":3,"file":"APIKey.js","names":["useModal","getTranslation","formatAdminURL","text","React","useEffect","useMemo","useRef","useState","toast","v4","uuidv4","Button","ConfirmationModal","CopyToClipboard","Spinner","FieldDescription","useFormFields","useFormModified","useField","EyeIcon","RefreshIcon","useConfig","useDocumentInfo","useLocale","useTranslation","APIKeyGenerationModal","path","baseClass","fieldBaseClass","maskedAPIKey","repeat","APIKey","readOnly","reveal","highlightedField","setHighlightedField","hasUpdatedPersistedAPIKey","setHasUpdatedPersistedAPIKey","isRevealing","setIsRevealing","revealedKey","setRevealedKey","showCopyWarning","setShowCopyWarning","showKey","setShowKey","modified","wasModified","i18n","t","toggleModal","config","getEntityConfig","id","collectionSlug","setData","setLastUpdateTime","code","locale","revokeModalSlug","hasAPIKey","fields","dispatchFields","apiKeyField","find","field","name","validate","val","type","blockData","data","event","maxLength","minLength","preferences","req","payload","siblingData","setValue","value","apiKeyValue","hasPersistedAPIKey","Boolean","canRevealPersistedAPIKey","apiKeyLabel","label","highlightField","updateKey","apiKey","response","fetch","apiRoute","routes","api","encodeURIComponent","String","body","JSON","stringify","enableAPIKey","headers","method","ok","Error","result","json","doc","updatedAt","Date","getTime","error","generateKey","key","revokeKey","success","revealKey","current","_jsxs","Fragment","className","filter","join","htmlFor","_jsx","disabled","buttonStyle","extraButtonProps","icon","loadingText","size","active","onClick","previous","setKey","description","willInvalidateExistingKey","confirmLabel","heading","modalSlug","onConfirm"],"sources":["../../../../src/views/Edit/Auth/APIKey.tsx"],"sourcesContent":["'use client'\nimport type { PayloadRequest, TextFieldClient } from 'payload'\n\nimport { useModal } from '@faceless-ui/modal'\nimport { getTranslation } from '@payloadcms/translations'\nimport { formatAdminURL, text } from 'payload/shared'\nimport React, { useEffect, useMemo, useRef, useState } from 'react'\nimport { toast } from 'sonner'\nimport { v4 as uuidv4 } from 'uuid'\n\nimport { Button } from '../../../elements/Button/index.js'\nimport { ConfirmationModal } from '../../../elements/ConfirmationModal/index.js'\nimport { CopyToClipboard } from '../../../elements/CopyToClipboard/index.js'\nimport { Spinner } from '../../../elements/Spinner/index.js'\nimport { FieldDescription } from '../../../fields/FieldDescription/index.js'\nimport { useFormFields, useFormModified } from '../../../forms/Form/context.js'\nimport { useField } from '../../../forms/useField/index.js'\nimport { EyeIcon } from '../../../icons/Eye/index.js'\nimport { RefreshIcon } from '../../../icons/Refresh/index.js'\nimport { useConfig } from '../../../providers/Config/index.js'\nimport { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'\nimport { useLocale } from '../../../providers/Locale/index.js'\nimport { useTranslation } from '../../../providers/Translation/index.js'\nimport { APIKeyGenerationModal } from './APIKeyGenerationModal.js'\n\nconst path = 'apiKey'\nconst baseClass = 'api-key'\nconst fieldBaseClass = 'field-type'\nconst maskedAPIKey = '•'.repeat(24)\n\nexport const APIKey: React.FC<{ readonly readOnly?: boolean; readonly reveal?: boolean }> = ({\n readOnly,\n reveal,\n}) => {\n const [highlightedField, setHighlightedField] = useState(false)\n const [hasUpdatedPersistedAPIKey, setHasUpdatedPersistedAPIKey] = useState<boolean | null>(null)\n const [isRevealing, setIsRevealing] = useState(false)\n const [revealedKey, setRevealedKey] = useState<null | string>(null)\n const [showCopyWarning, setShowCopyWarning] = useState(false)\n const [showKey, setShowKey] = useState(false)\n const modified = useFormModified()\n const wasModified = useRef(modified)\n const { i18n, t } = useTranslation()\n const { toggleModal } = useModal()\n const { config, getEntityConfig } = useConfig()\n const { id, collectionSlug, setData, setLastUpdateTime } = useDocumentInfo()\n const { code: locale } = useLocale()\n const revokeModalSlug = `revoke-api-key-${id}`\n\n const hasAPIKey = useFormFields(([fields]) => (fields && fields.hasAPIKey) || null)\n const dispatchFields = useFormFields(([, dispatchFields]) => dispatchFields)\n\n const apiKeyField: TextFieldClient = getEntityConfig({ collectionSlug })?.fields?.find(\n (field) => 'name' in field && field.name === 'apiKey',\n ) as TextFieldClient\n const validate = (val) =>\n text(val, {\n name: 'apiKey',\n type: 'text',\n blockData: {},\n data: {},\n event: 'onChange',\n maxLength: 48,\n minLength: 24,\n path: ['apiKey'],\n preferences: { fields: {} },\n req: {\n payload: {\n config,\n },\n t,\n } as unknown as PayloadRequest,\n siblingData: {},\n })\n\n const { setValue, value } = useField({\n path,\n validate,\n })\n const apiKeyValue = revealedKey || (value as null | string | undefined)\n const hasPersistedAPIKey =\n hasUpdatedPersistedAPIKey ?? Boolean(hasAPIKey?.value as boolean | undefined)\n const canRevealPersistedAPIKey = reveal && hasPersistedAPIKey && !revealedKey\n\n const apiKeyLabel = useMemo(() => {\n let label: Record<string, string> | string = 'API Key'\n\n if (apiKeyField?.label) {\n label = apiKeyField.label\n }\n\n return getTranslation(label, i18n)\n }, [apiKeyField, i18n])\n\n const highlightField = () => {\n setHighlightedField(true)\n }\n\n const updateKey = async (apiKey: null | string) => {\n if (!id) {\n return false\n }\n\n try {\n const response = await fetch(\n formatAdminURL({\n apiRoute: config.routes.api,\n path: `/${collectionSlug}/${encodeURIComponent(String(id))}?depth=0&fallback-locale=null&locale=${locale}`,\n }),\n {\n body: JSON.stringify({\n apiKey,\n // The `enableAPIKey` field is for backward compatibility only and will be removed in v4.\n enableAPIKey: Boolean(apiKey),\n }),\n headers: { 'Content-Type': 'application/json' },\n method: 'PATCH',\n },\n )\n\n if (!response.ok) {\n throw new Error('API key update failed')\n }\n\n const result = await response.json()\n\n setHasUpdatedPersistedAPIKey(Boolean(apiKey))\n dispatchFields({ type: 'REMOVE', path })\n // The `enableAPIKey` field is for backward compatibility only and will be removed in v4.\n dispatchFields({ type: 'REMOVE', path: 'enableAPIKey' })\n\n if (result.doc?.updatedAt) {\n setData(result.doc)\n setLastUpdateTime(new Date(result.doc.updatedAt).getTime())\n }\n\n return true\n } catch {\n toast.error('Failed to update the API key.')\n return false\n }\n }\n\n const generateKey = async () => {\n const key = uuidv4()\n\n if (!id) {\n setValue(key, true)\n setShowCopyWarning(true)\n setShowKey(true)\n highlightField()\n\n return true\n }\n\n if (!(await updateKey(key))) {\n return false\n }\n\n setRevealedKey(key)\n setShowCopyWarning(true)\n setShowKey(true)\n highlightField()\n\n return true\n }\n\n const revokeKey = async () => {\n if (!(await updateKey(null))) {\n return\n }\n\n setRevealedKey(null)\n setHasUpdatedPersistedAPIKey(false)\n setHighlightedField(false)\n setShowCopyWarning(false)\n setShowKey(false)\n toast.success('API key revoked successfully.')\n }\n\n const revealKey = async () => {\n if (isRevealing) {\n return\n }\n\n setIsRevealing(true)\n\n try {\n const response = await fetch(\n formatAdminURL({\n apiRoute: config.routes.api,\n path: `/${collectionSlug}/${encodeURIComponent(String(id))}/api-key/reveal`,\n }),\n { method: 'POST' },\n )\n\n if (!response.ok) {\n toast.error('Failed to reveal the API key.')\n return\n }\n\n const result = await response.json()\n\n setRevealedKey(result.apiKey)\n setShowCopyWarning(false)\n setShowKey(true)\n } catch {\n toast.error('Failed to reveal the API key.')\n } finally {\n setIsRevealing(false)\n }\n }\n\n useEffect(() => {\n if (wasModified.current && !modified && apiKeyValue) {\n setHasUpdatedPersistedAPIKey(true)\n setHighlightedField(false)\n setRevealedKey(null)\n setShowCopyWarning(false)\n dispatchFields({ type: 'REMOVE', path })\n setShowKey(false)\n }\n\n wasModified.current = modified\n }, [apiKeyValue, dispatchFields, modified])\n\n return (\n <React.Fragment>\n <div className={[fieldBaseClass, 'api-key', 'read-only'].filter(Boolean).join(' ')}>\n <label className={`${baseClass}__label field-label`} htmlFor=\"apiKey\">\n <span>{apiKeyLabel}</span>\n {apiKeyValue && <CopyToClipboard value={apiKeyValue} />}\n </label>\n <div\n className={[\n `${baseClass}__input-wrap`,\n !readOnly && hasPersistedAPIKey && `${baseClass}__input-wrap--has-regenerate`,\n highlightedField && `${baseClass}__input-wrap--highlighted`,\n ]\n .filter(Boolean)\n .join(' ')}\n >\n <input\n aria-label={apiKeyLabel}\n disabled\n id=\"apiKey\"\n name=\"apiKey\"\n type={apiKeyValue && !showKey ? 'password' : 'text'}\n value={apiKeyValue || (hasPersistedAPIKey ? maskedAPIKey : '')}\n />\n {(apiKeyValue || canRevealPersistedAPIKey || (!readOnly && hasPersistedAPIKey)) && (\n <div className={`${baseClass}__toggle-button-wrap`}>\n {(apiKeyValue || canRevealPersistedAPIKey) && (\n <Button\n aria-label={\n canRevealPersistedAPIKey ? 'Reveal API key' : 'Toggle API key visibility'\n }\n buttonStyle=\"none\"\n className={[\n `${baseClass}__visibility-button`,\n !readOnly &&\n hasPersistedAPIKey &&\n `${baseClass}__visibility-button--with-regenerate`,\n ]\n .filter(Boolean)\n .join(' ')}\n disabled={isRevealing}\n extraButtonProps={{ 'aria-busy': isRevealing }}\n icon={\n isRevealing ? (\n <Spinner loadingText={null} size=\"sm\" />\n ) : (\n <EyeIcon active={showKey} />\n )\n }\n id={canRevealPersistedAPIKey ? 'reveal-api-key' : 'toggle-api-key-visibility'}\n onClick={\n canRevealPersistedAPIKey ? revealKey : () => setShowKey((previous) => !previous)\n }\n />\n )}\n {!readOnly && hasPersistedAPIKey && (\n <APIKeyGenerationModal\n highlightField={highlightField}\n icon={<RefreshIcon />}\n id=\"regenerate-api-key\"\n setKey={generateKey}\n />\n )}\n </div>\n )}\n </div>\n {apiKeyValue && showCopyWarning && (\n <FieldDescription\n description={\n reveal\n ? 'Make sure to copy your API key. You may not have access to reveal it again.'\n : 'Make sure to copy your API key. It will not be displayed again.'\n }\n path={path}\n />\n )}\n </div>\n {!readOnly &&\n !apiKeyValue &&\n !hasPersistedAPIKey &&\n (id ? (\n <APIKeyGenerationModal\n highlightField={highlightField}\n id=\"generate-api-key\"\n setKey={generateKey}\n willInvalidateExistingKey={false}\n />\n ) : (\n <Button\n buttonStyle=\"secondary\"\n id=\"generate-api-key\"\n onClick={() => void generateKey()}\n size=\"small\"\n >\n {t('authentication:generateNewAPIKey')}\n </Button>\n ))}\n {!readOnly && hasPersistedAPIKey && (\n <div className={`${baseClass}__actions`}>\n <Button\n buttonStyle=\"secondary\"\n className={`${baseClass}__revoke-button`}\n id=\"revoke-api-key\"\n onClick={() => toggleModal(revokeModalSlug)}\n size=\"small\"\n >\n Revoke API key\n </Button>\n <ConfirmationModal\n body={\n <span>\n Are you sure you want to revoke the API key for user <strong>{id}</strong>? The key\n will no longer be usable, and this action cannot be undone.\n </span>\n }\n confirmLabel=\"Revoke\"\n heading=\"Revoke API key?\"\n modalSlug={revokeModalSlug}\n onConfirm={revokeKey}\n />\n </div>\n )}\n </React.Fragment>\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ export type APIKeyGenerationModalProps = {
3
+ highlightField: (Boolean: any) => void;
4
+ icon?: React.ReactNode;
5
+ id?: string;
6
+ setKey: () => boolean | Promise<boolean | void> | void;
7
+ willInvalidateExistingKey?: boolean;
8
+ };
9
+ export type GenerateConfirmationProps = APIKeyGenerationModalProps;
10
+ export declare function APIKeyGenerationModal(props: APIKeyGenerationModalProps): React.JSX.Element;
11
+ //# sourceMappingURL=APIKeyGenerationModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"APIKeyGenerationModal.d.ts","sourceRoot":"","sources":["../../../../src/views/Edit/Auth/APIKeyGenerationModal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsB,MAAM,OAAO,CAAA;AAS1C,MAAM,MAAM,0BAA0B,GAAG;IACvC,cAAc,EAAE,CAAC,OAAO,KAAA,KAAK,IAAI,CAAA;IACjC,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IACtD,yBAAyB,CAAC,EAAE,OAAO,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG,0BAA0B,CAAA;AAElE,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,qBAyDtE"}
@@ -0,0 +1,113 @@
1
+ 'use client';
2
+
3
+ import { c as _c } from "react/compiler-runtime";
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ import { useModal } from '@faceless-ui/modal';
6
+ import React, { useCallback } from 'react';
7
+ import { toast } from 'sonner';
8
+ import { Button } from '../../../elements/Button/index.js';
9
+ import { ConfirmationModal } from '../../../elements/ConfirmationModal/index.js';
10
+ import { Translation } from '../../../elements/Translation/index.js';
11
+ import { useDocumentInfo } from '../../../providers/DocumentInfo/index.js';
12
+ import { useTranslation } from '../../../providers/Translation/index.js';
13
+ export function APIKeyGenerationModal(props) {
14
+ const $ = _c(16);
15
+ const {
16
+ id,
17
+ highlightField,
18
+ icon,
19
+ setKey,
20
+ willInvalidateExistingKey: t0
21
+ } = props;
22
+ const willInvalidateExistingKey = t0 === undefined ? true : t0;
23
+ const {
24
+ id: documentID
25
+ } = useDocumentInfo();
26
+ const {
27
+ toggleModal
28
+ } = useModal();
29
+ const {
30
+ t
31
+ } = useTranslation();
32
+ const modalSlug = `generate-confirmation-${documentID}`;
33
+ let t1;
34
+ if ($[0] !== highlightField || $[1] !== setKey || $[2] !== t) {
35
+ t1 = async () => {
36
+ if ((await setKey()) === false) {
37
+ return;
38
+ }
39
+ toast.success(t("authentication:newAPIKeyGenerated"));
40
+ highlightField(true);
41
+ };
42
+ $[0] = highlightField;
43
+ $[1] = setKey;
44
+ $[2] = t;
45
+ $[3] = t1;
46
+ } else {
47
+ t1 = $[3];
48
+ }
49
+ const handleGenerate = t1;
50
+ let t2;
51
+ if ($[4] !== documentID || $[5] !== handleGenerate || $[6] !== icon || $[7] !== id || $[8] !== modalSlug || $[9] !== t || $[10] !== toggleModal || $[11] !== willInvalidateExistingKey) {
52
+ let t3;
53
+ if ($[13] !== modalSlug || $[14] !== toggleModal) {
54
+ t3 = () => {
55
+ toggleModal(modalSlug);
56
+ };
57
+ $[13] = modalSlug;
58
+ $[14] = toggleModal;
59
+ $[15] = t3;
60
+ } else {
61
+ t3 = $[15];
62
+ }
63
+ t2 = _jsxs(React.Fragment, {
64
+ children: [_jsx(Button, {
65
+ "aria-label": icon ? t("authentication:generateNewAPIKey") : undefined,
66
+ buttonStyle: icon ? "none" : "secondary",
67
+ className: icon ? "api-key__regenerate-button" : undefined,
68
+ icon,
69
+ id,
70
+ onClick: t3,
71
+ size: "small",
72
+ children: !icon && t("authentication:generateNewAPIKey")
73
+ }), _jsx(ConfirmationModal, {
74
+ body: willInvalidateExistingKey ? _jsx(Translation, {
75
+ elements: {
76
+ 1: _temp
77
+ },
78
+ i18nKey: "authentication:generatingNewAPIKeyWillInvalidate",
79
+ t
80
+ }) : _jsxs("span", {
81
+ children: ["Are you sure you want to generate an API key for user ", _jsx("strong", {
82
+ children: documentID
83
+ }), "? This will take effect immediately."]
84
+ }),
85
+ confirmLabel: t("authentication:generate"),
86
+ heading: t("authentication:confirmGeneration"),
87
+ modalSlug,
88
+ onConfirm: handleGenerate
89
+ })]
90
+ });
91
+ $[4] = documentID;
92
+ $[5] = handleGenerate;
93
+ $[6] = icon;
94
+ $[7] = id;
95
+ $[8] = modalSlug;
96
+ $[9] = t;
97
+ $[10] = toggleModal;
98
+ $[11] = willInvalidateExistingKey;
99
+ $[12] = t2;
100
+ } else {
101
+ t2 = $[12];
102
+ }
103
+ return t2;
104
+ }
105
+ function _temp(t0) {
106
+ const {
107
+ children
108
+ } = t0;
109
+ return _jsx("strong", {
110
+ children
111
+ });
112
+ }
113
+ //# sourceMappingURL=APIKeyGenerationModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"APIKeyGenerationModal.js","names":["c","_c","useModal","React","useCallback","toast","Button","ConfirmationModal","Translation","useDocumentInfo","useTranslation","APIKeyGenerationModal","props","$","id","highlightField","icon","setKey","willInvalidateExistingKey","t0","undefined","documentID","toggleModal","t","modalSlug","t1","success","handleGenerate","t2","t3","_jsxs","Fragment","children","_jsx","buttonStyle","className","onClick","size","body","elements","1","_temp","i18nKey","heading","onConfirm"],"sources":["../../../../src/views/Edit/Auth/APIKeyGenerationModal.tsx"],"sourcesContent":["'use client'\nimport { useModal } from '@faceless-ui/modal'\nimport React, { useCallback } from 'react'\nimport { toast } from 'sonner'\n\nimport { Button } from '../../../elements/Button/index.js'\nimport { ConfirmationModal } from '../../../elements/ConfirmationModal/index.js'\nimport { Translation } from '../../../elements/Translation/index.js'\nimport { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'\nimport { useTranslation } from '../../../providers/Translation/index.js'\n\nexport type APIKeyGenerationModalProps = {\n highlightField: (Boolean) => void\n icon?: React.ReactNode\n id?: string\n setKey: () => boolean | Promise<boolean | void> | void\n willInvalidateExistingKey?: boolean\n}\n\nexport type GenerateConfirmationProps = APIKeyGenerationModalProps\n\nexport function APIKeyGenerationModal(props: APIKeyGenerationModalProps) {\n const { id, highlightField, icon, setKey, willInvalidateExistingKey = true } = props\n\n const { id: documentID } = useDocumentInfo()\n const { toggleModal } = useModal()\n const { t } = useTranslation()\n\n const modalSlug = `generate-confirmation-${documentID}`\n\n const handleGenerate = useCallback(async () => {\n if ((await setKey()) === false) {\n return\n }\n\n toast.success(t('authentication:newAPIKeyGenerated'))\n highlightField(true)\n }, [highlightField, setKey, t])\n\n return (\n <React.Fragment>\n <Button\n aria-label={icon ? t('authentication:generateNewAPIKey') : undefined}\n buttonStyle={icon ? 'none' : 'secondary'}\n className={icon ? 'api-key__regenerate-button' : undefined}\n icon={icon}\n id={id}\n onClick={() => {\n toggleModal(modalSlug)\n }}\n size=\"small\"\n >\n {!icon && t('authentication:generateNewAPIKey')}\n </Button>\n <ConfirmationModal\n body={\n willInvalidateExistingKey ? (\n <Translation\n elements={{\n 1: ({ children }) => <strong>{children}</strong>,\n }}\n i18nKey=\"authentication:generatingNewAPIKeyWillInvalidate\"\n t={t}\n />\n ) : (\n <span>\n Are you sure you want to generate an API key for user <strong>{documentID}</strong>?\n This will take effect immediately.\n </span>\n )\n }\n confirmLabel={t('authentication:generate')}\n heading={t('authentication:confirmGeneration')}\n modalSlug={modalSlug}\n onConfirm={handleGenerate}\n />\n </React.Fragment>\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/views/Edit/Auth/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAA8D,MAAM,OAAO,CAAA;AAGlF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAWvC,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAuRhC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/views/Edit/Auth/index.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAGxE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAWvC,OAAO,cAAc,CAAA;AAKrB,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,CAoQhC,CAAA"}
@@ -3,7 +3,7 @@
3
3
  import { c as _c } from "react/compiler-runtime";
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  import { formatAdminURL, getFieldPermissions } from 'payload/shared';
6
- import React, { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
6
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
7
7
  import { toast } from 'sonner';
8
8
  import { Button } from '../../../elements/Button/index.js';
9
9
  import { EmailAndUsernameFields } from '../../../elements/EmailAndUsername/index.js';
@@ -34,8 +34,7 @@ export const Auth = props => {
34
34
  verify
35
35
  } = props;
36
36
  const [changingPassword, setChangingPassword] = useState(requirePassword);
37
- const enableAPIKey = useFormFields(_temp);
38
- const dispatchFields = useFormFields(_temp2);
37
+ const dispatchFields = useFormFields(_temp);
39
38
  const modified = useFormModified();
40
39
  const {
41
40
  i18n,
@@ -130,10 +129,8 @@ export const Auth = props => {
130
129
  }
131
130
  const enableFields = (!disableLocalStrategy || typeof disableLocalStrategy === "object" && disableLocalStrategy.enableFields === true) && (showUnlock || showPasswordFields);
132
131
  const disabled = readOnly || isInitializing || isTrashed;
133
- const apiKeyPermissions = docPermissions?.fields === true ? true : docPermissions?.fields?.enableAPIKey;
134
- const apiKeyReadOnly = readOnly || apiKeyPermissions === true || apiKeyPermissions && typeof apiKeyPermissions === "object" && !apiKeyPermissions?.update;
135
- const enableAPIKeyReadOnly = readOnly || apiKeyPermissions !== true && !apiKeyPermissions?.update;
136
- const canReadApiKey = apiKeyPermissions === true || apiKeyPermissions?.read;
132
+ const apiKeyPermissions = docPermissions?.fields === true ? true : docPermissions?.fields?.apiKey;
133
+ const canManageAPIKey = apiKeyPermissions === true || typeof apiKeyPermissions === "object" && Boolean(apiKeyPermissions?.[operation]);
137
134
  let t2;
138
135
  bb0: {
139
136
  if (docPermissions) {
@@ -237,7 +234,7 @@ export const Auth = props => {
237
234
  }
238
235
  useEffect(t5, t6);
239
236
  const showAuthBlock = enableFields;
240
- const showAPIKeyBlock = useAPIKey && canReadApiKey;
237
+ const showAPIKeyBlock = useAPIKey && canManageAPIKey;
241
238
  const showVerifyBlock = verify && isEditing;
242
239
  if (!(showAuthBlock || showAPIKeyBlock || showVerifyBlock)) {
243
240
  return null;
@@ -301,24 +298,11 @@ export const Auth = props => {
301
298
  children: t("authentication:forceUnlock")
302
299
  })]
303
300
  })]
304
- }), useAPIKey && _jsx("div", {
301
+ }), showAPIKeyBlock && _jsx("div", {
305
302
  className: `${baseClass}__api-key`,
306
- children: canReadApiKey && _jsxs(Fragment, {
307
- children: [_jsx(CheckboxField, {
308
- field: {
309
- name: "enableAPIKey",
310
- admin: {
311
- disabled,
312
- readOnly: enableAPIKeyReadOnly
313
- },
314
- label: t("authentication:enableAPIKey")
315
- },
316
- path: "enableAPIKey",
317
- schemaPath: `${collectionSlug}.enableAPIKey`
318
- }), _jsx(APIKey, {
319
- enabled: !!enableAPIKey?.value,
320
- readOnly: apiKeyReadOnly
321
- })]
303
+ children: _jsx(APIKey, {
304
+ readOnly: disabled,
305
+ reveal: typeof useAPIKey === "object" && useAPIKey.reveal === true
322
306
  })
323
307
  }), verify && isEditing && _jsx(CheckboxField, {
324
308
  field: {
@@ -334,11 +318,7 @@ export const Auth = props => {
334
318
  })]
335
319
  });
336
320
  };
337
- function _temp(t0) {
338
- const [fields] = t0;
339
- return fields && fields?.enableAPIKey || null;
340
- }
341
- function _temp2(reducer) {
321
+ function _temp(reducer) {
342
322
  return reducer[1];
343
323
  }
344
324
  //# sourceMappingURL=index.js.map