Skip to content

Commit 52516b5

Browse files
fix: recreate Auth0Client when configuration props change
1 parent e64a6e9 commit 52516b5

2 files changed

Lines changed: 104 additions & 3 deletions

File tree

__tests__/auth-provider.test.tsx

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,3 +1087,95 @@ describe('Auth0Provider', () => {
10871087
expect(screen.queryByText('__main_user__')).not.toBeInTheDocument();
10881088
});
10891089
});
1090+
1091+
describe('Auth0Provider - useMemo dependency behavior', () => {
1092+
1093+
afterEach(() => {
1094+
jest.clearAllMocks();
1095+
window.history.pushState({}, document.title, '/');
1096+
});
1097+
1098+
const TestComponent = ({
1099+
clientId = '__test_client_id__',
1100+
audience = '__test_audience__',
1101+
scope = 'read:profile openid'
1102+
}) => (
1103+
<Auth0Provider
1104+
domain="__test_domain__"
1105+
clientId={clientId}
1106+
authorizationParams={{
1107+
audience,
1108+
scope
1109+
}}
1110+
>
1111+
<div>test</div>
1112+
</Auth0Provider>
1113+
);
1114+
1115+
it('should recreate Auth0Client when clientId changes', async () => {
1116+
const { rerender } = render(<TestComponent />);
1117+
1118+
// Initial render
1119+
expect(Auth0Client).toHaveBeenCalledTimes(1);
1120+
expect(Auth0Client).toHaveBeenLastCalledWith(
1121+
expect.objectContaining({
1122+
clientId: '__test_client_id__',
1123+
authorizationParams: {
1124+
audience: '__test_audience__',
1125+
scope: 'read:profile openid'
1126+
}
1127+
})
1128+
);
1129+
1130+
// Change clientId - should recreate client
1131+
rerender(<TestComponent clientId="__new_client_id__" />);
1132+
expect(Auth0Client).toHaveBeenCalledTimes(2);
1133+
expect(Auth0Client).toHaveBeenLastCalledWith(
1134+
expect.objectContaining({
1135+
clientId: '__new_client_id__',
1136+
authorizationParams: {
1137+
audience: '__test_audience__',
1138+
scope: 'read:profile openid'
1139+
}
1140+
})
1141+
);
1142+
});
1143+
1144+
it('should recreate Auth0Client when audience changes', async () => {
1145+
const { rerender } = render(<TestComponent />);
1146+
1147+
expect(Auth0Client).toHaveBeenCalledTimes(1);
1148+
1149+
// Change audience - should recreate client
1150+
rerender(<TestComponent audience="__new_audience__" />);
1151+
expect(Auth0Client).toHaveBeenCalledTimes(2);
1152+
expect(Auth0Client).toHaveBeenLastCalledWith(
1153+
expect.objectContaining({
1154+
clientId: '__test_client_id__',
1155+
authorizationParams: {
1156+
audience: '__new_audience__',
1157+
scope: 'read:profile openid'
1158+
}
1159+
})
1160+
);
1161+
});
1162+
1163+
it('should recreate Auth0Client when scope changes', async () => {
1164+
const { rerender } = render(<TestComponent />);
1165+
1166+
expect(Auth0Client).toHaveBeenCalledTimes(1);
1167+
1168+
// Change scope with multiple permissions - should recreate client
1169+
rerender(<TestComponent scope="read:users write:users admin:all" />);
1170+
expect(Auth0Client).toHaveBeenCalledTimes(2);
1171+
expect(Auth0Client).toHaveBeenLastCalledWith(
1172+
expect.objectContaining({
1173+
clientId: '__test_client_id__',
1174+
authorizationParams: {
1175+
audience: '__test_audience__',
1176+
scope: 'read:users write:users admin:all'
1177+
}
1178+
})
1179+
);
1180+
});
1181+
});

src/auth0-provider.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import React, {
44
useMemo,
55
useReducer,
66
useRef,
7-
useState,
87
} from 'react';
98
import {
109
Auth0Client,
@@ -140,8 +139,18 @@ const Auth0Provider = <TUser extends User = User>(opts: Auth0ProviderOptions<TUs
140139
context = Auth0Context,
141140
...clientOpts
142141
} = opts;
143-
const [client] = useState(
144-
() => new Auth0Client(toAuth0ClientOptions(clientOpts))
142+
const client = useMemo(
143+
() => new Auth0Client(toAuth0ClientOptions(clientOpts)),
144+
[
145+
clientOpts.domain,
146+
clientOpts.clientId,
147+
clientOpts.authorizationParams?.audience,
148+
clientOpts.authorizationParams?.scope,
149+
clientOpts.authorizationParams?.redirect_uri,
150+
clientOpts.cacheLocation,
151+
clientOpts.useRefreshTokens,
152+
clientOpts.useCookiesForTransactions,
153+
]
145154
);
146155
const [state, dispatch] = useReducer(reducer<TUser>, initialAuthState as AuthState<TUser>);
147156
const didInitialise = useRef(false);

0 commit comments

Comments
 (0)