Skip to content

Commit a52029c

Browse files
authored
fix(clerk-js): Revalidate environment on window focus for Keyless (#4813)
1 parent 389133b commit a52029c

File tree

3 files changed

+69
-2
lines changed

3 files changed

+69
-2
lines changed

.changeset/bright-mangos-pump.md

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+
Revalidate environment on window focus for Keyless.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { useClerk } from '@clerk/shared/react';
33
import { css } from '@emotion/react';
44
import { useState } from 'react';
55

6-
import { useEnvironment } from '../../contexts';
76
import { descriptors, Flex, Link, Spinner } from '../../customizables';
87
import { Portal } from '../../elements/Portal';
98
import { InternalThemeProvider } from '../../styledSystem';
109
import { ClerkLogoIcon } from './ClerkLogoIcon';
1110
import { KeySlashIcon } from './KeySlashIcon';
11+
import { useRevalidateEnvironment } from './use-revalidate-environment';
1212

1313
type KeylessPromptProps = {
1414
claimUrl: string;
@@ -20,7 +20,7 @@ const _KeylessPrompt = (_props: KeylessPromptProps) => {
2020
const [isLoading, setIsLoading] = useState(false);
2121
const handleFocus = () => setIsExpanded(true);
2222

23-
const claimed = Boolean(useEnvironment().authConfig.claimedAt);
23+
const claimed = Boolean(useRevalidateEnvironment().authConfig.claimedAt);
2424
const clerk = useClerk();
2525

2626
return (
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { useClerk } from '@clerk/shared/react';
2+
import { useEffect, useReducer } from 'react';
3+
4+
import type { Clerk } from '../../../core/clerk';
5+
import type { Environment } from '../../../core/resources';
6+
import { useEnvironment } from '../../contexts';
7+
8+
/**
9+
* Revalidates environment on focus, highly optimized for Keyless mode.
10+
* Attention: this is not a generic solution, and should not be used for revalidating environment inside UI components that are end-user facing (e.g. SignIn)
11+
*/
12+
function useRevalidateEnvironment() {
13+
const clerk = useClerk();
14+
const [, forceUpdate] = useReducer(v => v + 1, 0);
15+
16+
useEffect(() => {
17+
const controller = new AbortController();
18+
window.addEventListener(
19+
'focus',
20+
21+
async () => {
22+
const environment = (clerk as Clerk).__unstable__environment as Environment | undefined;
23+
24+
if (!environment) {
25+
return;
26+
}
27+
28+
if (environment.authConfig.claimedAt !== null) {
29+
return controller.abort();
30+
}
31+
32+
if (document.visibilityState !== 'visible') {
33+
return;
34+
}
35+
36+
const maxRetries = 2;
37+
38+
for (let i = 0; i < maxRetries; i++) {
39+
const {
40+
authConfig: { claimedAt },
41+
} = await environment.fetch();
42+
43+
if (claimedAt !== null) {
44+
forceUpdate();
45+
break;
46+
}
47+
}
48+
},
49+
{
50+
signal: controller.signal,
51+
},
52+
);
53+
54+
return () => {
55+
controller.abort();
56+
};
57+
}, []);
58+
59+
return useEnvironment();
60+
}
61+
62+
export { useRevalidateEnvironment };

0 commit comments

Comments
 (0)