@dynamic-labs/sdk-react-core 2.5.3 → 2.6.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 +9 -0
- package/package.cjs +2 -2
- package/package.js +2 -2
- package/package.json +14 -14
- package/src/lib/components/QRCode/QRCode.d.ts +15 -0
- package/src/lib/components/UserProfile/parts/UserProfileSocialAccount/UserProfileSocialAccount.cjs +1 -1
- package/src/lib/components/UserProfile/parts/UserProfileSocialAccount/UserProfileSocialAccount.js +1 -1
- package/src/lib/config/ApiEndpoint.cjs +6 -20
- package/src/lib/config/ApiEndpoint.d.ts +1 -2
- package/src/lib/config/ApiEndpoint.js +6 -20
- package/src/lib/context/DynamicContext/DynamicContext.cjs +2 -0
- package/src/lib/context/DynamicContext/DynamicContext.d.ts +2 -0
- package/src/lib/context/DynamicContext/DynamicContext.js +2 -0
- package/src/lib/context/DynamicContext/types/SocialSettings.d.ts +7 -0
- package/src/lib/context/DynamicContext/types/index.d.ts +2 -0
- package/src/lib/context/SocialRedirectContext/SocialRedirectContext.cjs +4 -0
- package/src/lib/context/SocialRedirectContext/SocialRedirectContext.js +4 -0
- package/src/lib/context/SocialRedirectContext/hooks/useRedirectSocialHandler/index.d.ts +1 -0
- package/src/lib/context/SocialRedirectContext/hooks/useRedirectSocialHandler/useRedirectSocialHandler.cjs +150 -0
- package/src/lib/context/SocialRedirectContext/hooks/useRedirectSocialHandler/useRedirectSocialHandler.d.ts +7 -0
- package/src/lib/context/SocialRedirectContext/hooks/useRedirectSocialHandler/useRedirectSocialHandler.js +146 -0
- package/src/lib/data/api/embeddedWallets/embeddedWallets.cjs +1 -1
- package/src/lib/data/api/embeddedWallets/embeddedWallets.js +1 -1
- package/src/lib/data/api/oauth/oauth.cjs +13 -0
- package/src/lib/data/api/oauth/oauth.d.ts +2 -1
- package/src/lib/data/api/oauth/oauth.js +13 -1
- package/src/lib/shared/utils/hooks/index.d.ts +1 -0
- package/src/lib/shared/utils/hooks/useEffectOnceCondition/index.d.ts +1 -0
- package/src/lib/shared/utils/hooks/useEffectOnceCondition/useEffectOnceCondition.cjs +26 -0
- package/src/lib/shared/utils/hooks/useEffectOnceCondition/useEffectOnceCondition.d.ts +7 -0
- package/src/lib/shared/utils/hooks/useEffectOnceCondition/useEffectOnceCondition.js +22 -0
- package/src/lib/styles/index.shadow.cjs +1 -1
- package/src/lib/styles/index.shadow.js +1 -1
- package/src/lib/utils/functions/index.d.ts +1 -0
- package/src/lib/utils/functions/socialStorage/index.d.ts +1 -0
- package/src/lib/utils/functions/socialStorage/socialStorage.cjs +36 -0
- package/src/lib/utils/functions/socialStorage/socialStorage.d.ts +17 -0
- package/src/lib/utils/functions/socialStorage/socialStorage.js +29 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/connectWithAppleId.cjs +26 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/connectWithAppleId.d.ts +7 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/connectWithAppleId.js +22 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/loadAppleId.cjs +34 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/loadAppleId.d.ts +1 -0
- package/src/lib/utils/hooks/useSocialAuth/apple/loadAppleId.js +30 -0
- package/src/lib/utils/hooks/useSocialAuth/index.d.ts +1 -1
- package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.cjs +85 -27
- package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.d.ts +9 -1
- package/src/lib/utils/hooks/useSocialAuth/useSocialAuth.js +90 -32
- package/src/lib/widgets/DynamicEmbeddedWidget/DynamicEmbeddedAuthFlow/DynamicEmbeddedAuthFlow.cjs +1 -2
- package/src/lib/widgets/DynamicEmbeddedWidget/DynamicEmbeddedAuthFlow/DynamicEmbeddedAuthFlow.js +1 -2
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../../../_virtual/_tslib.js';
|
|
3
|
-
import { useState, useRef } from 'react';
|
|
3
|
+
import { useMemo, useState, useRef } from 'react';
|
|
4
4
|
import { ProviderEnum } from '@dynamic-labs/sdk-api-core';
|
|
5
5
|
import { SocialOAuthErrorCode } from '@dynamic-labs/types';
|
|
6
|
-
import { PlatformService, isMobile, SocialAccountAlreadyExistsError } from '@dynamic-labs/utils';
|
|
6
|
+
import { isSafariBrowser, isIOS, PlatformService, isMobile, SocialAccountAlreadyExistsError } from '@dynamic-labs/utils';
|
|
7
7
|
import '../../../context/DynamicContext/DynamicContext.js';
|
|
8
8
|
import { logger } from '../../../shared/logger.js';
|
|
9
9
|
import '@dynamic-labs/iconic';
|
|
@@ -31,8 +31,9 @@ import 'viem';
|
|
|
31
31
|
import 'viem/chains';
|
|
32
32
|
import '../../../config/ApiEndpoint.js';
|
|
33
33
|
import '@dynamic-labs/store';
|
|
34
|
-
import { signInOAuth, verifyOAuth, farcasterSignIn, farcasterVerify } from '../../../data/api/oauth/oauth.js';
|
|
34
|
+
import { initAuth, signInOAuth, verifyOAuth, farcasterSignIn, farcasterVerify } from '../../../data/api/oauth/oauth.js';
|
|
35
35
|
import '../../../locale/locale.js';
|
|
36
|
+
import { setSocialStorageFor } from '../../functions/socialStorage/socialStorage.js';
|
|
36
37
|
import '../../../context/AccessDeniedContext/AccessDeniedContext.js';
|
|
37
38
|
import '../../../context/AccountExistsContext/AccountExistsContext.js';
|
|
38
39
|
import '../../../context/UserWalletsContext/UserWalletsContext.js';
|
|
@@ -43,6 +44,7 @@ import '../../../context/ThemeContext/ThemeContext.js';
|
|
|
43
44
|
import '../useUserUpdateRequest/useUpdateUser/userFieldsSchema.js';
|
|
44
45
|
import { useUserAuth } from '../useUserAuth/useUserAuth.js';
|
|
45
46
|
import { connect, watchStatus } from './farcaster.js';
|
|
47
|
+
import { connectWithAppleId } from './apple/connectWithAppleId.js';
|
|
46
48
|
import 'yup';
|
|
47
49
|
import '../../../context/MockContext/MockContext.js';
|
|
48
50
|
import '../../../views/CollectUserDataView/useFields.js';
|
|
@@ -101,9 +103,13 @@ const socialProviders = [
|
|
|
101
103
|
const providersRequiringPkce = ['twitter', 'github'];
|
|
102
104
|
// Hook to handle common social auth logic (for social linking and social sign in)
|
|
103
105
|
const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, }) => {
|
|
104
|
-
const { environmentId, setShowAuthFlow, projectSettings, consumeNonce, redirectUrl, } = useInternalDynamicContext();
|
|
106
|
+
const { environmentId, setShowAuthFlow, projectSettings, consumeNonce, socialSettings, redirectUrl, } = useInternalDynamicContext();
|
|
107
|
+
/**
|
|
108
|
+
* Represents if the SDK will use a popup or redirect for social auth
|
|
109
|
+
*/
|
|
110
|
+
const strategy = useMemo(() => (socialSettings === null || socialSettings === void 0 ? void 0 : socialSettings.strategy) || 'popup', [socialSettings]);
|
|
105
111
|
const { setErrorMessage, setError: setContextError } = useErrorContext();
|
|
106
|
-
const { initAuth } = useUserAuth({
|
|
112
|
+
const { initAuth: initAuth$1 } = useUserAuth({
|
|
107
113
|
authMethod: 'social',
|
|
108
114
|
});
|
|
109
115
|
const [isProcessing, setIsProcessing] = useState(false);
|
|
@@ -159,7 +165,7 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
159
165
|
}
|
|
160
166
|
});
|
|
161
167
|
const signInAccount = (provider, apiCall) => __awaiter(void 0, void 0, void 0, function* () {
|
|
162
|
-
yield initAuth({
|
|
168
|
+
yield initAuth$1({
|
|
163
169
|
onError: () => handleError(provider, SocialOAuthErrorCode.SIGNIN_ERROR, `Failed to sign-in with social account: ${provider}`, { raiseAuthFailure: true }),
|
|
164
170
|
onSettled,
|
|
165
171
|
options: { provider },
|
|
@@ -167,7 +173,7 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
167
173
|
});
|
|
168
174
|
});
|
|
169
175
|
const connectSocialAccount = (_a) => __awaiter(void 0, [_a], void 0, function* ({ authMode, provider, validator, captchaToken, }) {
|
|
170
|
-
var _b, _c;
|
|
176
|
+
var _b, _c, _d;
|
|
171
177
|
clearInterval(authWindowInterval.current);
|
|
172
178
|
clearError();
|
|
173
179
|
setIsProcessing(true);
|
|
@@ -189,17 +195,40 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
189
195
|
});
|
|
190
196
|
if (provider === ProviderEnum.Farcaster)
|
|
191
197
|
return connectWithFarcaster(authMode, { captchaToken });
|
|
192
|
-
|
|
198
|
+
let authWindow = null;
|
|
193
199
|
const state = randomString(32);
|
|
194
200
|
const verifier = randomString(43);
|
|
201
|
+
const apiProvider = getProviderByType((_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _b !== void 0 ? _b : [], provider);
|
|
202
|
+
const loginUrl = getOauthLoginUrl((_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _c !== void 0 ? _c : [], provider);
|
|
203
|
+
// Whether we will use PKCE (code verifier/challenge) for this provider
|
|
204
|
+
const usingPkce = providersRequiringPkce.includes(provider);
|
|
205
|
+
setSocialStorageFor(provider, {
|
|
206
|
+
captchaToken,
|
|
207
|
+
codeVerifier: verifier,
|
|
208
|
+
state,
|
|
209
|
+
});
|
|
210
|
+
if (provider === ProviderEnum.Apple &&
|
|
211
|
+
(isSafariBrowser() || isIOS() || strategy === 'redirect')) {
|
|
212
|
+
yield initAuth(environmentId, provider, {
|
|
213
|
+
// When we set the redirectUrl, the backend gives preference to a redirect
|
|
214
|
+
// experience, which is only desired for mobile
|
|
215
|
+
redirectUrl: removeDynamicOauthParamsFromUrl(redirectUrl || window.location.href),
|
|
216
|
+
state,
|
|
217
|
+
});
|
|
218
|
+
yield connectWithAppleId({
|
|
219
|
+
clientId: apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.clientId,
|
|
220
|
+
oauthLoginUrl: new URL(loginUrl),
|
|
221
|
+
state,
|
|
222
|
+
});
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
195
225
|
const clearListeners = () => {
|
|
196
226
|
window.removeEventListener('message', handleAuthWindowMessage);
|
|
197
227
|
providersWaitingOauthMessage.current = Object.assign(Object.assign({}, providersWaitingOauthMessage.current), { [provider]: false });
|
|
198
228
|
};
|
|
199
229
|
const handleAuthWindowMessage = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
200
|
-
var
|
|
230
|
+
var _e;
|
|
201
231
|
const message = event.data;
|
|
202
|
-
const apiProvider = getProviderByType((_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _d !== void 0 ? _d : [], provider);
|
|
203
232
|
if (!(apiProvider === null || apiProvider === void 0 ? void 0 : apiProvider.redirectUrl)) {
|
|
204
233
|
return;
|
|
205
234
|
}
|
|
@@ -256,31 +285,20 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
256
285
|
handleError(provider, SocialOAuthErrorCode.NO_AUTH_CODE, `Failed to connect ${provider} social account: no authorization code`, { raiseAuthFailure: authMode === 'signin' });
|
|
257
286
|
return;
|
|
258
287
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
const apiCall = () => verifyOAuth(environmentId, provider, {
|
|
270
|
-
code,
|
|
271
|
-
codeVerifier: verifier,
|
|
272
|
-
state,
|
|
273
|
-
});
|
|
274
|
-
yield linkAccount(provider, apiCall);
|
|
275
|
-
}
|
|
276
|
-
setIsProcessing(false);
|
|
288
|
+
yield completeConnection({
|
|
289
|
+
authCode: code,
|
|
290
|
+
authMode,
|
|
291
|
+
captchaToken,
|
|
292
|
+
provider,
|
|
293
|
+
state,
|
|
294
|
+
verifier,
|
|
295
|
+
});
|
|
277
296
|
});
|
|
278
|
-
const loginUrl = getOauthLoginUrl((_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) !== null && _b !== void 0 ? _b : [], provider);
|
|
279
297
|
if (!loginUrl) {
|
|
280
298
|
handleError(provider, SocialOAuthErrorCode.NO_OAUTH_URL, `Failed to get login url to connect social account: ${provider}`, { raiseAuthFailure: authMode === 'signin' });
|
|
281
299
|
return;
|
|
282
300
|
}
|
|
283
|
-
if (!((
|
|
301
|
+
if (!((_d = providersWaitingOauthMessage.current) === null || _d === void 0 ? void 0 : _d[provider])) {
|
|
284
302
|
window.addEventListener('message', handleAuthWindowMessage);
|
|
285
303
|
providersWaitingOauthMessage.current = Object.assign(Object.assign({}, providersWaitingOauthMessage.current), { [provider]: true });
|
|
286
304
|
}
|
|
@@ -290,7 +308,7 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
290
308
|
});
|
|
291
309
|
let oauthLoginUrl = `${loginUrl}&${stateParam}`;
|
|
292
310
|
// only add pkce params for providers that support/require it
|
|
293
|
-
if (
|
|
311
|
+
if (usingPkce) {
|
|
294
312
|
const digest = yield digestSHA256(verifier);
|
|
295
313
|
const pkceParams = stringifyURIQuery({
|
|
296
314
|
code_challenge: encodeBase64URL(digest),
|
|
@@ -298,6 +316,19 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
298
316
|
});
|
|
299
317
|
oauthLoginUrl = `${oauthLoginUrl}&${pkceParams}`;
|
|
300
318
|
}
|
|
319
|
+
yield initAuth(environmentId, provider, {
|
|
320
|
+
// When we set the redirectUrl, the backend gives preference to a redirect
|
|
321
|
+
// experience, which is only desired for mobile
|
|
322
|
+
redirectUrl: strategy === 'redirect'
|
|
323
|
+
? removeDynamicOauthParamsFromUrl(redirectUrl || window.location.href)
|
|
324
|
+
: undefined,
|
|
325
|
+
state,
|
|
326
|
+
});
|
|
327
|
+
if (strategy === 'redirect') {
|
|
328
|
+
window.location.assign(oauthLoginUrl);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
authWindow = window.open('', '_blank', 'width=500,height=600');
|
|
301
332
|
authWindow === null || authWindow === void 0 ? void 0 : authWindow.location.assign(oauthLoginUrl);
|
|
302
333
|
// For provider that support window.opener, we need to clear all states/listeners when the window is closed
|
|
303
334
|
authWindowInterval.current = setInterval(() => {
|
|
@@ -313,7 +344,27 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
313
344
|
}
|
|
314
345
|
}, 2000);
|
|
315
346
|
});
|
|
316
|
-
const
|
|
347
|
+
const completeConnection = (_f) => __awaiter(void 0, [_f], void 0, function* ({ authMode, provider, state, authCode, verifier, captchaToken, }) {
|
|
348
|
+
if (authMode === 'signin') {
|
|
349
|
+
const apiCall = () => signInOAuth(environmentId, provider, {
|
|
350
|
+
captchaToken,
|
|
351
|
+
code: authCode,
|
|
352
|
+
codeVerifier: verifier,
|
|
353
|
+
state,
|
|
354
|
+
});
|
|
355
|
+
yield signInAccount(provider, apiCall);
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
const apiCall = () => verifyOAuth(environmentId, provider, {
|
|
359
|
+
code: authCode,
|
|
360
|
+
codeVerifier: verifier,
|
|
361
|
+
state,
|
|
362
|
+
});
|
|
363
|
+
yield linkAccount(provider, apiCall);
|
|
364
|
+
}
|
|
365
|
+
setIsProcessing(false);
|
|
366
|
+
});
|
|
367
|
+
const connectWithFarcaster = (authMode_1, _g) => __awaiter(void 0, [authMode_1, _g], void 0, function* (authMode, { captchaToken }) {
|
|
317
368
|
const dynamicNonce = consumeNonce();
|
|
318
369
|
const domain = PlatformService.getHost();
|
|
319
370
|
const data = yield connect({
|
|
@@ -382,6 +433,7 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
382
433
|
});
|
|
383
434
|
return {
|
|
384
435
|
checkValidProvider,
|
|
436
|
+
completeConnection,
|
|
385
437
|
connectSocialAccount,
|
|
386
438
|
error,
|
|
387
439
|
handleError,
|
|
@@ -390,5 +442,11 @@ const useSocialAuth = ({ sessionTimeout, onSettled, onError, onFarcasterUrl, })
|
|
|
390
442
|
setIsProcessing,
|
|
391
443
|
};
|
|
392
444
|
};
|
|
445
|
+
const removeDynamicOauthParamsFromUrl = (url) => {
|
|
446
|
+
const urlObject = new URL(url);
|
|
447
|
+
urlObject.searchParams.delete('dynamicOauthState');
|
|
448
|
+
urlObject.searchParams.delete('dynamicOauthCode');
|
|
449
|
+
return urlObject.toString();
|
|
450
|
+
};
|
|
393
451
|
|
|
394
452
|
export { useSocialAuth };
|
package/src/lib/widgets/DynamicEmbeddedWidget/DynamicEmbeddedAuthFlow/DynamicEmbeddedAuthFlow.cjs
CHANGED
|
@@ -78,7 +78,6 @@ var PopperContext = require('../../../components/Popper/PopperContext/PopperCont
|
|
|
78
78
|
require('qrcode');
|
|
79
79
|
var RenderView = require('../../../components/RenderView/RenderView.cjs');
|
|
80
80
|
var SandboxIndicatorWrapper = require('../../../components/SandboxIndicatorWrapper/SandboxIndicatorWrapper.cjs');
|
|
81
|
-
var SocialRedirectContext = require('../../../context/SocialRedirectContext/SocialRedirectContext.cjs');
|
|
82
81
|
|
|
83
82
|
const DynamicEmbeddedAuthFlow = ({ background = 'none', className, style, }) => {
|
|
84
83
|
const hide = useIsLoggedIn.useIsLoggedIn();
|
|
@@ -109,7 +108,7 @@ const DynamicEmbeddedAuthFlow = ({ background = 'none', className, style, }) =>
|
|
|
109
108
|
if (hide)
|
|
110
109
|
return null;
|
|
111
110
|
const content = (jsxRuntime.jsx(DynamicAuthLayout.DynamicAuthLayout, { className: className, style: style, projectSettings: projectSettings, children: jsxRuntime.jsx(RenderView.RenderView, {}) }));
|
|
112
|
-
return (jsxRuntime.jsx(ShadowDOM.ShadowDOM, { className: 'embedded-widget', children: jsxRuntime.jsx(PopperContext.PopperProvider, { children: jsxRuntime.jsx(
|
|
111
|
+
return (jsxRuntime.jsx(ShadowDOM.ShadowDOM, { className: 'embedded-widget', children: jsxRuntime.jsx(PopperContext.PopperProvider, { children: jsxRuntime.jsx(index.FooterAnimationContextProvider, { children: jsxRuntime.jsx(SandboxIndicatorWrapper.SandboxIndicatorWrapper, { children: background === 'none' ? (content) : (jsxRuntime.jsx(ModalCard.ModalCard, { border: background === 'with-border', sharpBottomRadiusOnMobile: false, children: content })) }) }) }) }));
|
|
113
112
|
};
|
|
114
113
|
|
|
115
114
|
exports.DynamicEmbeddedAuthFlow = DynamicEmbeddedAuthFlow;
|
package/src/lib/widgets/DynamicEmbeddedWidget/DynamicEmbeddedAuthFlow/DynamicEmbeddedAuthFlow.js
CHANGED
|
@@ -74,7 +74,6 @@ import { PopperProvider } from '../../../components/Popper/PopperContext/PopperC
|
|
|
74
74
|
import 'qrcode';
|
|
75
75
|
import { RenderView } from '../../../components/RenderView/RenderView.js';
|
|
76
76
|
import { SandboxIndicatorWrapper } from '../../../components/SandboxIndicatorWrapper/SandboxIndicatorWrapper.js';
|
|
77
|
-
import { SocialRedirectContextProvider } from '../../../context/SocialRedirectContext/SocialRedirectContext.js';
|
|
78
77
|
|
|
79
78
|
const DynamicEmbeddedAuthFlow = ({ background = 'none', className, style, }) => {
|
|
80
79
|
const hide = useIsLoggedIn();
|
|
@@ -105,7 +104,7 @@ const DynamicEmbeddedAuthFlow = ({ background = 'none', className, style, }) =>
|
|
|
105
104
|
if (hide)
|
|
106
105
|
return null;
|
|
107
106
|
const content = (jsx(DynamicAuthLayout, { className: className, style: style, projectSettings: projectSettings, children: jsx(RenderView, {}) }));
|
|
108
|
-
return (jsx(ShadowDOM, { className: 'embedded-widget', children: jsx(PopperProvider, { children: jsx(
|
|
107
|
+
return (jsx(ShadowDOM, { className: 'embedded-widget', children: jsx(PopperProvider, { children: jsx(FooterAnimationContextProvider, { children: jsx(SandboxIndicatorWrapper, { children: background === 'none' ? (content) : (jsx(ModalCard, { border: background === 'with-border', sharpBottomRadiusOnMobile: false, children: content })) }) }) }) }));
|
|
109
108
|
};
|
|
110
109
|
|
|
111
110
|
export { DynamicEmbeddedAuthFlow };
|