@dynamic-labs/sdk-react-core 4.96.0 → 4.96.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +12 -12
- package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.cjs +30 -0
- package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.d.ts +5 -0
- package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.js +26 -0
- package/src/lib/client/extension/functions/getSessionIdFromMinToken/index.d.ts +1 -0
- package/src/lib/client/extension/index.d.ts +1 -0
- package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.cjs +22 -8
- package/src/lib/utils/hooks/useSyncDynamicWaas/useSyncDynamicWaas.js +22 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.96.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.96.0...v4.96.1) (2026-08-10)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* security updates ([#12151](https://github.com/dynamic-labs/dynamic-auth/issues/12151)) ([faf22dd](https://github.com/dynamic-labs/dynamic-auth/commit/faf22dda11f5cfd888e860bd05731604ee19b51d))
|
|
8
|
+
* **sdk-react-core:** avoid spurious WaaS client rebuild on transient user sessionId churn ([#12183](https://github.com/dynamic-labs/dynamic-auth/issues/12183)) ([6248f74](https://github.com/dynamic-labs/dynamic-auth/commit/6248f7498fbd279031a4e9176fa707bca360f0f1))
|
|
9
|
+
|
|
2
10
|
## [4.96.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.95.2...v4.96.0) (2026-08-03)
|
|
3
11
|
|
|
4
12
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/sdk-react-core",
|
|
3
|
-
"version": "4.96.
|
|
3
|
+
"version": "4.96.1",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@dynamic-labs/sdk-api-core": "0.0.1093",
|
|
6
6
|
"@dynamic-labs-sdk/client": "1.20.0",
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
"react-i18next": "13.5.0",
|
|
19
19
|
"react-international-phone": "4.5.0",
|
|
20
20
|
"yup": "0.32.11",
|
|
21
|
-
"@dynamic-labs/assert-package-version": "4.96.
|
|
22
|
-
"@dynamic-labs/iconic": "4.96.
|
|
23
|
-
"@dynamic-labs/locale": "4.96.
|
|
24
|
-
"@dynamic-labs/logger": "4.96.
|
|
25
|
-
"@dynamic-labs/multi-wallet": "4.96.
|
|
26
|
-
"@dynamic-labs/rpc-providers": "4.96.
|
|
27
|
-
"@dynamic-labs/store": "4.96.
|
|
28
|
-
"@dynamic-labs/types": "4.96.
|
|
29
|
-
"@dynamic-labs/utils": "4.96.
|
|
30
|
-
"@dynamic-labs/wallet-book": "4.96.
|
|
31
|
-
"@dynamic-labs/wallet-connector-core": "4.96.
|
|
21
|
+
"@dynamic-labs/assert-package-version": "4.96.1",
|
|
22
|
+
"@dynamic-labs/iconic": "4.96.1",
|
|
23
|
+
"@dynamic-labs/locale": "4.96.1",
|
|
24
|
+
"@dynamic-labs/logger": "4.96.1",
|
|
25
|
+
"@dynamic-labs/multi-wallet": "4.96.1",
|
|
26
|
+
"@dynamic-labs/rpc-providers": "4.96.1",
|
|
27
|
+
"@dynamic-labs/store": "4.96.1",
|
|
28
|
+
"@dynamic-labs/types": "4.96.1",
|
|
29
|
+
"@dynamic-labs/utils": "4.96.1",
|
|
30
|
+
"@dynamic-labs/wallet-book": "4.96.1",
|
|
31
|
+
"@dynamic-labs/wallet-connector-core": "4.96.1",
|
|
32
32
|
"eventemitter3": "5.0.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var sdkApiCore = require('@dynamic-labs/sdk-api-core');
|
|
7
|
+
var parseToken = require('../../../../shared/utils/functions/parseToken/parseToken.cjs');
|
|
8
|
+
var getMinAuthToken = require('../getMinAuthToken/getMinAuthToken.cjs');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Reads the session id (`sid` claim) from the current min JWT claims.
|
|
12
|
+
* Returns `undefined` when no token, decode fails, or the claim is missing.
|
|
13
|
+
*/
|
|
14
|
+
const getSessionIdFromMinToken = () => {
|
|
15
|
+
const token = getMinAuthToken.getMinAuthToken();
|
|
16
|
+
if (!token)
|
|
17
|
+
return undefined;
|
|
18
|
+
const payload = parseToken.parseToken(token);
|
|
19
|
+
if (!payload || typeof payload !== 'object')
|
|
20
|
+
return undefined;
|
|
21
|
+
try {
|
|
22
|
+
const minJwt = sdkApiCore.MinifiedDynamicJwtFromJSON(payload);
|
|
23
|
+
return minJwt.sid;
|
|
24
|
+
}
|
|
25
|
+
catch (_a) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
exports.getSessionIdFromMinToken = getSessionIdFromMinToken;
|
package/src/lib/client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { MinifiedDynamicJwtFromJSON } from '@dynamic-labs/sdk-api-core';
|
|
3
|
+
import { parseToken } from '../../../../shared/utils/functions/parseToken/parseToken.js';
|
|
4
|
+
import { getMinAuthToken } from '../getMinAuthToken/getMinAuthToken.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reads the session id (`sid` claim) from the current min JWT claims.
|
|
8
|
+
* Returns `undefined` when no token, decode fails, or the claim is missing.
|
|
9
|
+
*/
|
|
10
|
+
const getSessionIdFromMinToken = () => {
|
|
11
|
+
const token = getMinAuthToken();
|
|
12
|
+
if (!token)
|
|
13
|
+
return undefined;
|
|
14
|
+
const payload = parseToken(token);
|
|
15
|
+
if (!payload || typeof payload !== 'object')
|
|
16
|
+
return undefined;
|
|
17
|
+
try {
|
|
18
|
+
const minJwt = MinifiedDynamicJwtFromJSON(payload);
|
|
19
|
+
return minJwt.sid;
|
|
20
|
+
}
|
|
21
|
+
catch (_a) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { getSessionIdFromMinToken };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getSessionIdFromMinToken } from './getSessionIdFromMinToken';
|
|
@@ -13,6 +13,7 @@ export { useRefetchProjectSettings } from './projectSettings/useRefetchProjectSe
|
|
|
13
13
|
export { isCookieEnabled } from './functions/isCookieEnabled';
|
|
14
14
|
export { getMinAuthToken } from './functions/getMinAuthToken';
|
|
15
15
|
export { getSignInCredentialIdFromMinToken } from './functions/getSignInCredentialIdFromMinToken';
|
|
16
|
+
export { getSessionIdFromMinToken } from './functions/getSessionIdFromMinToken';
|
|
16
17
|
export { getAuthToken } from './functions/getAuthToken';
|
|
17
18
|
export { getExpiresAt } from './functions/getExpiresAt';
|
|
18
19
|
export { hasElevatedAccessToken } from './functions/hasElevatedAccessToken';
|
|
@@ -32,6 +32,7 @@ require('../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.cjs');
|
|
|
32
32
|
require('../../../events/dynamicEvents.cjs');
|
|
33
33
|
var useOnboardingCompleteUser = require('../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.cjs');
|
|
34
34
|
var useProjectSettings = require('../../../client/extension/projectSettings/useProjectSettings/useProjectSettings.cjs');
|
|
35
|
+
var getSessionIdFromMinToken = require('../../../client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.cjs');
|
|
35
36
|
require('../../../context/DynamicContext/useDynamicContext/useDynamicContext.cjs');
|
|
36
37
|
var useInternalDynamicContext = require('../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.cjs');
|
|
37
38
|
var LoadingContext = require('../../../context/LoadingContext/LoadingContext.cjs');
|
|
@@ -219,19 +220,22 @@ const useSyncDynamicWaas = () => {
|
|
|
219
220
|
// Initialize waas iframe when user is authenticated
|
|
220
221
|
// This handles both page reload (user already authenticated) and fresh authentication
|
|
221
222
|
React.useEffect(() => {
|
|
223
|
+
const tokenSessionId = getSessionIdFromMinToken.getSessionIdFromMinToken();
|
|
224
|
+
const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
|
|
222
225
|
// handle logout case where user is logged out but session id is still valid
|
|
223
|
-
if (sessionIdRef.current && !
|
|
226
|
+
if (sessionIdRef.current && !currentSessionId) {
|
|
224
227
|
sessionIdRef.current = undefined;
|
|
225
228
|
hasWaasInitializedRef.current = false;
|
|
226
229
|
initializingWaasRef.current = false;
|
|
227
230
|
clearRecoveredWallets();
|
|
228
231
|
}
|
|
229
|
-
if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId)) {
|
|
230
|
-
const {
|
|
232
|
+
if (shouldInitializeWaas && currentSessionId && (user === null || user === void 0 ? void 0 : user.sessionId)) {
|
|
233
|
+
const { id: userId } = user;
|
|
231
234
|
const shouldInitialize = !initializingWaasRef.current &&
|
|
232
|
-
(!hasWaasInitializedRef.current ||
|
|
235
|
+
(!hasWaasInitializedRef.current ||
|
|
236
|
+
sessionIdRef.current !== currentSessionId);
|
|
233
237
|
if (shouldInitialize) {
|
|
234
|
-
const isSessionIdChanged = sessionIdRef.current !==
|
|
238
|
+
const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
|
|
235
239
|
// A swap from a prior session (e.g. step-up reauth) must rebuild the
|
|
236
240
|
// WaaS client so the iframe re-auths with the new session instead of
|
|
237
241
|
// 401-ing on the stale cached one. First init (no prior session) keeps
|
|
@@ -245,8 +249,11 @@ const useSyncDynamicWaas = () => {
|
|
|
245
249
|
initializeWaas({ forceClientRebuild })
|
|
246
250
|
.then(() => {
|
|
247
251
|
logger.logger.debug('[useSyncDynamicWaas] waas initialized');
|
|
252
|
+
// Persist the session id this init actually ran with so a token
|
|
253
|
+
// rotation that happened mid-flight is still detected on the next
|
|
254
|
+
// effect run and triggers a force-rebuild.
|
|
248
255
|
hasWaasInitializedRef.current = true;
|
|
249
|
-
sessionIdRef.current =
|
|
256
|
+
sessionIdRef.current = currentSessionId;
|
|
250
257
|
// Host-observed time to get the WaaS iframe/client ready. Ships to
|
|
251
258
|
// Datadog (sliced by @version + environmentId) as the host-side
|
|
252
259
|
// companion to the iframe app's `waas_iframe_*` timing — used to
|
|
@@ -261,13 +268,14 @@ const useSyncDynamicWaas = () => {
|
|
|
261
268
|
.catch((error) => {
|
|
262
269
|
logger.logger.warn('[useSyncDynamicWaas] Error initializing waas', {
|
|
263
270
|
error,
|
|
264
|
-
sessionId,
|
|
271
|
+
sessionId: currentSessionId,
|
|
265
272
|
userId,
|
|
266
273
|
});
|
|
267
274
|
logger.logger.instrument('WaaS host init failed', {
|
|
268
275
|
environmentId,
|
|
269
276
|
key: 'waas_host_init_failed',
|
|
270
277
|
reason: error instanceof Error ? error.message : String(error),
|
|
278
|
+
sessionId: currentSessionId,
|
|
271
279
|
time: Date.now() - initStartedAt,
|
|
272
280
|
userId,
|
|
273
281
|
});
|
|
@@ -277,7 +285,13 @@ const useSyncDynamicWaas = () => {
|
|
|
277
285
|
});
|
|
278
286
|
}
|
|
279
287
|
}
|
|
280
|
-
}, [
|
|
288
|
+
}, [
|
|
289
|
+
initializeWaas,
|
|
290
|
+
shouldInitializeWaas,
|
|
291
|
+
user,
|
|
292
|
+
environmentId,
|
|
293
|
+
clearRecoveredWallets,
|
|
294
|
+
]);
|
|
281
295
|
React.useEffect(() => {
|
|
282
296
|
if (shouldCreateWallets()) {
|
|
283
297
|
handleWalletCreation();
|
|
@@ -28,6 +28,7 @@ import '../../functions/getWaasAddressTypeLabel/getWaasAddressTypeLabel.js';
|
|
|
28
28
|
import '../../../events/dynamicEvents.js';
|
|
29
29
|
import { useOnboardingCompleteUser } from '../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.js';
|
|
30
30
|
import { useProjectSettings } from '../../../client/extension/projectSettings/useProjectSettings/useProjectSettings.js';
|
|
31
|
+
import { getSessionIdFromMinToken } from '../../../client/extension/functions/getSessionIdFromMinToken/getSessionIdFromMinToken.js';
|
|
31
32
|
import '../../../context/DynamicContext/useDynamicContext/useDynamicContext.js';
|
|
32
33
|
import { useInternalDynamicContext } from '../../../context/DynamicContext/useDynamicContext/useInternalDynamicContext/useInternalDynamicContext.js';
|
|
33
34
|
import { useLoadingContext } from '../../../context/LoadingContext/LoadingContext.js';
|
|
@@ -215,19 +216,22 @@ const useSyncDynamicWaas = () => {
|
|
|
215
216
|
// Initialize waas iframe when user is authenticated
|
|
216
217
|
// This handles both page reload (user already authenticated) and fresh authentication
|
|
217
218
|
useEffect(() => {
|
|
219
|
+
const tokenSessionId = getSessionIdFromMinToken();
|
|
220
|
+
const currentSessionId = tokenSessionId !== null && tokenSessionId !== void 0 ? tokenSessionId : user === null || user === void 0 ? void 0 : user.sessionId;
|
|
218
221
|
// handle logout case where user is logged out but session id is still valid
|
|
219
|
-
if (sessionIdRef.current && !
|
|
222
|
+
if (sessionIdRef.current && !currentSessionId) {
|
|
220
223
|
sessionIdRef.current = undefined;
|
|
221
224
|
hasWaasInitializedRef.current = false;
|
|
222
225
|
initializingWaasRef.current = false;
|
|
223
226
|
clearRecoveredWallets();
|
|
224
227
|
}
|
|
225
|
-
if (shouldInitializeWaas && (user === null || user === void 0 ? void 0 : user.sessionId)) {
|
|
226
|
-
const {
|
|
228
|
+
if (shouldInitializeWaas && currentSessionId && (user === null || user === void 0 ? void 0 : user.sessionId)) {
|
|
229
|
+
const { id: userId } = user;
|
|
227
230
|
const shouldInitialize = !initializingWaasRef.current &&
|
|
228
|
-
(!hasWaasInitializedRef.current ||
|
|
231
|
+
(!hasWaasInitializedRef.current ||
|
|
232
|
+
sessionIdRef.current !== currentSessionId);
|
|
229
233
|
if (shouldInitialize) {
|
|
230
|
-
const isSessionIdChanged = sessionIdRef.current !==
|
|
234
|
+
const isSessionIdChanged = sessionIdRef.current !== currentSessionId;
|
|
231
235
|
// A swap from a prior session (e.g. step-up reauth) must rebuild the
|
|
232
236
|
// WaaS client so the iframe re-auths with the new session instead of
|
|
233
237
|
// 401-ing on the stale cached one. First init (no prior session) keeps
|
|
@@ -241,8 +245,11 @@ const useSyncDynamicWaas = () => {
|
|
|
241
245
|
initializeWaas({ forceClientRebuild })
|
|
242
246
|
.then(() => {
|
|
243
247
|
logger.debug('[useSyncDynamicWaas] waas initialized');
|
|
248
|
+
// Persist the session id this init actually ran with so a token
|
|
249
|
+
// rotation that happened mid-flight is still detected on the next
|
|
250
|
+
// effect run and triggers a force-rebuild.
|
|
244
251
|
hasWaasInitializedRef.current = true;
|
|
245
|
-
sessionIdRef.current =
|
|
252
|
+
sessionIdRef.current = currentSessionId;
|
|
246
253
|
// Host-observed time to get the WaaS iframe/client ready. Ships to
|
|
247
254
|
// Datadog (sliced by @version + environmentId) as the host-side
|
|
248
255
|
// companion to the iframe app's `waas_iframe_*` timing — used to
|
|
@@ -257,13 +264,14 @@ const useSyncDynamicWaas = () => {
|
|
|
257
264
|
.catch((error) => {
|
|
258
265
|
logger.warn('[useSyncDynamicWaas] Error initializing waas', {
|
|
259
266
|
error,
|
|
260
|
-
sessionId,
|
|
267
|
+
sessionId: currentSessionId,
|
|
261
268
|
userId,
|
|
262
269
|
});
|
|
263
270
|
logger.instrument('WaaS host init failed', {
|
|
264
271
|
environmentId,
|
|
265
272
|
key: 'waas_host_init_failed',
|
|
266
273
|
reason: error instanceof Error ? error.message : String(error),
|
|
274
|
+
sessionId: currentSessionId,
|
|
267
275
|
time: Date.now() - initStartedAt,
|
|
268
276
|
userId,
|
|
269
277
|
});
|
|
@@ -273,7 +281,13 @@ const useSyncDynamicWaas = () => {
|
|
|
273
281
|
});
|
|
274
282
|
}
|
|
275
283
|
}
|
|
276
|
-
}, [
|
|
284
|
+
}, [
|
|
285
|
+
initializeWaas,
|
|
286
|
+
shouldInitializeWaas,
|
|
287
|
+
user,
|
|
288
|
+
environmentId,
|
|
289
|
+
clearRecoveredWallets,
|
|
290
|
+
]);
|
|
277
291
|
useEffect(() => {
|
|
278
292
|
if (shouldCreateWallets()) {
|
|
279
293
|
handleWalletCreation();
|