diff --git a/.changeset/gold-monkeys-collect.md b/.changeset/gold-monkeys-collect.md new file mode 100644 index 0000000000..513f59c0f2 --- /dev/null +++ b/.changeset/gold-monkeys-collect.md @@ -0,0 +1,7 @@ +--- +'@clerk/clerk-js': patch +'@clerk/nextjs': patch +'@clerk/types': patch +--- + +Introduce `__internal_copyInstanceKeysUrl` as property in `ClerkOptions`. It is intented for internall usage from other Clerk SDKs and will be used in Keyless mode. diff --git a/.changeset/twelve-spiders-obey.md b/.changeset/twelve-spiders-obey.md new file mode 100644 index 0000000000..71e5b5a1bf --- /dev/null +++ b/.changeset/twelve-spiders-obey.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +Add property `api_keys_url` in the `AccountlessApplication` class diff --git a/packages/backend/src/api/resources/AccountlessApplication.ts b/packages/backend/src/api/resources/AccountlessApplication.ts index e4fe3dc46c..b74584ad7f 100644 --- a/packages/backend/src/api/resources/AccountlessApplication.ts +++ b/packages/backend/src/api/resources/AccountlessApplication.ts @@ -5,9 +5,10 @@ export class AccountlessApplication { readonly publishableKey: string, readonly secretKey: string, readonly claimUrl: string, + readonly apiKeysUrl: string, ) {} static fromJSON(data: AccountlessApplicationJSON): AccountlessApplication { - return new AccountlessApplication(data.publishable_key, data.secret_key, data.claim_url); + return new AccountlessApplication(data.publishable_key, data.secret_key, data.claim_url, data.api_keys_url); } } diff --git a/packages/backend/src/api/resources/JSON.ts b/packages/backend/src/api/resources/JSON.ts index 077bba40f7..5ef4fb5d2a 100644 --- a/packages/backend/src/api/resources/JSON.ts +++ b/packages/backend/src/api/resources/JSON.ts @@ -54,6 +54,7 @@ export interface AccountlessApplicationJSON extends ClerkResourceJSON { publishable_key: string; secret_key: string; claim_url: string; + api_keys_url: string; } export interface AllowlistIdentifierJSON extends ClerkResourceJSON { diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 6f2296558d..7234b7a254 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -2052,7 +2052,10 @@ export class Clerk implements ClerkInterface { void this.#componentControls?.ensureMounted().then(controls => { if (this.#options.__internal_claimKeylessApplicationUrl) { controls.updateProps({ - options: { __internal_claimKeylessApplicationUrl: this.#options.__internal_claimKeylessApplicationUrl }, + options: { + __internal_claimKeylessApplicationUrl: this.#options.__internal_claimKeylessApplicationUrl, + __internal_copyInstanceKeysUrl: this.#options.__internal_copyInstanceKeysUrl, + }, }); } }); diff --git a/packages/clerk-js/src/ui/Components.tsx b/packages/clerk-js/src/ui/Components.tsx index b5afeb1c79..43babfb850 100644 --- a/packages/clerk-js/src/ui/Components.tsx +++ b/packages/clerk-js/src/ui/Components.tsx @@ -518,9 +518,13 @@ const Components = (props: ComponentsProps) => { )} {__BUILD_FLAG_KEYLESS_UI__ - ? state.options?.__internal_claimKeylessApplicationUrl && ( + ? state.options?.__internal_claimKeylessApplicationUrl && + state.options?.__internal_copyInstanceKeysUrl && ( - + ) : null} diff --git a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx index 3fa6ffd4ce..2ae30b92f0 100644 --- a/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx +++ b/packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx @@ -1,3 +1,4 @@ +import { useClerk } from '@clerk/shared/react'; // eslint-disable-next-line no-restricted-imports import { css } from '@emotion/react'; import { useState } from 'react'; @@ -9,12 +10,14 @@ import { ClerkLogoIcon } from './ClerkLogoIcon'; import { KeySlashIcon } from './KeySlashIcon'; type KeylessPromptProps = { - url?: string; + claimUrl: string; + copyKeysUrl: string; }; const _KeylessPrompt = (_props: KeylessPromptProps) => { const [isExpanded, setIsExpanded] = useState(true); const handleFocus = () => setIsExpanded(true); + const clerk = useClerk(); return ( @@ -310,6 +313,9 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => { type='button' onFocus={handleFocus} data-expanded={isExpanded} + onClick={() => { + void clerk.navigate(_props.claimUrl); + }} css={css` position: absolute; right: 0.375rem; diff --git a/packages/nextjs/src/app-router/client/keyless-creator-reader.tsx b/packages/nextjs/src/app-router/client/keyless-creator-reader.tsx index 47d959dc96..6b575fe078 100644 --- a/packages/nextjs/src/app-router/client/keyless-creator-reader.tsx +++ b/packages/nextjs/src/app-router/client/keyless-creator-reader.tsx @@ -20,6 +20,7 @@ export const KeylessCreatorOrReader = (props: NextClerkProviderProps) => { key: state?.publishableKey, publishableKey: state?.publishableKey, __internal_claimKeylessApplicationUrl: state?.claimUrl, + __internal_copyInstanceKeysUrl: state?.apiKeysUrl, __internal_bypassMissingPublishableKey: true, } as any); }; diff --git a/packages/nextjs/src/app-router/keyless-actions.ts b/packages/nextjs/src/app-router/keyless-actions.ts index cf73d6b72a..ad2d43ef64 100644 --- a/packages/nextjs/src/app-router/keyless-actions.ts +++ b/packages/nextjs/src/app-router/keyless-actions.ts @@ -30,7 +30,7 @@ export async function createOrReadKeylessAction(): Promise >; + /** + * The URL a developer should be redirected to in order to claim an instance created on Keyless mode. + */ __internal_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_copyInstanceKeysUrl?: string; + /** * [EXPERIMENTAL] Provide the underlying host router, required for the new experimental UI components. */