Skip to content

Commit e174858

Browse files
authored
feat(clerk-js,backend): Url for copying instance keys on Keyless mode (#4755)
1 parent 7f7edca commit e174858

File tree

11 files changed

+44
-6
lines changed

11 files changed

+44
-6
lines changed

.changeset/gold-monkeys-collect.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
'@clerk/nextjs': patch
4+
'@clerk/types': patch
5+
---
6+
7+
Introduce `__internal_copyInstanceKeysUrl` as property in `ClerkOptions`. It is intented for internall usage from other Clerk SDKs and will be used in Keyless mode.

.changeset/twelve-spiders-obey.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/backend': patch
3+
---
4+
5+
Add property `api_keys_url` in the `AccountlessApplication` class

packages/backend/src/api/resources/AccountlessApplication.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ export class AccountlessApplication {
55
readonly publishableKey: string,
66
readonly secretKey: string,
77
readonly claimUrl: string,
8+
readonly apiKeysUrl: string,
89
) {}
910

1011
static fromJSON(data: AccountlessApplicationJSON): AccountlessApplication {
11-
return new AccountlessApplication(data.publishable_key, data.secret_key, data.claim_url);
12+
return new AccountlessApplication(data.publishable_key, data.secret_key, data.claim_url, data.api_keys_url);
1213
}
1314
}

packages/backend/src/api/resources/JSON.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export interface AccountlessApplicationJSON extends ClerkResourceJSON {
5454
publishable_key: string;
5555
secret_key: string;
5656
claim_url: string;
57+
api_keys_url: string;
5758
}
5859

5960
export interface AllowlistIdentifierJSON extends ClerkResourceJSON {

packages/clerk-js/src/core/clerk.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2052,7 +2052,10 @@ export class Clerk implements ClerkInterface {
20522052
void this.#componentControls?.ensureMounted().then(controls => {
20532053
if (this.#options.__internal_claimKeylessApplicationUrl) {
20542054
controls.updateProps({
2055-
options: { __internal_claimKeylessApplicationUrl: this.#options.__internal_claimKeylessApplicationUrl },
2055+
options: {
2056+
__internal_claimKeylessApplicationUrl: this.#options.__internal_claimKeylessApplicationUrl,
2057+
__internal_copyInstanceKeysUrl: this.#options.__internal_copyInstanceKeysUrl,
2058+
},
20562059
});
20572060
}
20582061
});

packages/clerk-js/src/ui/Components.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,13 @@ const Components = (props: ComponentsProps) => {
518518
)}
519519

520520
{__BUILD_FLAG_KEYLESS_UI__
521-
? state.options?.__internal_claimKeylessApplicationUrl && (
521+
? state.options?.__internal_claimKeylessApplicationUrl &&
522+
state.options?.__internal_copyInstanceKeysUrl && (
522523
<LazyImpersonationFabProvider globalAppearance={state.appearance}>
523-
<KeylessPrompt url={state.options.__internal_claimKeylessApplicationUrl} />
524+
<KeylessPrompt
525+
claimUrl={state.options.__internal_claimKeylessApplicationUrl}
526+
copyKeysUrl={state.options.__internal_copyInstanceKeysUrl}
527+
/>
524528
</LazyImpersonationFabProvider>
525529
)
526530
: null}

packages/clerk-js/src/ui/components/KeylessPrompt/index.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useClerk } from '@clerk/shared/react';
12
// eslint-disable-next-line no-restricted-imports
23
import { css } from '@emotion/react';
34
import { useState } from 'react';
@@ -9,12 +10,14 @@ import { ClerkLogoIcon } from './ClerkLogoIcon';
910
import { KeySlashIcon } from './KeySlashIcon';
1011

1112
type KeylessPromptProps = {
12-
url?: string;
13+
claimUrl: string;
14+
copyKeysUrl: string;
1315
};
1416

1517
const _KeylessPrompt = (_props: KeylessPromptProps) => {
1618
const [isExpanded, setIsExpanded] = useState(true);
1719
const handleFocus = () => setIsExpanded(true);
20+
const clerk = useClerk();
1821

1922
return (
2023
<Portal>
@@ -310,6 +313,9 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
310313
type='button'
311314
onFocus={handleFocus}
312315
data-expanded={isExpanded}
316+
onClick={() => {
317+
void clerk.navigate(_props.claimUrl);
318+
}}
313319
css={css`
314320
position: absolute;
315321
right: 0.375rem;

packages/nextjs/src/app-router/client/keyless-creator-reader.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const KeylessCreatorOrReader = (props: NextClerkProviderProps) => {
2020
key: state?.publishableKey,
2121
publishableKey: state?.publishableKey,
2222
__internal_claimKeylessApplicationUrl: state?.claimUrl,
23+
__internal_copyInstanceKeysUrl: state?.apiKeysUrl,
2324
__internal_bypassMissingPublishableKey: true,
2425
} as any);
2526
};

packages/nextjs/src/app-router/keyless-actions.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export async function createOrReadKeylessAction(): Promise<null | Omit<Accountle
3030
return null;
3131
}
3232

33-
const { claimUrl, publishableKey, secretKey } = result;
33+
const { claimUrl, publishableKey, secretKey, apiKeysUrl } = result;
3434

3535
void (await cookies()).set(getKeylessCookieName(), JSON.stringify({ claimUrl, publishableKey, secretKey }), {
3636
secure: false,
@@ -40,5 +40,6 @@ export async function createOrReadKeylessAction(): Promise<null | Omit<Accountle
4040
return {
4141
claimUrl,
4242
publishableKey,
43+
apiKeysUrl,
4344
};
4445
}

packages/nextjs/src/app-router/server/ClerkProvider.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export async function ClerkProvider(
7373
...rest,
7474
publishableKey: newOrReadKeys.publishableKey,
7575
__internal_claimKeylessApplicationUrl: newOrReadKeys.claimUrl,
76+
__internal_copyInstanceKeysUrl: newOrReadKeys.apiKeysUrl,
7677
})}
7778
nonce={await nonce}
7879
initialState={await statePromise}

0 commit comments

Comments
 (0)