Skip to content

Commit 93ae27c

Browse files
authored
fix(clerk-js): Navigate to specific instance for configuration after keyless (#5013)
1 parent e113e47 commit 93ae27c

File tree

3 files changed

+83
-29
lines changed

3 files changed

+83
-29
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@clerk/clerk-js': patch
3+
---
4+
5+
Navigate to specific instance instead of /last-active for configuration after keyless.

packages/clerk-js/bundlewatch.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@
1818
{ "path": "./dist/userverification*.js", "maxSize": "5KB" },
1919
{ "path": "./dist/onetap*.js", "maxSize": "1KB" },
2020
{ "path": "./dist/waitlist*.js", "maxSize": "1.3KB" },
21-
{ "path": "./dist/keylessPrompt*.js", "maxSize": "5.7KB" }
21+
{ "path": "./dist/keylessPrompt*.js", "maxSize": "5.9KB" }
2222
]
2323
}

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

Lines changed: 77 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,60 @@ const buttonIdentifierPrefix = `--clerk-keyless-prompt`;
2222
const buttonIdentifier = `${buttonIdentifierPrefix}-button`;
2323
const contentIdentifier = `${buttonIdentifierPrefix}-content`;
2424

25+
const baseElementStyles = css`
26+
box-sizing: border-box;
27+
padding: 0;
28+
margin: 0;
29+
background: none;
30+
border: none;
31+
line-height: 1.5;
32+
font-family:
33+
-apple-system,
34+
BlinkMacSystemFont,
35+
avenir next,
36+
avenir,
37+
segoe ui,
38+
helvetica neue,
39+
helvetica,
40+
Cantarell,
41+
Ubuntu,
42+
roboto,
43+
noto,
44+
arial,
45+
sans-serif;
46+
text-decoration: none;
47+
`;
48+
49+
/**
50+
* If we cannot reconstruct the url properly, then simply fallback to Clerk Dashboard
51+
*/
52+
function withLastActiveFallback(cb: () => string): string {
53+
try {
54+
return cb();
55+
} catch {
56+
return 'https://dashboard.clerk.com/last-active';
57+
}
58+
}
59+
60+
function handleDashboardUrlParsing(url: string) {
61+
// make sure this is a valid url
62+
const __url = new URL(url);
63+
const regex = /^https?:\/\/(.*?)\/apps\/app_(.+?)\/instances\/ins_(.+?)(?:\/.*)?$/;
64+
65+
const match = __url.href.match(regex);
66+
67+
if (!match) {
68+
throw new Error('invalid value dashboard url structure');
69+
}
70+
71+
// Extracting base domain, app ID with prefix, and instanceId with prefix
72+
return {
73+
baseDomain: `https://${match[1]}`,
74+
appId: `app_${match[2]}`,
75+
instanceId: `ins_${match[3]}`,
76+
};
77+
}
78+
2579
const _KeylessPrompt = (_props: KeylessPromptProps) => {
2680
const { isSignedIn } = useUser();
2781
const [isExpanded, setIsExpanded] = useState(false);
@@ -38,8 +92,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
3892
const appName = environment.displayConfig.applicationName;
3993

4094
const isForcedExpanded = claimed || success || isExpanded;
41-
42-
const urlToDashboard = useMemo(() => {
95+
const claimUrlToDashboard = useMemo(() => {
4396
if (claimed) {
4497
return _props.copyKeysUrl;
4598
}
@@ -50,29 +103,23 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
50103
return url.href;
51104
}, [claimed, _props.copyKeysUrl, _props.claimUrl]);
52105

53-
const baseElementStyles = css`
54-
box-sizing: border-box;
55-
padding: 0;
56-
margin: 0;
57-
background: none;
58-
border: none;
59-
line-height: 1.5;
60-
font-family:
61-
-apple-system,
62-
BlinkMacSystemFont,
63-
avenir next,
64-
avenir,
65-
segoe ui,
66-
helvetica neue,
67-
helvetica,
68-
Cantarell,
69-
Ubuntu,
70-
roboto,
71-
noto,
72-
arial,
73-
sans-serif;
74-
text-decoration: none;
75-
`;
106+
const instanceUrlToDashboard = useMemo(() => {
107+
return withLastActiveFallback(() => {
108+
const redirectUrlParts = handleDashboardUrlParsing(_props.copyKeysUrl);
109+
const url = new URL(
110+
`${redirectUrlParts.baseDomain}/apps/${redirectUrlParts.appId}/instances/${redirectUrlParts.instanceId}/user-authentication/email-phone-username`,
111+
);
112+
return url.href;
113+
});
114+
}, [_props.copyKeysUrl]);
115+
116+
const getKeysUrlFromLastActive = useMemo(() => {
117+
return withLastActiveFallback(() => {
118+
const redirectUrlParts = handleDashboardUrlParsing(_props.copyKeysUrl);
119+
const url = new URL(`${redirectUrlParts.baseDomain}/last-active?path=api-keys`);
120+
return url.href;
121+
});
122+
}, [_props.copyKeysUrl]);
76123

77124
const mainCTAStyles = css`
78125
${baseElementStyles};
@@ -375,7 +422,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
375422
<Link
376423
isExternal
377424
aria-label='Go to Dashboard to configure settings'
378-
href='https://dashboard.clerk.com/last-active?path=user-authentication/email-phone-username'
425+
href={instanceUrlToDashboard}
379426
sx={t => ({
380427
color: t.colors.$whiteAlpha600,
381428
textDecoration: 'underline solid',
@@ -413,6 +460,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
413460
}}
414461
css={css`
415462
${mainCTAStyles};
463+
416464
&:hover {
417465
background: #4b4b4b;
418466
transition: all 120ms ease-in-out;
@@ -431,7 +479,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
431479
})}
432480
>
433481
<a
434-
href={urlToDashboard}
482+
href={claimUrlToDashboard}
435483
target='_blank'
436484
rel='noopener noreferrer'
437485
css={css`
@@ -481,14 +529,15 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
481529
/>
482530

483531
<a
484-
href='https://dashboard.clerk.com/last-active?path=api-keys'
532+
href={getKeysUrlFromLastActive}
485533
target='_blank'
486534
rel='noopener noreferrer'
487535
css={css`
488536
${baseElementStyles};
489537
color: #ffffff9e;
490538
font-size: 0.75rem;
491539
transition: color 120ms ease-out;
540+
492541
:hover {
493542
color: #ffffffcf;
494543
text-decoration: none;

0 commit comments

Comments
 (0)