@turnkey/react-wallet-kit 1.11.1 → 2.0.0
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/dist/components/auth/OTP.d.ts +1 -0
- package/dist/components/auth/OTP.d.ts.map +1 -1
- package/dist/components/auth/OTP.js +8 -2
- package/dist/components/auth/OTP.js.map +1 -1
- package/dist/components/auth/OTP.mjs +21 -13
- package/dist/components/auth/OTP.mjs.map +1 -1
- package/dist/components/auth/index.d.ts.map +1 -1
- package/dist/components/auth/index.js +11 -3
- package/dist/components/auth/index.js.map +1 -1
- package/dist/components/auth/index.mjs +12 -5
- package/dist/components/auth/index.mjs.map +1 -1
- package/dist/components/user/UpdateEmail.js +6 -3
- package/dist/components/user/UpdateEmail.js.map +1 -1
- package/dist/components/user/UpdateEmail.mjs +6 -4
- package/dist/components/user/UpdateEmail.mjs.map +1 -1
- package/dist/components/user/UpdatePhoneNumber.js +6 -3
- package/dist/components/user/UpdatePhoneNumber.js.map +1 -1
- package/dist/components/user/UpdatePhoneNumber.mjs +6 -4
- package/dist/components/user/UpdatePhoneNumber.mjs.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/providers/client/Provider.d.ts.map +1 -1
- package/dist/providers/client/Provider.js +319 -135
- package/dist/providers/client/Provider.js.map +1 -1
- package/dist/providers/client/Provider.mjs +1994 -1748
- package/dist/providers/client/Provider.mjs.map +1 -1
- package/dist/providers/client/Types.d.ts +14 -7
- package/dist/providers/client/Types.d.ts.map +1 -1
- package/dist/providers/client/Types.js.map +1 -1
- package/dist/providers/client/Types.mjs.map +1 -1
- package/dist/typedoc-entry/index.d.ts +1 -1
- package/dist/typedoc-entry/index.d.ts.map +1 -1
- package/dist/types/base.d.ts +38 -28
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/base.js.map +1 -1
- package/dist/types/base.mjs.map +1 -1
- package/dist/types/method-types.d.ts +12 -5
- package/dist/types/method-types.d.ts.map +1 -1
- package/dist/utils/oauth/storage.d.ts +11 -0
- package/dist/utils/oauth/storage.d.ts.map +1 -1
- package/dist/utils/oauth/storage.js +29 -0
- package/dist/utils/oauth/storage.js.map +1 -1
- package/dist/utils/oauth/storage.mjs +27 -1
- package/dist/utils/oauth/storage.mjs.map +1 -1
- package/dist/utils/oauth/url.d.ts.map +1 -1
- package/dist/utils/oauth/url.js +10 -1
- package/dist/utils/oauth/url.js.map +1 -1
- package/dist/utils/oauth/url.mjs +11 -2
- package/dist/utils/oauth/url.mjs.map +1 -1
- package/package.json +3 -3
|
@@ -191,10 +191,10 @@ const ClientProvider = ({
|
|
|
191
191
|
const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
|
|
192
192
|
/**
|
|
193
193
|
* Helper to complete PKCE redirect flow with optional modal wrapper.
|
|
194
|
-
* Uses
|
|
194
|
+
* Uses handlePKCEFlow from oauth utils for the core logic.
|
|
195
195
|
* We put this in a separate function to avoid duplicating for each provider.
|
|
196
196
|
*/
|
|
197
|
-
const completePKCERedirect = async (providerName, exchangeCodeFn) => {
|
|
197
|
+
const completePKCERedirect = async (providerName, exchangeCodeFn, secondaryClientIds) => {
|
|
198
198
|
const action = async () => {
|
|
199
199
|
try {
|
|
200
200
|
await completion.completePKCEFlow({
|
|
@@ -202,13 +202,29 @@ const ClientProvider = ({
|
|
|
202
202
|
providerName,
|
|
203
203
|
sessionKey: sessionKey ?? undefined,
|
|
204
204
|
callbacks,
|
|
205
|
-
completeOauth
|
|
205
|
+
completeOauth: completionParams => {
|
|
206
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
207
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? providerName, secondaryClientIds);
|
|
208
|
+
return completeOauth({
|
|
209
|
+
...completionParams,
|
|
210
|
+
...(secondaryProviders.length > 0 && {
|
|
211
|
+
createSubOrgParams: {
|
|
212
|
+
...existingCreateSubOrgParams,
|
|
213
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
214
|
+
}
|
|
215
|
+
})
|
|
216
|
+
});
|
|
217
|
+
},
|
|
206
218
|
onAddProvider:
|
|
207
219
|
// Only set onAddProvider if we are adding a provider and have metadata
|
|
208
220
|
isAddProvider && metadata ? async oidcToken => {
|
|
221
|
+
const oidcClaims = core.buildSecondaryOidcClaims(oidcToken, secondaryClientIds);
|
|
209
222
|
await addOauthProvider({
|
|
210
223
|
providerName: provider,
|
|
211
224
|
oidcToken,
|
|
225
|
+
...(oidcClaims.length > 0 && {
|
|
226
|
+
oidcClaims
|
|
227
|
+
}),
|
|
212
228
|
organizationId: metadata.organizationId,
|
|
213
229
|
userId: metadata.userId,
|
|
214
230
|
...(metadata.stampWith && {
|
|
@@ -238,7 +254,8 @@ const ClientProvider = ({
|
|
|
238
254
|
};
|
|
239
255
|
// FACEBOOK
|
|
240
256
|
if (provider === sdkTypes.OAuthProviders.FACEBOOK) {
|
|
241
|
-
const clientId = masterConfig?.auth?.oauthConfig?.
|
|
257
|
+
const clientId = masterConfig?.auth?.oauthConfig?.facebook?.primaryClientId;
|
|
258
|
+
const secondaryClientIds = masterConfig?.auth?.oauthConfig?.facebook?.secondaryClientIds ?? [];
|
|
242
259
|
const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
243
260
|
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.FACEBOOK);
|
|
244
261
|
if (clientId && redirectURI && hasVerifier) {
|
|
@@ -249,13 +266,14 @@ const ClientProvider = ({
|
|
|
249
266
|
throw new sdkTypes.TurnkeyError("Missing OIDC token", sdkTypes.TurnkeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
250
267
|
}
|
|
251
268
|
return oidcToken;
|
|
252
|
-
});
|
|
269
|
+
}, secondaryClientIds);
|
|
253
270
|
}
|
|
254
271
|
return;
|
|
255
272
|
}
|
|
256
273
|
// DISCORD
|
|
257
274
|
if (provider === sdkTypes.OAuthProviders.DISCORD) {
|
|
258
|
-
const clientId = masterConfig?.auth?.oauthConfig?.
|
|
275
|
+
const clientId = masterConfig?.auth?.oauthConfig?.discord?.primaryClientId;
|
|
276
|
+
const secondaryClientIds = masterConfig?.auth?.oauthConfig?.discord?.secondaryClientIds ?? [];
|
|
259
277
|
const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
260
278
|
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.DISCORD);
|
|
261
279
|
if (clientId && redirectURI && hasVerifier && nonce) {
|
|
@@ -273,13 +291,14 @@ const ClientProvider = ({
|
|
|
273
291
|
throw new sdkTypes.TurnkeyError("Missing OIDC token", sdkTypes.TurnkeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
274
292
|
}
|
|
275
293
|
return oidcToken;
|
|
276
|
-
});
|
|
294
|
+
}, secondaryClientIds);
|
|
277
295
|
}
|
|
278
296
|
return;
|
|
279
297
|
}
|
|
280
298
|
// X (Twitter)
|
|
281
299
|
if (provider === sdkTypes.OAuthProviders.X) {
|
|
282
|
-
const clientId = masterConfig?.auth?.oauthConfig?.
|
|
300
|
+
const clientId = masterConfig?.auth?.oauthConfig?.x?.primaryClientId;
|
|
301
|
+
const secondaryClientIds = masterConfig?.auth?.oauthConfig?.x?.secondaryClientIds ?? [];
|
|
283
302
|
const redirectURI = masterConfig?.auth?.oauthConfig?.oauthRedirectUri;
|
|
284
303
|
const hasVerifier = storage.hasPKCEVerifier(sdkTypes.OAuthProviders.X);
|
|
285
304
|
if (clientId && redirectURI && hasVerifier && nonce) {
|
|
@@ -297,7 +316,7 @@ const ClientProvider = ({
|
|
|
297
316
|
throw new sdkTypes.TurnkeyError("Missing OIDC token", sdkTypes.TurnkeyErrorCodes.OAUTH_LOGIN_ERROR);
|
|
298
317
|
}
|
|
299
318
|
return oidcToken;
|
|
300
|
-
});
|
|
319
|
+
}, secondaryClientIds);
|
|
301
320
|
}
|
|
302
321
|
return;
|
|
303
322
|
}
|
|
@@ -321,6 +340,8 @@ const ClientProvider = ({
|
|
|
321
340
|
const isAddProvider = oauthIntent === storage.OAUTH_INTENT_ADD_PROVIDER;
|
|
322
341
|
const metadata = isAddProvider ? storage.getOAuthAddProviderMetadata() : null;
|
|
323
342
|
const resolvedProvider = provider || sdkTypes.OAuthProviders.GOOGLE;
|
|
343
|
+
// Grab Google/Apple secondary client IDs from config for use in completion
|
|
344
|
+
const secondaryClientIds = (resolvedProvider === sdkTypes.OAuthProviders.GOOGLE ? masterConfig?.auth?.oauthConfig?.google?.secondaryClientIds : resolvedProvider === sdkTypes.OAuthProviders.APPLE ? masterConfig?.auth?.oauthConfig?.apple?.secondaryClientIds : undefined) ?? [];
|
|
324
345
|
// Use completeOAuthFlow from utils for the core completion logic
|
|
325
346
|
const action = async () => {
|
|
326
347
|
await completion.completeOAuthFlow({
|
|
@@ -329,11 +350,27 @@ const ClientProvider = ({
|
|
|
329
350
|
oidcToken: idToken,
|
|
330
351
|
sessionKey: sessionKey ?? undefined,
|
|
331
352
|
callbacks,
|
|
332
|
-
completeOauth
|
|
353
|
+
completeOauth: completionParams => {
|
|
354
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
355
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? resolvedProvider, secondaryClientIds);
|
|
356
|
+
return completeOauth({
|
|
357
|
+
...completionParams,
|
|
358
|
+
...(secondaryProviders.length > 0 && {
|
|
359
|
+
createSubOrgParams: {
|
|
360
|
+
...existingCreateSubOrgParams,
|
|
361
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
});
|
|
365
|
+
},
|
|
333
366
|
onAddProvider: isAddProvider && metadata ? async oidcToken => {
|
|
367
|
+
const oidcClaims = core.buildSecondaryOidcClaims(oidcToken, secondaryClientIds);
|
|
334
368
|
await addOauthProvider({
|
|
335
369
|
providerName: resolvedProvider,
|
|
336
370
|
oidcToken,
|
|
371
|
+
...(oidcClaims.length > 0 && {
|
|
372
|
+
oidcClaims
|
|
373
|
+
}),
|
|
337
374
|
organizationId: metadata.organizationId,
|
|
338
375
|
userId: metadata.userId,
|
|
339
376
|
...(metadata.stampWith && {
|
|
@@ -360,28 +397,43 @@ const ClientProvider = ({
|
|
|
360
397
|
const buildConfig = proxyAuthConfig => {
|
|
361
398
|
// Juggle the local overrides with the values set in the dashboard (proxyAuthConfig).
|
|
362
399
|
const resolvedMethods = {
|
|
363
|
-
emailOtpAuthEnabled: config.
|
|
364
|
-
smsOtpAuthEnabled: config.
|
|
365
|
-
passkeyAuthEnabled: config.
|
|
366
|
-
walletAuthEnabled: config.
|
|
367
|
-
googleOauthEnabled: config.
|
|
368
|
-
xOauthEnabled: config.
|
|
369
|
-
discordOauthEnabled: config.
|
|
370
|
-
appleOauthEnabled: config.
|
|
371
|
-
facebookOauthEnabled: config.
|
|
400
|
+
emailOtpAuthEnabled: config.ui?.authModal?.methods?.emailOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("email"),
|
|
401
|
+
smsOtpAuthEnabled: config.ui?.authModal?.methods?.smsOtpAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("sms"),
|
|
402
|
+
passkeyAuthEnabled: config.ui?.authModal?.methods?.passkeyAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("passkey"),
|
|
403
|
+
walletAuthEnabled: config.ui?.authModal?.methods?.walletAuthEnabled ?? proxyAuthConfig?.enabledProviders.includes("wallet"),
|
|
404
|
+
googleOauthEnabled: config.ui?.authModal?.methods?.googleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("google"),
|
|
405
|
+
xOauthEnabled: config.ui?.authModal?.methods?.xOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("x"),
|
|
406
|
+
discordOauthEnabled: config.ui?.authModal?.methods?.discordOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("discord"),
|
|
407
|
+
appleOauthEnabled: config.ui?.authModal?.methods?.appleOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("apple"),
|
|
408
|
+
facebookOauthEnabled: config.ui?.authModal?.methods?.facebookOauthEnabled ?? proxyAuthConfig?.enabledProviders.includes("facebook")
|
|
372
409
|
};
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
410
|
+
const resolvedOauthProviders = {
|
|
411
|
+
google: {
|
|
412
|
+
primaryClientId: config.auth?.oauthConfig?.google?.primaryClientId ?? proxyAuthConfig?.oauthClientIds?.google,
|
|
413
|
+
secondaryClientIds: config.auth?.oauthConfig?.google?.secondaryClientIds ?? []
|
|
414
|
+
},
|
|
415
|
+
apple: {
|
|
416
|
+
primaryClientId: config.auth?.oauthConfig?.apple?.primaryClientId ?? proxyAuthConfig?.oauthClientIds?.apple,
|
|
417
|
+
secondaryClientIds: config.auth?.oauthConfig?.apple?.secondaryClientIds ?? []
|
|
418
|
+
},
|
|
419
|
+
facebook: {
|
|
420
|
+
primaryClientId: config.auth?.oauthConfig?.facebook?.primaryClientId ?? proxyAuthConfig?.oauthClientIds?.facebook,
|
|
421
|
+
secondaryClientIds: config.auth?.oauthConfig?.facebook?.secondaryClientIds ?? []
|
|
422
|
+
},
|
|
423
|
+
x: {
|
|
424
|
+
primaryClientId: config.auth?.oauthConfig?.x?.primaryClientId ?? proxyAuthConfig?.oauthClientIds?.x,
|
|
425
|
+
secondaryClientIds: config.auth?.oauthConfig?.x?.secondaryClientIds ?? []
|
|
426
|
+
},
|
|
427
|
+
discord: {
|
|
428
|
+
primaryClientId: config.auth?.oauthConfig?.discord?.primaryClientId ?? proxyAuthConfig?.oauthClientIds?.discord,
|
|
429
|
+
secondaryClientIds: config.auth?.oauthConfig?.discord?.secondaryClientIds ?? []
|
|
430
|
+
}
|
|
379
431
|
};
|
|
380
432
|
const redirectUrl = config.auth?.oauthConfig?.oauthRedirectUri ?? proxyAuthConfig?.oauthRedirectUrl;
|
|
381
433
|
// Set a default ordering for the oAuth methods
|
|
382
|
-
const oauthOrder = config.
|
|
434
|
+
const oauthOrder = config.ui?.authModal?.oauthOrder ?? ["google", "apple", "x", "discord", "facebook"].filter(provider => resolvedMethods[`${provider}OauthEnabled`]);
|
|
383
435
|
// Set a default ordering for the overall auth methods
|
|
384
|
-
const methodOrder = config.
|
|
436
|
+
const methodOrder = config.ui?.authModal?.methodOrder ?? [oauthOrder.length > 0 ? "socials" : null, resolvedMethods.emailOtpAuthEnabled ? "email" : null, resolvedMethods.smsOtpAuthEnabled ? "sms" : null, resolvedMethods.passkeyAuthEnabled ? "passkey" : null, resolvedMethods.walletAuthEnabled ? "wallet" : null].filter(Boolean);
|
|
385
437
|
// Warn if they are trying to set auth proxy only settings directly
|
|
386
438
|
if (proxyAuthConfig) {
|
|
387
439
|
if (config.auth?.sessionExpirationSeconds) {
|
|
@@ -400,24 +452,33 @@ const ClientProvider = ({
|
|
|
400
452
|
otpAlphanumeric: proxyAuthConfig?.otpAlphanumeric ?? config.auth?.otpAlphanumeric ?? true,
|
|
401
453
|
otpLength: proxyAuthConfig?.otpLength ?? config.auth?.otpLength ?? "6"
|
|
402
454
|
};
|
|
455
|
+
const scopePasskeyToUser = config.auth?.scopePasskeyToUser ?? true;
|
|
403
456
|
return {
|
|
404
457
|
...config,
|
|
458
|
+
scopePasskeyToUser,
|
|
405
459
|
// Overrides:
|
|
406
460
|
auth: {
|
|
407
461
|
...config.auth,
|
|
408
462
|
...authProxyPrioSettings,
|
|
409
|
-
methods: resolvedMethods,
|
|
410
463
|
oauthConfig: {
|
|
411
464
|
...config.auth?.oauthConfig,
|
|
412
|
-
...
|
|
465
|
+
...resolvedOauthProviders,
|
|
413
466
|
oauthRedirectUri: redirectUrl,
|
|
414
467
|
// on mobile we default to true since many mobile browsers
|
|
415
468
|
// (e.g. Safari) block popups
|
|
416
469
|
openOauthInPage: isMobile ? true : config.auth?.oauthConfig?.openOauthInPage
|
|
417
470
|
},
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
471
|
+
autoRefreshSession: config.auth?.autoRefreshSession ?? true,
|
|
472
|
+
scopePasskeyToUser
|
|
473
|
+
},
|
|
474
|
+
ui: {
|
|
475
|
+
...config.ui,
|
|
476
|
+
authModal: {
|
|
477
|
+
...config.ui?.authModal,
|
|
478
|
+
methods: resolvedMethods,
|
|
479
|
+
methodOrder,
|
|
480
|
+
oauthOrder
|
|
481
|
+
}
|
|
421
482
|
},
|
|
422
483
|
autoRefreshManagedState: config.autoRefreshManagedState ?? true,
|
|
423
484
|
walletConfig: {
|
|
@@ -482,7 +543,8 @@ const ClientProvider = ({
|
|
|
482
543
|
walletConnect: masterConfig.walletConfig.walletConnect
|
|
483
544
|
})
|
|
484
545
|
},
|
|
485
|
-
defaultStamperType: masterConfig.defaultStamperType
|
|
546
|
+
defaultStamperType: masterConfig.defaultStamperType,
|
|
547
|
+
scopePasskeyToUser: masterConfig.scopePasskeyToUser ?? true
|
|
486
548
|
});
|
|
487
549
|
await turnkeyClient.init();
|
|
488
550
|
setClient(turnkeyClient);
|
|
@@ -535,7 +597,7 @@ const ClientProvider = ({
|
|
|
535
597
|
// specifically, if WalletConnect finishes initializing before this promise resolves,
|
|
536
598
|
// `maybeRefreshWallets()` could overwrite the WalletConnect wallet state with an outdated
|
|
537
599
|
// list of wallets that doesn’t yet include the WalletConnect wallets
|
|
538
|
-
const [, wallets] = await Promise.all([maybeRefreshUser(), (() => {
|
|
600
|
+
const [user, wallets] = await Promise.all([maybeRefreshUser(), (() => {
|
|
539
601
|
if (!masterConfig?.autoRefreshManagedState) return [];
|
|
540
602
|
return fetchWallets();
|
|
541
603
|
})()]);
|
|
@@ -543,6 +605,7 @@ const ClientProvider = ({
|
|
|
543
605
|
if (wallets) {
|
|
544
606
|
setWallets(prev => utils.mergeWalletsWithoutDuplicates(prev, wallets));
|
|
545
607
|
}
|
|
608
|
+
if (client) await core.applyPasskeyScope(client, client.config.passkeyConfig, user, masterConfig?.auth?.scopePasskeyToUser);
|
|
546
609
|
return;
|
|
547
610
|
}
|
|
548
611
|
} catch (error) {
|
|
@@ -730,7 +793,8 @@ const ClientProvider = ({
|
|
|
730
793
|
const allSessions = await client.getAllSessions();
|
|
731
794
|
setSession(session);
|
|
732
795
|
setAllSessions(allSessions);
|
|
733
|
-
await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
|
|
796
|
+
const [, user] = await Promise.all([maybeRefreshWallets(), maybeRefreshUser()]);
|
|
797
|
+
if (client) await core.applyPasskeyScope(client, client.config.passkeyConfig, user, masterConfig?.auth?.scopePasskeyToUser);
|
|
734
798
|
if (masterConfig?.auth?.verifyWalletOnSignup === true && appProofs && appProofs.length > 0 && action === sdkTypes.AuthAction.SIGNUP) {
|
|
735
799
|
// On signup, if we have appProofs, verify them
|
|
736
800
|
await handleVerifyAppProofs({
|
|
@@ -764,9 +828,10 @@ const ClientProvider = ({
|
|
|
764
828
|
* @returns void
|
|
765
829
|
* @throws {TurnkeyError} If there is an error during the post-logout process.
|
|
766
830
|
*/
|
|
767
|
-
const handlePostLogout = sessionKey => {
|
|
831
|
+
const handlePostLogout = react.useCallback(async sessionKey => {
|
|
768
832
|
try {
|
|
769
|
-
|
|
833
|
+
const timeoutKeys = sessionKey ? [sessionKey, `${sessionKey}-warning`] : undefined;
|
|
834
|
+
clearSessionTimeouts(timeoutKeys);
|
|
770
835
|
setAllSessions(prev => {
|
|
771
836
|
if (!prev) return prev;
|
|
772
837
|
if (sessionKey) {
|
|
@@ -781,16 +846,29 @@ const ClientProvider = ({
|
|
|
781
846
|
setSession(undefined);
|
|
782
847
|
setUser(undefined);
|
|
783
848
|
setWallets([]);
|
|
849
|
+
if (client) await core.resetPasskeyScope(client, client.config.passkeyConfig);
|
|
784
850
|
} catch (error) {
|
|
785
|
-
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to
|
|
851
|
+
callbacks?.onError?.(new sdkTypes.TurnkeyError(`Failed to handle post logout`, sdkTypes.TurnkeyErrorCodes.HANDLE_POST_LOGOUT_ERROR, error));
|
|
786
852
|
}
|
|
787
|
-
};
|
|
853
|
+
}, [callbacks, clearSessionTimeouts, client, masterConfig?.passkeyConfig]);
|
|
788
854
|
const createHttpClient = react.useCallback(params => {
|
|
789
855
|
if (!client) {
|
|
790
856
|
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
791
857
|
}
|
|
792
858
|
return client.createHttpClient(params);
|
|
793
859
|
}, [client]);
|
|
860
|
+
const overrideApiKeyStamper = react.useCallback(params => {
|
|
861
|
+
if (!client) {
|
|
862
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
863
|
+
}
|
|
864
|
+
return client.overrideApiKeyStamper(params);
|
|
865
|
+
}, [client]);
|
|
866
|
+
const overridePasskeyStamper = react.useCallback(params => {
|
|
867
|
+
if (!client) {
|
|
868
|
+
throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
869
|
+
}
|
|
870
|
+
return client.overridePasskeyStamper(params);
|
|
871
|
+
}, [client]);
|
|
794
872
|
const getActiveSessionKey = react.useCallback(async () => {
|
|
795
873
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
796
874
|
return utils.withTurnkeyErrorHandling(() => client.getActiveSessionKey(), undefined, callbacks, "Failed to get active session key");
|
|
@@ -805,10 +883,10 @@ const ClientProvider = ({
|
|
|
805
883
|
if (!sessionKey) sessionKey = await getActiveSessionKey();
|
|
806
884
|
await client.logout(params);
|
|
807
885
|
// We only handle post logout if the sessionKey is defined since that means we actually logged out of a session.
|
|
808
|
-
if (sessionKey) handlePostLogout(sessionKey);
|
|
886
|
+
if (sessionKey) await handlePostLogout(sessionKey);
|
|
809
887
|
}, undefined, callbacks, "Failed to logout");
|
|
810
888
|
return;
|
|
811
|
-
}, [client, callbacks, getActiveSessionKey]);
|
|
889
|
+
}, [client, callbacks, getActiveSessionKey, handlePostLogout]);
|
|
812
890
|
const getSession = react.useCallback(async params => {
|
|
813
891
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
814
892
|
return utils.withTurnkeyErrorHandling(() => client.getSession(params), undefined, callbacks, "Failed to get session");
|
|
@@ -868,6 +946,7 @@ const ClientProvider = ({
|
|
|
868
946
|
if (user) {
|
|
869
947
|
setUser(user);
|
|
870
948
|
}
|
|
949
|
+
return user;
|
|
871
950
|
}, [client, callbacks, fetchUser, logout]);
|
|
872
951
|
/**
|
|
873
952
|
* @internal
|
|
@@ -879,7 +958,7 @@ const ClientProvider = ({
|
|
|
879
958
|
* @returns A promise that resolves when the user is refreshed, or does nothing if auto-refresh is disabled
|
|
880
959
|
*/
|
|
881
960
|
const maybeRefreshUser = react.useCallback(async params => {
|
|
882
|
-
if (!masterConfig?.autoRefreshManagedState) return;
|
|
961
|
+
if (!masterConfig?.autoRefreshManagedState) return undefined;
|
|
883
962
|
return refreshUser(params);
|
|
884
963
|
}, [masterConfig, refreshUser]);
|
|
885
964
|
const refreshWallets = react.useCallback(async params => {
|
|
@@ -920,11 +999,15 @@ const ClientProvider = ({
|
|
|
920
999
|
}, [masterConfig, refreshWallets]);
|
|
921
1000
|
const clearSession = react.useCallback(async params => {
|
|
922
1001
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1002
|
+
const activeSessionKey = await getActiveSessionKey();
|
|
923
1003
|
await utils.withTurnkeyErrorHandling(async () => client.clearSession(params), undefined, callbacks, "Failed to clear session");
|
|
924
|
-
const sessionKey = params?.sessionKey ??
|
|
1004
|
+
const sessionKey = params?.sessionKey ?? activeSessionKey;
|
|
925
1005
|
if (!sessionKey) return;
|
|
926
|
-
if (!params?.sessionKey) {
|
|
1006
|
+
if (!params?.sessionKey || params.sessionKey === activeSessionKey) {
|
|
927
1007
|
setSession(undefined);
|
|
1008
|
+
setUser(undefined);
|
|
1009
|
+
setWallets([]);
|
|
1010
|
+
if (client) await core.resetPasskeyScope(client, client.config.passkeyConfig);
|
|
928
1011
|
}
|
|
929
1012
|
clearSessionTimeouts([sessionKey]);
|
|
930
1013
|
// clear only the cleared session from allSessions
|
|
@@ -936,7 +1019,7 @@ const ClientProvider = ({
|
|
|
936
1019
|
}
|
|
937
1020
|
setAllSessions(newAllSessions);
|
|
938
1021
|
return;
|
|
939
|
-
}, [client, callbacks, getActiveSessionKey, allSessions]);
|
|
1022
|
+
}, [client, callbacks, getActiveSessionKey, allSessions, masterConfig?.passkeyConfig]);
|
|
940
1023
|
/**
|
|
941
1024
|
* @internal
|
|
942
1025
|
* Schedules a session expiration and warning timer for the given session key.
|
|
@@ -1606,17 +1689,20 @@ const ClientProvider = ({
|
|
|
1606
1689
|
const addPasskey = react.useCallback(async params => {
|
|
1607
1690
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1608
1691
|
const res = await utils.withTurnkeyErrorHandling(() => client.addPasskey(params), () => logout(), callbacks, "Failed to add passkey");
|
|
1609
|
-
if (res)
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
organizationId
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
userId
|
|
1616
|
-
|
|
1617
|
-
|
|
1692
|
+
if (res) {
|
|
1693
|
+
const updatedUser = await maybeRefreshUser({
|
|
1694
|
+
stampWith: params?.stampWith,
|
|
1695
|
+
...(params?.organizationId && {
|
|
1696
|
+
organizationId: params.organizationId
|
|
1697
|
+
}),
|
|
1698
|
+
...(params?.userId && {
|
|
1699
|
+
userId: params.userId
|
|
1700
|
+
})
|
|
1701
|
+
});
|
|
1702
|
+
await core.applyPasskeyScope(client, client.config.passkeyConfig, updatedUser, masterConfig?.auth?.scopePasskeyToUser);
|
|
1703
|
+
}
|
|
1618
1704
|
return res;
|
|
1619
|
-
}, [client, callbacks, logout, maybeRefreshUser]);
|
|
1705
|
+
}, [client, callbacks, logout, maybeRefreshUser, masterConfig?.passkeyConfig, masterConfig?.auth?.scopePasskeyToUser]);
|
|
1620
1706
|
const removePasskeys = react.useCallback(async params => {
|
|
1621
1707
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1622
1708
|
const res = await utils.withTurnkeyErrorHandling(() => client.removePasskeys(params), () => logout(), callbacks, "Failed to remove passkeys");
|
|
@@ -1724,15 +1810,20 @@ const ClientProvider = ({
|
|
|
1724
1810
|
const allSessions = await getAllSessions();
|
|
1725
1811
|
setSession(session);
|
|
1726
1812
|
setAllSessions(allSessions);
|
|
1727
|
-
await
|
|
1728
|
-
|
|
1813
|
+
const nextUser = await maybeRefreshUser();
|
|
1814
|
+
await maybeRefreshWallets();
|
|
1815
|
+
if (client) await core.applyPasskeyScope(client, client.config.passkeyConfig, nextUser, masterConfig?.auth?.scopePasskeyToUser);
|
|
1816
|
+
}, [client, callbacks, logout, getActiveSessionKey, getSession, scheduleSessionExpiration, getAllSessions, masterConfig?.passkeyConfig, masterConfig?.auth?.scopePasskeyToUser, maybeRefreshWallets, maybeRefreshUser]);
|
|
1729
1817
|
const clearAllSessions = react.useCallback(async () => {
|
|
1730
1818
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1731
1819
|
setSession(undefined);
|
|
1732
1820
|
setAllSessions(undefined);
|
|
1821
|
+
setUser(undefined);
|
|
1822
|
+
setWallets([]);
|
|
1733
1823
|
clearSessionTimeouts();
|
|
1734
|
-
|
|
1735
|
-
|
|
1824
|
+
await utils.withTurnkeyErrorHandling(() => client.clearAllSessions(), () => logout(), callbacks, "Failed to clear all sessions");
|
|
1825
|
+
await core.resetPasskeyScope(client, client.config.passkeyConfig);
|
|
1826
|
+
}, [client, callbacks, logout, clearSessionTimeouts, masterConfig?.passkeyConfig]);
|
|
1736
1827
|
const setActiveSession = react.useCallback(async params => {
|
|
1737
1828
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1738
1829
|
const session = await utils.withTurnkeyErrorHandling(() => client.getSession({
|
|
@@ -1745,10 +1836,12 @@ const ClientProvider = ({
|
|
|
1745
1836
|
await utils.withTurnkeyErrorHandling(() => client.setActiveSession(params), () => logout(), callbacks, "Failed to set active session");
|
|
1746
1837
|
setSession(session);
|
|
1747
1838
|
await utils.withTurnkeyErrorHandling(async () => {
|
|
1748
|
-
await
|
|
1839
|
+
const nextUser = await maybeRefreshUser();
|
|
1840
|
+
await maybeRefreshWallets();
|
|
1841
|
+
if (client) await core.applyPasskeyScope(client, client.config.passkeyConfig, nextUser, masterConfig?.auth?.scopePasskeyToUser);
|
|
1749
1842
|
}, () => logout(), callbacks, "Failed to refresh data after setting active session");
|
|
1750
1843
|
return;
|
|
1751
|
-
}, [client, callbacks, logout, getSession, maybeRefreshWallets, maybeRefreshUser]);
|
|
1844
|
+
}, [client, callbacks, logout, getSession, masterConfig?.passkeyConfig, masterConfig?.auth?.scopePasskeyToUser, maybeRefreshWallets, maybeRefreshUser]);
|
|
1752
1845
|
const clearUnusedKeyPairs = react.useCallback(async () => {
|
|
1753
1846
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1754
1847
|
return utils.withTurnkeyErrorHandling(() => client.clearUnusedKeyPairs(), undefined, callbacks, "Failed to clear unused key pairs");
|
|
@@ -1757,6 +1850,14 @@ const ClientProvider = ({
|
|
|
1757
1850
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1758
1851
|
return utils.withTurnkeyErrorHandling(() => client.createApiKeyPair(params), undefined, callbacks, "Failed to create API key pair");
|
|
1759
1852
|
}, [client, callbacks]);
|
|
1853
|
+
const deleteApiKeyPair = react.useCallback(async params => {
|
|
1854
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1855
|
+
return utils.withTurnkeyErrorHandling(() => client.deleteApiKeyPair(params), undefined, callbacks, "Failed to delete API key pair");
|
|
1856
|
+
}, [client, callbacks]);
|
|
1857
|
+
const signWithApiKey = react.useCallback(async params => {
|
|
1858
|
+
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1859
|
+
return utils.withTurnkeyErrorHandling(() => client.signWithApiKey(params), undefined, callbacks, "Failed to sign with API key");
|
|
1860
|
+
}, [client, callbacks]);
|
|
1760
1861
|
const getProxyAuthConfig = react.useCallback(async () => {
|
|
1761
1862
|
if (!client) throw new sdkTypes.TurnkeyError("Client is not initialized.", sdkTypes.TurnkeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
1762
1863
|
return utils.withTurnkeyErrorHandling(() => client.getProxyAuthConfig(), undefined, callbacks, "Failed to get proxy auth config");
|
|
@@ -1771,10 +1872,12 @@ const ClientProvider = ({
|
|
|
1771
1872
|
}, [client, callbacks, logout]);
|
|
1772
1873
|
const handleDiscordOauth = react.useCallback(async params => {
|
|
1773
1874
|
const {
|
|
1774
|
-
|
|
1875
|
+
primaryClientId = masterConfig?.auth?.oauthConfig?.discord?.primaryClientId,
|
|
1876
|
+
secondaryClientIds = masterConfig?.auth?.oauthConfig?.discord?.secondaryClientIds ?? [],
|
|
1775
1877
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1776
1878
|
additionalState: additionalParameters
|
|
1777
1879
|
} = params || {};
|
|
1880
|
+
const clientId = primaryClientId;
|
|
1778
1881
|
const provider = sdkTypes.OAuthProviders.DISCORD;
|
|
1779
1882
|
if (!masterConfig) {
|
|
1780
1883
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
@@ -1839,7 +1942,19 @@ const ClientProvider = ({
|
|
|
1839
1942
|
publicKey,
|
|
1840
1943
|
result,
|
|
1841
1944
|
callbacks,
|
|
1842
|
-
completeOauth
|
|
1945
|
+
completeOauth: completionParams => {
|
|
1946
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
1947
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? provider, secondaryClientIds);
|
|
1948
|
+
return completeOauth({
|
|
1949
|
+
...completionParams,
|
|
1950
|
+
...(secondaryProviders.length > 0 && {
|
|
1951
|
+
createSubOrgParams: {
|
|
1952
|
+
...existingCreateSubOrgParams,
|
|
1953
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
1954
|
+
}
|
|
1955
|
+
})
|
|
1956
|
+
});
|
|
1957
|
+
},
|
|
1843
1958
|
onOauthSuccess: params?.onOauthSuccess,
|
|
1844
1959
|
exchangeCodeForToken: async codeVerifier => {
|
|
1845
1960
|
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
@@ -1866,10 +1981,12 @@ const ClientProvider = ({
|
|
|
1866
1981
|
}, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
1867
1982
|
const handleXOauth = react.useCallback(async params => {
|
|
1868
1983
|
const {
|
|
1869
|
-
|
|
1984
|
+
primaryClientId = masterConfig?.auth?.oauthConfig?.x?.primaryClientId,
|
|
1985
|
+
secondaryClientIds = masterConfig?.auth?.oauthConfig?.x?.secondaryClientIds ?? [],
|
|
1870
1986
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1871
1987
|
additionalState: additionalParameters
|
|
1872
1988
|
} = params || {};
|
|
1989
|
+
const clientId = primaryClientId;
|
|
1873
1990
|
const provider = sdkTypes.OAuthProviders.X;
|
|
1874
1991
|
if (!masterConfig) {
|
|
1875
1992
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
@@ -1934,7 +2051,19 @@ const ClientProvider = ({
|
|
|
1934
2051
|
publicKey,
|
|
1935
2052
|
result,
|
|
1936
2053
|
callbacks,
|
|
1937
|
-
completeOauth
|
|
2054
|
+
completeOauth: completionParams => {
|
|
2055
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
2056
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? provider, secondaryClientIds);
|
|
2057
|
+
return completeOauth({
|
|
2058
|
+
...completionParams,
|
|
2059
|
+
...(secondaryProviders.length > 0 && {
|
|
2060
|
+
createSubOrgParams: {
|
|
2061
|
+
...existingCreateSubOrgParams,
|
|
2062
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
2063
|
+
}
|
|
2064
|
+
})
|
|
2065
|
+
});
|
|
2066
|
+
},
|
|
1938
2067
|
onOauthSuccess: params?.onOauthSuccess,
|
|
1939
2068
|
exchangeCodeForToken: async codeVerifier => {
|
|
1940
2069
|
const resp = await client?.httpClient.proxyOAuth2Authenticate({
|
|
@@ -1961,10 +2090,12 @@ const ClientProvider = ({
|
|
|
1961
2090
|
}, [client, callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
1962
2091
|
const handleGoogleOauth = react.useCallback(async params => {
|
|
1963
2092
|
const {
|
|
1964
|
-
|
|
2093
|
+
primaryClientId = masterConfig?.auth?.oauthConfig?.google?.primaryClientId,
|
|
2094
|
+
secondaryClientIds = masterConfig?.auth?.oauthConfig?.google?.secondaryClientIds ?? [],
|
|
1965
2095
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
1966
2096
|
additionalState: additionalParameters
|
|
1967
2097
|
} = params || {};
|
|
2098
|
+
const clientId = primaryClientId;
|
|
1968
2099
|
const provider = sdkTypes.OAuthProviders.GOOGLE;
|
|
1969
2100
|
if (!masterConfig) {
|
|
1970
2101
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
@@ -2023,7 +2154,19 @@ const ClientProvider = ({
|
|
|
2023
2154
|
publicKey,
|
|
2024
2155
|
result,
|
|
2025
2156
|
callbacks,
|
|
2026
|
-
completeOauth
|
|
2157
|
+
completeOauth: completionParams => {
|
|
2158
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
2159
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? provider, secondaryClientIds);
|
|
2160
|
+
return completeOauth({
|
|
2161
|
+
...completionParams,
|
|
2162
|
+
...(secondaryProviders.length > 0 && {
|
|
2163
|
+
createSubOrgParams: {
|
|
2164
|
+
...existingCreateSubOrgParams,
|
|
2165
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
2166
|
+
}
|
|
2167
|
+
})
|
|
2168
|
+
});
|
|
2169
|
+
},
|
|
2027
2170
|
onOauthSuccess: params?.onOauthSuccess
|
|
2028
2171
|
}).then(() => resolve()).catch(reject);
|
|
2029
2172
|
}
|
|
@@ -2039,10 +2182,12 @@ const ClientProvider = ({
|
|
|
2039
2182
|
}, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
2040
2183
|
const handleAppleOauth = react.useCallback(async params => {
|
|
2041
2184
|
const {
|
|
2042
|
-
|
|
2185
|
+
primaryClientId = masterConfig?.auth?.oauthConfig?.apple?.primaryClientId,
|
|
2186
|
+
secondaryClientIds = masterConfig?.auth?.oauthConfig?.apple?.secondaryClientIds ?? [],
|
|
2043
2187
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
2044
2188
|
additionalState: additionalParameters
|
|
2045
2189
|
} = params || {};
|
|
2190
|
+
const clientId = primaryClientId;
|
|
2046
2191
|
const provider = sdkTypes.OAuthProviders.APPLE;
|
|
2047
2192
|
if (!masterConfig) {
|
|
2048
2193
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
@@ -2101,7 +2246,19 @@ const ClientProvider = ({
|
|
|
2101
2246
|
publicKey,
|
|
2102
2247
|
result,
|
|
2103
2248
|
callbacks,
|
|
2104
|
-
completeOauth
|
|
2249
|
+
completeOauth: completionParams => {
|
|
2250
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
2251
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? provider, secondaryClientIds);
|
|
2252
|
+
return completeOauth({
|
|
2253
|
+
...completionParams,
|
|
2254
|
+
...(secondaryProviders.length > 0 && {
|
|
2255
|
+
createSubOrgParams: {
|
|
2256
|
+
...existingCreateSubOrgParams,
|
|
2257
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
2258
|
+
}
|
|
2259
|
+
})
|
|
2260
|
+
});
|
|
2261
|
+
},
|
|
2105
2262
|
onOauthSuccess: params?.onOauthSuccess
|
|
2106
2263
|
}).then(() => resolve()).catch(reject);
|
|
2107
2264
|
}
|
|
@@ -2117,10 +2274,12 @@ const ClientProvider = ({
|
|
|
2117
2274
|
}, [callbacks, completeOauth, createApiKeyPair, masterConfig]);
|
|
2118
2275
|
const handleFacebookOauth = react.useCallback(async params => {
|
|
2119
2276
|
const {
|
|
2120
|
-
|
|
2277
|
+
primaryClientId = masterConfig?.auth?.oauthConfig?.facebook?.primaryClientId,
|
|
2278
|
+
secondaryClientIds = masterConfig?.auth?.oauthConfig?.facebook?.secondaryClientIds ?? [],
|
|
2121
2279
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false,
|
|
2122
2280
|
additionalState: additionalParameters
|
|
2123
2281
|
} = params || {};
|
|
2282
|
+
const clientId = primaryClientId;
|
|
2124
2283
|
const provider = sdkTypes.OAuthProviders.FACEBOOK;
|
|
2125
2284
|
if (!masterConfig) {
|
|
2126
2285
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.INVALID_CONFIGURATION);
|
|
@@ -2185,7 +2344,19 @@ const ClientProvider = ({
|
|
|
2185
2344
|
publicKey,
|
|
2186
2345
|
result,
|
|
2187
2346
|
callbacks,
|
|
2188
|
-
completeOauth
|
|
2347
|
+
completeOauth: completionParams => {
|
|
2348
|
+
const existingCreateSubOrgParams = masterConfig?.auth?.createSuborgParams?.oauth;
|
|
2349
|
+
const secondaryProviders = core.buildSecondaryOauthProviders(completionParams.oidcToken, completionParams.providerName ?? provider, secondaryClientIds);
|
|
2350
|
+
return completeOauth({
|
|
2351
|
+
...completionParams,
|
|
2352
|
+
...(secondaryProviders.length > 0 && {
|
|
2353
|
+
createSubOrgParams: {
|
|
2354
|
+
...existingCreateSubOrgParams,
|
|
2355
|
+
oauthProviders: [...(existingCreateSubOrgParams?.oauthProviders ?? []), ...secondaryProviders]
|
|
2356
|
+
}
|
|
2357
|
+
})
|
|
2358
|
+
});
|
|
2359
|
+
},
|
|
2189
2360
|
onOauthSuccess: params?.onOauthSuccess,
|
|
2190
2361
|
exchangeCodeForToken: async codeVerifier => {
|
|
2191
2362
|
const tokenData = await pkce.exchangeFacebookCodeForToken(clientId, redirectUri, result.authCode, codeVerifier);
|
|
@@ -2489,9 +2660,6 @@ const ClientProvider = ({
|
|
|
2489
2660
|
if (!masterConfig) {
|
|
2490
2661
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
2491
2662
|
}
|
|
2492
|
-
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
2493
|
-
throw new sdkTypes.TurnkeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
2494
|
-
}
|
|
2495
2663
|
const s = await getSession();
|
|
2496
2664
|
const organizationId = params?.organizationId || s?.organizationId;
|
|
2497
2665
|
if (!organizationId) {
|
|
@@ -2541,7 +2709,10 @@ const ClientProvider = ({
|
|
|
2541
2709
|
});
|
|
2542
2710
|
}), () => logout());
|
|
2543
2711
|
} else {
|
|
2544
|
-
const
|
|
2712
|
+
const {
|
|
2713
|
+
otpId,
|
|
2714
|
+
otpEncryptionTargetBundle
|
|
2715
|
+
} = await initOtp({
|
|
2545
2716
|
otpType: core.OtpType.Sms,
|
|
2546
2717
|
contact: params.phoneNumber
|
|
2547
2718
|
});
|
|
@@ -2552,6 +2723,7 @@ const ClientProvider = ({
|
|
|
2552
2723
|
otpType: core.OtpType.Sms,
|
|
2553
2724
|
contact: params.phoneNumber,
|
|
2554
2725
|
otpId: otpId,
|
|
2726
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2555
2727
|
otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2556
2728
|
alphanumeric: masterConfig.auth?.otpAlphanumeric,
|
|
2557
2729
|
onContinue: async otpCode => {
|
|
@@ -2561,8 +2733,7 @@ const ClientProvider = ({
|
|
|
2561
2733
|
} = await verifyOtp({
|
|
2562
2734
|
otpId,
|
|
2563
2735
|
otpCode,
|
|
2564
|
-
|
|
2565
|
-
otpType: core.OtpType.Sms
|
|
2736
|
+
otpEncryptionTargetBundle
|
|
2566
2737
|
});
|
|
2567
2738
|
const res = await updateUserPhoneNumber({
|
|
2568
2739
|
phoneNumber: params.phoneNumber,
|
|
@@ -2659,7 +2830,10 @@ const ClientProvider = ({
|
|
|
2659
2830
|
});
|
|
2660
2831
|
}), () => logout());
|
|
2661
2832
|
} else {
|
|
2662
|
-
const
|
|
2833
|
+
const {
|
|
2834
|
+
otpId,
|
|
2835
|
+
otpEncryptionTargetBundle
|
|
2836
|
+
} = await initOtp({
|
|
2663
2837
|
otpType: core.OtpType.Email,
|
|
2664
2838
|
contact: params.email
|
|
2665
2839
|
});
|
|
@@ -2670,6 +2844,7 @@ const ClientProvider = ({
|
|
|
2670
2844
|
otpType: core.OtpType.Email,
|
|
2671
2845
|
contact: params.email,
|
|
2672
2846
|
otpId: otpId,
|
|
2847
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2673
2848
|
otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2674
2849
|
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2675
2850
|
onContinue: async otpCode => {
|
|
@@ -2679,8 +2854,7 @@ const ClientProvider = ({
|
|
|
2679
2854
|
} = await verifyOtp({
|
|
2680
2855
|
otpId,
|
|
2681
2856
|
otpCode,
|
|
2682
|
-
|
|
2683
|
-
otpType: core.OtpType.Email
|
|
2857
|
+
otpEncryptionTargetBundle
|
|
2684
2858
|
});
|
|
2685
2859
|
const res = await updateUserEmail({
|
|
2686
2860
|
email: params.email,
|
|
@@ -2774,7 +2948,10 @@ const ClientProvider = ({
|
|
|
2774
2948
|
});
|
|
2775
2949
|
}), () => logout());
|
|
2776
2950
|
} else {
|
|
2777
|
-
const
|
|
2951
|
+
const {
|
|
2952
|
+
otpId,
|
|
2953
|
+
otpEncryptionTargetBundle
|
|
2954
|
+
} = await initOtp({
|
|
2778
2955
|
otpType: core.OtpType.Email,
|
|
2779
2956
|
contact: params.email
|
|
2780
2957
|
});
|
|
@@ -2785,6 +2962,7 @@ const ClientProvider = ({
|
|
|
2785
2962
|
otpType: core.OtpType.Email,
|
|
2786
2963
|
contact: params.email,
|
|
2787
2964
|
otpId: otpId,
|
|
2965
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2788
2966
|
otpLength: masterConfig?.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2789
2967
|
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2790
2968
|
onContinue: async otpCode => {
|
|
@@ -2794,8 +2972,7 @@ const ClientProvider = ({
|
|
|
2794
2972
|
} = await verifyOtp({
|
|
2795
2973
|
otpId,
|
|
2796
2974
|
otpCode,
|
|
2797
|
-
|
|
2798
|
-
otpType: core.OtpType.Email
|
|
2975
|
+
otpEncryptionTargetBundle
|
|
2799
2976
|
});
|
|
2800
2977
|
const res = await updateUserEmail({
|
|
2801
2978
|
email: params.email,
|
|
@@ -2839,9 +3016,6 @@ const ClientProvider = ({
|
|
|
2839
3016
|
if (!masterConfig) {
|
|
2840
3017
|
throw new sdkTypes.TurnkeyError("Config is not ready yet!", sdkTypes.TurnkeyErrorCodes.CONFIG_NOT_INITIALIZED);
|
|
2841
3018
|
}
|
|
2842
|
-
if (!masterConfig.auth?.methods?.smsOtpAuthEnabled) {
|
|
2843
|
-
throw new sdkTypes.TurnkeyError("SMS OTP authentication is not enabled in the configuration.", sdkTypes.TurnkeyErrorCodes.AUTH_METHOD_NOT_ENABLED);
|
|
2844
|
-
}
|
|
2845
3019
|
const s = await getSession();
|
|
2846
3020
|
const organizationId = params?.organizationId || s?.organizationId;
|
|
2847
3021
|
if (!organizationId) {
|
|
@@ -2893,7 +3067,10 @@ const ClientProvider = ({
|
|
|
2893
3067
|
});
|
|
2894
3068
|
}), () => logout(), callbacks, "Failed to add phone number");
|
|
2895
3069
|
} else {
|
|
2896
|
-
const
|
|
3070
|
+
const {
|
|
3071
|
+
otpId,
|
|
3072
|
+
otpEncryptionTargetBundle
|
|
3073
|
+
} = await initOtp({
|
|
2897
3074
|
otpType: core.OtpType.Sms,
|
|
2898
3075
|
contact: params.phoneNumber
|
|
2899
3076
|
});
|
|
@@ -2904,6 +3081,7 @@ const ClientProvider = ({
|
|
|
2904
3081
|
otpType: core.OtpType.Sms,
|
|
2905
3082
|
contact: params.phoneNumber,
|
|
2906
3083
|
otpId: otpId,
|
|
3084
|
+
otpEncryptionTargetBundle: otpEncryptionTargetBundle,
|
|
2907
3085
|
otpLength: masterConfig.auth?.otpLength !== undefined ? Number(masterConfig.auth.otpLength) : undefined,
|
|
2908
3086
|
alphanumeric: masterConfig?.auth?.otpAlphanumeric,
|
|
2909
3087
|
onContinue: async otpCode => {
|
|
@@ -2913,8 +3091,7 @@ const ClientProvider = ({
|
|
|
2913
3091
|
} = await verifyOtp({
|
|
2914
3092
|
otpId,
|
|
2915
3093
|
otpCode,
|
|
2916
|
-
|
|
2917
|
-
otpType: core.OtpType.Sms
|
|
3094
|
+
otpEncryptionTargetBundle
|
|
2918
3095
|
});
|
|
2919
3096
|
const res = await updateUserPhoneNumber({
|
|
2920
3097
|
phoneNumber: params.phoneNumber,
|
|
@@ -3107,6 +3284,29 @@ const ClientProvider = ({
|
|
|
3107
3284
|
successPageDuration = 2000,
|
|
3108
3285
|
openInPage = masterConfig?.auth?.oauthConfig?.openOauthInPage ?? false
|
|
3109
3286
|
} = params;
|
|
3287
|
+
// Resolve the provider's per-provider config, then apply per-call overrides.
|
|
3288
|
+
let providerConfig;
|
|
3289
|
+
switch (providerName) {
|
|
3290
|
+
case sdkTypes.OAuthProviders.DISCORD:
|
|
3291
|
+
providerConfig = masterConfig?.auth?.oauthConfig?.discord;
|
|
3292
|
+
break;
|
|
3293
|
+
case sdkTypes.OAuthProviders.X:
|
|
3294
|
+
providerConfig = masterConfig?.auth?.oauthConfig?.x;
|
|
3295
|
+
break;
|
|
3296
|
+
case sdkTypes.OAuthProviders.GOOGLE:
|
|
3297
|
+
providerConfig = masterConfig?.auth?.oauthConfig?.google;
|
|
3298
|
+
break;
|
|
3299
|
+
case sdkTypes.OAuthProviders.APPLE:
|
|
3300
|
+
providerConfig = masterConfig?.auth?.oauthConfig?.apple;
|
|
3301
|
+
break;
|
|
3302
|
+
case sdkTypes.OAuthProviders.FACEBOOK:
|
|
3303
|
+
providerConfig = masterConfig?.auth?.oauthConfig?.facebook;
|
|
3304
|
+
break;
|
|
3305
|
+
default:
|
|
3306
|
+
providerConfig = undefined;
|
|
3307
|
+
}
|
|
3308
|
+
const primaryClientId = params.primaryClientId ?? providerConfig?.primaryClientId;
|
|
3309
|
+
const secondaryClientIds = params.secondaryClientIds ?? providerConfig?.secondaryClientIds ?? [];
|
|
3110
3310
|
const s = await getSession();
|
|
3111
3311
|
const organizationId = params?.organizationId || s?.organizationId;
|
|
3112
3312
|
if (!organizationId) {
|
|
@@ -3119,9 +3319,13 @@ const ClientProvider = ({
|
|
|
3119
3319
|
return new Promise(async (resolve, reject) => {
|
|
3120
3320
|
try {
|
|
3121
3321
|
const onOauthSuccess = async params => {
|
|
3322
|
+
const oidcClaims = core.buildSecondaryOidcClaims(params.oidcToken, secondaryClientIds);
|
|
3122
3323
|
await addOauthProvider({
|
|
3123
3324
|
providerName: params.providerName,
|
|
3124
3325
|
oidcToken: params.oidcToken,
|
|
3326
|
+
...(oidcClaims.length > 0 && {
|
|
3327
|
+
oidcClaims
|
|
3328
|
+
}),
|
|
3125
3329
|
stampWith,
|
|
3126
3330
|
organizationId,
|
|
3127
3331
|
userId
|
|
@@ -3156,66 +3360,42 @@ const ClientProvider = ({
|
|
|
3156
3360
|
openModal: "true"
|
|
3157
3361
|
})
|
|
3158
3362
|
} : undefined;
|
|
3363
|
+
// Forward overrides so the inner handler uses the same client IDs.
|
|
3364
|
+
const sharedOauthParams = {
|
|
3365
|
+
openInPage,
|
|
3366
|
+
...(primaryClientId && {
|
|
3367
|
+
primaryClientId
|
|
3368
|
+
}),
|
|
3369
|
+
...(secondaryClientIds.length > 0 && {
|
|
3370
|
+
secondaryClientIds
|
|
3371
|
+
}),
|
|
3372
|
+
...(additionalState && {
|
|
3373
|
+
additionalState
|
|
3374
|
+
}),
|
|
3375
|
+
...(!openInPage && {
|
|
3376
|
+
onOauthSuccess
|
|
3377
|
+
})
|
|
3378
|
+
};
|
|
3159
3379
|
switch (providerName) {
|
|
3160
3380
|
case sdkTypes.OAuthProviders.DISCORD:
|
|
3161
3381
|
{
|
|
3162
|
-
return await handleDiscordOauth(
|
|
3163
|
-
openInPage,
|
|
3164
|
-
...(additionalState && {
|
|
3165
|
-
additionalState
|
|
3166
|
-
}),
|
|
3167
|
-
...(!openInPage && {
|
|
3168
|
-
onOauthSuccess
|
|
3169
|
-
})
|
|
3170
|
-
});
|
|
3382
|
+
return await handleDiscordOauth(sharedOauthParams);
|
|
3171
3383
|
}
|
|
3172
3384
|
case sdkTypes.OAuthProviders.X:
|
|
3173
3385
|
{
|
|
3174
|
-
return await handleXOauth(
|
|
3175
|
-
openInPage,
|
|
3176
|
-
...(additionalState && {
|
|
3177
|
-
additionalState
|
|
3178
|
-
}),
|
|
3179
|
-
...(!openInPage && {
|
|
3180
|
-
onOauthSuccess
|
|
3181
|
-
})
|
|
3182
|
-
});
|
|
3386
|
+
return await handleXOauth(sharedOauthParams);
|
|
3183
3387
|
}
|
|
3184
3388
|
case sdkTypes.OAuthProviders.GOOGLE:
|
|
3185
3389
|
{
|
|
3186
|
-
return await handleGoogleOauth(
|
|
3187
|
-
openInPage,
|
|
3188
|
-
...(additionalState && {
|
|
3189
|
-
additionalState
|
|
3190
|
-
}),
|
|
3191
|
-
...(!openInPage && {
|
|
3192
|
-
onOauthSuccess
|
|
3193
|
-
})
|
|
3194
|
-
});
|
|
3390
|
+
return await handleGoogleOauth(sharedOauthParams);
|
|
3195
3391
|
}
|
|
3196
3392
|
case sdkTypes.OAuthProviders.APPLE:
|
|
3197
3393
|
{
|
|
3198
|
-
return await handleAppleOauth(
|
|
3199
|
-
openInPage,
|
|
3200
|
-
...(additionalState && {
|
|
3201
|
-
additionalState
|
|
3202
|
-
}),
|
|
3203
|
-
...(!openInPage && {
|
|
3204
|
-
onOauthSuccess
|
|
3205
|
-
})
|
|
3206
|
-
});
|
|
3394
|
+
return await handleAppleOauth(sharedOauthParams);
|
|
3207
3395
|
}
|
|
3208
3396
|
case sdkTypes.OAuthProviders.FACEBOOK:
|
|
3209
3397
|
{
|
|
3210
|
-
return await handleFacebookOauth(
|
|
3211
|
-
openInPage,
|
|
3212
|
-
...(additionalState && {
|
|
3213
|
-
additionalState
|
|
3214
|
-
}),
|
|
3215
|
-
...(!openInPage && {
|
|
3216
|
-
onOauthSuccess
|
|
3217
|
-
})
|
|
3218
|
-
});
|
|
3398
|
+
return await handleFacebookOauth(sharedOauthParams);
|
|
3219
3399
|
}
|
|
3220
3400
|
default:
|
|
3221
3401
|
{
|
|
@@ -3379,7 +3559,7 @@ const ClientProvider = ({
|
|
|
3379
3559
|
const tx = {
|
|
3380
3560
|
from,
|
|
3381
3561
|
to,
|
|
3382
|
-
caip2,
|
|
3562
|
+
caip2: caip2,
|
|
3383
3563
|
sponsor: sponsor ?? false,
|
|
3384
3564
|
...(value ? {
|
|
3385
3565
|
value
|
|
@@ -3812,6 +3992,8 @@ const ClientProvider = ({
|
|
|
3812
3992
|
config: masterConfig,
|
|
3813
3993
|
httpClient: client?.httpClient,
|
|
3814
3994
|
createHttpClient,
|
|
3995
|
+
overrideApiKeyStamper,
|
|
3996
|
+
overridePasskeyStamper,
|
|
3815
3997
|
createPasskey,
|
|
3816
3998
|
logout,
|
|
3817
3999
|
loginWithPasskey,
|
|
@@ -3874,6 +4056,8 @@ const ClientProvider = ({
|
|
|
3874
4056
|
clearUnusedKeyPairs,
|
|
3875
4057
|
getActiveSessionKey,
|
|
3876
4058
|
createApiKeyPair,
|
|
4059
|
+
deleteApiKeyPair,
|
|
4060
|
+
signWithApiKey,
|
|
3877
4061
|
getProxyAuthConfig,
|
|
3878
4062
|
fetchBootProofForAppProof,
|
|
3879
4063
|
verifyAppProofs,
|