diff --git a/.changeset/chilly-boxes-warn.md b/.changeset/chilly-boxes-warn.md new file mode 100644 index 00000000000..f49d965e127 --- /dev/null +++ b/.changeset/chilly-boxes-warn.md @@ -0,0 +1,5 @@ +--- +"@clerk/localizations": minor +--- + +Added localization entry for the API key copy modal component. diff --git a/.changeset/heavy-books-protect.md b/.changeset/heavy-books-protect.md new file mode 100644 index 00000000000..30f230680ac --- /dev/null +++ b/.changeset/heavy-books-protect.md @@ -0,0 +1,5 @@ +--- +"@clerk/clerk-js": minor +--- + +Replaced the persistent key column in the API keys table with a one-time modal that displays the secret immediately after creation. diff --git a/integration/testUtils/usersService.ts b/integration/testUtils/usersService.ts index 7ad4b6f67b1..a95114a6fb7 100644 --- a/integration/testUtils/usersService.ts +++ b/integration/testUtils/usersService.ts @@ -204,11 +204,9 @@ export const createUserService = (clerkClient: ClerkClient) => { secondsUntilExpiration: TWENTY_MINUTES, }); - const { secret } = await clerkClient.apiKeys.getSecret(apiKey.id); - return { apiKey, - secret, + secret: apiKey.secret ?? '', revoke: () => clerkClient.apiKeys.revoke({ apiKeyId: apiKey.id, revocationReason: 'For testing purposes' }), } satisfies FakeAPIKey; }, diff --git a/integration/tests/machine-auth/component.test.ts b/integration/tests/machine-auth/component.test.ts index 86c49d08548..8b7cab040ab 100644 --- a/integration/tests/machine-auth/component.test.ts +++ b/integration/tests/machine-auth/component.test.ts @@ -43,6 +43,10 @@ testAgainstRunningApps({ await u.po.apiKeys.selectExpiration('1d'); await u.po.apiKeys.clickSaveButton(); + // Close copy modal + await u.po.apiKeys.waitForCopyModalOpened(); + await u.po.apiKeys.clickCopyAndCloseButton(); + await u.po.apiKeys.waitForCopyModalClosed(); await u.po.apiKeys.waitForFormClosed(); // Create API key 2 @@ -52,8 +56,14 @@ testAgainstRunningApps({ await u.po.apiKeys.selectExpiration('7d'); await u.po.apiKeys.clickSaveButton(); + // Wait and close copy modal + await u.po.apiKeys.waitForCopyModalOpened(); + await u.po.apiKeys.clickCopyAndCloseButton(); + await u.po.apiKeys.waitForCopyModalClosed(); + await u.po.apiKeys.waitForFormClosed(); + // Check if both API keys are created - await expect(u.page.locator('.cl-apiKeysTable .cl-tableRow')).toHaveCount(2); + await expect(u.page.locator('.cl-apiKeysTable .cl-tableBody .cl-tableRow')).toHaveCount(2); }); test('can revoke api keys', async ({ page, context }) => { @@ -74,6 +84,11 @@ testAgainstRunningApps({ await u.po.apiKeys.typeName(apiKeyName); await u.po.apiKeys.selectExpiration('1d'); await u.po.apiKeys.clickSaveButton(); + + // Wait and close copy modal + await u.po.apiKeys.waitForCopyModalOpened(); + await u.po.apiKeys.clickCopyAndCloseButton(); + await u.po.apiKeys.waitForCopyModalClosed(); await u.po.apiKeys.waitForFormClosed(); // Retrieve API key @@ -97,7 +112,7 @@ testAgainstRunningApps({ await expect(table.locator('.cl-tableRow', { hasText: apiKeyName })).toHaveCount(0); }); - test('can copy api key secret', async ({ page, context }) => { + test('can copy api key secret after creation', async ({ page, context }) => { const u = createTestUtils({ app, page, context }); await u.po.signIn.goTo(); await u.po.signIn.waitForMounted(); @@ -109,71 +124,30 @@ testAgainstRunningApps({ const apiKeyName = `${fakeAdmin.firstName}-${Date.now()}`; - // Create API key + // Create API key and capture the secret from the response + const createResponsePromise = page.waitForResponse( + response => response.url().includes('/api_keys') && response.request().method() === 'POST', + ); await u.po.apiKeys.clickAddButton(); await u.po.apiKeys.waitForFormOpened(); await u.po.apiKeys.typeName(apiKeyName); await u.po.apiKeys.selectExpiration('1d'); await u.po.apiKeys.clickSaveButton(); - await u.po.apiKeys.waitForFormClosed(); - const responsePromise = page.waitForResponse( - response => response.url().includes('/secret') && response.request().method() === 'GET', - ); - - // Copy API key - const table = u.page.locator('.cl-apiKeysTable'); - const row = table.locator('.cl-tableRow', { hasText: apiKeyName }); - await row.waitFor({ state: 'attached' }); - await row.locator('.cl-apiKeysCopyButton').click(); + const createResponse = await createResponsePromise; + const secret = (await createResponse.json()).secret; - // Read clipboard contents - const data = await (await responsePromise).json(); + // Copy secret via modal and verify clipboard contents + // Wait and close copy modal + await u.po.apiKeys.waitForCopyModalOpened(); await context.grantPermissions(['clipboard-read']); - const clipboardText = await page.evaluate('navigator.clipboard.readText()'); - await context.clearPermissions(); - expect(clipboardText).toBe(data.secret); - }); - - test('can toggle api key secret visibility', async ({ page, context }) => { - const u = createTestUtils({ app, page, context }); - await u.po.signIn.goTo(); - await u.po.signIn.waitForMounted(); - await u.po.signIn.signInWithEmailAndInstantPassword({ email: fakeAdmin.email, password: fakeAdmin.password }); - await u.po.expect.toBeSignedIn(); - - await u.po.page.goToRelative('/api-keys'); - await u.po.apiKeys.waitForMounted(); - - const apiKeyName = `${fakeAdmin.firstName}-${Date.now()}`; - - // Create API key - await u.po.apiKeys.clickAddButton(); - await u.po.apiKeys.waitForFormOpened(); - await u.po.apiKeys.typeName(apiKeyName); - await u.po.apiKeys.selectExpiration('1d'); - await u.po.apiKeys.clickSaveButton(); + await u.po.apiKeys.clickCopyAndCloseButton(); + await u.po.apiKeys.waitForCopyModalClosed(); await u.po.apiKeys.waitForFormClosed(); - const responsePromise = page.waitForResponse( - response => response.url().includes('/secret') && response.request().method() === 'GET', - ); - - // Toggle API key secret visibility - const table = u.page.locator('.cl-apiKeysTable'); - const row = table.locator('.cl-tableRow', { hasText: apiKeyName }); - await row.waitFor({ state: 'attached' }); - await expect(row.locator('input')).toHaveAttribute('type', 'password'); - await row.locator('.cl-apiKeysRevealButton').click(); - - // Verify if secret matches the input value - const data = await (await responsePromise).json(); - await expect(row.locator('input')).toHaveAttribute('type', 'text'); - await expect(row.locator('input')).toHaveValue(data.secret); - - // Toggle visibility off - await row.locator('.cl-apiKeysRevealButton').click(); - await expect(row.locator('input')).toHaveAttribute('type', 'password'); + const clipboardText = await page.evaluate('navigator.clipboard.readText()'); + await context.clearPermissions(); + expect(clipboardText).toBe(secret); }); test('component does not render for orgs when user does not have permissions', async ({ page, context }) => { diff --git a/packages/clerk-js/src/core/modules/apiKeys/index.ts b/packages/clerk-js/src/core/modules/apiKeys/index.ts index fcf2b20497e..e7634766689 100644 --- a/packages/clerk-js/src/core/modules/apiKeys/index.ts +++ b/packages/clerk-js/src/core/modules/apiKeys/index.ts @@ -54,50 +54,32 @@ export class APIKeys implements APIKeysNamespace { }); } - async getSecret(id: string): Promise { - return BaseResource.clerk - .getFapiClient() - .request<{ secret: string }>({ - ...(await this.getBaseFapiProxyOptions()), - method: 'GET', - path: `/api_keys/${id}/secret`, - }) - .then(res => { - const { secret } = res.payload as unknown as { secret: string }; - return secret; - }); - } - async create(params: CreateAPIKeyParams): Promise { - const json = ( - await BaseResource._fetch({ - ...(await this.getBaseFapiProxyOptions()), - path: '/api_keys', - method: 'POST', - body: JSON.stringify({ - type: params.type ?? 'api_key', - name: params.name, - subject: params.subject ?? BaseResource.clerk.organization?.id ?? BaseResource.clerk.user?.id ?? '', - description: params.description, - seconds_until_expiration: params.secondsUntilExpiration, - }), - }) - )?.response as ApiKeyJSON; + const json = (await BaseResource._fetch({ + ...(await this.getBaseFapiProxyOptions()), + path: '/api_keys', + method: 'POST', + body: JSON.stringify({ + type: params.type ?? 'api_key', + name: params.name, + subject: params.subject ?? BaseResource.clerk.organization?.id ?? BaseResource.clerk.user?.id ?? '', + description: params.description, + seconds_until_expiration: params.secondsUntilExpiration, + }), + })) as unknown as ApiKeyJSON; return new APIKey(json); } async revoke(params: RevokeAPIKeyParams): Promise { - const json = ( - await BaseResource._fetch({ - ...(await this.getBaseFapiProxyOptions()), - method: 'POST', - path: `/api_keys/${params.apiKeyID}/revoke`, - body: JSON.stringify({ - revocation_reason: params.revocationReason, - }), - }) - )?.response as ApiKeyJSON; + const json = (await BaseResource._fetch({ + ...(await this.getBaseFapiProxyOptions()), + method: 'POST', + path: `/api_keys/${params.apiKeyID}/revoke`, + body: JSON.stringify({ + revocation_reason: params.revocationReason, + }), + })) as unknown as ApiKeyJSON; return new APIKey(json); } diff --git a/packages/clerk-js/src/core/resources/APIKey.ts b/packages/clerk-js/src/core/resources/APIKey.ts index 240708b6710..509e07cf56d 100644 --- a/packages/clerk-js/src/core/resources/APIKey.ts +++ b/packages/clerk-js/src/core/resources/APIKey.ts @@ -18,6 +18,7 @@ export class APIKey extends BaseResource implements APIKeyResource { expiration!: Date | null; createdBy!: string | null; description!: string | null; + secret?: string; lastUsedAt!: Date | null; createdAt!: Date; updatedAt!: Date; @@ -44,6 +45,7 @@ export class APIKey extends BaseResource implements APIKeyResource { this.expiration = data.expiration ? unixEpochToDate(data.expiration) : null; this.createdBy = data.created_by; this.description = data.description; + this.secret = data.secret; this.lastUsedAt = data.last_used_at ? unixEpochToDate(data.last_used_at) : null; this.updatedAt = unixEpochToDate(data.updated_at); this.createdAt = unixEpochToDate(data.created_at); diff --git a/packages/clerk-js/src/ui/components/ApiKeys/ApiKeyModal.tsx b/packages/clerk-js/src/ui/components/ApiKeys/ApiKeyModal.tsx new file mode 100644 index 00000000000..02584622844 --- /dev/null +++ b/packages/clerk-js/src/ui/components/ApiKeys/ApiKeyModal.tsx @@ -0,0 +1,44 @@ +import React from 'react'; + +import { Modal } from '@/ui/elements/Modal'; +import type { ThemableCssProp } from '@/ui/styledSystem'; + +type ApiKeyModalProps = React.ComponentProps & { + modalRoot?: React.MutableRefObject; +}; + +/** + * Container styles for modals rendered within a custom portal root (e.g., UserProfile or OrganizationProfile). + * When a modalRoot is provided, the modal is scoped to that container rather than the document root, + * requiring different positioning (absolute instead of fixed) and backdrop styling. + */ +const getScopedPortalContainerStyles = (modalRoot?: React.MutableRefObject): ThemableCssProp => { + return [ + { alignItems: 'center' }, + modalRoot + ? t => ({ + position: 'absolute', + right: 0, + bottom: 0, + backgroundColor: 'inherit', + backdropFilter: `blur(${t.sizes.$2})`, + display: 'flex', + justifyContent: 'center', + minHeight: '100%', + height: '100%', + width: '100%', + borderRadius: t.radii.$lg, + }) + : {}, + ]; +}; + +export const ApiKeyModal = ({ modalRoot, containerSx, ...modalProps }: ApiKeyModalProps) => { + return ( + + ); +}; diff --git a/packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx b/packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx index e555672c241..5cd1477ba3e 100644 --- a/packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx +++ b/packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx @@ -42,6 +42,12 @@ const RevokeAPIKeyConfirmationModal = lazy(() => })), ); +const CopyApiKeyModal = lazy(() => + import(/* webpackChunkName: "copy-api-key-modal"*/ './CopyApiKeyModal').then(module => ({ + default: module.CopyApiKeyModal, + })), +); + export const APIKeysPage = ({ subject, perPage, revokeModalRoot }: APIKeysPageProps) => { const isOrg = isOrganizationId(subject); const canReadAPIKeys = useProtect({ permission: 'org:sys_api_keys:read' }); @@ -61,23 +67,26 @@ export const APIKeysPage = ({ subject, perPage, revokeModalRoot }: APIKeysPagePr cacheKey, } = useApiKeys({ subject, perPage, enabled: isOrg ? canReadAPIKeys : true }); const card = useCardState(); - const { trigger: createApiKey, isMutating } = useSWRMutation(cacheKey, (_, { arg }: { arg: CreateAPIKeyParams }) => - clerk.apiKeys.create(arg), - ); - const { t } = useLocalizations(); const clerk = useClerk(); + const { + data: createdApiKey, + trigger: createApiKey, + isMutating, + } = useSWRMutation(cacheKey, (_key, { arg }: { arg: CreateAPIKeyParams }) => clerk.apiKeys.create(arg)); + const { t } = useLocalizations(); const [isRevokeModalOpen, setIsRevokeModalOpen] = useState(false); const [selectedApiKeyId, setSelectedApiKeyId] = useState(''); const [selectedApiKeyName, setSelectedApiKeyName] = useState(''); + const [isCopyModalOpen, setIsCopyModalOpen] = useState(false); - const handleCreateApiKey = async (params: OnCreateParams, closeCardFn: () => void) => { + const handleCreateApiKey = async (params: OnCreateParams) => { try { await createApiKey({ ...params, subject, }); - closeCardFn(); card.setError(undefined); + setIsCopyModalOpen(true); } catch (err: any) { if (isClerkAPIResponseError(err)) { if (err.status === 409) { @@ -147,7 +156,17 @@ export const APIKeysPage = ({ subject, perPage, revokeModalRoot }: APIKeysPagePr + + setIsCopyModalOpen(true)} + onClose={() => setIsCopyModalOpen(false)} + apiKeyName={createdApiKey?.name ?? ''} + apiKeySecret={createdApiKey?.secret ?? ''} + modalRoot={revokeModalRoot} + /> + )} + + {/* Modals */} { - const clerk = useClerk(); - - return useSWR(enabled ? ['api-key-secret', apiKeyID] : null, () => clerk.apiKeys.getSecret(apiKeyID)); -}; - -const CopySecretButton = ({ apiKeyID }: { apiKeyID: string }) => { - const [enabled, setEnabled] = useState(false); - const { data: apiKeySecret } = useApiKeySecret({ apiKeyID, enabled }); - const { onCopy, hasCopied } = useClipboard(apiKeySecret ?? ''); - - useEffect(() => { - if (enabled && apiKeySecret) { - onCopy(); - setEnabled(false); - } - }, [enabled, apiKeySecret, onCopy]); - - return ( - - ); -}; - -const SecretInputWithToggle = ({ apiKeyID }: { apiKeyID: string }) => { - const [revealed, setRevealed] = useState(false); - const { data: apiKeySecret } = useApiKeySecret({ apiKeyID, enabled: revealed }); - - return ( - - ({ - paddingInlineEnd: t.sizes.$12, - })} - /> - - - ); -}; - export const ApiKeysTable = ({ rows, isLoading, @@ -129,14 +42,13 @@ export const ApiKeysTable = ({ Name Last used - Key {canManageAPIKeys && Actions} {isLoading ? ( - + - - - - - - {canManageAPIKeys && ( void; + onClose: () => void; + apiKeyName: string; + apiKeySecret: string; + modalRoot?: React.MutableRefObject; +}; + +export const CopyApiKeyModal = ({ + isOpen, + onOpen, + onClose, + apiKeyName, + apiKeySecret, + modalRoot, +}: CopyApiKeyModalProps) => { + const apiKeyField = useFormControl('apiKeySecret', apiKeySecret, { + type: 'text', + label: localizationKeys('formFieldLabel__apiKey'), + isRequired: false, + }); + + const { onCopy } = useClipboard(apiKeySecret); + const { close: closeActionCard } = useActionContext(); + + const handleSubmit = () => { + onCopy(); + onClose(); + setTimeout(() => { + closeActionCard(); + }, 100); + }; + + if (!isOpen) { + return null; + } + + return ( + + + ({ + textAlign: 'left', + padding: `${t.sizes.$4} ${t.sizes.$5} ${t.sizes.$4} ${t.sizes.$6}`, + })} + > + + + + + {/* TODO: Use unified Input + Appended icon button component */} + + + + + + + + + + ); +}; diff --git a/packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx b/packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx index 6bfa96623bf..4d87be4c2d1 100644 --- a/packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx +++ b/packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx @@ -27,7 +27,7 @@ export type OnCreateParams = { }; interface CreateApiKeyFormProps { - onCreate: (params: OnCreateParams, closeCardFn: () => void) => void; + onCreate: (params: OnCreateParams) => void; isSubmitting: boolean; } @@ -164,14 +164,11 @@ export const CreateApiKeyForm: React.FC = ({ onCreate, is const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - onCreate( - { - name: nameField.value, - description: descriptionField.value || undefined, - secondsUntilExpiration: getTimeLeftInSeconds(selectedExpiration?.value), - }, - closeCardFn, - ); + onCreate({ + name: nameField.value, + description: descriptionField.value || undefined, + secondsUntilExpiration: getTimeLeftInSeconds(selectedExpiration?.value), + }); }; return ( diff --git a/packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx b/packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx index c8881c9b18c..747b96b6003 100644 --- a/packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx +++ b/packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx @@ -6,10 +6,11 @@ import { Card } from '@/ui/elements/Card'; import { Form } from '@/ui/elements/Form'; import { FormButtons } from '@/ui/elements/FormButtons'; import { FormContainer } from '@/ui/elements/FormContainer'; -import { Modal } from '@/ui/elements/Modal'; import { localizationKeys, useLocalizations } from '@/ui/localization'; import { useFormControl } from '@/ui/utils/useFormControl'; +import { ApiKeyModal } from './ApiKeyModal'; + type RevokeAPIKeyConfirmationModalProps = { subject: string; isOpen: boolean; @@ -65,29 +66,11 @@ export const RevokeAPIKeyConfirmationModal = ({ } return ( - ({ - position: 'absolute', - right: 0, - bottom: 0, - backgroundColor: 'inherit', - backdropFilter: `blur(${t.sizes.$2})`, - display: 'flex', - justifyContent: 'center', - minHeight: '100%', - height: '100%', - width: '100%', - borderRadius: t.radii.$lg, - }) - : {}, - ]} + modalRoot={modalRoot} > - + ); }; diff --git a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts index 30535333dc0..8f9ba0bfcf7 100644 --- a/packages/clerk-js/src/ui/customizables/elementDescriptors.ts +++ b/packages/clerk-js/src/ui/customizables/elementDescriptors.ts @@ -495,6 +495,9 @@ export const APPEARANCE_KEYS = containsAllElementsConfigKeys([ 'apiKeysRevokeModal', 'apiKeysRevokeModalInput', 'apiKeysRevokeModalSubmitButton', + 'apiKeysCopyModal', + 'apiKeysCopyModalInput', + 'apiKeysCopyModalSubmitButton', 'subscriptionDetailsCard', 'subscriptionDetailsCardHeader', diff --git a/packages/clerk-js/src/ui/elements/ClipboardInput.tsx b/packages/clerk-js/src/ui/elements/ClipboardInput.tsx index f0e9f73610e..0a622a814cb 100644 --- a/packages/clerk-js/src/ui/elements/ClipboardInput.tsx +++ b/packages/clerk-js/src/ui/elements/ClipboardInput.tsx @@ -1,17 +1,24 @@ +import type { ComponentType } from 'react'; + import { Button, descriptors, Flex, Icon, Input } from '../customizables'; import { useClipboard } from '../hooks'; import { Clipboard, TickShield } from '../icons'; import type { PropsOfComponent } from '../styledSystem'; -export const ClipboardInput = (props: PropsOfComponent) => { - const { id, value, ...rest } = props; +type ClipboardInputProps = PropsOfComponent & { + copyIcon?: ComponentType; + copiedIcon?: ComponentType; +}; + +export const ClipboardInput = (props: ClipboardInputProps) => { + const { id, value, copyIcon = Clipboard, copiedIcon = TickShield, sx, ...rest } = props; const { onCopy, hasCopied } = useClipboard(value as string); return ( ) => { > diff --git a/packages/clerk-js/src/ui/elements/Form.tsx b/packages/clerk-js/src/ui/elements/Form.tsx index c8e6a6eabee..933b09ff461 100644 --- a/packages/clerk-js/src/ui/elements/Form.tsx +++ b/packages/clerk-js/src/ui/elements/Form.tsx @@ -318,6 +318,7 @@ export const Form = { Checkbox, SubmitButton: FormSubmit, ResetButton: FormReset, + CommonInputWrapper, }; export { useFormState }; diff --git a/packages/localizations/src/ar-SA.ts b/packages/localizations/src/ar-SA.ts index 5cfc051cb19..ddfce8c95d6 100644 --- a/packages/localizations/src/ar-SA.ts +++ b/packages/localizations/src/ar-SA.ts @@ -17,6 +17,11 @@ export const arSA: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const arSA: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/be-BY.ts b/packages/localizations/src/be-BY.ts index 03d643c7f58..362dfe06a8b 100644 --- a/packages/localizations/src/be-BY.ts +++ b/packages/localizations/src/be-BY.ts @@ -17,6 +17,11 @@ export const beBY: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -222,6 +227,7 @@ export const beBY: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Увядзіце ваш нумар тэлефона', formFieldInputPlaceholder__username: 'Увядзіце імя карыстальніка', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/bg-BG.ts b/packages/localizations/src/bg-BG.ts index de9a8d6032e..2d5341cdd49 100644 --- a/packages/localizations/src/bg-BG.ts +++ b/packages/localizations/src/bg-BG.ts @@ -17,6 +17,11 @@ export const bgBG: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const bgBG: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: '+359 123 456 789', formFieldInputPlaceholder__username: 'Име на потребител', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/bn-IN.ts b/packages/localizations/src/bn-IN.ts index c9b5c1be652..003397ec730 100644 --- a/packages/localizations/src/bn-IN.ts +++ b/packages/localizations/src/bn-IN.ts @@ -17,6 +17,11 @@ export const bnIN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const bnIN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'আপনার ফোন নম্বর লিখুন', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/ca-ES.ts b/packages/localizations/src/ca-ES.ts index 8db3a976c2b..2a985277566 100644 --- a/packages/localizations/src/ca-ES.ts +++ b/packages/localizations/src/ca-ES.ts @@ -17,6 +17,11 @@ export const caES: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const caES: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Número de telèfon', formFieldInputPlaceholder__username: "Nom d'usuari", formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/cs-CZ.ts b/packages/localizations/src/cs-CZ.ts index b2eebb6594f..dcf4258baa2 100644 --- a/packages/localizations/src/cs-CZ.ts +++ b/packages/localizations/src/cs-CZ.ts @@ -17,6 +17,11 @@ export const csCZ: LocalizationResource = { apiKeys: { action__add: 'Přidat nový klíč', action__search: 'Vyhledat klíče', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Vytvořeno {{ createdDate | shortDate('cs-CZ') }} • Platí do {{ expiresDate | longDate('cs-CZ') }}", createdAndExpirationStatus__never: "Vytvořeno {{ createdDate | shortDate('cs-CZ') }} • Nikdy nevyprší", @@ -225,6 +230,7 @@ export const csCZ: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Zadejte své telefonní číslo', formFieldInputPlaceholder__username: 'Zadejte své uživatelské jméno', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Popis', formFieldLabel__apiKeyExpiration: 'Platnost', formFieldLabel__apiKeyName: 'Název tajného klíče', diff --git a/packages/localizations/src/da-DK.ts b/packages/localizations/src/da-DK.ts index b9d53e1caf5..4a2f387a1f9 100644 --- a/packages/localizations/src/da-DK.ts +++ b/packages/localizations/src/da-DK.ts @@ -17,6 +17,11 @@ export const daDK: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const daDK: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Indtast telefonnummer', formFieldInputPlaceholder__username: 'Indtast brugernavn', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/de-DE.ts b/packages/localizations/src/de-DE.ts index a3c4aa5f391..6741b64d8fa 100644 --- a/packages/localizations/src/de-DE.ts +++ b/packages/localizations/src/de-DE.ts @@ -17,6 +17,11 @@ export const deDE: LocalizationResource = { apiKeys: { action__add: 'Neuen API-Key hinzufügen', action__search: 'Suche', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Erstellt {{ createdDate | shortDate('de-DE') }} • Läuft ab {{ expiresDate | longDate('de-DE') }}", createdAndExpirationStatus__never: "Erstellt {{ createdDate | shortDate('de-DE') }} • Läuft nie ab", @@ -228,6 +233,7 @@ export const deDE: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Telefonnummer eingeben', formFieldInputPlaceholder__username: 'Benutzername eingeben', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Beschreibung', formFieldLabel__apiKeyExpiration: 'Ablaufdatum', formFieldLabel__apiKeyName: 'Name', diff --git a/packages/localizations/src/el-GR.ts b/packages/localizations/src/el-GR.ts index d855ba3491e..13436776e84 100644 --- a/packages/localizations/src/el-GR.ts +++ b/packages/localizations/src/el-GR.ts @@ -17,6 +17,11 @@ export const elGR: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const elGR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Εισάγετε τον αριθμό τηλεφώνου σας', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/en-GB.ts b/packages/localizations/src/en-GB.ts index 1bb47fc1714..f1693be414c 100644 --- a/packages/localizations/src/en-GB.ts +++ b/packages/localizations/src/en-GB.ts @@ -17,6 +17,11 @@ export const enGB: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const enGB: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Enter your phone number', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/en-US.ts b/packages/localizations/src/en-US.ts index b90d0e0ceaa..bbdae776412 100644 --- a/packages/localizations/src/en-US.ts +++ b/packages/localizations/src/en-US.ts @@ -5,6 +5,11 @@ export const enUS: LocalizationResource = { apiKeys: { action__add: 'Add new key', action__search: 'Search keys', + copySecret: { + formButtonPrimary__copyAndClose: 'Copy & Close', + formHint: "For security reasons, we won't allow you to view it again later.", + formTitle: 'Copy your "{{name}}" API Key now', + }, createdAndExpirationStatus__expiresOn: "Created {{ createdDate | shortDate('en-US') }} • Expires {{ expiresDate | longDate('en-US') }}", createdAndExpirationStatus__never: "Created {{ createdDate | shortDate('en-US') }} • Never expires", @@ -215,6 +220,7 @@ export const enUS: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Enter your phone number', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: 'Example format: name@example.com', + formFieldLabel__apiKey: 'API key', formFieldLabel__apiKeyDescription: 'Description', formFieldLabel__apiKeyExpiration: 'Expiration', formFieldLabel__apiKeyName: 'Secret key name', diff --git a/packages/localizations/src/es-CR.ts b/packages/localizations/src/es-CR.ts index f9ee47c2255..1dcda6457e8 100644 --- a/packages/localizations/src/es-CR.ts +++ b/packages/localizations/src/es-CR.ts @@ -17,6 +17,11 @@ export const esCR: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -222,6 +227,7 @@ export const esCR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Ingresa tu número de teléfono', formFieldInputPlaceholder__username: 'Ingresa tu nombre de usuario', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/es-ES.ts b/packages/localizations/src/es-ES.ts index cd96d77e671..0d9dbc2cfeb 100644 --- a/packages/localizations/src/es-ES.ts +++ b/packages/localizations/src/es-ES.ts @@ -17,6 +17,11 @@ export const esES: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const esES: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Ingrese su número telefónico', formFieldInputPlaceholder__username: 'Ingrese su nombre de usuario', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/es-MX.ts b/packages/localizations/src/es-MX.ts index ea8e8e567de..ec281e2f94a 100644 --- a/packages/localizations/src/es-MX.ts +++ b/packages/localizations/src/es-MX.ts @@ -17,6 +17,11 @@ export const esMX: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -223,6 +228,7 @@ export const esMX: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Ingresa tu número de teléfono', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/es-UY.ts b/packages/localizations/src/es-UY.ts index 7ba2589b35c..6c3bfdb1e18 100644 --- a/packages/localizations/src/es-UY.ts +++ b/packages/localizations/src/es-UY.ts @@ -17,6 +17,11 @@ export const esUY: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -222,6 +227,7 @@ export const esUY: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Ingresá tu número de teléfono', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/fa-IR.ts b/packages/localizations/src/fa-IR.ts index 94dcd77068e..2dd36bb91d5 100644 --- a/packages/localizations/src/fa-IR.ts +++ b/packages/localizations/src/fa-IR.ts @@ -17,6 +17,11 @@ export const faIR: LocalizationResource = { apiKeys: { action__add: 'افزودن کلید جدید', action__search: 'جستجوی کلیدها', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "ایجاد شده {{ createdDate | shortDate('en-US') }} • منقضی می‌شود {{ expiresDate | longDate('en-US') }}", createdAndExpirationStatus__never: "ایجاد شده {{ createdDate | shortDate('en-US') }} • هرگز منقضی نمی‌شود", @@ -226,6 +231,7 @@ export const faIR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'شماره تلفن خود را وارد کنید', formFieldInputPlaceholder__username: 'نام کاربری خود را وارد کنید', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'توضیحات کلید API', formFieldLabel__apiKeyExpiration: 'انقضای کلید API', formFieldLabel__apiKeyName: 'نام کلید API', diff --git a/packages/localizations/src/fi-FI.ts b/packages/localizations/src/fi-FI.ts index 83165454c7d..cce8aa8f034 100644 --- a/packages/localizations/src/fi-FI.ts +++ b/packages/localizations/src/fi-FI.ts @@ -17,6 +17,11 @@ export const fiFI: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const fiFI: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/fr-FR.ts b/packages/localizations/src/fr-FR.ts index 4b4786ba300..811abeac018 100644 --- a/packages/localizations/src/fr-FR.ts +++ b/packages/localizations/src/fr-FR.ts @@ -17,6 +17,11 @@ export const frFR: LocalizationResource = { apiKeys: { action__add: 'Ajouter une nouvelle clé', action__search: 'Rechercher des clés', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Créée le {{ createdDate | shortDate('fr-FR') }} • Expire le {{ expiresDate | longDate('fr-FR') }}", createdAndExpirationStatus__never: "Créée le {{ createdDate | shortDate('fr-FR') }} • N’expire jamais", @@ -229,6 +234,7 @@ export const frFR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Numéro de téléphone', formFieldInputPlaceholder__username: "Nom d'utilisateur", formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Description', formFieldLabel__apiKeyExpiration: 'Expiration', formFieldLabel__apiKeyName: 'Nom de la clé secrète', diff --git a/packages/localizations/src/he-IL.ts b/packages/localizations/src/he-IL.ts index bafeb6b48bc..03aa2f4ac0c 100644 --- a/packages/localizations/src/he-IL.ts +++ b/packages/localizations/src/he-IL.ts @@ -17,6 +17,11 @@ export const heIL: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const heIL: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/hi-IN.ts b/packages/localizations/src/hi-IN.ts index 3833e71324e..e13be29a787 100644 --- a/packages/localizations/src/hi-IN.ts +++ b/packages/localizations/src/hi-IN.ts @@ -17,6 +17,11 @@ export const hiIN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const hiIN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'अपना फोन नंबर दर्ज करें', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/hr-HR.ts b/packages/localizations/src/hr-HR.ts index 58a90e7716c..6b53fa0be66 100644 --- a/packages/localizations/src/hr-HR.ts +++ b/packages/localizations/src/hr-HR.ts @@ -17,6 +17,11 @@ export const hrHR: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const hrHR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/hu-HU.ts b/packages/localizations/src/hu-HU.ts index 418061289e7..31f6865e92e 100644 --- a/packages/localizations/src/hu-HU.ts +++ b/packages/localizations/src/hu-HU.ts @@ -17,6 +17,11 @@ export const huHU: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const huHU: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/id-ID.ts b/packages/localizations/src/id-ID.ts index 47ce2c06460..5d81cf2d6d0 100644 --- a/packages/localizations/src/id-ID.ts +++ b/packages/localizations/src/id-ID.ts @@ -17,6 +17,11 @@ export const idID: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const idID: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/is-IS.ts b/packages/localizations/src/is-IS.ts index ea467ec3a15..624459cdf52 100644 --- a/packages/localizations/src/is-IS.ts +++ b/packages/localizations/src/is-IS.ts @@ -17,6 +17,11 @@ export const isIS: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const isIS: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/it-IT.ts b/packages/localizations/src/it-IT.ts index 3884fb9d015..164694d4693 100644 --- a/packages/localizations/src/it-IT.ts +++ b/packages/localizations/src/it-IT.ts @@ -17,6 +17,11 @@ export const itIT: LocalizationResource = { apiKeys: { action__add: 'Aggiungi nuova chiave', action__search: 'Cerca chiavi', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Creata {{ createdDate | shortDate('it-IT') }} • Scadenza {{ expiresDate | longDate('it-IT') }}", createdAndExpirationStatus__never: "Creata {{ createdDate | shortDate('it-IT') }} • Nessuna scadenza", @@ -228,6 +233,7 @@ export const itIT: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Inserisci il numero di telefono', formFieldInputPlaceholder__username: 'Inserisci il nome utente', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Descrizione', formFieldLabel__apiKeyExpiration: 'Scadenza', formFieldLabel__apiKeyName: 'Nome chiave segreta', diff --git a/packages/localizations/src/ja-JP.ts b/packages/localizations/src/ja-JP.ts index 1c1ffb8332e..2349e4e06f0 100644 --- a/packages/localizations/src/ja-JP.ts +++ b/packages/localizations/src/ja-JP.ts @@ -17,6 +17,11 @@ export const jaJP: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const jaJP: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: '電話番号', formFieldInputPlaceholder__username: 'ユーザー名', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/kk-KZ.ts b/packages/localizations/src/kk-KZ.ts index 068de91d5e5..2626d1c0f56 100644 --- a/packages/localizations/src/kk-KZ.ts +++ b/packages/localizations/src/kk-KZ.ts @@ -17,6 +17,11 @@ export const kkKZ: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const kkKZ: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Телефон нөмірін енгізіңіз', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/ko-KR.ts b/packages/localizations/src/ko-KR.ts index 838673b18eb..f2570074ced 100644 --- a/packages/localizations/src/ko-KR.ts +++ b/packages/localizations/src/ko-KR.ts @@ -17,6 +17,11 @@ export const koKR: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const koKR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/mn-MN.ts b/packages/localizations/src/mn-MN.ts index 12e82ff7754..7cd2430bedf 100644 --- a/packages/localizations/src/mn-MN.ts +++ b/packages/localizations/src/mn-MN.ts @@ -17,6 +17,11 @@ export const mnMN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const mnMN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Утасны дугаар', formFieldInputPlaceholder__username: 'Хэрэглэгчийн нэр', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/ms-MY.ts b/packages/localizations/src/ms-MY.ts index f16949701c4..ff825f68c67 100644 --- a/packages/localizations/src/ms-MY.ts +++ b/packages/localizations/src/ms-MY.ts @@ -17,6 +17,11 @@ export const msMY: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const msMY: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Masukkan nombor telefon anda', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/nb-NO.ts b/packages/localizations/src/nb-NO.ts index 1f62712339c..92da1fd5ec5 100644 --- a/packages/localizations/src/nb-NO.ts +++ b/packages/localizations/src/nb-NO.ts @@ -17,6 +17,11 @@ export const nbNO: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const nbNO: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/nl-BE.ts b/packages/localizations/src/nl-BE.ts index a0f90efdb06..1fe853a6d6f 100644 --- a/packages/localizations/src/nl-BE.ts +++ b/packages/localizations/src/nl-BE.ts @@ -17,6 +17,11 @@ export const nlBE: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const nlBE: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Telefoonnummer', formFieldInputPlaceholder__username: 'Gebruikersnaam', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/nl-NL.ts b/packages/localizations/src/nl-NL.ts index 4d1fb941e32..6afcabc5b7a 100644 --- a/packages/localizations/src/nl-NL.ts +++ b/packages/localizations/src/nl-NL.ts @@ -17,6 +17,11 @@ export const nlNL: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const nlNL: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Telefoonnummer', formFieldInputPlaceholder__username: 'Gebruikersnaam', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/pl-PL.ts b/packages/localizations/src/pl-PL.ts index 12a9f612fa1..8e2d5c7f2cb 100644 --- a/packages/localizations/src/pl-PL.ts +++ b/packages/localizations/src/pl-PL.ts @@ -17,6 +17,11 @@ export const plPL: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const plPL: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Wprowadź numer telefonu', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/pt-BR.ts b/packages/localizations/src/pt-BR.ts index 3610071e2f6..7eb391e3651 100644 --- a/packages/localizations/src/pt-BR.ts +++ b/packages/localizations/src/pt-BR.ts @@ -17,6 +17,11 @@ export const ptBR: LocalizationResource = { apiKeys: { action__add: 'Adicionar nova chave', action__search: 'Pesquisar chaves', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Criada {{ createdDate | shortDate('pt-BR') }} • Expira {{ expiresDate | longDate('pt-BR') }}", createdAndExpirationStatus__never: "Criada {{ createdDate | shortDate('pt-BR') }} • Nunca expira", @@ -227,6 +232,7 @@ export const ptBR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Digite seu número de telefone', formFieldInputPlaceholder__username: 'Digite seu nome de usuário', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Descrição', formFieldLabel__apiKeyExpiration: 'Expiração', formFieldLabel__apiKeyName: 'Nome da chave de API', diff --git a/packages/localizations/src/pt-PT.ts b/packages/localizations/src/pt-PT.ts index 01557b78d99..88ac4a21dce 100644 --- a/packages/localizations/src/pt-PT.ts +++ b/packages/localizations/src/pt-PT.ts @@ -17,6 +17,11 @@ export const ptPT: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const ptPT: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Insira o seu número de telefone', formFieldInputPlaceholder__username: 'Insira o seu nome de utilizador', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/ro-RO.ts b/packages/localizations/src/ro-RO.ts index 228d14347ec..d03b52c582c 100644 --- a/packages/localizations/src/ro-RO.ts +++ b/packages/localizations/src/ro-RO.ts @@ -17,6 +17,11 @@ export const roRO: LocalizationResource = { apiKeys: { action__add: 'Adaugă cheie nouă', action__search: 'Caută chei', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Creată {{ createdDate | shortDate('ro-RO') }} • Expiră {{ expiresDate | longDate('ro-RO') }}", createdAndExpirationStatus__never: "Creată {{ createdDate | shortDate('ro-RO') }} • Nu expiră niciodată", @@ -227,6 +232,7 @@ export const roRO: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Introdu numărul de telefon', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Descriere', formFieldLabel__apiKeyExpiration: 'Expirare', formFieldLabel__apiKeyName: 'Numele cheii secrete', diff --git a/packages/localizations/src/ru-RU.ts b/packages/localizations/src/ru-RU.ts index e5bc9d4f560..dd7cf02fa80 100644 --- a/packages/localizations/src/ru-RU.ts +++ b/packages/localizations/src/ru-RU.ts @@ -17,6 +17,11 @@ export const ruRU: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -223,6 +228,7 @@ export const ruRU: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Введите ваш номер телефона', formFieldInputPlaceholder__username: 'Имя пользователя', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/sk-SK.ts b/packages/localizations/src/sk-SK.ts index f2a6e18b8f9..1ec05da0145 100644 --- a/packages/localizations/src/sk-SK.ts +++ b/packages/localizations/src/sk-SK.ts @@ -17,6 +17,11 @@ export const skSK: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const skSK: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Zadajte telefónne číslo', formFieldInputPlaceholder__username: 'Zadajte užívateľské meno', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/sr-RS.ts b/packages/localizations/src/sr-RS.ts index b5c07d15e49..23a5b63b107 100644 --- a/packages/localizations/src/sr-RS.ts +++ b/packages/localizations/src/sr-RS.ts @@ -17,6 +17,11 @@ export const srRS: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const srRS: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/sv-SE.ts b/packages/localizations/src/sv-SE.ts index b24f5af276d..8c4ddeb8854 100644 --- a/packages/localizations/src/sv-SE.ts +++ b/packages/localizations/src/sv-SE.ts @@ -17,6 +17,11 @@ export const svSE: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const svSE: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Ange ditt telefonnummer', formFieldInputPlaceholder__username: 'Ange ditt användarnamn', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/ta-IN.ts b/packages/localizations/src/ta-IN.ts index 3c0d6b0efc2..e1239846b6b 100644 --- a/packages/localizations/src/ta-IN.ts +++ b/packages/localizations/src/ta-IN.ts @@ -17,6 +17,11 @@ export const taIN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const taIN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'உங்கள் தொலைபேசி எண்ணை உள்ளிடவும்', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/te-IN.ts b/packages/localizations/src/te-IN.ts index 46a53b09c12..2df972bd463 100644 --- a/packages/localizations/src/te-IN.ts +++ b/packages/localizations/src/te-IN.ts @@ -17,6 +17,11 @@ export const teIN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const teIN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'మీ ఫోన్ నంబర్‌ను నమోదు చేయండి', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/th-TH.ts b/packages/localizations/src/th-TH.ts index 3afbc1429bf..8ae2fadeb49 100644 --- a/packages/localizations/src/th-TH.ts +++ b/packages/localizations/src/th-TH.ts @@ -17,6 +17,11 @@ export const thTH: LocalizationResource = { apiKeys: { action__add: 'เพิ่มคีย์ใหม่', action__search: 'ค้นหาคีย์', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "สร้างเมื่อ {{ createdDate | shortDate('th-TH') }} • หมดอายุ {{ expiresDate | longDate('th-TH') }}", createdAndExpirationStatus__never: "สร้างเมื่อ {{ createdDate | shortDate('th-TH') }} • ไม่มีวันหมดอายุ", @@ -224,6 +229,7 @@ export const thTH: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'ใส่หมายเลขโทรศัพท์ของคุณ', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'คำอธิบาย', formFieldLabel__apiKeyExpiration: 'วันหมดอายุ', formFieldLabel__apiKeyName: 'ชื่อคีย์ลับ', diff --git a/packages/localizations/src/tr-TR.ts b/packages/localizations/src/tr-TR.ts index 8988be4a259..f3e6633983f 100644 --- a/packages/localizations/src/tr-TR.ts +++ b/packages/localizations/src/tr-TR.ts @@ -17,6 +17,11 @@ export const trTR: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const trTR: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Telefon numaranızı girin', formFieldInputPlaceholder__username: 'Kullanıcı adınızı girin', formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/uk-UA.ts b/packages/localizations/src/uk-UA.ts index 9873a6b7fbc..cf0ad8c38c6 100644 --- a/packages/localizations/src/uk-UA.ts +++ b/packages/localizations/src/uk-UA.ts @@ -17,6 +17,11 @@ export const ukUA: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -221,6 +226,7 @@ export const ukUA: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/vi-VN.ts b/packages/localizations/src/vi-VN.ts index 921d8a60d31..1bb314ac13e 100644 --- a/packages/localizations/src/vi-VN.ts +++ b/packages/localizations/src/vi-VN.ts @@ -17,6 +17,11 @@ export const viVN: LocalizationResource = { apiKeys: { action__add: 'Thêm khoá mới', action__search: 'Tìm kiếm khoá', + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: "Tạo {{ createdDate | shortDate('vi-VN') }} • Hết hạn {{ expiresDate | longDate('vi-VN') }}", createdAndExpirationStatus__never: "Tạo {{ createdDate | shortDate('vi-VN') }} • Không hết hạn", @@ -225,6 +230,7 @@ export const viVN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: 'Nhập số điện thoại của bạn', formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: 'Mô tả', formFieldLabel__apiKeyExpiration: 'Hết hạn', formFieldLabel__apiKeyName: 'Tên khoá bí mật', diff --git a/packages/localizations/src/zh-CN.ts b/packages/localizations/src/zh-CN.ts index f716b64ec69..3d2cd2ec7f5 100644 --- a/packages/localizations/src/zh-CN.ts +++ b/packages/localizations/src/zh-CN.ts @@ -17,6 +17,11 @@ export const zhCN: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const zhCN: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/localizations/src/zh-TW.ts b/packages/localizations/src/zh-TW.ts index 7588dfd7e6e..d33538ac930 100644 --- a/packages/localizations/src/zh-TW.ts +++ b/packages/localizations/src/zh-TW.ts @@ -17,6 +17,11 @@ export const zhTW: LocalizationResource = { apiKeys: { action__add: undefined, action__search: undefined, + copySecret: { + formButtonPrimary__copyAndClose: undefined, + formHint: undefined, + formTitle: undefined, + }, createdAndExpirationStatus__expiresOn: undefined, createdAndExpirationStatus__never: undefined, detailsTitle__emptyRow: undefined, @@ -220,6 +225,7 @@ export const zhTW: LocalizationResource = { formFieldInputPlaceholder__phoneNumber: undefined, formFieldInputPlaceholder__username: undefined, formFieldInput__emailAddress_format: undefined, + formFieldLabel__apiKey: undefined, formFieldLabel__apiKeyDescription: undefined, formFieldLabel__apiKeyExpiration: undefined, formFieldLabel__apiKeyName: undefined, diff --git a/packages/shared/src/types/apiKeys.ts b/packages/shared/src/types/apiKeys.ts index 7074a7c3571..3d2dc84a27b 100644 --- a/packages/shared/src/types/apiKeys.ts +++ b/packages/shared/src/types/apiKeys.ts @@ -14,6 +14,7 @@ export interface APIKeyResource extends ClerkResource { expiration: Date | null; createdBy: string | null; description: string | null; + secret?: string; lastUsedAt: Date | null; createdAt: Date; updatedAt: Date; @@ -26,12 +27,6 @@ export interface APIKeysNamespace { * Retrieves all API keys for the current user or organization. */ getAll(params?: GetAPIKeysParams): Promise; - /** - * @experimental This API is in early access and may change in future releases. - * - * Retrieves the secret for a given API key ID. - */ - getSecret(id: string): Promise; /** * @experimental This API is in early access and may change in future releases. * diff --git a/packages/shared/src/types/appearance.ts b/packages/shared/src/types/appearance.ts index b4f1d00c36e..7f0cb4f32fd 100644 --- a/packages/shared/src/types/appearance.ts +++ b/packages/shared/src/types/appearance.ts @@ -630,6 +630,9 @@ export type ElementsConfig = { apiKeysRevokeModal: WithOptions; apiKeysRevokeModalInput: WithOptions; apiKeysRevokeModalSubmitButton: WithOptions; + apiKeysCopyModal: WithOptions; + apiKeysCopyModalInput: WithOptions; + apiKeysCopyModalSubmitButton: WithOptions; subscriptionDetailsCard: WithOptions; subscriptionDetailsCardHeader: WithOptions; diff --git a/packages/shared/src/types/clerk.ts b/packages/shared/src/types/clerk.ts index a8fc6103bc9..d2336044eaf 100644 --- a/packages/shared/src/types/clerk.ts +++ b/packages/shared/src/types/clerk.ts @@ -249,6 +249,7 @@ export interface Clerk { /** * Signs out the current user on single-session instances, or all users on multi-session instances + * * @param signOutCallback - Optional A callback that runs after sign out completes. * @param options - Optional Configuration options, see {@link SignOutOptions} * @returns A promise that resolves when the sign out process completes. @@ -257,7 +258,8 @@ export interface Clerk { /** * Opens the Clerk SignIn component in a modal. - * @param props Optional sign in configuration parameters. + * + * @param props - Optional sign in configuration parameters. */ openSignIn: (props?: SignInModalProps) => void; @@ -268,7 +270,8 @@ export interface Clerk { /** * Opens the Clerk Checkout component in a drawer. - * @param props Optional checkout configuration parameters. + * + * @param props - Optional checkout configuration parameters. */ __internal_openCheckout: (props?: __internal_CheckoutProps) => void; @@ -279,7 +282,8 @@ export interface Clerk { /** * Opens the Clerk PlanDetails drawer component in a drawer. - * @param props `plan` or `planId` parameters are required. + * + * @param props - `plan` or `planId` parameters are required. */ __internal_openPlanDetails: (props: __internal_PlanDetailsProps) => void; @@ -290,7 +294,8 @@ export interface Clerk { /** * Opens the Clerk SubscriptionDetails drawer component in a drawer. - * @param props Optional configuration parameters. + * + * @param props - Optional configuration parameters. */ __internal_openSubscriptionDetails: (props?: __internal_SubscriptionDetailsProps) => void; @@ -301,7 +306,8 @@ export interface Clerk { /** * Opens the Clerk UserVerification component in a modal. - * @param props Optional user verification configuration parameters. + * + * @param props - Optional user verification configuration parameters. */ __internal_openReverification: (props?: __internal_UserVerificationModalProps) => void; @@ -312,7 +318,8 @@ export interface Clerk { /** * Opens the Google One Tap component. - * @param props Optional props that will be passed to the GoogleOneTap component. + * + * @param props - Optional props that will be passed to the GoogleOneTap component. */ openGoogleOneTap: (props?: GoogleOneTapProps) => void; @@ -324,7 +331,8 @@ export interface Clerk { /** * Opens the Clerk SignUp component in a modal. - * @param props Optional props that will be passed to the SignUp component. + * + * @param props - Optional props that will be passed to the SignUp component. */ openSignUp: (props?: SignUpModalProps) => void; @@ -335,7 +343,8 @@ export interface Clerk { /** * Opens the Clerk UserProfile modal. - * @param props Optional props that will be passed to the UserProfile component. + * + * @param props - Optional props that will be passed to the UserProfile component. */ openUserProfile: (props?: UserProfileModalProps) => void; @@ -346,7 +355,8 @@ export interface Clerk { /** * Opens the Clerk OrganizationProfile modal. - * @param props Optional props that will be passed to the OrganizationProfile component. + * + * @param props - Optional props that will be passed to the OrganizationProfile component. */ openOrganizationProfile: (props?: OrganizationProfileModalProps) => void; @@ -357,7 +367,8 @@ export interface Clerk { /** * Opens the Clerk CreateOrganization modal. - * @param props Optional props that will be passed to the CreateOrganization component. + * + * @param props - Optional props that will be passed to the CreateOrganization component. */ openCreateOrganization: (props?: CreateOrganizationModalProps) => void; @@ -368,7 +379,8 @@ export interface Clerk { /** * Opens the Clerk Waitlist modal. - * @param props Optional props that will be passed to the Waitlist component. + * + * @param props - Optional props that will be passed to the Waitlist component. */ openWaitlist: (props?: WaitlistModalProps) => void; @@ -379,8 +391,9 @@ export interface Clerk { /** * Mounts a sign in flow component at the target element. - * @param targetNode Target node to mount the SignIn component. - * @param signInProps sign in configuration parameters. + * + * @param targetNode - Target node to mount the SignIn component. + * @param signInProps - sign in configuration parameters. */ mountSignIn: (targetNode: HTMLDivElement, signInProps?: SignInProps) => void; @@ -388,15 +401,15 @@ export interface Clerk { * Unmount a sign in flow component from the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the SignIn component from. + * @param targetNode - Target node to unmount the SignIn component from. */ unmountSignIn: (targetNode: HTMLDivElement) => void; /** * Mounts a sign up flow component at the target element. * - * @param targetNode Target node to mount the SignUp component. - * @param signUpProps sign up configuration parameters. + * @param targetNode - Target node to mount the SignUp component. + * @param signUpProps - sign up configuration parameters. */ mountSignUp: (targetNode: HTMLDivElement, signUpProps?: SignUpProps) => void; @@ -404,14 +417,14 @@ export interface Clerk { * Unmount a sign up flow component from the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the SignUp component from. + * @param targetNode - Target node to unmount the SignUp component from. */ unmountSignUp: (targetNode: HTMLDivElement) => void; /** * Mount a user avatar component at the target element. * - * @param targetNode Target node to mount the UserAvatar component. + * @param targetNode - Target node to mount the UserAvatar component. */ mountUserAvatar: (targetNode: HTMLDivElement, userAvatarProps?: UserAvatarProps) => void; @@ -419,15 +432,15 @@ export interface Clerk { * Unmount a user avatar component at the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the UserAvatar component from. + * @param targetNode - Target node to unmount the UserAvatar component from. */ unmountUserAvatar: (targetNode: HTMLDivElement) => void; /** * Mount a user button component at the target element. * - * @param targetNode Target node to mount the UserButton component. - * @param userButtonProps User button configuration parameters. + * @param targetNode - Target node to mount the UserButton component. + * @param userButtonProps - User button configuration parameters. */ mountUserButton: (targetNode: HTMLDivElement, userButtonProps?: UserButtonProps) => void; @@ -435,15 +448,15 @@ export interface Clerk { * Unmount a user button component at the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the UserButton component from. + * @param targetNode - Target node to unmount the UserButton component from. */ unmountUserButton: (targetNode: HTMLDivElement) => void; /** * Mount a user profile component at the target element. * - * @param targetNode Target to mount the UserProfile component. - * @param userProfileProps User profile configuration parameters. + * @param targetNode - Target to mount the UserProfile component. + * @param userProfileProps - User profile configuration parameters. */ mountUserProfile: (targetNode: HTMLDivElement, userProfileProps?: UserProfileProps) => void; @@ -451,46 +464,52 @@ export interface Clerk { * Unmount a user profile component at the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the UserProfile component from. + * @param targetNode - Target node to unmount the UserProfile component from. */ unmountUserProfile: (targetNode: HTMLDivElement) => void; /** * Mount an organization profile component at the target element. - * @param targetNode Target to mount the OrganizationProfile component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the OrganizationProfile component. + * @param props - Configuration parameters. */ mountOrganizationProfile: (targetNode: HTMLDivElement, props?: OrganizationProfileProps) => void; /** * Unmount the organization profile component from the target node. - * @param targetNode Target node to unmount the OrganizationProfile component from. + * + * @param targetNode - Target node to unmount the OrganizationProfile component from. */ unmountOrganizationProfile: (targetNode: HTMLDivElement) => void; /** * Mount a CreateOrganization component at the target element. - * @param targetNode Target to mount the CreateOrganization component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the CreateOrganization component. + * @param props - Configuration parameters. */ mountCreateOrganization: (targetNode: HTMLDivElement, props?: CreateOrganizationProps) => void; /** * Unmount the CreateOrganization component from the target node. - * @param targetNode Target node to unmount the CreateOrganization component from. + * + * @param targetNode - Target node to unmount the CreateOrganization component from. */ unmountCreateOrganization: (targetNode: HTMLDivElement) => void; /** * Mount an organization switcher component at the target element. - * @param targetNode Target to mount the OrganizationSwitcher component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the OrganizationSwitcher component. + * @param props - Configuration parameters. */ mountOrganizationSwitcher: (targetNode: HTMLDivElement, props?: OrganizationSwitcherProps) => void; /** * Unmount the organization profile component from the target node.* - * @param targetNode Target node to unmount the OrganizationSwitcher component from. + * + * @param targetNode - Target node to unmount the OrganizationSwitcher component from. */ unmountOrganizationSwitcher: (targetNode: HTMLDivElement) => void; @@ -499,40 +518,46 @@ export interface Clerk { * It can be used when `mountOrganizationSwitcher({ asStandalone: true})`, to avoid unwanted loading states. * * @experimental This experimental API is subject to change. - * @param props Optional user verification configuration parameters. + * + * @param props - Optional user verification configuration parameters. */ __experimental_prefetchOrganizationSwitcher: () => void; /** * Mount an organization list component at the target element. - * @param targetNode Target to mount the OrganizationList component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the OrganizationList component. + * @param props - Configuration parameters. */ mountOrganizationList: (targetNode: HTMLDivElement, props?: OrganizationListProps) => void; /** * Unmount the organization list component from the target node.* - * @param targetNode Target node to unmount the OrganizationList component from. + * + * @param targetNode - Target node to unmount the OrganizationList component from. */ unmountOrganizationList: (targetNode: HTMLDivElement) => void; /** * Mount a waitlist at the target element. - * @param targetNode Target to mount the Waitlist component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the Waitlist component. + * @param props - Configuration parameters. */ mountWaitlist: (targetNode: HTMLDivElement, props?: WaitlistProps) => void; /** * Unmount the Waitlist component from the target node. - * @param targetNode Target node to unmount the Waitlist component from. + * + * @param targetNode - Target node to unmount the Waitlist component from. */ unmountWaitlist: (targetNode: HTMLDivElement) => void; /** * Mounts a pricing table component at the target element. - * @param targetNode Target node to mount the PricingTable component. - * @param props configuration parameters. + * + * @param targetNode - Target node to mount the PricingTable component. + * @param props - configuration parameters. */ mountPricingTable: (targetNode: HTMLDivElement, props?: PricingTableProps) => void; @@ -540,7 +565,7 @@ export interface Clerk { * Unmount a pricing table component from the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the PricingTable component from. + * @param targetNode - Target node to unmount the PricingTable component from. */ unmountPricingTable: (targetNode: HTMLDivElement) => void; @@ -548,9 +573,11 @@ export interface Clerk { * This API is in early access and may change in future releases. * * Mount a api keys component at the target element. + * * @experimental - * @param targetNode Target to mount the APIKeys component. - * @param props Configuration parameters. + * + * @param targetNode - Target to mount the APIKeys component. + * @param props - Configuration parameters. */ mountApiKeys: (targetNode: HTMLDivElement, props?: APIKeysProps) => void; @@ -559,28 +586,33 @@ export interface Clerk { * * Unmount a api keys component from the target element. * If there is no component mounted at the target node, results in a noop. + * * @experimental - * @param targetNode Target node to unmount the ApiKeys component from. + * + * @param targetNode - Target node to unmount the ApiKeys component from. */ unmountApiKeys: (targetNode: HTMLDivElement) => void; /** * Mounts a OAuth consent component at the target element. - * @param targetNode Target node to mount the OAuth consent component. - * @param oauthConsentProps OAuth consent configuration parameters. + * + * @param targetNode - Target node to mount the OAuth consent component. + * @param oauthConsentProps - OAuth consent configuration parameters. */ __internal_mountOAuthConsent: (targetNode: HTMLDivElement, oauthConsentProps?: __internal_OAuthConsentProps) => void; /** * Unmounts a OAuth consent component from the target element. - * @param targetNode Target node to unmount the OAuth consent component from. + * + * @param targetNode - Target node to unmount the OAuth consent component from. */ __internal_unmountOAuthConsent: (targetNode: HTMLDivElement) => void; /** * Mounts a TaskChooseOrganization component at the target element. - * @param targetNode Target node to mount the TaskChooseOrganization component. - * @param props configuration parameters. + * + * @param targetNode - Target node to mount the TaskChooseOrganization component. + * @param props - configuration parameters. */ mountTaskChooseOrganization: (targetNode: HTMLDivElement, props?: TaskChooseOrganizationProps) => void; @@ -588,7 +620,7 @@ export interface Clerk { * Unmount a TaskChooseOrganization component from the target element. * If there is no component mounted at the target node, results in a noop. * - * @param targetNode Target node to unmount the TaskChooseOrganization component from. + * @param targetNode - Target node to unmount the TaskChooseOrganization component from. */ unmountTaskChooseOrganization: (targetNode: HTMLDivElement) => void; @@ -607,13 +639,14 @@ export interface Clerk { * When there is no active session, user and session will both be null. * When a session is loading, user and session will be undefined. * - * @param callback Callback function receiving the most updated Clerk resources after a change. + * @param callback - Callback function receiving the most updated Clerk resources after a change. * @returns - Unsubscribe callback */ addListener: (callback: ListenerCallback) => UnsubscribeCallback; /** * Registers an event handler for a specific Clerk event. + * * @param event - The event name to subscribe to * @param handler - The callback function to execute when the event is dispatched * @param opt - Optional configuration object @@ -623,6 +656,7 @@ export interface Clerk { /** * Removes an event handler for a specific Clerk event. + * * @param event - The event name to unsubscribe from * @param handler - The callback function to remove */ @@ -631,6 +665,7 @@ export interface Clerk { /** * Registers an internal listener that triggers a callback each time `Clerk.navigate` is called. * Its purpose is to notify modal UI components when a navigation event occurs, allowing them to close if necessary. + * * @internal */ __internal_addNavigationListener: (callback: () => void) => UnsubscribeCallback; @@ -651,21 +686,21 @@ export interface Clerk { /** * Decorates the provided url with the auth token for development instances. * - * @param {string} to + * @param to */ buildUrlWithAuth(to: string): string; /** * Returns the configured url where `` is mounted or a custom sign-in page is rendered. * - * @param opts A {@link RedirectOptions} object + * @param opts - A {@link RedirectOptions} object */ buildSignInUrl(opts?: RedirectOptions): string; /** * Returns the configured url where `` is mounted or a custom sign-up page is rendered. * - * @param opts A {@link RedirectOptions} object + * @param opts - A {@link RedirectOptions} object */ buildSignUpUrl(opts?: RedirectOptions): string; @@ -723,21 +758,21 @@ export interface Clerk { * * Redirects to the provided url after decorating it with the auth token for development instances. * - * @param {string} to + * @param to */ redirectWithAuth(to: string): Promise; /** * Redirects to the configured URL where `` is mounted. * - * @param opts A {@link RedirectOptions} object + * @param opts - A {@link RedirectOptions} object */ redirectToSignIn(opts?: SignInRedirectOptions): Promise; /** * Redirects to the configured URL where `` is mounted. * - * @param opts A {@link RedirectOptions} object + * @param opts - A {@link RedirectOptions} object */ redirectToSignUp(opts?: SignUpRedirectOptions): Promise; @@ -779,7 +814,7 @@ export interface Clerk { /** * Redirects to the configured URL where tasks are mounted. * - * @param opts A {@link RedirectOptions} object + * @param opts - A {@link RedirectOptions} object */ redirectToTasks(opts?: TasksRedirectOptions): Promise; @@ -862,6 +897,7 @@ export interface Clerk { /** * This is an optional function. * This function is used to load cached Client and Environment resources if Clerk fails to load them from the Frontend API. + * * @internal */ __internal_getCachedResources: @@ -870,6 +906,7 @@ export interface Clerk { /** * This function is used to reload the initial resources (Environment/Client) from the Frontend API. + * * @internal */ __internal_reloadInitialResources: () => Promise; @@ -882,6 +919,7 @@ export interface Clerk { /** * API Keys Object + * * @experimental * This API is in early access and may change in future releases. */ @@ -889,6 +927,7 @@ export interface Clerk { /** * Checkout API + * * @experimental * This API is in early access and may change in future releases. */ @@ -1052,6 +1091,7 @@ export type ClerkOptions = ClerkOptionsNavigation & debug?: boolean; /** * If false, the sampling rates provided per telemetry event will be ignored and all events will be sent. + * * @default true */ perEventSampling?: boolean; @@ -1072,6 +1112,7 @@ export type ClerkOptions = ClerkOptionsNavigation & { /** * Persist the Clerk client to match the user's device with a client. + * * @default true */ persistClient: boolean; @@ -1086,12 +1127,14 @@ export type ClerkOptions = ClerkOptionsNavigation & /** * The URL a developer should be redirected to in order to claim an instance created in Keyless mode. + * * @internal */ __internal_keyless_claimKeylessApplicationUrl?: string; /** * After a developer has claimed their instance created by Keyless mode, they can use this URL to find their instance's keys + * * @internal */ __internal_keyless_copyInstanceKeysUrl?: string; @@ -1099,6 +1142,7 @@ export type ClerkOptions = ClerkOptionsNavigation & /** * Pass a function that will trigger the unmounting of the Keyless Prompt. * It should cause the values of `__internal_claimKeylessApplicationUrl` and `__internal_copyInstanceKeysUrl` to become undefined. + * * @internal */ __internal_keyless_dismissPrompt?: (() => Promise) | null; @@ -1108,6 +1152,7 @@ export type ClerkOptions = ClerkOptionsNavigation & * session tasks need to be completed. * * When `undefined`, it uses Clerk's default task flow URLs. + * * @default undefined */ taskUrls?: Record; @@ -1213,6 +1258,7 @@ export type SignUpRedirectOptions = RedirectOptions & /** * The parameters for the `setActive()` method. + * * @interface */ export type SetActiveParams = { @@ -1276,12 +1322,14 @@ export type SignInProps = RoutingOptions & { * Full URL or path to navigate to after successful sign in. * This value has precedence over other redirect props, environment variables or search params. * Use this prop to override the redirect URL when needed. + * * @default undefined */ forceRedirectUrl?: string | null; /** * Full URL or path to navigate to after successful sign in. * This value is used when no other redirect props, environment variables or search params are present. + * * @default undefined */ fallbackRedirectUrl?: string | null; @@ -1340,6 +1388,7 @@ export interface TransferableOption { /** * Indicates whether or not sign in attempts are transferable to the sign up flow. * When set to false, prevents opaque sign ups when a user attempts to sign in via OAuth with an email that doesn't exist. + * * @default true */ transferable?: boolean; @@ -1361,6 +1410,7 @@ export type __internal_UserVerificationProps = RoutingOptions & { /** * Defines the steps of the verification flow. * When `multiFactor` is used, the user will be prompt for a first factor flow followed by a second factor flow. + * * @default `'secondFactor'` */ level?: SessionVerificationLevel; @@ -1401,12 +1451,14 @@ type GoogleOneTapRedirectUrlProps = SignInForceRedirectUrl & SignUpForceRedirect export type GoogleOneTapProps = GoogleOneTapRedirectUrlProps & { /** * Whether to cancel the Google One Tap request if a user clicks outside the prompt. + * * @default true */ cancelOnTapOutside?: boolean; /** * Enables upgraded One Tap UX on ITP browsers. * Turning this options off, would hide any One Tap UI in such browsers. + * * @default true */ itpSupport?: boolean; @@ -1414,6 +1466,7 @@ export type GoogleOneTapProps = GoogleOneTapRedirectUrlProps & { * FedCM enables more private sign-in flows without requiring the use of third-party cookies. * The browser controls user settings, displays user prompts, and only contacts an Identity Provider such as Google after explicit user consent is given. * Backwards compatible with browsers that still support third-party cookies. + * * @default true */ fedCmSupport?: boolean; @@ -1425,12 +1478,14 @@ export type SignUpProps = RoutingOptions & { * Full URL or path to navigate to after successful sign up. * This value has precedence over other redirect props, environment variables or search params. * Use this prop to override the redirect URL when needed. + * * @default undefined */ forceRedirectUrl?: string | null; /** * Full URL or path to navigate to after successful sign up. * This value is used when no other redirect props, environment variables or search params are present. + * * @default undefined */ fallbackRedirectUrl?: string | null; @@ -1496,15 +1551,18 @@ export type UserProfileProps = RoutingOptions & { customPages?: CustomPage[]; /** * Specify on which page the user profile modal will open. + * * @example __experimental_startPath: '/members' + * * @experimental - **/ + */ __experimental_startPath?: string; /** * Specify options for the underlying component. * e.g. + * * @experimental - **/ + */ apiKeysProps?: APIKeysProps; }; @@ -1513,6 +1571,7 @@ export type UserProfileModalProps = WithoutRouting; export type OrganizationProfileProps = RoutingOptions & { /** * Full URL or path to navigate to after the user leaves the currently active organization. + * * @default undefined */ afterLeaveOrganizationUrl?: string; @@ -1528,15 +1587,18 @@ export type OrganizationProfileProps = RoutingOptions & { customPages?: CustomPage[]; /** * Specify on which page the organization profile modal will open. + * * @example __experimental_startPath: '/organization-members' + * * @experimental - **/ + */ __experimental_startPath?: string; /** * Specify options for the underlying component. * e.g. + * * @experimental - **/ + */ apiKeysProps?: APIKeysProps; }; @@ -1545,6 +1607,7 @@ export type OrganizationProfileModalProps = WithoutRouting>; /** * Hides the screen for sending invitations after an organization is created. + * * @default undefined When left undefined Clerk will automatically hide the screen if * the number of max allowed members is equal to 1 */ @@ -1598,18 +1662,21 @@ export type UserButtonProps = UserButtonProfileMode & { * Enables developers to implement a custom dialog. * * @default undefined + * * @experimental This API is experimental and may change at any moment. */ __experimental_asStandalone?: boolean | ((opened: boolean) => void); /** * Full URL or path to navigate to after sign out is complete + * * @deprecated Configure `afterSignOutUrl` as a global configuration, either in `` or in `await Clerk.load()`. */ afterSignOutUrl?: string; /** * Full URL or path to navigate to after signing out the current user is complete. * This option applies to multi-session applications. + * * @deprecated Configure `afterMultiSessionSingleSignOutUrl` as a global configuration, either in `` or in `await Clerk.load()`. */ afterMultiSessionSingleSignOutUrl?: string; @@ -1673,6 +1740,7 @@ export type OrganizationSwitcherProps = CreateOrganizationMode & * Enables developers to implement a custom dialog. * * @default undefined + * * @experimental This API is experimental and may change at any moment. */ __experimental_asStandalone?: boolean | ((opened: boolean) => void); @@ -1682,17 +1750,21 @@ export type OrganizationSwitcherProps = CreateOrganizationMode & * This option controls whether OrganizationSwitcher will include the user's personal account * in the organization list. Setting this to `false` will hide the personal account entry, * and users will only be able to switch between organizations. + * * @default true */ hidePersonal?: boolean; /** * Full URL or path to navigate to after a successful organization switch. + * * @default undefined + * * @deprecated Use `afterSelectOrganizationUrl` or `afterSelectPersonalUrl`. */ afterSwitchOrganizationUrl?: string; /** * Full URL or path to navigate to after creating a new organization. + * * @default undefined */ afterCreateOrganizationUrl?: @@ -1701,6 +1773,7 @@ export type OrganizationSwitcherProps = CreateOrganizationMode & /** * Full URL or path to navigate to after a successful organization selection. * Accepts a function that returns URL or path + * * @default undefined` */ afterSelectOrganizationUrl?: @@ -1709,16 +1782,19 @@ export type OrganizationSwitcherProps = CreateOrganizationMode & /** * Full URL or path to navigate to after a successful selection of personal workspace. * Accepts a function that returns URL or path + * * @default undefined */ afterSelectPersonalUrl?: ((user: UserResource) => string) | LooseExtractedParams>; /** * Full URL or path to navigate to after the user leaves the currently active organization. + * * @default undefined */ afterLeaveOrganizationUrl?: string; /** * Hides the screen for sending invitations after an organization is created. + * * @default undefined When left undefined Clerk will automatically hide the screen if * the number of max allowed members is equal to 1 */ @@ -1745,6 +1821,7 @@ export type OrganizationSwitcherProps = CreateOrganizationMode & export type OrganizationListProps = { /** * Full URL or path to navigate to after creating a new organization. + * * @default undefined */ afterCreateOrganizationUrl?: @@ -1753,6 +1830,7 @@ export type OrganizationListProps = { /** * Full URL or path to navigate to after a successful organization selection. * Accepts a function that returns URL or path + * * @default undefined` */ afterSelectOrganizationUrl?: @@ -1766,6 +1844,7 @@ export type OrganizationListProps = { appearance?: OrganizationListTheme; /** * Hides the screen for sending invitations after an organization is created. + * * @default undefined When left undefined Clerk will automatically hide the screen if * the number of max allowed members is equal to 1 */ @@ -1775,12 +1854,14 @@ export type OrganizationListProps = { * This option controls whether OrganizationList will include the user's personal account * in the organization list. Setting this to `false` will hide the personal account entry, * and users will only be able to switch between organizations. + * * @default true */ hidePersonal?: boolean; /** * Full URL or path to navigate to after a successful selection of personal workspace. * Accepts a function that returns URL or path + * * @default undefined` */ afterSelectPersonalUrl?: ((user: UserResource) => string) | LooseExtractedParams>; @@ -1814,16 +1895,19 @@ export type WaitlistModalProps = WaitlistProps; type PricingTableDefaultProps = { /** * The position of the CTA button. + * * @default 'bottom' */ ctaPosition?: 'top' | 'bottom'; /** * Whether to collapse features on the pricing table. + * * @default false */ collapseFeatures?: boolean; /** * Full URL or path to navigate to after checkout is complete and the user clicks the "Continue" button. + * * @default undefined */ newSubscriptionRedirectUrl?: string; @@ -1833,6 +1917,7 @@ type PricingTableBaseProps = { /** * The subscriber type to display plans for. * If `organization`, show plans for the active organization; otherwise for the user. + * * @default 'user' */ for?: ForPayerType; @@ -1857,11 +1942,13 @@ export type APIKeysProps = { /** * The type of API key to filter by. * Currently, only 'api_key' is supported. + * * @default 'api_key' */ type?: 'api_key'; /** * The number of API keys to show per page. + * * @default 5 */ perPage?: number; @@ -1873,6 +1960,7 @@ export type APIKeysProps = { appearance?: APIKeysTheme; /** * Whether to show the description field in the API key creation form. + * * @default false */ showDescription?: boolean; @@ -1908,6 +1996,7 @@ export type __internal_CheckoutProps = { portalRoot?: PortalRoot; /** * Full URL or path to navigate to after checkout is complete and the user clicks the "Continue" button. + * * @default undefined */ newSubscriptionRedirectUrl?: string; @@ -1930,6 +2019,7 @@ export type __experimental_CheckoutButtonProps = { }; /** * Full URL or path to navigate to after checkout is complete and the user clicks the "Continue" button. + * * @default undefined */ newSubscriptionRedirectUrl?: string; @@ -1988,6 +2078,7 @@ export type __internal_SubscriptionDetailsProps = { /** * The subscriber type to display the subscription details for. * If `organization` is provided, the subscription details will be displayed for the active organization. + * * @default 'user' */ for?: ForPayerType; @@ -2004,6 +2095,7 @@ export type __experimental_SubscriptionDetailsButtonProps = { /** * The subscriber type to display the subscription details for. * If `organization` is provided, the subscription details will be displayed for the active organization. + * * @default 'user' */ for?: ForPayerType; diff --git a/packages/shared/src/types/elementIds.ts b/packages/shared/src/types/elementIds.ts index 50ba96df7f5..8ba40eb431c 100644 --- a/packages/shared/src/types/elementIds.ts +++ b/packages/shared/src/types/elementIds.ts @@ -24,7 +24,8 @@ export type FieldId = | 'legalAccepted' | 'apiKeyDescription' | 'apiKeyExpirationDate' - | 'apiKeyRevokeConfirmation'; + | 'apiKeyRevokeConfirmation' + | 'apiKeySecret'; export type ProfileSectionId = | 'profile' | 'username' diff --git a/packages/shared/src/types/json.ts b/packages/shared/src/types/json.ts index fe642cf1c2b..516c198c183 100644 --- a/packages/shared/src/types/json.ts +++ b/packages/shared/src/types/json.ts @@ -857,6 +857,10 @@ export interface ApiKeyJSON extends ClerkResourceJSON { expiration: number | null; created_by: string | null; description: string | null; + /** + * This property is only present in the response from `create()`. + */ + secret?: string; last_used_at: number | null; created_at: number; updated_at: number; diff --git a/packages/shared/src/types/localization.ts b/packages/shared/src/types/localization.ts index 2bf928a129a..6ee2f731fc8 100644 --- a/packages/shared/src/types/localization.ts +++ b/packages/shared/src/types/localization.ts @@ -3,6 +3,7 @@ import type { CamelToSnake, DeepPartial } from './utils'; /** * @internal + * * @example * type PageTitle = LocalizationValue<'name', 'greeting'>; * // ?^ @@ -69,6 +70,7 @@ export type __internal_LocalizationResource = { maintenanceMode: LocalizationValue; /** * Add role keys and their localized values, e.g. `roles: { 'org:teacher': 'Teacher'}`. + * * @experimental */ roles: { @@ -107,6 +109,7 @@ export type __internal_LocalizationResource = { formFieldLabel__confirmDeletion: LocalizationValue; formFieldLabel__role: LocalizationValue; formFieldLabel__passkeyName: LocalizationValue; + formFieldLabel__apiKey: LocalizationValue; formFieldLabel__apiKeyName: LocalizationValue; formFieldLabel__apiKeyDescription: LocalizationValue; formFieldLabel__apiKeyExpiration: LocalizationValue; @@ -1236,6 +1239,11 @@ export type __internal_LocalizationResource = { createdAndExpirationStatus__expiresOn: LocalizationValue<'createdDate' | 'expiresDate'>; formFieldCaption__expiration__never: LocalizationValue; formFieldCaption__expiration__expiresOn: LocalizationValue<'date'>; + copySecret: { + formTitle: LocalizationValue<'name'>; + formHint: LocalizationValue; + formButtonPrimary__copyAndClose: LocalizationValue; + }; }; taskChooseOrganization: { title: LocalizationValue; diff --git a/packages/testing/src/playwright/unstable/page-objects/apiKeys.ts b/packages/testing/src/playwright/unstable/page-objects/apiKeys.ts index 75793c26970..589c2a2f80f 100644 --- a/packages/testing/src/playwright/unstable/page-objects/apiKeys.ts +++ b/packages/testing/src/playwright/unstable/page-objects/apiKeys.ts @@ -35,6 +35,15 @@ export const createAPIKeysComponentPageObject = (testArgs: { page: EnhancedPage waitForRevokeModalClosed: () => { return page.waitForSelector('.cl-apiKeysRevokeModal', { state: 'detached' }); }, + waitForCopyModalOpened: () => { + return page.waitForSelector('.cl-apiKeysCopyModal', { state: 'attached' }); + }, + waitForCopyModalClosed: () => { + return page.waitForSelector('.cl-apiKeysCopyModal', { state: 'detached' }); + }, + clickCopyAndCloseButton: () => { + return page.locator('.cl-apiKeysCopyModal .cl-apiKeysCopyModalSubmitButton').click(); + }, typeName: (value: string) => { return page.getByLabel(/Secret key name/i).fill(value); },