Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support eager refresh prop #877

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/sdks/react-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ const AppRoot = () => {
// must be configured (e.g., https://auth.app.example.com)
// and should be set as the baseUrl property.
// baseUrl = "https://auth.app.example.com"
// Allows to override the base URL that is used to fetch static files
// baseStaticUrl? = "https://auth.static.app.example.com"
// Determines if tokens will be stored on local storage and can accessed with getToken function
// persistTokens={false} // Default is true
// If true, session token (jwt) will be stored on cookie. Otherwise, the session token will be stored on local storage and can accessed with getSessionToken function.
// Use this option if session token will stay small (less than 1k)
// NOTE: Session token can grow, especially in cases of using authorization, or adding custom claims
// sessionTokenViaCookie={true}
// If true, last authenticated user will be stored on local storage and can accessed with getUser function
// storeLastAuthenticatedUser={false} // Default is true
// If true, last authenticated user will not be removed after logout
// keepLastAuthenticatedUserAfterLogout?: boolean;
// If true, session will be refreshed on first useSession call, even if the session is never fetched before
// eagerRefreshOnFirstUseSession={false} // Default is true
>
<App />
</AuthProvider>
Expand Down Expand Up @@ -602,6 +616,18 @@ const handleUpdateUser = useCallback(() => {
}, [sdk]);
```

### I see a `/refresh` API call failure in my logs

By default, the Descope SDK eagerly attempts to refresh the session when the `useSession` hook is first called regardless the previous logged in state. If you want to disable this behavior, you can set the `eagerRefreshOnFirstUseSession={false}` prop on the `AuthProvider` component. With this property set to `false`, the SDK will only attempt to refresh the session if the user has previously logged in.

Example:

```jsx
<AuthProvider eagerRefreshOnFirstUseSession={false}>
<App />
</AuthProvider>
```

## Learn More

To learn more please see the [Descope Documentation and API reference page](https://docs.descope.com/).
Expand Down
1 change: 1 addition & 0 deletions packages/sdks/react-sdk/examples/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ root.render(
<AuthProvider
projectId={process.env.DESCOPE_PROJECT_ID!}
baseUrl={process.env.DESCOPE_BASE_URL}
eagerRefreshOnFirstUseSession={false}
baseStaticUrl={process.env.DESCOPE_BASE_STATIC_URL}
>
<App />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ interface IAuthProviderProps {
storeLastAuthenticatedUser?: boolean;
// If true, last authenticated user will not be removed after logout
keepLastAuthenticatedUserAfterLogout?: boolean;
// If true, session will be refreshed on first useSession call, even if the session is never fetched before
eagerRefreshOnFirstUseSession?: boolean;
children?: React.ReactNode;
}

Expand All @@ -38,6 +40,7 @@ const AuthProvider: FC<IAuthProviderProps> = ({
persistTokens = true,
storeLastAuthenticatedUser = true,
keepLastAuthenticatedUserAfterLogout = false,
eagerRefreshOnFirstUseSession = true,
children = undefined,
}) => {
const [user, setUser] = useState<User>();
Expand Down Expand Up @@ -77,10 +80,14 @@ const AuthProvider: FC<IAuthProviderProps> = ({
isSessionFetched.current = true;

setIsSessionLoading(true);
withValidation(sdk?.refresh)().then(() => {

const refreshFn = eagerRefreshOnFirstUseSession
? sdk?.refresh
: sdk.refreshIfSessionTokenExists;
withValidation(refreshFn)().then(() => {
setIsSessionLoading(false);
});
}, [sdk]);
}, [sdk, eagerRefreshOnFirstUseSession]);

const fetchUser = useCallback(() => {
// We want that the user will fetched only once
Expand Down
20 changes: 16 additions & 4 deletions packages/sdks/web-js-sdk/src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,25 @@ import { getSessionToken } from '../enhancers/withPersistTokens/helpers';
const createSdk = (...args: Parameters<typeof createCoreSdk>) => {
const coreSdk = createCoreSdk(...args);

const refresh = (token?: string) => {
// Descope use this query param to monitor if refresh is made
// When the user is already logged in in the past or not (We want to optimize that in the future)
const currentSessionToken = getSessionToken();
return coreSdk.refresh(token, { dcs: currentSessionToken ? 't' : 'f' });
};

return {
...coreSdk,
refresh: (token?: string) => {
// Descope use this query param to monitor if refresh is made
// When the user is already logged in in the past or not (We want to optimize that in the future)
refresh,
refreshIfSessionTokenExists: (token?: string) => {
const currentSessionToken = getSessionToken();
return coreSdk.refresh(token, { dcs: currentSessionToken ? 't' : 'f' });
if (currentSessionToken || token) {
return refresh(token);
}
// If session token does not exist, we return a failed promise
return Promise.resolve({
ok: false,
});
},
flow: withFlow(coreSdk),
webauthn: createWebAuthn(coreSdk),
Expand Down
Loading