Skip to content

Commit

Permalink
chore(clerk-js): Invalidate Session Verification when UserVerificatio…
Browse files Browse the repository at this point in the history
…n unmounts (#4359)
  • Loading branch information
panteliselef authored Oct 18, 2024
1 parent 5c6391b commit 1be6dac
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-avocados-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/clerk-js": patch
---

Bug fix: Always receive a new session verification object when UserVerification component mounts.
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import type { __experimental_UserVerificationModalProps, __experimental_UserVerificationProps } from '@clerk/types';
import React from 'react';
import React, { useEffect } from 'react';

import { ComponentContext, withCoreSessionSwitchGuard } from '../../contexts';
import { Flow } from '../../customizables';
import { Route, Switch } from '../../router';
import { UserVerificationFactorOne } from './UserVerificationFactorOne';
import { UserVerificationFactorTwo } from './UserVerificationFactorTwo';
import { useUserVerificationSession } from './useUserVerificationSession';

function UserVerificationRoutes(): JSX.Element {
const { invalidate } = useUserVerificationSession();
useEffect(() => {
return () => {
invalidate();
};
}, []);
return (
<Flow.Root flow='userVerification'>
<Switch>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { useSession } from '@clerk/shared/react';
import { useMemo } from 'react';

import { useUserVerification } from '../../contexts';
import { LoadingCard } from '../../elements';
import { useFetch } from '../../hooks';

const useUserVerificationSession = () => {
const { session } = useSession();
const useUserVerificationSessionKey = () => {
const { level } = useUserVerification();
const data = useFetch(
session ? session.__experimental_startVerification : undefined,
{
return useMemo(
() => ({
level: level || 'secondFactor',
// TODO(STEP-UP): Figure out if this needs to be a prop
maxAgeMinutes: 10,
},
{
throttleTime: 300,
},
}),
[level],
);
};

const useUserVerificationSession = () => {
const { session } = useSession();
const key = useUserVerificationSessionKey();
const data = useFetch(session ? session.__experimental_startVerification : undefined, key, {
throttleTime: 300,
});

return { ...data };
};
Expand All @@ -39,4 +42,4 @@ function withUserVerificationSessionGuard<P>(Component: React.ComponentType<P>):
return Hoc;
}

export { useUserVerificationSession, withUserVerificationSessionGuard };
export { useUserVerificationSessionKey, useUserVerificationSession, withUserVerificationSessionGuard };
30 changes: 22 additions & 8 deletions packages/clerk-js/src/ui/hooks/useFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ export const clearFetchCache = () => {

const serialize = (key: unknown) => (typeof key === 'string' ? key : JSON.stringify(key));

const useCache = <K = any, V = any>(
export const useCache = <K = any, V = any>(
key: K,
serializer = serialize,
): {
getCache: () => State<V> | undefined;
setCache: (state: State<V>) => void;
clearCache: () => void;
subscribeCache: (callback: () => void) => () => void;
} => {
const serializedKey = serialize(key);
const serializedKey = serializer(key);
const get = useCallback(() => requestCache.get(serializedKey), [serializedKey]);
const set = useCallback(
(data: State) => {
Expand All @@ -49,6 +51,16 @@ const useCache = <K = any, V = any>(
},
[serializedKey],
);

const clear = useCallback(() => {
set({
isLoading: false,
isValidating: false,
data: null,
error: null,
cachedAt: undefined,
});
}, [set]);
const subscribe = useCallback((callback: () => void) => {
subscribers.add(callback);
return () => subscribers.delete(callback);
Expand All @@ -58,6 +70,7 @@ const useCache = <K = any, V = any>(
getCache: get,
setCache: set,
subscribeCache: subscribe,
clearCache: clear,
};
};

Expand All @@ -76,9 +89,9 @@ export const useFetch = <K, T>(
staleTime?: number;
},
) => {
const { subscribeCache, getCache, setCache } = useCache<K, T>(params);
const { subscribeCache, getCache, setCache, clearCache } = useCache<K, T>(params);

const staleTime = options?.staleTime || 1000 * 60 * 2; //cache for 2 minutes by default
const staleTime = options?.staleTime ?? 1000 * 60 * 2; //cache for 2 minutes by default
const throttleTime = options?.throttleTime || 0;
const fetcherRef = useRef(fetcher);

Expand All @@ -91,7 +104,7 @@ export const useFetch = <K, T>(
useEffect(() => {
const fetcherMissing = !fetcherRef.current;
const isCacheStale = Date.now() - (getCache()?.cachedAt || 0) >= staleTime;
const isRequestOnGoing = getCache()?.isValidating;
const isRequestOnGoing = getCache()?.isValidating ?? false;

if (fetcherMissing || !isCacheStale || isRequestOnGoing) {
return;
Expand All @@ -100,8 +113,8 @@ export const useFetch = <K, T>(
const d = performance.now();

setCache({
data: null,
isLoading: !getCache(),
data: getCache()?.data ?? null,
isLoading: !getCache()?.data,
isValidating: true,
error: null,
});
Expand All @@ -126,7 +139,7 @@ export const useFetch = <K, T>(
})
.catch(() => {
setCache({
data: null,
data: getCache()?.data ?? null,
isLoading: false,
isValidating: false,
error: true,
Expand All @@ -138,5 +151,6 @@ export const useFetch = <K, T>(
return {
...cached,
setCache,
invalidate: clearCache,
};
};

0 comments on commit 1be6dac

Please sign in to comment.